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