2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * ncval_tests.c - simple unit tests for NaCl validator
35 #include "native_client/include/portability.h"
39 #include "native_client/ncv/ncvalidate.h"
40 #include "native_client/ncv/ncvalidate_internaltypes.h"
42 struct NCValTestCase
{
46 uint32_t instructions
;
53 struct NCValTestCase NCValTests
[] = {
56 "a first very simple test with an illegal inst.",
57 1, 9, 1, 26, 0x80000000,
61 "\xe8\x81\x00\x00\x00"
62 "\xe8\xd3\x00\x00\x00"
63 "\xe8\xf3\x04\x00\x00"
70 "like test 1 but no illegal inst",
71 1, 9, 0, 26, 0x80000000,
75 "\xe8\x81\x00\x00\x00"
76 "\xe8\xd3\x00\x00\x00"
77 "\xe8\xf3\x04\x00\x00"
84 "like test 1 but no illegal inst, with bad alignment",
85 1, 9, 0, 26, 0x80000001,
89 "\xe8\x81\x00\x00\x00"
90 "\xe8\xd3\x00\x00\x00"
91 "\xe8\xf3\x04\x00\x00"
98 "a longer simple test with a bad jump target",
99 1, 90, 0, 336, 0x8054600,
100 (uint8_t *)"\x8d\x4c\x24\x04"
109 "\xc7\x45\xf4\x0a\x00\x00\x00"
118 "\xc7\x04\x24\x54\x14\x00\x08"
119 "\xe8\xc0\x02\x00\x00"
120 "\xc7\x04\x24\x01\x00\x00\x00"
122 "\xe8\xc0\x01\x00\x00"
130 "\x8d\xbc\x27\x00\x00\x00\x00"
131 "\xe8\x90\x09\x00\x00"
142 "\xe8\x70\x09\x00\x00"
144 "\x8d\xb6\x00\x00\x00\x00"
145 "\x8d\xbc\x27\x00\x00\x00\x00"
147 "\xa3\x28\x2f\x00\x08"
149 "\x8d\xb6\x00\x00\x00\x00"
150 "\xc7\x44\x24\x08\x03\x00\x00\x00"
151 "\xc7\x44\x24\x04\x01\x00\x00\x00"
156 "\xe8\x20\x00\x00\x00"
163 "\xc7\x04\x24\x00\x00\x00\x00"
165 "\xe8\x20\x01\x00\x00"
173 "\x8b\x04\x95\x24\x2f\x00\x08"
175 "\x8d\xb6\x00\x00\x00\x00"
176 "\x89\x04\x95\x24\x2f\x00\x08"
178 "\x8d\xb6\x00\x00\x00\x00"
179 "\x8b\x04\x95\x24\x2f\x00\x08"
181 "\x8d\xb6\x00\x00\x00\x00"
182 "\x89\x04\x95\x24\x2f\x00\x08"
184 "\x8d\xb4\x26\x00\x00\x00\x00"
188 "\xb8\x06\x00\x00\x00"
194 "like test 4; with bad jump target",
195 1, 90, 0, 336, 0x8054600,
196 (uint8_t *)"\x8d\x4c\x24\x04"
205 "\xc7\x45\xf4\x0a\x00\x00\x00"
214 "\xc7\x04\x24\x54\x14\x00\x08"
215 "\xe8\xc0\x02\x00\x00"
216 "\xc7\x04\x24\x01\x00\x00\x00"
218 "\xe8\xc0\x01\x00\x00"
226 "\x8d\xbc\x27\x00\x00\x00\x00"
227 "\xe8\x90\x09\x00\x00"
238 "\xe8\x70\x09\x00\x00"
240 "\x8d\xb6\x00\x00\x00\x00"
241 "\x8d\xbc\x27\x00\x00\x00\x00"
243 "\xa3\x28\x2f\x00\x08"
245 "\x8d\xb6\x00\x00\x00\x00"
246 "\xc7\x44\x24\x08\x03\x00\x00\x00"
247 "\xc7\x44\x24\x04\x01\x00\x00\x00"
252 "\xe8\x20\x00\x00\x00"
259 "\xc7\x04\x24\x00\x00\x00\x00"
261 "\xe8\x20\x01\x00\x00"
269 "\x8b\x04\x95\x24\x2f\x00\x08"
271 "\x8d\xb6\x00\x00\x00\x00"
272 "\x89\x04\x95\x24\x2f\x00\x08"
274 "\x8d\xb6\x00\x00\x00\x00"
275 "\x8b\x04\x95\x24\x2f\x00\x08"
277 "\x8d\xb6\x00\x00\x00\x00"
278 "\x89\x04\x95\x24\x2f\x00\x08"
280 "\x8d\xb4\x26\x00\x00\x00\x00"
284 "\xb8\x06\x00\x00\x00"
290 "test 6: 3c 25 cmp %al, $I",
291 0, 7, 0, 9, 0x80000000,
292 (uint8_t *)"\x3c\x25"
293 "\x90\x90\x90\x90\x90\x90\xf4"
297 "test 7: group2, three byte move",
298 0, 8, 0, 13, 0x80000000,
299 (uint8_t *)"\xc1\xf9\x1f\x89\x4d\xe4"
300 "\x90\x90\x90\x90\x90\x90\xf4"
304 "test 8: five byte move",
305 0, 7, 0, 12, 0x80000000,
306 (uint8_t *)"\xc6\x44\x05\xd6\x00"
307 "\x90\x90\x90\x90\x90\x90\xf4"
311 "test 9: seven byte control transfer, unprotected",
312 1, 7, 0, 14, 0x80000000,
313 (uint8_t *)"\xff\x24\x95\xc8\x6e\x05\x08"
314 "\x90\x90\x90\x90\x90\x90\xf4"
318 "test 10: eight byte bts instruction",
319 1, 7, 1, 15, 0x80000000,
320 (uint8_t *)"\x0f\xab\x14\x85\x40\xfb\x27\x08"
321 "\x90\x90\x90\x90\x90\x90\xf4",
325 "test 11: four byte move",
326 0, 7, 0, 11, 0x80000000,
327 (uint8_t *)"\x66\xbf\x08\x00"
328 "\x90\x90\x90\x90\x90\x90\xf4",
332 "test 12: five byte movsx",
333 0, 7, 0, 12, 0x80000000,
334 (uint8_t *)"\x66\x0f\xbe\x04\x10"
335 "\x90\x90\x90\x90\x90\x90\xf4"
339 "test 13: eight byte bts instruction, missing full stop",
340 1, 7, 1, 15, 0x80000000,
341 (uint8_t *)"\x0f\xab\x14\x85\x40\xfb\x27\x08"
342 "\x90\x90\x90\x90\x90\x90\x90",
344 /* ldmxcsr, stmxcsr */
347 "test 14: ldmxcsr, stmxcsr",
348 1, 10, 2, 15, 0x80000000,
349 (uint8_t *)"\x90\x0f\xae\x10\x90\x0f\xae\x18"
350 "\x90\x90\x90\x90\x90\x90\xf4",
355 "test 15: invalid instruction",
356 1, 8, 1, 11, 0x80000000,
357 (uint8_t *)"\x90\x0f\xae\x21"
358 "\x90\x90\x90\x90\x90\x90\xf4",
364 1, 8, 1, 11, 0x80000000,
365 (uint8_t *)"\x90\x0f\xae\x28"
366 "\x90\x90\x90\x90\x90\x90\xf4",
370 "test 17: lock cmpxchg",
371 0, 4, 0, 12, 0x80000000,
372 (uint8_t *)"\xf0\x0f\xb1\x8f\xa8\x01\x00\x00"
377 "test 18: loop branch into overlapping instruction",
378 1, 3, 1, 10, 0x80000000,
379 (uint8_t *)"\xbb\x90\x40\xcd\x80\x85\xc0\xe1\xf8\xf4",
384 1, 5, 2, 15, 0x80000000,
385 (uint8_t *)"\x68\x8a\x80\x04\x08\xd5\xb0\xc3\x90\xbb\x90\x40\xcd\x80\xf4"
389 "test 20: addr16 lea",
390 1, 5, 2, 19, 0x80000000,
391 (uint8_t *)"\x68\x8e\x80\x04\x08\x66\x67\x8d\x98\xff\xff\xc3\x90\xbb\x90\x40\xcd\x80\xf4"
396 1, 4, 2, 14, 0x80000000,
397 (uint8_t *)"\x68\x89\x80\x04\x08\xd4\xb0\xc3\xbb\x90\x40\xcd\xf4",
402 1, 4, 1, 16, 0x80000000,
403 (uint8_t *)"\x68\x8b\x80\x04\x08\x0f\x70\xca\xb3\xc3\xbb\x90\x40\xcd\x80\xf4",
407 "test 23: 14-byte nacljmp using eax",
408 1, 3, 0, 15, 0x80000000,
409 (uint8_t *)"\x81\xe0\xff\xff\xff\xff\x81\xc8\x00\x00\x00\x00\xff\xd0\xf4",
413 "test 24: 5-byte nacljmp",
414 0, 2, 0, 6, 0x80000000,
415 (uint8_t *)"\x83\xe0\xf0\xff\xe0\xf4",
420 1, 1, 1, 3, 0x80000000,
421 (uint8_t *)"\xe3\x00\xf4",
425 "test 26: 0xe9 jmp, nop",
426 0, 2, 0, 7, 0x80000000,
427 (uint8_t *)"\xe9\x00\x00\x00\x00\x90\xf4",
431 "test 27: 0xf0 0x80 jmp, nop",
432 0, 2, 0, 8, 0x80000000,
433 (uint8_t *)"\x0f\x80\x00\x00\x00\x00\x90\xf4",
438 1, 1, 0, 6, 0x80000000,
439 (uint8_t *)"\xe9\x00\x00\x00\x00\xf4",
443 "test 30: addr16 lea ret",
444 1, 3, 2, 8, 0x80000000,
445 (uint8_t *)"\x67\x8d\xb4\x9a\x40\xc3\x90\xf4",
449 "test 31: repz movsbl",
450 1, 3, 2, 8, 0x80000000,
451 (uint8_t *)"\xf3\x0f\xbe\x40\xd0\xc3\x90\xf4",
455 "test 32: infinite loop",
456 0, 1, 0, 3, 0x80000000,
457 (uint8_t *)"\x7f\xfe\xf4",
461 "test 33: bad branch",
462 1, 1, 0, 3, 0x80000000,
463 (uint8_t *)"\x7f\xfd\xf4",
467 "test 34: bad branch",
468 1, 1, 0, 3, 0x80000000,
469 (uint8_t *)"\x7f\xff\xf4",
473 "test 35: bad branch",
474 1, 1, 0, 3, 0x80000000,
475 (uint8_t *)"\x7f\x00\xf4",
479 "test 36: bad branch",
480 1, 1, 0, 3, 0x80000000,
481 (uint8_t *)"\x7f\x01\xf4",
485 "test 37: bad branch",
486 1, 1, 0, 3, 0x80000000,
487 (uint8_t *)"\x7f\x02\xf4",
492 1, 10, 8, 18, 0x80000000,
493 (uint8_t *)"\x66\xeb\x1b\x31\x51\x3d\xef\xcc\x2f\x36\x48\x6e\x44\x2e\xcc\x14\xf4\xf4",
497 "test 39: bad branch",
498 1, 7, 2, 18, 0x80000000,
499 (uint8_t *)"\x67\x8d\x1d\x22\xa0\x05\xe3\x7b\x9c\xdb\x08\x04\xb1\x90\xed\x12\xf4\xf4",
503 "test 40: more addr16 problems",
504 1, 4, 2, 9, 0x80000000,
505 (uint8_t *)"\x67\xa0\x00\x00\xcd\x80\x90\x90\xf4",
509 "test 41: the latest non-bug from hcf",
510 1, 5, 1, 17, 0x80000000,
511 (uint8_t *)"\x84\xd4\x04\x53\xa0\x04\x6a\x5a\x20\xcc\xb8\x48\x03\x2b\x96\x11\xf4"
515 "test 42: another case from hcf",
516 1, 7, 1, 17, 0x80000000,
517 (uint8_t *)"\x45\x7f\x89\x58\x94\x04\x24\x1b\xc3\xe2\x6f\x1a\x94\x87\x8f\x0b\xf4",
521 "test 43: too many prefix bytes",
522 1, 2, 1, 8, 0x80000000,
523 (uint8_t *)"\x66\x66\x66\x66\x00\x00\x90\xf4"
527 "test 44: palignr (SSSE3)",
528 0, 2, 0, 8, 0x80000000,
529 (uint8_t *)"\x66\x0f\x3a\x0f\xd0\xc0\x90\xf4"
533 "test 45: undefined inst in 3-byte opcode space",
534 1, 2, 2, 8, 0x80000000,
535 (uint8_t *)"\x66\x0f\x39\x0f\xd0\xc0\x90\xf4"
539 "test 46: SSE2x near miss",
540 1, 2, 1, 7, 0x80000000,
541 (uint8_t *)"\x66\x0f\x73\x00\x00\x90\xf4"
546 0, 2, 0, 7, 0x80000000,
547 (uint8_t *)"\x66\x0f\x73\xff\x00\x90\xf4"
551 "test 48: SSE2x, missing required prefix byte",
552 1, 2, 1, 6, 0x80000000,
553 (uint8_t *)"\x0f\x73\xff\x00\x90\xf4"
557 "test 49: 3DNow example",
558 0, 2, 0, 7, 0x80000000,
559 (uint8_t *)"\x0f\x0f\x46\x01\xbf\x90\xf4"
563 "test 50: 3DNow error example 1",
564 1, 2, 1, 7, 0x80000000,
565 (uint8_t *)"\x0f\x0f\x46\x01\x00\x90\xf4"
569 "test 51: 3DNow error example 2",
570 1, 0, 0, 5, 0x80000000,
571 (uint8_t *)"\x0f\x0f\x46\x01\xf4"
575 "test 52: 3DNow error example 3",
576 1, 2, 1, 7, 0x80000000,
577 (uint8_t *)"\x0f\x0f\x46\x01\xbe\x90\xf4"
581 "test 53: 3DNow error example 4",
582 1, 2, 1, 7, 0x80000000,
583 (uint8_t *)"\x0f\x0f\x46\x01\xaf\x90\xf4"
588 0, 2, 0, 8, 0x80000000,
589 (uint8_t *)"\x66\x0f\x3a\x0e\xd0\xc0\x90\xf4"
594 0, 3, 0, 8, 0x80000000,
595 (uint8_t *)"\x66\x0f\x38\x0a\xd0\x90\x90\xf4"
599 "test 56: incb decb",
600 0, 3, 0, 14, 0x80000000,
601 (uint8_t *)"\xfe\x85\x4f\xfd\xff\xff\xfe\x8d\x73\xfd\xff\xff\x90\xf4",
606 0, 2, 0, 6, 0x80000000,
607 (uint8_t *)"\xf3\x0f\xbd\x00\x90\xf4",
612 0, 2, 0, 4, 0x80000000,
613 (uint8_t *)"\xd9\xee\x90\xf4",
618 0, 7, 0, 25, 0x80000000,
619 (uint8_t *)"\xdd\x9c\xfd\xb0\xfe\xff\xff"
620 "\xdd\x9d\x40\xff\xff\xff"
629 "test 60: x87 bad instructions",
630 1, 19, 9, 40, 0x80000000,
631 (uint8_t *)"\xdd\xcc"
653 "test 61: 3DNow prefetch",
654 0, 2, 0, 5, 0x80000000,
655 (uint8_t *)"\x0f\x0d\x00"
660 "test 61.1: F2 0F ...",
661 1, 3, 1, 13, 0x80000000,
662 (uint8_t *)"\xf2\x0f\x48\x0f\x48\xa4\x52"
668 "test 62: f6/f7 test Ib/Iv ...",
669 0, 10, 0, 28, 0x80000000,
670 (uint8_t *)"\xf6\xc1\xff"
671 "\xf6\x44\x43\x01\x02"
672 "\xf7\xc6\x03\x00\x00\x00"
673 "\x90\x90\x90\x90\x90"
674 "\xf7\x45\x18\x00\x00\x00\x20"
679 "test 63: addr16 corner cases ...",
680 1, 5, 4, 17, 0x80000000,
681 (uint8_t *)"\x67\x01\x00"
683 "\x67\x01\x80\x00\x90"
689 "test 64: text starts with indirect jmp ...",
690 1, 2, 0, 4, 0x80000000,
691 (uint8_t *)"\xff\xd0\x90\xf4"
695 "test 65: nacljmp crosses 32-byte boundary ...",
696 1, 32, 0, 36, 0x80000000,
697 (uint8_t *)"\x90\x90\x90\x90\x90\x90\x90\x90"
698 "\x90\x90\x90\x90\x90\x90\x90\x90"
699 "\x90\x90\x90\x90\x90\x90\x90\x90"
700 "\x90\x90\x90\x90\x90\x83\xe0\xff"
704 /* I think this is currently NACLi_ILLEGAL */
706 "test 65: NACLi_CFLUSH",
707 1, 2, 1, 10, 0x80000000,
708 (uint8_t *)"\x0f\xae\x00\x00\x90\x90\x90\x90\x90\xf4"
712 "test 66: NACLi_CMPXCHG8B",
713 0, 2, 0, 6, 0x80000000,
714 (uint8_t *)"\xf0\x0f\xc7\010\x90\xf4"
718 "test 67: NACLi_FCMOV",
719 0, 7, 0, 10, 0x80000000,
720 (uint8_t *)"\xda\xc0\x00\x00\x90\x90\x90\x90\x90\xf4"
724 "test 68: NACLi_MMX",
725 0, 4, 0, 7, 0x80000000,
726 (uint8_t *)"\x0f\x60\x00\x90\x90\x90\xf4"
730 "test 69: NACLi_SSE",
731 0, 2, 0, 9, 0x80000000,
732 (uint8_t *)"\x0f\x5e\x90\x90\x90\x90\x90\x90\xf4"
736 "test 70: NACLi_SSE2",
737 0, 4, 0, 8, 0x80000000,
738 (uint8_t *)"\x66\x0f\x60\x00\x90\x90\x90\xf4"
742 "test 71: NACLi_SSE3",
743 0, 4, 0, 8, 0x80000000,
744 (uint8_t *)"\x66\x0f\x7d\x00\x90\x90\x90\xf4"
748 "test 72: NACLi_SSE4A",
749 0, 4, 0, 8, 0x80000000,
750 (uint8_t *)"\xf2\x0f\x79\x00\x90\x90\x90\xf4"
754 "test 73: NACLi_POPCNT",
755 0, 2, 0, 6, 0x80000000,
756 (uint8_t *)"\xf3\x0f\xb8\x00\x90\xf4"
760 "test 74: NACLi_E3DNOW",
761 0, 2, 0, 7, 0x80000000,
762 (uint8_t *)"\x0f\x0f\x46\x01\xbb\x90\xf4"
766 "test 75: NACLi_MMXSSE2",
767 0, 2, 0, 7, 0x80000000,
768 (uint8_t *)"\x66\x0f\x71\xf6\x00\x90\xf4",
772 "test 76: mov eax, ss",
773 1, 4, 4, 9, 0x80000000,
774 (uint8_t *)"\x8e\xd0\x8c\xd0\x66\x8c\xd0\x90\xf4",
779 1, 3, 0, 7, 0x80000000,
780 (uint8_t *)"\x83\xe4\xf0\xff\xd4\x90\xf4",
782 /* code.google.com issue 23 reported by defend.the.world on 11 Dec 2008 */
785 "test 78: call (*edx)",
786 1, 30, 0, 34, 0x80000000,
788 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
789 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
790 "\x83\xe2\xf0" /* and */
791 "\xff\x12" /* call (*edx) */
792 "\x90\xf4", /* nop halt */
796 "test 79: call *edx",
797 0, 30, 0, 34, 0x80000000,
799 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
800 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
801 "\x83\xe2\xf0" /* and */
802 "\xff\xd2" /* call *edx */
803 "\x90\xf4", /* nop halt */
808 0, 3, 0, 9, 0x80000000,
809 (uint8_t *)"\x66\x0f\x3a\x0a\xc0\x00"
816 0, 3, 0, 8, 0x80000000,
817 (uint8_t *)"\xf2\x0f\x38\xf1\xc8"
823 "test 82: SSE4 error 1",
824 1, 4, 2, 8, 0x80000000,
825 (uint8_t *)"\xf3\x0f\x3a\x0e\xd0\xc0\x90\xf4"
829 "test 83: SSE4 error 2",
830 1, 2, 2, 8, 0x80000000,
831 (uint8_t *)"\xf3\x0f\x38\x0f\xd0\xc0\x90\xf4"
835 "test 84: SSE4 error 3",
836 1, 3, 1, 8, 0x80000000,
837 (uint8_t *)"\x66\x0f\x38\x0f\xd0\xc0\x90\xf4"
841 "test 85: SSE4 error 4",
842 1, 3, 1, 10, 0x80000000,
843 (uint8_t *)"\xf2\x66\x0f\x3a\x0a\xc0\x00"
849 "test 86: bad SSE4 crc32",
850 1, 3, 1, 9, 0x80000000,
851 (uint8_t *)"\xf2\xf3\x0f\x38\xf1\xc8"
857 "test 87: bad NACLi_3BYTE instruction (SEGCS prefix)",
858 1, 3, 1, 13, 0x80000000,
859 (uint8_t *)"\x2e\x0f\x3a\x7d\xbb\xab\x00\x00\x00\x00"
866 static uint8_t *memdup(uint8_t *s
, int len
) {
867 return memcpy(malloc(len
), s
, len
);
870 static void TestValidator(struct NCValTestCase
*vtest
) {
871 struct NCValidatorState
*vstate
;
872 uint8_t *byte0
= memdup(vtest
->testbytes
, vtest
->testsize
);
875 vstate
= NCValidateInit(vtest
->vaddr
,
876 vtest
->vaddr
+ vtest
->testsize
, 16);
877 NCValidateSegment(byte0
, (uint32_t)vtest
->vaddr
, vtest
->testsize
, vstate
);
879 rc
= NCValidateFinish(vstate
);
881 if (vtest
->sawfailure
^ vstate
->stats
.sawfailure
) break;
882 if (vtest
->instructions
!= vstate
->stats
.instructions
) break;
883 if (vtest
->illegalinst
!= vstate
->stats
.illegalinst
) break;
884 fprintf(stderr
, "*** %s passed (%s)\n", vtest
->name
, vtest
->description
);
885 NCValidateFreeState(&vstate
);
888 Stats_Print(stderr
, vstate
);
889 NCValidateFreeState(&vstate
);
890 fprintf(stderr
, "*** %s failed (%s)\n", vtest
->name
, vtest
->description
);
894 #define sizeofA(array) (sizeof(array)/sizeof(array[0]))
895 void ncvalidate_unittests() {
898 for (i
= 0; i
< sizeofA(NCValTests
); i
++) {
899 TestValidator(&NCValTests
[i
]);
901 fprintf(stderr
, "\nAll tests passed.\n\n");