xref: /openbmc/libcper/tests/ir-tests.cpp (revision 40519cb4)
1 /**
2  * Defines tests for validating CPER-JSON IR output from the cper-parse library.
3  *
4  * Author: Lawrence.Tang@arm.com
5  **/
6 
7 #include <ctype.h>
8 #include "gtest/gtest.h"
9 #include "test-utils.hpp"
10 extern "C" {
11 #include <json.h>
12 #include "../cper-parse.h"
13 #include "../json-schema.h"
14 #include "../generator/cper-generate.h"
15 #include "../sections/cper-section.h"
16 #include "../generator/sections/gen-section.h"
17 }
18 
19 /*
20 * Test templates.
21 */
22 
23 //Tests a single randomly generated CPER section of the given type to ensure CPER-JSON IR validity.
24 void cper_log_section_ir_test(const char *section_name, int single_section)
25 {
26 	//Generate full CPER record for the given type.
27 	char *buf;
28 	size_t size;
29 	FILE *record = generate_record_memstream(&section_name, 1, &buf, &size,
30 						 single_section);
31 
32 	//Convert to IR, free resources.
33 	json_object *ir;
34 	if (single_section)
35 		ir = cper_single_section_to_ir(record);
36 	else
37 		ir = cper_to_ir(record);
38 	fclose(record);
39 	free(buf);
40 
41 	//Validate against schema.
42 	char error_message[JSON_ERROR_MSG_MAX_LEN] = { 0 };
43 	int valid = validate_schema_from_file("./specification/cper-json.json",
44 					      ir, error_message);
45 	ASSERT_TRUE(valid)
46 		<< "IR validation test failed (single section mode = "
47 		<< single_section << ") with message: " << error_message;
48 }
49 
50 //Checks for binary round-trip equality for a given randomly generated CPER record.
51 void cper_log_section_binary_test(const char *section_name, int single_section)
52 {
53 	//Generate CPER record for the given type.
54 	char *buf;
55 	size_t size;
56 	FILE *record = generate_record_memstream(&section_name, 1, &buf, &size,
57 						 single_section);
58 
59 	//Convert to IR.
60 	json_object *ir;
61 	if (single_section)
62 		ir = cper_single_section_to_ir(record);
63 	else
64 		ir = cper_to_ir(record);
65 
66 	//Now convert back to binary, and get a stream out.
67 	char *cper_buf;
68 	size_t cper_buf_size;
69 	FILE *stream = open_memstream(&cper_buf, &cper_buf_size);
70 	if (single_section)
71 		ir_single_section_to_cper(ir, stream);
72 	else
73 		ir_to_cper(ir, stream);
74 	size_t cper_len = ftell(stream);
75 	fclose(stream);
76 
77 	//Validate the two are identical.
78 	ASSERT_GE(size, cper_len);
79 	ASSERT_EQ(memcmp(buf, cper_buf, cper_len), 0)
80 		<< "Binary output was not identical to input (single section mode = "
81 		<< single_section << ").";
82 
83 	//Free everything up.
84 	fclose(record);
85 	free(buf);
86 	free(cper_buf);
87 }
88 
89 //Tests randomly generated CPER sections for IR validity of a given type, in both single section mode and full CPER log mode.
90 void cper_log_section_dual_ir_test(const char *section_name)
91 {
92 	cper_log_section_ir_test(section_name, 0);
93 	cper_log_section_ir_test(section_name, 1);
94 }
95 
96 //Tests randomly generated CPER sections for binary compatibility of a given type, in both single section mode and full CPER log mode.
97 void cper_log_section_dual_binary_test(const char *section_name)
98 {
99 	cper_log_section_binary_test(section_name, 0);
100 	cper_log_section_binary_test(section_name, 1);
101 }
102 
103 /*
104 * Non-single section assertions.
105 */
106 TEST(CompileTimeAssertions, TwoWayConversion)
107 {
108 	for (int i = 0; i < section_definitions_len; i++) {
109 		//If a conversion one way exists, a conversion the other way must exist.
110 		std::string err =
111 			"If a CPER conversion exists one way, there must be an equivalent method in reverse.";
112 		if (section_definitions[i].ToCPER != NULL)
113 			ASSERT_NE(section_definitions[i].ToIR, NULL) << err;
114 		if (section_definitions[i].ToIR != NULL)
115 			ASSERT_NE(section_definitions[i].ToCPER, NULL) << err;
116 	}
117 }
118 
119 TEST(CompileTimeAssertions, ShortcodeNoSpaces)
120 {
121 	for (int i = 0; i < generator_definitions_len; i++) {
122 		for (int j = 0;
123 		     generator_definitions[i].ShortName[j + 1] != '\0'; j++) {
124 			ASSERT_FALSE(
125 				isspace(generator_definitions[i].ShortName[j]))
126 				<< "Illegal space character detected in shortcode '"
127 				<< generator_definitions[i].ShortName << "'.";
128 		}
129 	}
130 }
131 
132 /*
133 * Single section tests.
134 */
135 
136 //Generic processor tests.
137 TEST(GenericProcessorTests, IRValid)
138 {
139 	cper_log_section_dual_ir_test("generic");
140 }
141 TEST(GenericProcessorTests, BinaryEqual)
142 {
143 	cper_log_section_dual_binary_test("generic");
144 }
145 
146 //IA32/x64 tests.
147 TEST(IA32x64Tests, IRValid)
148 {
149 	cper_log_section_dual_ir_test("ia32x64");
150 }
151 TEST(IA32x64Tests, BinaryEqual)
152 {
153 	cper_log_section_dual_binary_test("ia32x64");
154 }
155 
156 // TEST(IPFTests, IRValid) {
157 //     cper_log_section_dual_ir_test("ipf");
158 // }
159 
160 //ARM tests.
161 TEST(ArmTests, IRValid)
162 {
163 	cper_log_section_dual_ir_test("arm");
164 }
165 TEST(ArmTests, BinaryEqual)
166 {
167 	cper_log_section_dual_binary_test("arm");
168 }
169 
170 //Memory tests.
171 TEST(MemoryTests, IRValid)
172 {
173 	cper_log_section_dual_ir_test("memory");
174 }
175 TEST(MemoryTests, BinaryEqual)
176 {
177 	cper_log_section_dual_binary_test("memory");
178 }
179 
180 //Memory 2 tests.
181 TEST(Memory2Tests, IRValid)
182 {
183 	cper_log_section_dual_ir_test("memory2");
184 }
185 TEST(Memory2Tests, BinaryEqual)
186 {
187 	cper_log_section_dual_binary_test("memory2");
188 }
189 
190 //PCIe tests.
191 TEST(PCIeTests, IRValid)
192 {
193 	cper_log_section_dual_ir_test("pcie");
194 }
195 TEST(PCIeTests, BinaryEqual)
196 {
197 	cper_log_section_dual_binary_test("pcie");
198 }
199 
200 //Firmware tests.
201 TEST(FirmwareTests, IRValid)
202 {
203 	cper_log_section_dual_ir_test("firmware");
204 }
205 TEST(FirmwareTests, BinaryEqual)
206 {
207 	cper_log_section_dual_binary_test("firmware");
208 }
209 
210 //PCI Bus tests.
211 TEST(PCIBusTests, IRValid)
212 {
213 	cper_log_section_dual_ir_test("pcibus");
214 }
215 TEST(PCIBusTests, BinaryEqual)
216 {
217 	cper_log_section_dual_binary_test("pcibus");
218 }
219 
220 //PCI Device tests.
221 TEST(PCIDevTests, IRValid)
222 {
223 	cper_log_section_dual_ir_test("pcidev");
224 }
225 TEST(PCIDevTests, BinaryEqual)
226 {
227 	cper_log_section_dual_binary_test("pcidev");
228 }
229 
230 //Generic DMAr tests.
231 TEST(DMArGenericTests, IRValid)
232 {
233 	cper_log_section_dual_ir_test("dmargeneric");
234 }
235 TEST(DMArGenericTests, BinaryEqual)
236 {
237 	cper_log_section_dual_binary_test("dmargeneric");
238 }
239 
240 //VT-d DMAr tests.
241 TEST(DMArVtdTests, IRValid)
242 {
243 	cper_log_section_dual_ir_test("dmarvtd");
244 }
245 TEST(DMArVtdTests, BinaryEqual)
246 {
247 	cper_log_section_dual_binary_test("dmarvtd");
248 }
249 
250 //IOMMU DMAr tests.
251 TEST(DMArIOMMUTests, IRValid)
252 {
253 	cper_log_section_dual_ir_test("dmariommu");
254 }
255 TEST(DMArIOMMUTests, BinaryEqual)
256 {
257 	cper_log_section_dual_binary_test("dmariommu");
258 }
259 
260 //CCIX PER tests.
261 TEST(CCIXPERTests, IRValid)
262 {
263 	cper_log_section_dual_ir_test("ccixper");
264 }
265 TEST(CCIXPERTests, BinaryEqual)
266 {
267 	cper_log_section_dual_binary_test("ccixper");
268 }
269 
270 //CXL Protocol tests.
271 TEST(CXLProtocolTests, IRValid)
272 {
273 	cper_log_section_dual_ir_test("cxlprotocol");
274 }
275 TEST(CXLProtocolTests, BinaryEqual)
276 {
277 	cper_log_section_dual_binary_test("cxlprotocol");
278 }
279 
280 //CXL Component tests.
281 TEST(CXLComponentTests, IRValid)
282 {
283 	cper_log_section_dual_ir_test("cxlcomponent-media");
284 }
285 TEST(CXLComponentTests, BinaryEqual)
286 {
287 	cper_log_section_dual_binary_test("cxlcomponent-media");
288 }
289 
290 //Unknown section tests.
291 TEST(UnknownSectionTests, IRValid)
292 {
293 	cper_log_section_dual_ir_test("unknown");
294 }
295 TEST(UnknownSectionTests, BinaryEqual)
296 {
297 	cper_log_section_dual_binary_test("unknown");
298 }
299 
300 //Entrypoint for the testing program.
301 int main()
302 {
303 	testing::InitGoogleTest();
304 	return RUN_ALL_TESTS();
305 }