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