test.c (2868B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include "crc16-xmodem.h" 6 7 static int tests_run = 0; 8 static int tests_passed = 0; 9 10 #define ASSERT(cond, msg) do { \ 11 tests_run++; \ 12 if (cond) { \ 13 tests_passed++; \ 14 printf(" PASS: %s\n", msg); \ 15 } else { \ 16 printf(" FAIL: %s\n", msg); \ 17 } \ 18 } while(0) 19 20 #define RUN(name) do { \ 21 printf("Running %s...\n", #name); \ 22 name(); \ 23 } while(0) 24 25 void test_crc16_xmodem_basic() { 26 uint8_t message[] = "Hi!\0\0"; 27 28 uint16_t crc = crc16_xmodem(message, 3); 29 ASSERT(crc == 12797, "'Hi!' produces good known-value numerically"); 30 ASSERT(crc == 0x31FD, "'Hi!' produces 0x31FD"); 31 32 uint8_t out[2]; 33 crc16_xmodem_b(message, 3, out); 34 ASSERT(out[0] == 0x31 && out[1] == 0xFD, "'Hi!' produces 0x31FD as bytes"); 35 } 36 37 void test_crc16_xmodem_known_values() { 38 struct { 39 const char *input; 40 uint16_t expected; 41 } known[] = { 42 {"Hello World\0\0" , 0x992A}, 43 {"Hello World!\0\0" , 0x0CD3}, 44 {"Pizza Calzone\0\0", 0x795B}, 45 }; 46 47 for (size_t i = 0; i < sizeof(known) / sizeof(known[0]); i++) { 48 size_t len = strlen(known[i].input); 49 uint16_t crc = crc16_xmodem((const uint8_t *)known[i].input, len); 50 char buf[256]; 51 snprintf(buf, sizeof(buf), "known value '%s' produces correct output", known[i].input); 52 ASSERT(crc == known[i].expected, buf); 53 } 54 } 55 56 void test_crc16_xmodem_inverse() { 57 struct { 58 const char *input; 59 uint16_t expected; 60 } known[] = { 61 {"Hello World\0\0" , 0x992A}, 62 {"Hello World!\0\0" , 0x0CD3}, 63 {"Pizza Calzone\0\0", 0x795B}, 64 }; 65 66 for (size_t i = 0; i < sizeof(known) / sizeof(known[0]); i++) { 67 size_t len = strlen(known[i].input); 68 uint8_t *nb = malloc(len + 2); 69 memcpy(nb, known[i].input, len); 70 71 crc16_xmodem_b(nb, len, &nb[len]); 72 73 char buf[256]; 74 75 snprintf(buf, sizeof(buf), "inverse '%s' resolves to 0 when no errors introduced", known[i].input); 76 ASSERT(crc16_xmodem(nb, len + 2) == 0, buf); 77 78 nb[0]++; 79 snprintf(buf, sizeof(buf), "inverse '%s' resolves to non-0 with increment error", known[i].input); 80 ASSERT(crc16_xmodem(nb, len + 2) != 0, buf); 81 nb[0]--; 82 83 nb[1] ^= 0x02; 84 snprintf(buf, sizeof(buf), "inverse '%s' resolves to non-0 with 1 bit-flip", known[i].input); 85 ASSERT(crc16_xmodem(nb, len + 2) != 0, buf); 86 nb[1] ^= 0x02; 87 88 nb[1] ^= 0x04; 89 snprintf(buf, sizeof(buf), "inverse '%s' resolves to non-0 with 2 consecutive bit-flips", known[i].input); 90 ASSERT(crc16_xmodem(nb, len + 2) != 0, buf); 91 92 free(nb); 93 } 94 } 95 96 int main() { 97 printf("CRC16-XMODEM Tests\n"); 98 printf("==================\n\n"); 99 100 RUN(test_crc16_xmodem_basic); 101 RUN(test_crc16_xmodem_known_values); 102 RUN(test_crc16_xmodem_inverse); 103 104 printf("\n------------------\n"); 105 printf("Results: %d/%d tests passed\n", tests_passed, tests_run); 106 107 return tests_passed == tests_run ? 0 : 1; 108 }