0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <kunit/test.h>
0010
0011 #include "fat.h"
0012
0013 static void fat_checksum_test(struct kunit *test)
0014 {
0015
0016 KUNIT_EXPECT_EQ(test, fat_checksum("VMLINUX "), (u8)44);
0017
0018 KUNIT_EXPECT_EQ(test, fat_checksum("README TXT"), (u8)115);
0019
0020 KUNIT_EXPECT_EQ(test, fat_checksum("ABCDEFGHA "), (u8)98);
0021 }
0022
0023 struct fat_timestamp_testcase {
0024 const char *name;
0025 struct timespec64 ts;
0026 __le16 time;
0027 __le16 date;
0028 u8 cs;
0029 int time_offset;
0030 };
0031
0032 static struct fat_timestamp_testcase time_test_cases[] = {
0033 {
0034 .name = "Earliest possible UTC (1980-01-01 00:00:00)",
0035 .ts = {.tv_sec = 315532800LL, .tv_nsec = 0L},
0036 .time = cpu_to_le16(0),
0037 .date = cpu_to_le16(33),
0038 .cs = 0,
0039 .time_offset = 0,
0040 },
0041 {
0042 .name = "Latest possible UTC (2107-12-31 23:59:58)",
0043 .ts = {.tv_sec = 4354819198LL, .tv_nsec = 0L},
0044 .time = cpu_to_le16(49021),
0045 .date = cpu_to_le16(65439),
0046 .cs = 0,
0047 .time_offset = 0,
0048 },
0049 {
0050 .name = "Earliest possible (UTC-11) (== 1979-12-31 13:00:00 UTC)",
0051 .ts = {.tv_sec = 315493200LL, .tv_nsec = 0L},
0052 .time = cpu_to_le16(0),
0053 .date = cpu_to_le16(33),
0054 .cs = 0,
0055 .time_offset = 11 * 60,
0056 },
0057 {
0058 .name = "Latest possible (UTC+11) (== 2108-01-01 10:59:58 UTC)",
0059 .ts = {.tv_sec = 4354858798LL, .tv_nsec = 0L},
0060 .time = cpu_to_le16(49021),
0061 .date = cpu_to_le16(65439),
0062 .cs = 0,
0063 .time_offset = -11 * 60,
0064 },
0065 {
0066 .name = "Leap Day / Year (1996-02-29 00:00:00)",
0067 .ts = {.tv_sec = 825552000LL, .tv_nsec = 0L},
0068 .time = cpu_to_le16(0),
0069 .date = cpu_to_le16(8285),
0070 .cs = 0,
0071 .time_offset = 0,
0072 },
0073 {
0074 .name = "Year 2000 is leap year (2000-02-29 00:00:00)",
0075 .ts = {.tv_sec = 951782400LL, .tv_nsec = 0L},
0076 .time = cpu_to_le16(0),
0077 .date = cpu_to_le16(10333),
0078 .cs = 0,
0079 .time_offset = 0,
0080 },
0081 {
0082 .name = "Year 2100 not leap year (2100-03-01 00:00:00)",
0083 .ts = {.tv_sec = 4107542400LL, .tv_nsec = 0L},
0084 .time = cpu_to_le16(0),
0085 .date = cpu_to_le16(61537),
0086 .cs = 0,
0087 .time_offset = 0,
0088 },
0089 {
0090 .name = "Leap year + timezone UTC+1 (== 2004-02-29 00:30:00 UTC)",
0091 .ts = {.tv_sec = 1078014600LL, .tv_nsec = 0L},
0092 .time = cpu_to_le16(48064),
0093 .date = cpu_to_le16(12380),
0094 .cs = 0,
0095 .time_offset = -60,
0096 },
0097 {
0098 .name = "Leap year + timezone UTC-1 (== 2004-02-29 23:30:00 UTC)",
0099 .ts = {.tv_sec = 1078097400LL, .tv_nsec = 0L},
0100 .time = cpu_to_le16(960),
0101 .date = cpu_to_le16(12385),
0102 .cs = 0,
0103 .time_offset = 60,
0104 },
0105 {
0106 .name = "VFAT odd-second resolution (1999-12-31 23:59:59)",
0107 .ts = {.tv_sec = 946684799LL, .tv_nsec = 0L},
0108 .time = cpu_to_le16(49021),
0109 .date = cpu_to_le16(10143),
0110 .cs = 100,
0111 .time_offset = 0,
0112 },
0113 {
0114 .name = "VFAT 10ms resolution (1980-01-01 00:00:00:0010)",
0115 .ts = {.tv_sec = 315532800LL, .tv_nsec = 10000000L},
0116 .time = cpu_to_le16(0),
0117 .date = cpu_to_le16(33),
0118 .cs = 1,
0119 .time_offset = 0,
0120 },
0121 };
0122
0123 static void time_testcase_desc(struct fat_timestamp_testcase *t,
0124 char *desc)
0125 {
0126 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
0127 }
0128
0129 KUNIT_ARRAY_PARAM(fat_time, time_test_cases, time_testcase_desc);
0130
0131 static void fat_time_fat2unix_test(struct kunit *test)
0132 {
0133 static struct msdos_sb_info fake_sb;
0134 struct timespec64 ts;
0135 struct fat_timestamp_testcase *testcase =
0136 (struct fat_timestamp_testcase *)test->param_value;
0137
0138 fake_sb.options.tz_set = 1;
0139 fake_sb.options.time_offset = testcase->time_offset;
0140
0141 fat_time_fat2unix(&fake_sb, &ts,
0142 testcase->time,
0143 testcase->date,
0144 testcase->cs);
0145 KUNIT_EXPECT_EQ_MSG(test,
0146 testcase->ts.tv_sec,
0147 ts.tv_sec,
0148 "Timestamp mismatch (seconds)\n");
0149 KUNIT_EXPECT_EQ_MSG(test,
0150 testcase->ts.tv_nsec,
0151 ts.tv_nsec,
0152 "Timestamp mismatch (nanoseconds)\n");
0153 }
0154
0155 static void fat_time_unix2fat_test(struct kunit *test)
0156 {
0157 static struct msdos_sb_info fake_sb;
0158 __le16 date, time;
0159 u8 cs;
0160 struct fat_timestamp_testcase *testcase =
0161 (struct fat_timestamp_testcase *)test->param_value;
0162
0163 fake_sb.options.tz_set = 1;
0164 fake_sb.options.time_offset = testcase->time_offset;
0165
0166 fat_time_unix2fat(&fake_sb, &testcase->ts,
0167 &time, &date, &cs);
0168 KUNIT_EXPECT_EQ_MSG(test,
0169 le16_to_cpu(testcase->time),
0170 le16_to_cpu(time),
0171 "Time mismatch\n");
0172 KUNIT_EXPECT_EQ_MSG(test,
0173 le16_to_cpu(testcase->date),
0174 le16_to_cpu(date),
0175 "Date mismatch\n");
0176 KUNIT_EXPECT_EQ_MSG(test,
0177 testcase->cs,
0178 cs,
0179 "Centisecond mismatch\n");
0180 }
0181
0182 static struct kunit_case fat_test_cases[] = {
0183 KUNIT_CASE(fat_checksum_test),
0184 KUNIT_CASE_PARAM(fat_time_fat2unix_test, fat_time_gen_params),
0185 KUNIT_CASE_PARAM(fat_time_unix2fat_test, fat_time_gen_params),
0186 {},
0187 };
0188
0189 static struct kunit_suite fat_test_suite = {
0190 .name = "fat_test",
0191 .test_cases = fat_test_cases,
0192 };
0193
0194 kunit_test_suites(&fat_test_suite);
0195
0196 MODULE_LICENSE("GPL v2");