blob: 837957efd7113ba472d46037b691345a07b3b99a [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>
Laurence Lundblade42e294b2020-01-23 11:10:19 -080016#include <stddef.h>
Laurence Lundblade00257182019-12-06 20:51:00 -080017
18#include "t_cose_test.h"
19#include "t_cose_sign_verify_test.h"
20
21
22/*
23 Test configuration
24 */
25
Laurence Lundblade42e294b2020-01-23 11:10:19 -080026typedef int_fast32_t (test_fun_t)(void);
Laurence Lundblade00257182019-12-06 20:51:00 -080027typedef const char * (test_fun2_t)(void);
28
29
30#define TEST_ENTRY(test_name) {#test_name, test_name, true}
31#define TEST_ENTRY_DISABLED(test_name) {#test_name, test_name, false}
32
33typedef struct {
34 const char *szTestName;
35 test_fun_t *test_fun;
36 bool bEnabled;
37} test_entry;
38
39#ifdef STRING_RETURNING_TESTS
40typedef struct {
41 const char *szTestName;
42 test_fun2_t *test_fun;
43 bool bEnabled;
44} test_entry2;
45
46
47static test_entry2 s_tests2[] = {
48};
49#endif
50
51static test_entry s_tests[] = {
Laurence Lundblade42e294b2020-01-23 11:10:19 -080052 TEST_ENTRY(sign1_structure_decode_test),
53 TEST_ENTRY(crit_parameters_test),
54 TEST_ENTRY(bad_parameters_test),
55
Laurence Lundblade00257182019-12-06 20:51:00 -080056#ifndef T_COSE_DISABLE_SIGN_VERIFY_TESTS
Laurence Lundblade42e294b2020-01-23 11:10:19 -080057 /* Many tests can be run without a crypto library integration and
58 * provide good test coverage of everything but the signing and
59 * verification. These tests can't be run with signing and
60 * verification short circuited. They must have a real crypto
61 * library integrated. */
Laurence Lundblade00257182019-12-06 20:51:00 -080062 TEST_ENTRY(sign_verify_basic_test),
63 TEST_ENTRY(sign_verify_make_cwt_test),
64 TEST_ENTRY(sign_verify_sig_fail_test),
65 TEST_ENTRY(sign_verify_get_size_test),
Laurence Lundblade42e294b2020-01-23 11:10:19 -080066#endif /* T_COSE_DISABLE_SIGN_VERIFY_TESTS */
67
68#ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN
69 /* These tests can't run if short-circuit signatures are disabled.
70 * The most critical ones are replicated in the group of tests
71 * that require a real crypto library. Typically short-circuit
72 * signing is only disabled for extreme code size savings so these
73 * tests are typically always run.
74 */
Laurence Lundblade00257182019-12-06 20:51:00 -080075 TEST_ENTRY(content_type_test),
76 TEST_ENTRY(all_header_parameters_test),
77 TEST_ENTRY(cose_example_test),
Laurence Lundblade42e294b2020-01-23 11:10:19 -080078 TEST_ENTRY(short_circuit_signing_error_conditions_test),
79 TEST_ENTRY(short_circuit_self_test),
Laurence Lundblade00257182019-12-06 20:51:00 -080080 TEST_ENTRY(short_circuit_decode_only_test),
81 TEST_ENTRY(short_circuit_make_cwt_test),
Laurence Lundblade00257182019-12-06 20:51:00 -080082 TEST_ENTRY(short_circuit_verify_fail_test),
Laurence Lundblade42e294b2020-01-23 11:10:19 -080083#endif /* T_COSE_DISABLE_SHORT_CIRCUIT_SIGN */
Laurence Lundblade00257182019-12-06 20:51:00 -080084
85#ifdef T_COSE_ENABLE_HASH_FAIL_TEST
86 TEST_ENTRY(short_circuit_hash_fail_test),
87#endif /* T_COSE_DISABLE_HASH_FAIL_TEST */
88};
89
90
91
92/**
93 \brief Convert number to ASCII string, similar to sprint
94
95 \param [in] nNum The 32-bit integer to convert.
96 \param [in] StringMem The buffer to output to.
97
98 \return POinter to NULL-terminated string with result or "XXX" on failure.
99
100 Convert a number up to 999999999 to a string. This is so sprintf doesn't
101 have to be linked in so as to minimized dependencies even in test code.
102
103 StringMem should be 12 bytes long, 9 for digits, 1 for minus and
104 1 for \0 termination.
105 */
106static const char *NumToString(int32_t nNum, UsefulBuf StringMem)
107{
108 const int32_t nMax = 1000000000;
109
110 UsefulOutBuf OutBuf;
111 UsefulOutBuf_Init(&OutBuf, StringMem);
112
113 if(nNum < 0) {
114 UsefulOutBuf_AppendByte(&OutBuf, '-');
115 nNum = -nNum;
116 }
117 if(nNum > nMax-1) {
118 return "XXX";
119 }
120
121 bool bDidSomeOutput = false;
Laurence Lundblade42e294b2020-01-23 11:10:19 -0800122 for(int32_t n = nMax; n > 0; n/=10) {
123 int32_t nDigitValue = nNum/n;
124 if(nDigitValue || bDidSomeOutput){
Laurence Lundblade00257182019-12-06 20:51:00 -0800125 bDidSomeOutput = true;
Laurence Lundblade42e294b2020-01-23 11:10:19 -0800126 UsefulOutBuf_AppendByte(&OutBuf, (uint8_t)('0' + nDigitValue));
127 nNum -= nDigitValue * n;
Laurence Lundblade00257182019-12-06 20:51:00 -0800128 }
129 }
130 if(!bDidSomeOutput){
131 UsefulOutBuf_AppendByte(&OutBuf, '0');
132 }
133 UsefulOutBuf_AppendByte(&OutBuf, '\0');
134
135 return UsefulOutBuf_GetError(&OutBuf) ? "" : StringMem.ptr;
136}
137
138
139/*
140 Public function. See run_test.h.
141 */
Tamas Ban132c42f2020-01-07 14:57:37 +0000142int RunTestsTCose(const char *szTestNames[],
143 OutputStringCB pfOutput,
144 void *poutCtx,
145 int *pNumTestsRun)
Laurence Lundblade00257182019-12-06 20:51:00 -0800146{
Laurence Lundblade42e294b2020-01-23 11:10:19 -0800147 // int (-32767 to 32767 according to C standard) used by conscious choice
Laurence Lundblade00257182019-12-06 20:51:00 -0800148 int nTestsFailed = 0;
149 int nTestsRun = 0;
150 UsefulBuf_MAKE_STACK_UB(StringStorage, 12);
151
152#ifdef STRING_RETURNING_TESTS
153
154 test_entry2 *t2;
155 const test_entry2 *s_tests2_end = s_tests2 + sizeof(s_tests2)/sizeof(test_entry2);
156
157 for(t2 = s_tests2; t2 < s_tests2_end; t2++) {
158 if(szTestNames[0]) {
159 // Some tests have been named
160 const char **szRequestedNames;
161 for(szRequestedNames = szTestNames; *szRequestedNames; szRequestedNames++) {
162 if(!strcmp(t2->szTestName, *szRequestedNames)) {
163 break; // Name matched
164 }
165 }
166 if(*szRequestedNames == NULL) {
167 // Didn't match this test
168 continue;
169 }
170 } else {
171 // no tests named, but don't run "disabled" tests
172 if(!t2->bEnabled) {
173 // Don't run disabled tests when all tests are being run
174 // as indicated by no specific test names being given
175 continue;
176 }
177 }
178 const char * szTestResult = (t2->test_fun)();
179 nTestsRun++;
180 if(pfOutput) {
181 (*pfOutput)(t2->szTestName, poutCtx, 0);
182 }
183
184 if(szTestResult) {
185 if(pfOutput) {
186 (*pfOutput)(" FAILED (returned ", poutCtx, 0);
187 (*pfOutput)(szTestResult, poutCtx, 0);
188 (*pfOutput)(")", poutCtx, 1);
189 }
190 nTestsFailed++;
191 } else {
192 if(pfOutput) {
193 (*pfOutput)( " PASSED", poutCtx, 1);
194 }
195 }
196 }
197#endif
198
199
200 test_entry *t;
201 const test_entry *s_tests_end = s_tests + sizeof(s_tests)/sizeof(test_entry);
202
203 for(t = s_tests; t < s_tests_end; t++) {
204 if(szTestNames[0]) {
205 // Some tests have been named
206 const char **szRequestedNames;
207 for(szRequestedNames = szTestNames; *szRequestedNames; szRequestedNames++) {
208 if(!strcmp(t->szTestName, *szRequestedNames)) {
209 break; // Name matched
210 }
211 }
212 if(*szRequestedNames == NULL) {
213 // Didn't match this test
214 continue;
215 }
216 } else {
217 // no tests named, but don't run "disabled" tests
218 if(!t->bEnabled) {
219 // Don't run disabled tests when all tests are being run
220 // as indicated by no specific test names being given
221 continue;
222 }
223 }
224
225 int nTestResult = (t->test_fun)();
226 nTestsRun++;
227 if(pfOutput) {
228 (*pfOutput)(t->szTestName, poutCtx, 0);
229 }
230
231 if(nTestResult) {
232 if(pfOutput) {
233 (*pfOutput)(" FAILED (returned ", poutCtx, 0);
234 (*pfOutput)(NumToString(nTestResult, StringStorage), poutCtx, 0);
235 (*pfOutput)(")", poutCtx, 1);
236 }
237 nTestsFailed++;
238 } else {
239 if(pfOutput) {
240 (*pfOutput)( " PASSED", poutCtx, 1);
241 }
242 }
243 }
244
245 if(pNumTestsRun) {
246 *pNumTestsRun = nTestsRun;
247 }
248
249 if(pfOutput) {
250 (*pfOutput)( "SUMMARY: ", poutCtx, 0);
251 (*pfOutput)( NumToString(nTestsRun, StringStorage), poutCtx, 0);
252 (*pfOutput)( " tests run; ", poutCtx, 0);
253 (*pfOutput)( NumToString(nTestsFailed, StringStorage), poutCtx, 0);
254 (*pfOutput)( " tests failed", poutCtx, 1);
255 }
256
257 return nTestsFailed;
258}
259
260
261/*
262 Public function. See run_test.h.
263 */
264static void PrintSize(const char *szWhat,
265 uint32_t uSize,
266 OutputStringCB pfOutput,
267 void *pOutCtx)
268{
269 UsefulBuf_MAKE_STACK_UB(buffer, 20);
270
271 (*pfOutput)(szWhat, pOutCtx, 0);
272 (*pfOutput)(" ", pOutCtx, 0);
Laurence Lundblade42e294b2020-01-23 11:10:19 -0800273 (*pfOutput)(NumToString((int32_t)uSize, buffer), pOutCtx, 0);
Laurence Lundblade00257182019-12-06 20:51:00 -0800274 (*pfOutput)("", pOutCtx, 1);
275}
276
277
278
279
280#include "t_cose_sign1_sign.h" /* For struct size printing */
281#include "t_cose_sign1_verify.h" /* For struct size printing */
282#include "t_cose_crypto.h" /* For struct size printing */
283
284
285/*
286 Public function. See run_test.h.
287 */
Tamas Ban132c42f2020-01-07 14:57:37 +0000288void PrintSizesTCose(OutputStringCB pfOutput, void *pOutCtx)
Laurence Lundblade00257182019-12-06 20:51:00 -0800289{
290 // Type and size of return from sizeof() varies. These will never be large
291 // so cast is safe.
292 PrintSize("sizeof(struct t_cose_sign1_ctx)",
293 (uint32_t)sizeof(struct t_cose_sign1_sign_ctx),
294 pfOutput, pOutCtx);
295 PrintSize("sizeof(struct t_cose_signing_key)",
296 (uint32_t)sizeof(struct t_cose_key),
297 pfOutput, pOutCtx);
298 PrintSize("sizeof(struct t_cose_crypto_hash)",
299 (uint32_t)sizeof(struct t_cose_crypto_hash),
300 pfOutput, pOutCtx);
301 PrintSize("sizeof(struct t_cose_parameters)",
302 (uint32_t)sizeof(struct t_cose_parameters),
303 pfOutput, pOutCtx);
304 PrintSize("sizeof(struct t_cose_sign1_verify_ctx)",
305 (uint32_t)sizeof(struct t_cose_sign1_verify_ctx),
306 pfOutput, pOutCtx);
307 (*pfOutput)("", pOutCtx, 1);
308}