1148459Spjd/*
2148459Spjd * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved.
3148459Spjd *
4148459Spjd * Licensed under the Apache License 2.0 (the "License").  You may not use
5148459Spjd * this file except in compliance with the License.  You can obtain a copy
6148459Spjd * in the file LICENSE in the source distribution or at
7148459Spjd * https://www.openssl.org/source/license.html
8148459Spjd */
9148459Spjd
10148459Spjd#include <openssl/trace.h>
11148459Spjd
12148459Spjd#include "testutil.h"
13148459Spjd
14182452Spjdstatic int test_trace_categories(void)
15148459Spjd{
16148459Spjd    int cat_num;
17148459Spjd
18148459Spjd    for (cat_num = -1; cat_num <= OSSL_TRACE_CATEGORY_NUM + 1; ++cat_num) {
19148459Spjd        const char *cat_name = OSSL_trace_get_category_name(cat_num);
20148459Spjd        int is_cat_name_eq = 0;
21148459Spjd        int ret_cat_num;
22148459Spjd        int expected_ret;
23148459Spjd
24148459Spjd        switch (cat_num) {
25148459Spjd#define CASE(name) \
26148459Spjd        case OSSL_TRACE_CATEGORY_##name: \
27148459Spjd            is_cat_name_eq = TEST_str_eq(cat_name, #name); \
28148459Spjd            break
29148459Spjd
30148459Spjd        CASE(ALL);
31148459Spjd        CASE(TRACE);
32148459Spjd        CASE(INIT);
33148459Spjd        CASE(TLS);
34148459Spjd        CASE(TLS_CIPHER);
35148459Spjd        CASE(CONF);
36148459Spjd        CASE(ENGINE_TABLE);
37148459Spjd        CASE(ENGINE_REF_COUNT);
38148459Spjd        CASE(PKCS5V2);
39        CASE(PKCS12_KEYGEN);
40        CASE(PKCS12_DECRYPT);
41        CASE(X509V3_POLICY);
42        CASE(BN_CTX);
43        CASE(CMP);
44        CASE(STORE);
45        CASE(DECODER);
46        CASE(ENCODER);
47        CASE(REF_COUNT);
48#undef CASE
49        default:
50            is_cat_name_eq = TEST_ptr_null(cat_name);
51            break;
52        }
53
54        if (!TEST_true(is_cat_name_eq))
55            return 0;
56        ret_cat_num =
57            OSSL_trace_get_category_num(cat_name);
58        expected_ret = cat_name != NULL ? cat_num : -1;
59        if (!TEST_int_eq(expected_ret, ret_cat_num))
60            return 0;
61    }
62
63    return 1;
64}
65
66#ifndef OPENSSL_NO_TRACE
67static void put_trace_output(void)
68{
69    OSSL_TRACE_BEGIN(REF_COUNT) {
70        BIO_printf(trc_out, "Hello World\n");
71        BIO_printf(trc_out, "Good Bye Universe\n");
72    } OSSL_TRACE_END(REF_COUNT);
73}
74
75static int test_trace_channel(void)
76{
77    static const char expected[] = "xyz-\nHello World\nGood Bye Universe\n-abc\n";
78    static const char expected_len = sizeof(expected) - 1;
79    BIO *bio = NULL;
80    char *p_buf = NULL;
81    long len = 0;
82    int ret = 0;
83
84    bio = BIO_new(BIO_s_mem());
85    if (!TEST_ptr(bio))
86        goto end;
87
88    if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_REF_COUNT, bio), 1))
89        goto end;
90
91    if (!TEST_true(OSSL_trace_enabled(OSSL_TRACE_CATEGORY_REF_COUNT)))
92        goto end;
93
94    if (!TEST_int_eq(OSSL_trace_set_prefix(OSSL_TRACE_CATEGORY_REF_COUNT, "xyz-"), 1))
95        goto end;
96    if (!TEST_int_eq(OSSL_trace_set_suffix(OSSL_TRACE_CATEGORY_REF_COUNT, "-abc"), 1))
97        goto end;
98
99    put_trace_output();
100    len = BIO_get_mem_data(bio, &p_buf);
101    if (!TEST_strn2_eq(p_buf, len, expected, expected_len))
102        goto end;
103    if (!TEST_int_eq(OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_REF_COUNT, NULL), 1))
104        goto end;
105    bio = NULL;
106
107    ret = 1;
108 end:
109    BIO_free(bio);
110    return ret;
111}
112
113static int trace_cb_failure;
114static int trace_cb_called;
115
116static size_t trace_cb(const char *buffer, size_t count,
117                       int category, int cmd, void *data)
118{
119    trace_cb_called = 1;
120    if (!TEST_true(category == OSSL_TRACE_CATEGORY_TRACE))
121        trace_cb_failure = 1;
122    return count;
123}
124
125static int test_trace_callback(void)
126{
127    int ret = 0;
128
129    if (!TEST_true(OSSL_trace_set_callback(OSSL_TRACE_CATEGORY_TRACE, trace_cb,
130                                           NULL)))
131        goto end;
132
133    put_trace_output();
134
135    if (!TEST_false(trace_cb_failure) || !TEST_true(trace_cb_called))
136        goto end;
137
138    ret = 1;
139 end:
140    return ret;
141}
142#endif
143
144OPT_TEST_DECLARE_USAGE("\n")
145
146int setup_tests(void)
147{
148    if (!test_skip_common_options()) {
149        TEST_error("Error parsing test options\n");
150        return 0;
151    }
152
153    ADD_TEST(test_trace_categories);
154#ifndef OPENSSL_NO_TRACE
155    ADD_TEST(test_trace_channel);
156    ADD_TEST(test_trace_callback);
157#endif
158    return 1;
159}
160
161void cleanup_tests(void)
162{
163}
164