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