Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2017 Intel Corporation.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "spdk/stdinc.h"
7 : :
8 : : #include "spdk_internal/cunit.h"
9 : :
10 : : #include "util/crc32.c"
11 : : #include "util/crc32c.c"
12 : :
13 : : static void
14 : 5 : test_crc32c(void)
15 : : {
16 : : uint32_t crc;
17 : 5 : char buf[1024], buf1[1024];
18 : 5 : struct iovec iov[2] = {};
19 : :
20 : : /* Verify a string's CRC32-C value against the known correct result. */
21 : 5 : snprintf(buf, sizeof(buf), "%s", "Hello world!");
22 : 5 : crc = 0xFFFFFFFFu;
23 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
24 : 5 : crc ^= 0xFFFFFFFFu;
25 : 5 : CU_ASSERT(crc == 0x7b98e751);
26 : :
27 : 5 : crc = 0xFFFFFFFFu;
28 : 5 : iov[0].iov_base = buf;
29 : 5 : iov[0].iov_len = strlen(buf);
30 : 5 : crc = spdk_crc32c_iov_update(iov, 1, crc);
31 : 5 : crc ^= 0xFFFFFFFFu;
32 : 5 : CU_ASSERT(crc == 0x7b98e751);
33 : :
34 : 5 : crc = 0xFFFFFFFFu;
35 : 5 : snprintf(buf, sizeof(buf), "%s", "Hello");
36 : 5 : iov[0].iov_base = buf;
37 : 5 : iov[0].iov_len = strlen(buf);
38 : :
39 : 5 : snprintf(buf1, sizeof(buf1), "%s", " world!");
40 : 5 : iov[1].iov_base = buf1;
41 : 5 : iov[1].iov_len = strlen(buf1);
42 : :
43 : 5 : crc = spdk_crc32c_iov_update(iov, 2, crc);
44 : 5 : crc ^= 0xFFFFFFFFu;
45 : 5 : CU_ASSERT(crc == 0x7b98e751);
46 : :
47 : : /*
48 : : * The main loop of the optimized CRC32-C implementation processes data in 8-byte blocks,
49 : : * followed by a loop to handle the 0-7 trailing bytes.
50 : : * Test all buffer sizes from 0 to 7 in order to hit all possible trailing byte counts.
51 : : */
52 : :
53 : : /* 0-byte buffer should not modify CRC at all, so final result should be ~0 ^ ~0 == 0 */
54 : 5 : snprintf(buf, sizeof(buf), "%s", "");
55 : 5 : crc = 0xFFFFFFFFu;
56 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
57 : 5 : crc ^= 0xFFFFFFFFu;
58 : 5 : CU_ASSERT(crc == 0);
59 : :
60 : : /* 1-byte buffer */
61 : 5 : snprintf(buf, sizeof(buf), "%s", "1");
62 : 5 : crc = 0xFFFFFFFFu;
63 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
64 : 5 : crc ^= 0xFFFFFFFFu;
65 : 5 : CU_ASSERT(crc == 0x90F599E3);
66 : :
67 : : /* 2-byte buffer */
68 : 5 : snprintf(buf, sizeof(buf), "%s", "12");
69 : 5 : crc = 0xFFFFFFFFu;
70 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
71 : 5 : crc ^= 0xFFFFFFFFu;
72 : 5 : CU_ASSERT(crc == 0x7355C460);
73 : :
74 : : /* 3-byte buffer */
75 : 5 : snprintf(buf, sizeof(buf), "%s", "123");
76 : 5 : crc = 0xFFFFFFFFu;
77 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
78 : 5 : crc ^= 0xFFFFFFFFu;
79 : 5 : CU_ASSERT(crc == 0x107B2FB2);
80 : :
81 : : /* 4-byte buffer */
82 : 5 : snprintf(buf, sizeof(buf), "%s", "1234");
83 : 5 : crc = 0xFFFFFFFFu;
84 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
85 : 5 : crc ^= 0xFFFFFFFFu;
86 : 5 : CU_ASSERT(crc == 0xF63AF4EE);
87 : :
88 : : /* 5-byte buffer */
89 : 5 : snprintf(buf, sizeof(buf), "%s", "12345");
90 : 5 : crc = 0xFFFFFFFFu;
91 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
92 : 5 : crc ^= 0xFFFFFFFFu;
93 : 5 : CU_ASSERT(crc == 0x18D12335);
94 : :
95 : : /* 6-byte buffer */
96 : 5 : snprintf(buf, sizeof(buf), "%s", "123456");
97 : 5 : crc = 0xFFFFFFFFu;
98 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
99 : 5 : crc ^= 0xFFFFFFFFu;
100 : 5 : CU_ASSERT(crc == 0x41357186);
101 : :
102 : : /* 7-byte buffer */
103 : 5 : snprintf(buf, sizeof(buf), "%s", "1234567");
104 : 5 : crc = 0xFFFFFFFFu;
105 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
106 : 5 : crc ^= 0xFFFFFFFFu;
107 : 5 : CU_ASSERT(crc == 0x124297EA);
108 : :
109 : : /* Test a buffer of exactly 8 bytes (one block in the main CRC32-C loop). */
110 : 5 : snprintf(buf, sizeof(buf), "%s", "12345678");
111 : 5 : crc = 0xFFFFFFFFu;
112 : 5 : crc = spdk_crc32c_update(buf, strlen(buf), crc);
113 : 5 : crc ^= 0xFFFFFFFFu;
114 : 5 : CU_ASSERT(crc == 0x6087809A);
115 : 5 : }
116 : :
117 : : static void
118 : 5 : test_crc32c_nvme(void)
119 : 5 : {
120 : 5 : unsigned int buf_size = 4096;
121 [ - + ]: 5 : char buf[buf_size];
122 : : uint32_t crc;
123 : : unsigned int i, j;
124 : :
125 : : /* All the expected CRC values are compliant with
126 : : * the NVM Command Set Specification 1.0c */
127 : :
128 : : /* Input buffer = 0s */
129 [ - + ]: 5 : memset(buf, 0, buf_size);
130 : 5 : crc = spdk_crc32c_nvme(buf, buf_size, 0);
131 : 5 : CU_ASSERT(crc == 0x98F94189);
132 : :
133 : : /* Input buffer = 1s */
134 [ - + ]: 5 : memset(buf, 0xFF, buf_size);
135 : 5 : crc = spdk_crc32c_nvme(buf, buf_size, 0);
136 : 5 : CU_ASSERT(crc == 0x25C1FE13);
137 : :
138 : : /* Input buffer = 0x00, 0x01, 0x02, ... */
139 [ - + ]: 5 : memset(buf, 0, buf_size);
140 : 5 : j = 0;
141 [ + + ]: 20485 : for (i = 0; i < buf_size; i++) {
142 : 20480 : buf[i] = (char)j;
143 [ + + ]: 20480 : if (j == 0xFF) {
144 : 80 : j = 0;
145 : : } else {
146 : 20400 : j++;
147 : : }
148 : : }
149 : 5 : crc = spdk_crc32c_nvme(buf, buf_size, 0);
150 : 5 : CU_ASSERT(crc == 0x9C71FE32);
151 : :
152 : : /* Input buffer = 0xFF, 0xFE, 0xFD, ... */
153 [ - + ]: 5 : memset(buf, 0, buf_size);
154 : 5 : j = 0xFF;
155 [ + + ]: 20485 : for (i = 0; i < buf_size ; i++) {
156 : 20480 : buf[i] = (char)j;
157 [ + + ]: 20480 : if (j == 0) {
158 : 80 : j = 0xFF;
159 : : } else {
160 : 20400 : j--;
161 : : }
162 : : }
163 : 5 : crc = spdk_crc32c_nvme(buf, buf_size, 0);
164 : 5 : CU_ASSERT(crc == 0x214941A8);
165 : 5 : }
166 : :
167 : : int
168 : 5 : main(int argc, char **argv)
169 : : {
170 : 5 : CU_pSuite suite = NULL;
171 : : unsigned int num_failures;
172 : :
173 : 5 : CU_initialize_registry();
174 : :
175 : 5 : suite = CU_add_suite("crc32c", NULL, NULL);
176 : :
177 : 5 : CU_ADD_TEST(suite, test_crc32c);
178 : 5 : CU_ADD_TEST(suite, test_crc32c_nvme);
179 : :
180 : :
181 : 5 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
182 : :
183 : 5 : CU_cleanup_registry();
184 : :
185 : 5 : return num_failures;
186 : : }
|