Edit

thodg/ext4fs/test/ext4fs_test.c

Branch :

  • test/ext4fs_test.c
  • /* ext4fs
     * Copyright 2025 kmx.io <contact@kmx.io>
     *
     * Permission is hereby granted to use this software granted the above
     * copyright notice and this permission paragraph are included in all
     * copies and substantial portions of this software.
     *
     * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
     * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
     * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
     * THIS SOFTWARE.
     */
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include <strings.h>
    
    #include <ext4fs.h>
    #include <crc32c.h>
    #include <uuid.h>
    
    static int    g_test_argc = 0;
    static char **g_test_argv = NULL;
    
    static long g_test_ko = 0;
    static long g_test_ok = 0;
    static long g_test_total = 0;
    
    static const uint8_t g_test_bgd_data[64] = {
      0x03, 0x04, 0x00, 0x00, 0x13, 0x04, 0x00, 0x00,
      0x23, 0x04, 0x00, 0x00, 0x07, 0x5C, 0xC5, 0x1F,
      0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
      0xCB, 0x35, 0x02, 0x35, 0xC5, 0x1F, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x3B, 0x1D, 0x72, 0x80, 0x00, 0x00, 0x00, 0x00
    };
    
    static const uint8_t g_test_sb_data[1024] = {
      0xe0, 0xa9, 0x0e, 0x00, 0x40, 0x93, 0x3a, 0x00,
      0xc3, 0xed, 0x02, 0x00, 0x92, 0x3f, 0x39, 0x00,
      0xd5, 0xa9, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
      0xd0, 0x1f, 0x00, 0x00, 0x75, 0xfb, 0x7f, 0x68,
      0x03, 0x00, 0x80, 0x68, 0x11, 0x00, 0xff, 0xff,
      0x53, 0xef, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
      0xae, 0x9f, 0x61, 0x68, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
      0x00, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
      0xc2, 0x02, 0x00, 0x00, 0x6b, 0x04, 0x00, 0x00,
      0x31, 0x88, 0xb7, 0x06, 0xd0, 0xcb, 0x42, 0x1f,
      0xb9, 0x61, 0xd9, 0x13, 0x63, 0xe4, 0x41, 0x58,
      0x65, 0x78, 0x74, 0x34, 0x66, 0x73, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x5e, 0x68, 0x93, 0x7f,
      0x43, 0x87, 0x4f, 0xae, 0x93, 0x67, 0xc0, 0x02,
      0x89, 0xeb, 0x8f, 0x55, 0x01, 0x01, 0x40, 0x00,
      0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0xae, 0x9f, 0x61, 0x68, 0x0a, 0xf3, 0x01, 0x00,
      0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
      0x03, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x20, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
      0xb9, 0xbd, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0xa8, 0x53, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x9f, 0xe2, 0xac, 0xe3
    };
      
    #define TEST_ASSERT(test)                       \
      do {                                          \
        if (! (test)) {                             \
          fprintf(stderr, "KO: %s\n", # test);      \
          g_test_ko++;                              \
          g_test_total++;                           \
        }                                           \
        else {                                      \
          g_test_ok++;                              \
          g_test_total++;                           \
        }                                           \
      } while (0)
    
    #define TEST_EQ(test, expected)                                         \
      do {                                                                  \
        int64_t i_test = (test);                                            \
        int64_t i_expected = (expected);                                    \
        if (! ((i_test) == (i_expected))) {                                 \
          fprintf(stderr, "KO: expected %s == %ld, got %ld instead\n",      \
                  # test, i_expected, i_test);                              \
          g_test_ko++;                                                      \
          g_test_total++;                                                   \
        }                                                                   \
        else {                                                              \
          g_test_ok++;                                                      \
          g_test_total++;                                                   \
        }                                                                   \
      } while (0)
    
    void test_summary (void)
    {
      fflush(stdout);
      fprintf(stderr, "OK: %ld\tKO: %ld\tTotal: %ld\n",
              g_test_ok, g_test_ko, g_test_total);
      fflush(stderr);
    }
    
    void test_crc32c (void)
    {
      uint8_t b[32] = {0};
      uint32_t u32 = 0;
      TEST_EQ(crc32c(0, &u32, 4), 0x48674BC7U);
      TEST_EQ(crc32c(0, b, sizeof(b)), 0x8A9136AAU);
      memset(b, -1, sizeof(b));
      TEST_EQ(crc32c(0, b, sizeof(b)), 0x62A8AB43U);
      TEST_EQ(crc32c(0, "123456789", 9), 0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "1", 1), "23456789", 8),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "12", 2), "3456789", 7),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "123", 3), "456789", 6),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "1234", 4), "56789", 5),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "12345", 5), "6789", 4),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "123456", 6), "789", 3),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "1234567", 7), "89", 2),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(0, "12345678", 8), "9", 1),
              0xE3069283U);
      TEST_EQ(crc32c(crc32c(crc32c(0, "123", 3), "456", 3), "789", 3),
              0xE3069283U);
    }
    
    void test_bgd (void)
    {
      struct ext4fs_super_block sb = {0};
      struct ext4fs_block_group_descriptor bgd = {0};
      uint16_t                             bgd_checksum = 0;
      TEST_EQ(offsetof(struct ext4fs_block_group_descriptor, bgd_checksum),
              0x1E);
      TEST_EQ(sizeof(struct ext4fs_block_group_descriptor),
              64);
      memcpy(&sb, g_test_sb_data, sizeof(sb));
      memcpy(&bgd, g_test_bgd_data, sizeof(bgd));
      TEST_EQ(ext4fs_bgd_checksum_compute(&sb, &bgd, 0, &bgd_checksum), 0);
      TEST_EQ(bgd_checksum, 0x7E71U);
    }
    
    void test_sb (void)
    {
      struct ext4fs_super_block sb = {0};
      uint32_t                  sb_checksum;
      TEST_EQ(offsetof(struct ext4fs_super_block, sb_default_mount_opts),
              0x100);
      TEST_EQ(offsetof(struct ext4fs_super_block, sb_mount_opts), 0x200);
      TEST_EQ(offsetof(struct ext4fs_super_block, sb_orphan_file_inode),
              0x280);
      TEST_EQ(offsetof(struct ext4fs_super_block, sb_checksum), 0x3FC);
      TEST_EQ(sizeof(sb.sb_uuid), 16);
      TEST_EQ(sizeof(struct ext4fs_super_block), 1024);
      memcpy(&sb, g_test_sb_data, sizeof(sb));
      TEST_EQ(ext4fs_sb_checksum_compute(&sb, &sb_checksum), 0);
      TEST_EQ(sb_checksum, 0xE3ACE29FU);
    }
    
    #define TEST_CASE_RUN(name)                            \
      do {                                                 \
        int i = 1;                                         \
        if (g_test_argc == 1)                              \
          test_ ## name();                                 \
        else {                                             \
          while (i < g_test_argc) {                       \
            if (! strcmp(g_test_argv[i], # name)) {        \
              test_ ## name();                             \
              break;                                       \
            }                                              \
            i++;                                           \
          }                                                \
        }                                                  \
      } while (0)
    
    int main (int argc, char **argv)
    {
      g_test_argc = argc;
      g_test_argv = argv;
      TEST_CASE_RUN(crc32c);
      TEST_CASE_RUN(sb);
      TEST_CASE_RUN(bgd);
      test_summary();
      return g_test_ko ? 1 : 0;
    }