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