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