xref: /spdk/test/unit/lib/util/crc32c.c/crc32c_ut.c (revision 784b9d48746955f210926648a0131f84f58de76f)
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_cunit.h"
9 
10 #include "util/crc32.c"
11 #include "util/crc32c.c"
12 
13 static void
14 test_crc32c(void)
15 {
16 	uint32_t crc;
17 	char buf[1024], buf1[1024];
18 	struct iovec iov[2] = {};
19 
20 	/* Verify a string's CRC32-C value against the known correct result. */
21 	snprintf(buf, sizeof(buf), "%s", "Hello world!");
22 	crc = 0xFFFFFFFFu;
23 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
24 	crc ^= 0xFFFFFFFFu;
25 	CU_ASSERT(crc == 0x7b98e751);
26 
27 	crc = 0xFFFFFFFFu;
28 	iov[0].iov_base = buf;
29 	iov[0].iov_len = strlen(buf);
30 	crc = spdk_crc32c_iov_update(iov, 1, crc);
31 	crc ^= 0xFFFFFFFFu;
32 	CU_ASSERT(crc == 0x7b98e751);
33 
34 	crc = 0xFFFFFFFFu;
35 	snprintf(buf, sizeof(buf), "%s", "Hello");
36 	iov[0].iov_base = buf;
37 	iov[0].iov_len = strlen(buf);
38 
39 	snprintf(buf1, sizeof(buf1), "%s", " world!");
40 	iov[1].iov_base = buf1;
41 	iov[1].iov_len = strlen(buf1);
42 
43 	crc = spdk_crc32c_iov_update(iov, 2, crc);
44 	crc ^= 0xFFFFFFFFu;
45 	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 	snprintf(buf, sizeof(buf), "%s", "");
55 	crc = 0xFFFFFFFFu;
56 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
57 	crc ^= 0xFFFFFFFFu;
58 	CU_ASSERT(crc == 0);
59 
60 	/* 1-byte buffer */
61 	snprintf(buf, sizeof(buf), "%s", "1");
62 	crc = 0xFFFFFFFFu;
63 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
64 	crc ^= 0xFFFFFFFFu;
65 	CU_ASSERT(crc == 0x90F599E3);
66 
67 	/* 2-byte buffer */
68 	snprintf(buf, sizeof(buf), "%s", "12");
69 	crc = 0xFFFFFFFFu;
70 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
71 	crc ^= 0xFFFFFFFFu;
72 	CU_ASSERT(crc == 0x7355C460);
73 
74 	/* 3-byte buffer */
75 	snprintf(buf, sizeof(buf), "%s", "123");
76 	crc = 0xFFFFFFFFu;
77 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
78 	crc ^= 0xFFFFFFFFu;
79 	CU_ASSERT(crc == 0x107B2FB2);
80 
81 	/* 4-byte buffer */
82 	snprintf(buf, sizeof(buf), "%s", "1234");
83 	crc = 0xFFFFFFFFu;
84 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
85 	crc ^= 0xFFFFFFFFu;
86 	CU_ASSERT(crc == 0xF63AF4EE);
87 
88 	/* 5-byte buffer */
89 	snprintf(buf, sizeof(buf), "%s", "12345");
90 	crc = 0xFFFFFFFFu;
91 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
92 	crc ^= 0xFFFFFFFFu;
93 	CU_ASSERT(crc == 0x18D12335);
94 
95 	/* 6-byte buffer */
96 	snprintf(buf, sizeof(buf), "%s", "123456");
97 	crc = 0xFFFFFFFFu;
98 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
99 	crc ^= 0xFFFFFFFFu;
100 	CU_ASSERT(crc == 0x41357186);
101 
102 	/* 7-byte buffer */
103 	snprintf(buf, sizeof(buf), "%s", "1234567");
104 	crc = 0xFFFFFFFFu;
105 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
106 	crc ^= 0xFFFFFFFFu;
107 	CU_ASSERT(crc == 0x124297EA);
108 
109 	/* Test a buffer of exactly 8 bytes (one block in the main CRC32-C loop). */
110 	snprintf(buf, sizeof(buf), "%s", "12345678");
111 	crc = 0xFFFFFFFFu;
112 	crc = spdk_crc32c_update(buf, strlen(buf), crc);
113 	crc ^= 0xFFFFFFFFu;
114 	CU_ASSERT(crc == 0x6087809A);
115 }
116 
117 int
118 main(int argc, char **argv)
119 {
120 	CU_pSuite	suite = NULL;
121 	unsigned int	num_failures;
122 
123 	CU_set_error_action(CUEA_ABORT);
124 	CU_initialize_registry();
125 
126 	suite = CU_add_suite("crc32c", NULL, NULL);
127 
128 	CU_ADD_TEST(suite, test_crc32c);
129 
130 	CU_basic_set_mode(CU_BRM_VERBOSE);
131 
132 	CU_basic_run_tests();
133 
134 	num_failures = CU_get_number_of_failures();
135 	CU_cleanup_registry();
136 
137 	return num_failures;
138 }
139