blob: 061f0a87b46a42647aae4be0e020f90625bf753e [file] [log] [blame]
Lawrence Tangd34f2b12022-07-19 15:36:31 +01001/**
2 * Defines tests for validating CPER-JSON IR output from the cper-parse library.
Ed Tanousfedd4572024-07-12 13:56:00 -07003 *
Lawrence Tangd34f2b12022-07-19 15:36:31 +01004 * Author: Lawrence.Tang@arm.com
5 **/
6
John Chungf8fc7052024-05-03 20:05:29 +08007#include <cctype>
Lawrence Tangd34f2b12022-07-19 15:36:31 +01008#include "gtest/gtest.h"
9#include "test-utils.hpp"
Lawrence Tang5202bbb2022-08-12 14:54:36 +010010#include <json.h>
Lawrence Tangd34f2b12022-07-19 15:36:31 +010011#include "../cper-parse.h"
12#include "../json-schema.h"
13#include "../generator/cper-generate.h"
Lawrence Tang580423f2022-08-24 09:37:53 +010014#include "../sections/cper-section.h"
Lawrence Tang40519cb2022-08-24 15:50:08 +010015#include "../generator/sections/gen-section.h"
Lawrence Tangd34f2b12022-07-19 15:36:31 +010016
17/*
18* Test templates.
19*/
Lawrence Tangcd505202022-07-19 16:55:11 +010020
21//Tests a single randomly generated CPER section of the given type to ensure CPER-JSON IR validity.
Lawrence Tanga4f662f2022-08-08 14:37:36 +010022void cper_log_section_ir_test(const char *section_name, int single_section)
Lawrence Tangd34f2b12022-07-19 15:36:31 +010023{
Lawrence Tanga4f662f2022-08-08 14:37:36 +010024 //Generate full CPER record for the given type.
Lawrence Tange407b4c2022-07-21 13:54:01 +010025 char *buf;
26 size_t size;
Lawrence Tanga4f662f2022-08-08 14:37:36 +010027 FILE *record = generate_record_memstream(&section_name, 1, &buf, &size,
28 single_section);
Lawrence Tangd34f2b12022-07-19 15:36:31 +010029
Lawrence Tange407b4c2022-07-21 13:54:01 +010030 //Convert to IR, free resources.
Lawrence Tanga4f662f2022-08-08 14:37:36 +010031 json_object *ir;
John Chungf8fc7052024-05-03 20:05:29 +080032 if (single_section) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010033 ir = cper_single_section_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080034 } else {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010035 ir = cper_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080036 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010037 fclose(record);
38 free(buf);
Lawrence Tangd34f2b12022-07-19 15:36:31 +010039
Lawrence Tange407b4c2022-07-21 13:54:01 +010040 //Validate against schema.
41 char error_message[JSON_ERROR_MSG_MAX_LEN] = { 0 };
Ed Tanous358c7e12024-07-15 13:54:57 -070042 int valid =
43 validate_schema_from_file(LIBCPER_JSON_SPEC, ir, error_message);
John Chungf8fc7052024-05-03 20:05:29 +080044 json_object_put(ir);
Lawrence Tanga4f662f2022-08-08 14:37:36 +010045 ASSERT_TRUE(valid)
46 << "IR validation test failed (single section mode = "
47 << single_section << ") with message: " << error_message;
Lawrence Tangd34f2b12022-07-19 15:36:31 +010048}
49
Lawrence Tangcd505202022-07-19 16:55:11 +010050//Checks for binary round-trip equality for a given randomly generated CPER record.
Lawrence Tanga4f662f2022-08-08 14:37:36 +010051void cper_log_section_binary_test(const char *section_name, int single_section)
Lawrence Tangcd505202022-07-19 16:55:11 +010052{
Lawrence Tange407b4c2022-07-21 13:54:01 +010053 //Generate CPER record for the given type.
54 char *buf;
55 size_t size;
Lawrence Tanga4f662f2022-08-08 14:37:36 +010056 FILE *record = generate_record_memstream(&section_name, 1, &buf, &size,
57 single_section);
Lawrence Tangcd505202022-07-19 16:55:11 +010058
Lawrence Tanga4f662f2022-08-08 14:37:36 +010059 //Convert to IR.
60 json_object *ir;
John Chungf8fc7052024-05-03 20:05:29 +080061 if (single_section) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010062 ir = cper_single_section_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080063 } else {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010064 ir = cper_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080065 }
Lawrence Tanga4f662f2022-08-08 14:37:36 +010066
67 //Now convert back to binary, and get a stream out.
Lawrence Tange407b4c2022-07-21 13:54:01 +010068 char *cper_buf;
69 size_t cper_buf_size;
70 FILE *stream = open_memstream(&cper_buf, &cper_buf_size);
John Chungf8fc7052024-05-03 20:05:29 +080071 if (single_section) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010072 ir_single_section_to_cper(ir, stream);
John Chungf8fc7052024-05-03 20:05:29 +080073 } else {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010074 ir_to_cper(ir, stream);
John Chungf8fc7052024-05-03 20:05:29 +080075 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010076 size_t cper_len = ftell(stream);
77 fclose(stream);
Lawrence Tangcd505202022-07-19 16:55:11 +010078
Lawrence Tange407b4c2022-07-21 13:54:01 +010079 //Validate the two are identical.
80 ASSERT_GE(size, cper_len);
81 ASSERT_EQ(memcmp(buf, cper_buf, cper_len), 0)
Lawrence Tanga4f662f2022-08-08 14:37:36 +010082 << "Binary output was not identical to input (single section mode = "
83 << single_section << ").";
Lawrence Tange407b4c2022-07-21 13:54:01 +010084
85 //Free everything up.
86 fclose(record);
87 free(buf);
88 free(cper_buf);
John Chungf8fc7052024-05-03 20:05:29 +080089 json_object_put(ir);
Lawrence Tangcd505202022-07-19 16:55:11 +010090}
91
Lawrence Tanga4f662f2022-08-08 14:37:36 +010092//Tests randomly generated CPER sections for IR validity of a given type, in both single section mode and full CPER log mode.
93void cper_log_section_dual_ir_test(const char *section_name)
94{
95 cper_log_section_ir_test(section_name, 0);
96 cper_log_section_ir_test(section_name, 1);
97}
98
99//Tests randomly generated CPER sections for binary compatibility of a given type, in both single section mode and full CPER log mode.
100void cper_log_section_dual_binary_test(const char *section_name)
101{
102 cper_log_section_binary_test(section_name, 0);
103 cper_log_section_binary_test(section_name, 1);
104}
105
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100106/*
Lawrence Tang580423f2022-08-24 09:37:53 +0100107* Non-single section assertions.
108*/
109TEST(CompileTimeAssertions, TwoWayConversion)
110{
John Chungf8fc7052024-05-03 20:05:29 +0800111 for (size_t i = 0; i < section_definitions_len; i++) {
Lawrence Tang580423f2022-08-24 09:37:53 +0100112 //If a conversion one way exists, a conversion the other way must exist.
Lawrence Tang40519cb2022-08-24 15:50:08 +0100113 std::string err =
114 "If a CPER conversion exists one way, there must be an equivalent method in reverse.";
John Chungf8fc7052024-05-03 20:05:29 +0800115 if (section_definitions[i].ToCPER != NULL) {
116 ASSERT_NE(section_definitions[i].ToIR, nullptr) << err;
117 }
118 if (section_definitions[i].ToIR != NULL) {
119 ASSERT_NE(section_definitions[i].ToCPER, nullptr)
120 << err;
121 }
Lawrence Tang580423f2022-08-24 09:37:53 +0100122 }
123}
124
Lawrence Tang40519cb2022-08-24 15:50:08 +0100125TEST(CompileTimeAssertions, ShortcodeNoSpaces)
126{
John Chungf8fc7052024-05-03 20:05:29 +0800127 for (size_t i = 0; i < generator_definitions_len; i++) {
Lawrence Tang40519cb2022-08-24 15:50:08 +0100128 for (int j = 0;
129 generator_definitions[i].ShortName[j + 1] != '\0'; j++) {
130 ASSERT_FALSE(
131 isspace(generator_definitions[i].ShortName[j]))
132 << "Illegal space character detected in shortcode '"
133 << generator_definitions[i].ShortName << "'.";
134 }
135 }
136}
137
Lawrence Tang580423f2022-08-24 09:37:53 +0100138/*
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100139* Single section tests.
140*/
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100141
Lawrence Tangcd505202022-07-19 16:55:11 +0100142//Generic processor tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100143TEST(GenericProcessorTests, IRValid)
144{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100145 cper_log_section_dual_ir_test("generic");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100146}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100147TEST(GenericProcessorTests, BinaryEqual)
148{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100149 cper_log_section_dual_binary_test("generic");
Lawrence Tangcd505202022-07-19 16:55:11 +0100150}
151
152//IA32/x64 tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100153TEST(IA32x64Tests, IRValid)
154{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100155 cper_log_section_dual_ir_test("ia32x64");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100156}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100157TEST(IA32x64Tests, BinaryEqual)
158{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100159 cper_log_section_dual_binary_test("ia32x64");
Lawrence Tangcd505202022-07-19 16:55:11 +0100160}
161
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100162// TEST(IPFTests, IRValid) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100163// cper_log_section_dual_ir_test("ipf");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100164// }
Lawrence Tangcd505202022-07-19 16:55:11 +0100165
166//ARM tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100167TEST(ArmTests, IRValid)
168{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100169 cper_log_section_dual_ir_test("arm");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100170}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100171TEST(ArmTests, BinaryEqual)
172{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100173 cper_log_section_dual_binary_test("arm");
Lawrence Tangcd505202022-07-19 16:55:11 +0100174}
175
176//Memory tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100177TEST(MemoryTests, IRValid)
178{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100179 cper_log_section_dual_ir_test("memory");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100180}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100181TEST(MemoryTests, BinaryEqual)
182{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100183 cper_log_section_dual_binary_test("memory");
Lawrence Tangcd505202022-07-19 16:55:11 +0100184}
185
186//Memory 2 tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100187TEST(Memory2Tests, IRValid)
188{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100189 cper_log_section_dual_ir_test("memory2");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100190}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100191TEST(Memory2Tests, BinaryEqual)
192{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100193 cper_log_section_dual_binary_test("memory2");
Lawrence Tangcd505202022-07-19 16:55:11 +0100194}
195
196//PCIe tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100197TEST(PCIeTests, IRValid)
198{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100199 cper_log_section_dual_ir_test("pcie");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100200}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100201TEST(PCIeTests, BinaryEqual)
202{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100203 cper_log_section_dual_binary_test("pcie");
Lawrence Tangcd505202022-07-19 16:55:11 +0100204}
205
206//Firmware tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100207TEST(FirmwareTests, IRValid)
208{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100209 cper_log_section_dual_ir_test("firmware");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100210}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100211TEST(FirmwareTests, BinaryEqual)
212{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100213 cper_log_section_dual_binary_test("firmware");
Lawrence Tangcd505202022-07-19 16:55:11 +0100214}
215
216//PCI Bus tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100217TEST(PCIBusTests, IRValid)
218{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100219 cper_log_section_dual_ir_test("pcibus");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100220}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100221TEST(PCIBusTests, BinaryEqual)
222{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100223 cper_log_section_dual_binary_test("pcibus");
Lawrence Tangcd505202022-07-19 16:55:11 +0100224}
225
226//PCI Device tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100227TEST(PCIDevTests, IRValid)
228{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100229 cper_log_section_dual_ir_test("pcidev");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100230}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100231TEST(PCIDevTests, BinaryEqual)
232{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100233 cper_log_section_dual_binary_test("pcidev");
Lawrence Tangcd505202022-07-19 16:55:11 +0100234}
235
236//Generic DMAr tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100237TEST(DMArGenericTests, IRValid)
238{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100239 cper_log_section_dual_ir_test("dmargeneric");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100240}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100241TEST(DMArGenericTests, BinaryEqual)
242{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100243 cper_log_section_dual_binary_test("dmargeneric");
Lawrence Tangcd505202022-07-19 16:55:11 +0100244}
245
246//VT-d DMAr tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100247TEST(DMArVtdTests, IRValid)
248{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100249 cper_log_section_dual_ir_test("dmarvtd");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100250}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100251TEST(DMArVtdTests, BinaryEqual)
252{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100253 cper_log_section_dual_binary_test("dmarvtd");
Lawrence Tangcd505202022-07-19 16:55:11 +0100254}
255
256//IOMMU DMAr tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100257TEST(DMArIOMMUTests, IRValid)
258{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100259 cper_log_section_dual_ir_test("dmariommu");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100260}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100261TEST(DMArIOMMUTests, BinaryEqual)
262{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100263 cper_log_section_dual_binary_test("dmariommu");
Lawrence Tangcd505202022-07-19 16:55:11 +0100264}
265
266//CCIX PER tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100267TEST(CCIXPERTests, IRValid)
268{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100269 cper_log_section_dual_ir_test("ccixper");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100270}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100271TEST(CCIXPERTests, BinaryEqual)
272{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100273 cper_log_section_dual_binary_test("ccixper");
Lawrence Tangcd505202022-07-19 16:55:11 +0100274}
275
276//CXL Protocol tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100277TEST(CXLProtocolTests, IRValid)
278{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100279 cper_log_section_dual_ir_test("cxlprotocol");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100280}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100281TEST(CXLProtocolTests, BinaryEqual)
282{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100283 cper_log_section_dual_binary_test("cxlprotocol");
Lawrence Tangcd505202022-07-19 16:55:11 +0100284}
285
286//CXL Component tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100287TEST(CXLComponentTests, IRValid)
288{
Lawrence Tang8f977452022-08-24 14:55:07 +0100289 cper_log_section_dual_ir_test("cxlcomponent-media");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100290}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100291TEST(CXLComponentTests, BinaryEqual)
292{
Lawrence Tang8f977452022-08-24 14:55:07 +0100293 cper_log_section_dual_binary_test("cxlcomponent-media");
Lawrence Tangcd505202022-07-19 16:55:11 +0100294}
295
296//Unknown section tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100297TEST(UnknownSectionTests, IRValid)
298{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100299 cper_log_section_dual_ir_test("unknown");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100300}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100301TEST(UnknownSectionTests, BinaryEqual)
302{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100303 cper_log_section_dual_binary_test("unknown");
Lawrence Tangcd505202022-07-19 16:55:11 +0100304}
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100305
306//Entrypoint for the testing program.
307int main()
308{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100309 testing::InitGoogleTest();
310 return RUN_ALL_TESTS();
John Chungf8fc7052024-05-03 20:05:29 +0800311}