blob: 8f65e0e868f3a5305dc515721f1ca1804722270e [file] [log] [blame]
Laurence Lundblade00257182019-12-06 20:51:00 -08001/*==============================================================================
2 run_tests.c -- test aggregator and results reporting
3
Tamas Ban132c42f2020-01-07 14:57:37 +00004 Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
Laurence Lundblade00257182019-12-06 20:51:00 -08005
6 SPDX-License-Identifier: BSD-3-Clause
7
8 See BSD-3-Clause license in README.md
9
10 Created on 9/30/18
11 =============================================================================*/
12
13#include "run_tests.h"
14#include "UsefulBuf.h"
15#include <stdbool.h>
16
17#include "t_cose_test.h"
18#include "t_cose_sign_verify_test.h"
19
20
21/*
22 Test configuration
23 */
24
25typedef int (test_fun_t)(void);
26typedef const char * (test_fun2_t)(void);
27
28
29#define TEST_ENTRY(test_name) {#test_name, test_name, true}
30#define TEST_ENTRY_DISABLED(test_name) {#test_name, test_name, false}
31
32typedef struct {
33 const char *szTestName;
34 test_fun_t *test_fun;
35 bool bEnabled;
36} test_entry;
37
38#ifdef STRING_RETURNING_TESTS
39typedef struct {
40 const char *szTestName;
41 test_fun2_t *test_fun;
42 bool bEnabled;
43} test_entry2;
44
45
46static test_entry2 s_tests2[] = {
47};
48#endif
49
50static test_entry s_tests[] = {
51#ifndef T_COSE_DISABLE_SIGN_VERIFY_TESTS
52 /* Many tests can be run without a crypto library integration and provide
53 * good test coverage of everything but the signing and verification. These
54 * tests can't be run with signing and verification short circuited */
55 TEST_ENTRY(sign_verify_basic_test),
56 TEST_ENTRY(sign_verify_make_cwt_test),
57 TEST_ENTRY(sign_verify_sig_fail_test),
58 TEST_ENTRY(sign_verify_get_size_test),
59#endif
60 TEST_ENTRY(sign1_structure_decode_test),
61 TEST_ENTRY(content_type_test),
62 TEST_ENTRY(all_header_parameters_test),
63 TEST_ENTRY(cose_example_test),
64 TEST_ENTRY(crit_parameters_test),
65 TEST_ENTRY(bad_parameters_test),
66 TEST_ENTRY(short_circuit_decode_only_test),
67 TEST_ENTRY(short_circuit_make_cwt_test),
68 TEST_ENTRY(short_circuit_signing_error_conditions_test),
69 TEST_ENTRY(short_circuit_verify_fail_test),
70 TEST_ENTRY(short_circuit_self_test),
71
72#ifdef T_COSE_ENABLE_HASH_FAIL_TEST
73 TEST_ENTRY(short_circuit_hash_fail_test),
74#endif /* T_COSE_DISABLE_HASH_FAIL_TEST */
75};
76
77
78
79/**
80 \brief Convert number to ASCII string, similar to sprint
81
82 \param [in] nNum The 32-bit integer to convert.
83 \param [in] StringMem The buffer to output to.
84
85 \return POinter to NULL-terminated string with result or "XXX" on failure.
86
87 Convert a number up to 999999999 to a string. This is so sprintf doesn't
88 have to be linked in so as to minimized dependencies even in test code.
89
90 StringMem should be 12 bytes long, 9 for digits, 1 for minus and
91 1 for \0 termination.
92 */
93static const char *NumToString(int32_t nNum, UsefulBuf StringMem)
94{
95 const int32_t nMax = 1000000000;
96
97 UsefulOutBuf OutBuf;
98 UsefulOutBuf_Init(&OutBuf, StringMem);
99
100 if(nNum < 0) {
101 UsefulOutBuf_AppendByte(&OutBuf, '-');
102 nNum = -nNum;
103 }
104 if(nNum > nMax-1) {
105 return "XXX";
106 }
107
108 bool bDidSomeOutput = false;
109 for(int n = nMax; n > 0; n/=10) {
110 int x = nNum/n;
111 if(x || bDidSomeOutput){
112 bDidSomeOutput = true;
113 UsefulOutBuf_AppendByte(&OutBuf, '0' + x);
114 nNum -= x * n;
115 }
116 }
117 if(!bDidSomeOutput){
118 UsefulOutBuf_AppendByte(&OutBuf, '0');
119 }
120 UsefulOutBuf_AppendByte(&OutBuf, '\0');
121
122 return UsefulOutBuf_GetError(&OutBuf) ? "" : StringMem.ptr;
123}
124
125
126/*
127 Public function. See run_test.h.
128 */
Tamas Ban132c42f2020-01-07 14:57:37 +0000129int RunTestsTCose(const char *szTestNames[],
130 OutputStringCB pfOutput,
131 void *poutCtx,
132 int *pNumTestsRun)
Laurence Lundblade00257182019-12-06 20:51:00 -0800133{
134 int nTestsFailed = 0;
135 int nTestsRun = 0;
136 UsefulBuf_MAKE_STACK_UB(StringStorage, 12);
137
138#ifdef STRING_RETURNING_TESTS
139
140 test_entry2 *t2;
141 const test_entry2 *s_tests2_end = s_tests2 + sizeof(s_tests2)/sizeof(test_entry2);
142
143 for(t2 = s_tests2; t2 < s_tests2_end; t2++) {
144 if(szTestNames[0]) {
145 // Some tests have been named
146 const char **szRequestedNames;
147 for(szRequestedNames = szTestNames; *szRequestedNames; szRequestedNames++) {
148 if(!strcmp(t2->szTestName, *szRequestedNames)) {
149 break; // Name matched
150 }
151 }
152 if(*szRequestedNames == NULL) {
153 // Didn't match this test
154 continue;
155 }
156 } else {
157 // no tests named, but don't run "disabled" tests
158 if(!t2->bEnabled) {
159 // Don't run disabled tests when all tests are being run
160 // as indicated by no specific test names being given
161 continue;
162 }
163 }
164 const char * szTestResult = (t2->test_fun)();
165 nTestsRun++;
166 if(pfOutput) {
167 (*pfOutput)(t2->szTestName, poutCtx, 0);
168 }
169
170 if(szTestResult) {
171 if(pfOutput) {
172 (*pfOutput)(" FAILED (returned ", poutCtx, 0);
173 (*pfOutput)(szTestResult, poutCtx, 0);
174 (*pfOutput)(")", poutCtx, 1);
175 }
176 nTestsFailed++;
177 } else {
178 if(pfOutput) {
179 (*pfOutput)( " PASSED", poutCtx, 1);
180 }
181 }
182 }
183#endif
184
185
186 test_entry *t;
187 const test_entry *s_tests_end = s_tests + sizeof(s_tests)/sizeof(test_entry);
188
189 for(t = s_tests; t < s_tests_end; t++) {
190 if(szTestNames[0]) {
191 // Some tests have been named
192 const char **szRequestedNames;
193 for(szRequestedNames = szTestNames; *szRequestedNames; szRequestedNames++) {
194 if(!strcmp(t->szTestName, *szRequestedNames)) {
195 break; // Name matched
196 }
197 }
198 if(*szRequestedNames == NULL) {
199 // Didn't match this test
200 continue;
201 }
202 } else {
203 // no tests named, but don't run "disabled" tests
204 if(!t->bEnabled) {
205 // Don't run disabled tests when all tests are being run
206 // as indicated by no specific test names being given
207 continue;
208 }
209 }
210
211 int nTestResult = (t->test_fun)();
212 nTestsRun++;
213 if(pfOutput) {
214 (*pfOutput)(t->szTestName, poutCtx, 0);
215 }
216
217 if(nTestResult) {
218 if(pfOutput) {
219 (*pfOutput)(" FAILED (returned ", poutCtx, 0);
220 (*pfOutput)(NumToString(nTestResult, StringStorage), poutCtx, 0);
221 (*pfOutput)(")", poutCtx, 1);
222 }
223 nTestsFailed++;
224 } else {
225 if(pfOutput) {
226 (*pfOutput)( " PASSED", poutCtx, 1);
227 }
228 }
229 }
230
231 if(pNumTestsRun) {
232 *pNumTestsRun = nTestsRun;
233 }
234
235 if(pfOutput) {
236 (*pfOutput)( "SUMMARY: ", poutCtx, 0);
237 (*pfOutput)( NumToString(nTestsRun, StringStorage), poutCtx, 0);
238 (*pfOutput)( " tests run; ", poutCtx, 0);
239 (*pfOutput)( NumToString(nTestsFailed, StringStorage), poutCtx, 0);
240 (*pfOutput)( " tests failed", poutCtx, 1);
241 }
242
243 return nTestsFailed;
244}
245
246
247/*
248 Public function. See run_test.h.
249 */
250static void PrintSize(const char *szWhat,
251 uint32_t uSize,
252 OutputStringCB pfOutput,
253 void *pOutCtx)
254{
255 UsefulBuf_MAKE_STACK_UB(buffer, 20);
256
257 (*pfOutput)(szWhat, pOutCtx, 0);
258 (*pfOutput)(" ", pOutCtx, 0);
259 (*pfOutput)(NumToString(uSize, buffer), pOutCtx, 0);
260 (*pfOutput)("", pOutCtx, 1);
261}
262
263
264
265
266#include "t_cose_sign1_sign.h" /* For struct size printing */
267#include "t_cose_sign1_verify.h" /* For struct size printing */
268#include "t_cose_crypto.h" /* For struct size printing */
269
270
271/*
272 Public function. See run_test.h.
273 */
Tamas Ban132c42f2020-01-07 14:57:37 +0000274void PrintSizesTCose(OutputStringCB pfOutput, void *pOutCtx)
Laurence Lundblade00257182019-12-06 20:51:00 -0800275{
276 // Type and size of return from sizeof() varies. These will never be large
277 // so cast is safe.
278 PrintSize("sizeof(struct t_cose_sign1_ctx)",
279 (uint32_t)sizeof(struct t_cose_sign1_sign_ctx),
280 pfOutput, pOutCtx);
281 PrintSize("sizeof(struct t_cose_signing_key)",
282 (uint32_t)sizeof(struct t_cose_key),
283 pfOutput, pOutCtx);
284 PrintSize("sizeof(struct t_cose_crypto_hash)",
285 (uint32_t)sizeof(struct t_cose_crypto_hash),
286 pfOutput, pOutCtx);
287 PrintSize("sizeof(struct t_cose_parameters)",
288 (uint32_t)sizeof(struct t_cose_parameters),
289 pfOutput, pOutCtx);
290 PrintSize("sizeof(struct t_cose_sign1_verify_ctx)",
291 (uint32_t)sizeof(struct t_cose_sign1_verify_ctx),
292 pfOutput, pOutCtx);
293 (*pfOutput)("", pOutCtx, 1);
294}