summaryrefslogtreecommitdiff
path: root/src/regress/lib/libcrypto/test/test.h
blob: 1c8391d4eca25e594bfc4950b79d34fd50f279c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*	$OpenBSD: test.h,v 1.4 2025/05/31 11:37:18 tb Exp $ */
/*
 * Copyright (c) 2025 Joshua Sing <joshua@joshuasing.dev>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef HEADER_TEST_H
#define HEADER_TEST_H

#include <stddef.h>
#include <stdint.h>

struct test;

/*
 * test_init creates a new root test struct.
 *
 * Additional tests may be run under the root test struct by calling test_run.
 *
 * If the TEST_VERBOSE environment variable is set and not equal to "0", then
 * verbose mode will be enabled and all test logs will be written to stderr.
 */
struct test *test_init(void);

/*
 * test_result cleans up after all tests have completed and returns an
 * appropriate exit code indicating the result of the tests.
 */
int test_result(struct test *_t);

/*
 * test_run_func is an individual test function. It is passed the test struct
 * and an arbitrary argument which may be passed when test_run is called.
 */
typedef void (test_run_func)(struct test *_t, const void *_arg);

/*
 * test_fail marks the test and its parents as failed.
 */
void test_fail(struct test *_t);

/*
 * test_printf prints a test log message. When in verbose mode, the log message
 * will be written to stderr, otherwise it will be buffered and only written to
 * stderr if the test fails.
 *
 * This printf will write directly, without any additional formatting.
 */
void test_printf(struct test *_t, const char *_fmt, ...)
    __attribute__((__format__ (printf, 2, 3)))
    __attribute__((__nonnull__ (2)));

/*
 * test_logf_internal prints a test log message. When in verbose mode, the
 * log message will be written to stderr, otherwise it will be buffered and
 * only written to stderr if the test fails.
 *
 * label is an optional label indicating the severity of the log.
 * func, file and line are used to show where the log comes from and are
 * automatically set in the test log macros.
 *
 * This function should never be called directly.
 */
void test_logf_internal(struct test *_t, const char *_label, const char *_func,
    const char *_file, int _line, const char *_fmt, ...)
    __attribute__((__format__ (printf, 6, 7)))
    __attribute__((__nonnull__ (6)));

/*
 * test_logf prints an informational log message. When in verbose mode, the log
 * will be written to stderr, otherwise it will be buffered and only written to
 * stderr if the test fails.
 */
#define test_logf(t, fmt, ...) \
    do { \
	test_logf_internal(t, NULL, __func__, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \
    } while (0)

/*
 * test_errorf prints an error message. It will also cause the test to fail.
 * If the test cannot proceed, it is recommended to return or goto a cleanup
 * label.
 *
 * Tests should not fail-fast if continuing will provide more detailed
 * information about what is broken.
 */
#define test_errorf(t, fmt, ...) \
    do { \
	test_logf_internal(t, "ERROR", __func__, __FILE__, __LINE__, fmt, ##__VA_ARGS__); \
	test_fail(t); \
    } while (0)

/*
 * test_skip marks the test as skipped. Once called, the test should return.
 */
void test_skip(struct test *_t, const char *_reason);

/*
 * test_skipf marks the test as skipped with a formatted reason. Once called,
 * the test should return.
 */
void test_skipf(struct test *_t, const char *_fmt, ...)
    __attribute__((__format__ (printf, 2, 3)))
    __attribute__((__nonnull__ (2)));

/*
 * test_run runs a test function. It will create a new test struct with the
 * given test as the parent. An argument may be provided to pass data to the
 * test function, otherwise NULL should be passed.
 *
 * Each test should have a unique and informational name.
 */
void test_run(struct test *_t, const char *_name, test_run_func *_fn, const void *_arg);

/*
 * test_hexdump prints the given data as hexadecimal.
 */
void test_hexdump(struct test *_t, const unsigned char *_buf, size_t _len);

/*
 * test_hexdiff prints the given data as hexadecimal. If a second comparison
 * buffer is not NULL, any differing bytes will be marked with an astrix.
 */
void test_hexdiff(struct test *_t, const uint8_t *_buf, size_t _len, const uint8_t *_compare);

#endif /* HEADER_TEST_H */