blob: 6da285b6c0fdb5b68b4a174f86b33ae7453647bd [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"
10extern "C" {
Lawrence Tang5202bbb2022-08-12 14:54:36 +010011#include <json.h>
Lawrence Tangd34f2b12022-07-19 15:36:31 +010012#include "../cper-parse.h"
13#include "../json-schema.h"
14#include "../generator/cper-generate.h"
Lawrence Tang580423f2022-08-24 09:37:53 +010015#include "../sections/cper-section.h"
Lawrence Tang40519cb2022-08-24 15:50:08 +010016#include "../generator/sections/gen-section.h"
Lawrence Tangd34f2b12022-07-19 15:36:31 +010017}
18
19/*
20* Test templates.
21*/
Lawrence Tangcd505202022-07-19 16:55:11 +010022
23//Tests a single randomly generated CPER section of the given type to ensure CPER-JSON IR validity.
Lawrence Tanga4f662f2022-08-08 14:37:36 +010024void cper_log_section_ir_test(const char *section_name, int single_section)
Lawrence Tangd34f2b12022-07-19 15:36:31 +010025{
Lawrence Tanga4f662f2022-08-08 14:37:36 +010026 //Generate full CPER record for the given type.
Lawrence Tange407b4c2022-07-21 13:54:01 +010027 char *buf;
28 size_t size;
Lawrence Tanga4f662f2022-08-08 14:37:36 +010029 FILE *record = generate_record_memstream(&section_name, 1, &buf, &size,
30 single_section);
Lawrence Tangd34f2b12022-07-19 15:36:31 +010031
Lawrence Tange407b4c2022-07-21 13:54:01 +010032 //Convert to IR, free resources.
Lawrence Tanga4f662f2022-08-08 14:37:36 +010033 json_object *ir;
John Chungf8fc7052024-05-03 20:05:29 +080034 if (single_section) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010035 ir = cper_single_section_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080036 } else {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010037 ir = cper_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080038 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010039 fclose(record);
40 free(buf);
Lawrence Tangd34f2b12022-07-19 15:36:31 +010041
Lawrence Tange407b4c2022-07-21 13:54:01 +010042 //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);
John Chungf8fc7052024-05-03 20:05:29 +080046 json_object_put(ir);
Lawrence Tanga4f662f2022-08-08 14:37:36 +010047 ASSERT_TRUE(valid)
48 << "IR validation test failed (single section mode = "
49 << single_section << ") with message: " << error_message;
Lawrence Tangd34f2b12022-07-19 15:36:31 +010050}
51
Lawrence Tangcd505202022-07-19 16:55:11 +010052//Checks for binary round-trip equality for a given randomly generated CPER record.
Lawrence Tanga4f662f2022-08-08 14:37:36 +010053void cper_log_section_binary_test(const char *section_name, int single_section)
Lawrence Tangcd505202022-07-19 16:55:11 +010054{
Lawrence Tange407b4c2022-07-21 13:54:01 +010055 //Generate CPER record for the given type.
56 char *buf;
57 size_t size;
Lawrence Tanga4f662f2022-08-08 14:37:36 +010058 FILE *record = generate_record_memstream(&section_name, 1, &buf, &size,
59 single_section);
Lawrence Tangcd505202022-07-19 16:55:11 +010060
Lawrence Tanga4f662f2022-08-08 14:37:36 +010061 //Convert to IR.
62 json_object *ir;
John Chungf8fc7052024-05-03 20:05:29 +080063 if (single_section) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010064 ir = cper_single_section_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080065 } else {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010066 ir = cper_to_ir(record);
John Chungf8fc7052024-05-03 20:05:29 +080067 }
Lawrence Tanga4f662f2022-08-08 14:37:36 +010068
69 //Now convert back to binary, and get a stream out.
Lawrence Tange407b4c2022-07-21 13:54:01 +010070 char *cper_buf;
71 size_t cper_buf_size;
72 FILE *stream = open_memstream(&cper_buf, &cper_buf_size);
John Chungf8fc7052024-05-03 20:05:29 +080073 if (single_section) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010074 ir_single_section_to_cper(ir, stream);
John Chungf8fc7052024-05-03 20:05:29 +080075 } else {
Lawrence Tanga4f662f2022-08-08 14:37:36 +010076 ir_to_cper(ir, stream);
John Chungf8fc7052024-05-03 20:05:29 +080077 }
Lawrence Tange407b4c2022-07-21 13:54:01 +010078 size_t cper_len = ftell(stream);
79 fclose(stream);
Lawrence Tangcd505202022-07-19 16:55:11 +010080
Lawrence Tange407b4c2022-07-21 13:54:01 +010081 //Validate the two are identical.
82 ASSERT_GE(size, cper_len);
83 ASSERT_EQ(memcmp(buf, cper_buf, cper_len), 0)
Lawrence Tanga4f662f2022-08-08 14:37:36 +010084 << "Binary output was not identical to input (single section mode = "
85 << single_section << ").";
Lawrence Tange407b4c2022-07-21 13:54:01 +010086
87 //Free everything up.
88 fclose(record);
89 free(buf);
90 free(cper_buf);
John Chungf8fc7052024-05-03 20:05:29 +080091 json_object_put(ir);
Lawrence Tangcd505202022-07-19 16:55:11 +010092}
93
Lawrence Tanga4f662f2022-08-08 14:37:36 +010094//Tests randomly generated CPER sections for IR validity of a given type, in both single section mode and full CPER log mode.
95void 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.
102void 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
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100108/*
Lawrence Tang580423f2022-08-24 09:37:53 +0100109* Non-single section assertions.
110*/
111TEST(CompileTimeAssertions, TwoWayConversion)
112{
John Chungf8fc7052024-05-03 20:05:29 +0800113 for (size_t i = 0; i < section_definitions_len; i++) {
Lawrence Tang580423f2022-08-24 09:37:53 +0100114 //If a conversion one way exists, a conversion the other way must exist.
Lawrence Tang40519cb2022-08-24 15:50:08 +0100115 std::string err =
116 "If a CPER conversion exists one way, there must be an equivalent method in reverse.";
John Chungf8fc7052024-05-03 20:05:29 +0800117 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 }
Lawrence Tang580423f2022-08-24 09:37:53 +0100124 }
125}
126
Lawrence Tang40519cb2022-08-24 15:50:08 +0100127TEST(CompileTimeAssertions, ShortcodeNoSpaces)
128{
John Chungf8fc7052024-05-03 20:05:29 +0800129 for (size_t i = 0; i < generator_definitions_len; i++) {
Lawrence Tang40519cb2022-08-24 15:50:08 +0100130 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
Lawrence Tang580423f2022-08-24 09:37:53 +0100140/*
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100141* Single section tests.
142*/
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100143
Lawrence Tangcd505202022-07-19 16:55:11 +0100144//Generic processor tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100145TEST(GenericProcessorTests, IRValid)
146{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100147 cper_log_section_dual_ir_test("generic");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100148}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100149TEST(GenericProcessorTests, BinaryEqual)
150{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100151 cper_log_section_dual_binary_test("generic");
Lawrence Tangcd505202022-07-19 16:55:11 +0100152}
153
154//IA32/x64 tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100155TEST(IA32x64Tests, IRValid)
156{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100157 cper_log_section_dual_ir_test("ia32x64");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100158}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100159TEST(IA32x64Tests, BinaryEqual)
160{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100161 cper_log_section_dual_binary_test("ia32x64");
Lawrence Tangcd505202022-07-19 16:55:11 +0100162}
163
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100164// TEST(IPFTests, IRValid) {
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100165// cper_log_section_dual_ir_test("ipf");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100166// }
Lawrence Tangcd505202022-07-19 16:55:11 +0100167
168//ARM tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100169TEST(ArmTests, IRValid)
170{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100171 cper_log_section_dual_ir_test("arm");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100172}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100173TEST(ArmTests, BinaryEqual)
174{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100175 cper_log_section_dual_binary_test("arm");
Lawrence Tangcd505202022-07-19 16:55:11 +0100176}
177
178//Memory tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100179TEST(MemoryTests, IRValid)
180{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100181 cper_log_section_dual_ir_test("memory");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100182}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100183TEST(MemoryTests, BinaryEqual)
184{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100185 cper_log_section_dual_binary_test("memory");
Lawrence Tangcd505202022-07-19 16:55:11 +0100186}
187
188//Memory 2 tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100189TEST(Memory2Tests, IRValid)
190{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100191 cper_log_section_dual_ir_test("memory2");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100192}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100193TEST(Memory2Tests, BinaryEqual)
194{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100195 cper_log_section_dual_binary_test("memory2");
Lawrence Tangcd505202022-07-19 16:55:11 +0100196}
197
198//PCIe tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100199TEST(PCIeTests, IRValid)
200{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100201 cper_log_section_dual_ir_test("pcie");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100202}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100203TEST(PCIeTests, BinaryEqual)
204{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100205 cper_log_section_dual_binary_test("pcie");
Lawrence Tangcd505202022-07-19 16:55:11 +0100206}
207
208//Firmware tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100209TEST(FirmwareTests, IRValid)
210{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100211 cper_log_section_dual_ir_test("firmware");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100212}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100213TEST(FirmwareTests, BinaryEqual)
214{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100215 cper_log_section_dual_binary_test("firmware");
Lawrence Tangcd505202022-07-19 16:55:11 +0100216}
217
218//PCI Bus tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100219TEST(PCIBusTests, IRValid)
220{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100221 cper_log_section_dual_ir_test("pcibus");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100222}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100223TEST(PCIBusTests, BinaryEqual)
224{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100225 cper_log_section_dual_binary_test("pcibus");
Lawrence Tangcd505202022-07-19 16:55:11 +0100226}
227
228//PCI Device tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100229TEST(PCIDevTests, IRValid)
230{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100231 cper_log_section_dual_ir_test("pcidev");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100232}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100233TEST(PCIDevTests, BinaryEqual)
234{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100235 cper_log_section_dual_binary_test("pcidev");
Lawrence Tangcd505202022-07-19 16:55:11 +0100236}
237
238//Generic DMAr tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100239TEST(DMArGenericTests, IRValid)
240{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100241 cper_log_section_dual_ir_test("dmargeneric");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100242}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100243TEST(DMArGenericTests, BinaryEqual)
244{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100245 cper_log_section_dual_binary_test("dmargeneric");
Lawrence Tangcd505202022-07-19 16:55:11 +0100246}
247
248//VT-d DMAr tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100249TEST(DMArVtdTests, IRValid)
250{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100251 cper_log_section_dual_ir_test("dmarvtd");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100252}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100253TEST(DMArVtdTests, BinaryEqual)
254{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100255 cper_log_section_dual_binary_test("dmarvtd");
Lawrence Tangcd505202022-07-19 16:55:11 +0100256}
257
258//IOMMU DMAr tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100259TEST(DMArIOMMUTests, IRValid)
260{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100261 cper_log_section_dual_ir_test("dmariommu");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100262}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100263TEST(DMArIOMMUTests, BinaryEqual)
264{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100265 cper_log_section_dual_binary_test("dmariommu");
Lawrence Tangcd505202022-07-19 16:55:11 +0100266}
267
268//CCIX PER tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100269TEST(CCIXPERTests, IRValid)
270{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100271 cper_log_section_dual_ir_test("ccixper");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100272}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100273TEST(CCIXPERTests, BinaryEqual)
274{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100275 cper_log_section_dual_binary_test("ccixper");
Lawrence Tangcd505202022-07-19 16:55:11 +0100276}
277
278//CXL Protocol tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100279TEST(CXLProtocolTests, IRValid)
280{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100281 cper_log_section_dual_ir_test("cxlprotocol");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100282}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100283TEST(CXLProtocolTests, BinaryEqual)
284{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100285 cper_log_section_dual_binary_test("cxlprotocol");
Lawrence Tangcd505202022-07-19 16:55:11 +0100286}
287
288//CXL Component tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100289TEST(CXLComponentTests, IRValid)
290{
Lawrence Tang8f977452022-08-24 14:55:07 +0100291 cper_log_section_dual_ir_test("cxlcomponent-media");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100292}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100293TEST(CXLComponentTests, BinaryEqual)
294{
Lawrence Tang8f977452022-08-24 14:55:07 +0100295 cper_log_section_dual_binary_test("cxlcomponent-media");
Lawrence Tangcd505202022-07-19 16:55:11 +0100296}
297
298//Unknown section tests.
Lawrence Tange407b4c2022-07-21 13:54:01 +0100299TEST(UnknownSectionTests, IRValid)
300{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100301 cper_log_section_dual_ir_test("unknown");
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100302}
Lawrence Tange407b4c2022-07-21 13:54:01 +0100303TEST(UnknownSectionTests, BinaryEqual)
304{
Lawrence Tanga4f662f2022-08-08 14:37:36 +0100305 cper_log_section_dual_binary_test("unknown");
Lawrence Tangcd505202022-07-19 16:55:11 +0100306}
Lawrence Tangd34f2b12022-07-19 15:36:31 +0100307
308//Entrypoint for the testing program.
309int main()
310{
Lawrence Tange407b4c2022-07-21 13:54:01 +0100311 testing::InitGoogleTest();
312 return RUN_ALL_TESTS();
John Chungf8fc7052024-05-03 20:05:29 +0800313}