crc16-xmodem.c

Simple implementation of crc16-xmodem
git clone git://git.finwo.net/lib/crc16-xmodem.c
Log | Files | Refs | README | LICENSE

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 }