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