Json daccor
json daccor is a json-schema validation library that accepts json-c
objects as input, and seems to be designed for openwrt, a system
with very similar requirements to BMCs.
Using this library has several motivations. First, it keeps
libcper as a C application so integrations aren't required to provide
a c++ toolchain to be able to run unit tests.
Next, it means that we avoid an "expensive" conversion in unit tests
from json-c -> nlohmann just so we can use a third library, valijson
In terms of dependency count, it drops one dependency.
(nlohmann+valijson) to (json daccor)
Finally, it means that in the future versions of the library, we
can allow json-schema verification as an option in the library
itself, which would allow us to give a CLI option for verifying
schema on any arbitrary output (helping in debugging).
Testing to see if it will work and what improvements it makes
Change-Id: I1c00bf2ef9b898b2e5decd90b749c784fb4de109
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/.clang-tidy b/.clang-tidy
index c9fa39f..56265b7 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -147,7 +147,6 @@
misc-uniqueptr-reset-release,
misc-unused-using-decls,
modernize-avoid-bind,
-modernize-deprecated-headers,
modernize-deprecated-ios-base-aliases,
modernize-loop-convert,
modernize-make-shared,
@@ -214,4 +213,3 @@
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
- { key: readability-identifier-naming.StructCase, value: lower_case }
- - { key: cppcoreguidelines-macro-usage.AllowedRegexp, value: DEBUG*|NLOHMANN_JSON_SERIALIZE_ENUM }
diff --git a/meson.build b/meson.build
index a946d11..e669bb8 100644
--- a/meson.build
+++ b/meson.build
@@ -73,15 +73,7 @@
cc = meson.get_compiler('c')
-json_c_dep = dependency('json-c', required: false)
-if not json_c_dep.found()
- json_c = subproject(
- 'json-c',
- required: true,
- default_options: ['warning_level=0'],
- )
- json_c_dep = json_c.get_variable('json_c_dep')
-endif
+json_c_dep = dependency('json-c')
libcper_include = ['include']
libcper_include_dir = include_directories(libcper_include, is_system: true)
diff --git a/subprojects/json-c.wrap b/subprojects/json-c.wrap
index aca2cef..e68e6ef 100644
--- a/subprojects/json-c.wrap
+++ b/subprojects/json-c.wrap
@@ -1,14 +1,7 @@
-[wrap-file]
-directory = json-c-0.18
-source_url = https://s3.amazonaws.com/json-c_releases/releases/json-c-0.18.tar.gz
-source_filename = json-c-0.18.tar.gz
-source_hash = 876ab046479166b869afc6896d288183bbc0e5843f141200c677b3e8dfb11724
-patch_filename = json-c_0.18-1_patch.zip
-patch_url = https://wrapdb.mesonbuild.com/v2/json-c_0.18-1/get_patch
-patch_hash = c9d2c0449a9686755445cd18d7cff597f21e418e11a786441de7b8947ff43798
-source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/json-c_0.18-1/json-c-0.18.tar.gz
-wrapdb_version = 0.18-1
+[wrap-git]
+revision = json-c-0.18-20240915
+url = https://github.com/json-c/json-c.git
+patch_directory = json-c
[provide]
json-c = json_c_dep
-
diff --git a/subprojects/jsoncdac.wrap b/subprojects/jsoncdac.wrap
new file mode 100644
index 0000000..e2636a1
--- /dev/null
+++ b/subprojects/jsoncdac.wrap
@@ -0,0 +1,8 @@
+[wrap-git]
+revision = HEAD
+url = https://github.com/domoslabs/jsonc-daccord.git
+patch_directory = jsoncdac
+
+[provide]
+jsoncdac = jsoncdac_dep
+
diff --git a/subprojects/packagefiles/jsoncdac/meson.build b/subprojects/packagefiles/jsoncdac/meson.build
new file mode 100644
index 0000000..6cc3bfc
--- /dev/null
+++ b/subprojects/packagefiles/jsoncdac/meson.build
@@ -0,0 +1,59 @@
+project(
+ 'libjsoncdac',
+ ['c'],
+ meson_version: '>=1.1.1',
+ default_options: ['default_library=static', 'c_std=gnu23'],
+)
+conf_data = configuration_data(
+ {
+ 'PROJECT_NAME': 'jsoncdac',
+ 'PROJECT_VERSION': '0.1',
+ 'PROJECT_VERSION_MAJOR': '0',
+ 'PROJECT_VERSION_MINOR': '1',
+ 'PROJECT_VERSION_PATCH': '0',
+ },
+)
+configure_file(
+ input: 'config.h.in',
+ output: 'version_config.h',
+ configuration: conf_data,
+)
+deps = []
+
+add_project_arguments('-Wno-unused-parameter', language: 'c')
+add_project_arguments('-Wformat=0', language: 'c')
+
+jsonc = dependency('json-c')
+deps += jsonc
+
+jsoncdac_sources = files(
+ 'libjsoncdac/additionalproperties.c',
+ 'libjsoncdac/contains.c',
+ 'libjsoncdac/dependent.c',
+ #'libjsoncdac/download.c',
+ #'libjsoncdac/jdac-cli.c',
+ 'libjsoncdac/output.c',
+ 'libjsoncdac/pattern.c',
+ 'libjsoncdac/patternproperties.c',
+ 'libjsoncdac/propertynames.c',
+ 'libjsoncdac/ref.c',
+ 'libjsoncdac/regex_match.c',
+ 'libjsoncdac/store.c',
+ 'libjsoncdac/subschemalogic.c',
+ 'libjsoncdac/validate.c',
+)
+
+jsoncdac_deps = [dependency('json-c')]
+cc = meson.get_compiler('c')
+m_dep = cc.find_library('m', required: false)
+if m_dep.found()
+ deps += m_dep
+endif
+
+jsoncdac = library('jsoncdac', jsoncdac_sources, dependencies: deps)
+
+jsoncdac_dep = declare_dependency(
+ link_with: jsoncdac,
+ dependencies: deps,
+ include_directories: include_directories('include'),
+)
diff --git a/tests/fuzz_cper_buf_to_ir.cpp b/tests/fuzz_cper_buf_to_ir.cpp
index 4baef7b..b947782 100644
--- a/tests/fuzz_cper_buf_to_ir.cpp
+++ b/tests/fuzz_cper_buf_to_ir.cpp
@@ -1,3 +1,4 @@
+#include <cassert>
#include "libcper/cper-parse.h"
#include "test-utils.hpp"
@@ -7,19 +8,11 @@
if (ir == NULL) {
return 0;
}
- char *str = strdup(json_object_to_json_string(ir));
- nlohmann::json jsonData = nlohmann::json::parse(str, nullptr, false);
- free(str);
- assert(jsonData.is_discarded() == false);
- std::string error_message;
- static std::unique_ptr<valijson::Schema> schema =
- load_schema(AddRequiredProps::NO, 0);
-
- int valid = schema_validate_from_file(*schema, jsonData, error_message);
+ int valid = schema_validate_from_file(ir, 0 /* single_section */,
+ /*all_valid_bits*/ 0);
if (!valid) {
- std::cout << "JSON: " << jsonData.dump(4) << std::endl;
- std::cout << "Error: " << error_message << std::endl;
+ printf("JSON: %s\n", json_object_to_json_string(ir));
}
assert(valid);
json_object_put(ir);
diff --git a/tests/ir-tests.cpp b/tests/ir-tests.cpp
index a43aced..b30e2ec 100644
--- a/tests/ir-tests.cpp
+++ b/tests/ir-tests.cpp
@@ -4,20 +4,19 @@
* Author: Lawrence.Tang@arm.com
**/
-#include <cctype>
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
#include "test-utils.hpp"
-#include <json.h>
+#include <cctype>
#include <charconv>
-#include <nlohmann/json.hpp>
#include <filesystem>
-#include <fstream>
-#include <libcper/cper-parse.h>
-#include <libcper/json-schema.h>
-#include <libcper/generator/cper-generate.h>
-#include <libcper/sections/cper-section.h>
-#include <libcper/generator/sections/gen-section.h>
#include <format>
+#include <fstream>
+#include <json.h>
+#include <libcper/cper-parse.h>
+#include <libcper/generator/cper-generate.h>
+#include <libcper/generator/sections/gen-section.h>
+#include <libcper/json-schema.h>
+#include <libcper/sections/cper-section.h>
namespace fs = std::filesystem;
@@ -76,20 +75,13 @@
FAIL();
return;
}
- char *str = strdup(json_object_to_json_string(ir));
- nlohmann::json jsonData = nlohmann::json::parse(str, nullptr, false);
- if (jsonData.is_discarded()) {
- std::cerr << "cper_create_examples: JSON parse error:"
- << std::endl;
- }
- free(str);
- fclose(record);
- free(buf);
//Write json output to disk
- std::ofstream jsonOutFile(json_out);
- jsonOutFile << std::setw(4) << jsonData << std::endl;
- jsonOutFile.close();
+ json_object_to_file_ext(json_out.c_str(), ir, JSON_C_TO_STRING_PRETTY);
+ json_object_put(ir);
+
+ fclose(record);
+ free(buf);
}
std::vector<unsigned char> string_to_binary(const std::string &source)
@@ -141,28 +133,22 @@
FAIL();
return;
}
- const char *str = json_object_to_json_string(ir);
- nlohmann::json jsonData = nlohmann::json::parse(str, nullptr, false);
- if (jsonData.is_discarded()) {
- std::cerr << "cper_example_section_ir_test: JSON parse error:"
- << std::endl;
- FAIL() << "cper_example_section_ir_test: JSON parse error:";
- json_object_put(ir);
+ json_object *expected = json_object_from_file(json.c_str());
+ ASSERT_NE(expected, nullptr);
+ if (expected == nullptr) {
+ const char *str = json_object_to_json_string(ir);
+
+ const char *expected_str = json_object_to_json_string(expected);
+
+ EXPECT_EQ(str, expected_str);
return;
}
- //Open json example file
- nlohmann::json jGolden = loadJson(json.string().c_str());
- if (jGolden.is_discarded()) {
- std::cerr << "Could not open JSON example file: " << json
- << std::endl;
- FAIL() << "Could not open JSON example file";
- }
+ EXPECT_TRUE(json_object_equal(ir, expected));
json_object_put(ir);
-
- EXPECT_EQ(jGolden, jsonData);
+ json_object_put(expected);
}
//Tests a single randomly generated CPER section of the given type to ensure CPER-JSON IR validity.
@@ -183,25 +169,16 @@
ir = cper_to_ir(record);
}
- char *str = strdup(json_object_to_json_string(ir));
- nlohmann::json jsonData = nlohmann::json::parse(str, nullptr, false);
- if (jsonData.is_discarded()) {
- std::cerr << "Could not parse json output" << std::endl;
- }
- free(str);
fclose(record);
free(buf);
//Validate against schema.
- std::string error_message;
- std::unique_ptr<valijson::Schema> schema =
- load_schema(AddRequiredProps::YES, single_section);
- int valid = schema_validate_from_file(*schema, jsonData, error_message);
+ int valid = schema_validate_from_file(ir, single_section,
+ /*all_valid_bits*/ 1);
json_object_put(ir);
- ASSERT_TRUE(valid)
+ EXPECT_TRUE(valid)
<< "IR validation test failed (single section mode = "
- << single_section << ") with message: " << error_message
- << jsonData.dump(4) << "\n";
+ << single_section << ")\n";
}
std::string to_hex(char *input, size_t size)
diff --git a/tests/meson.build b/tests/meson.build
index ca21b42..2f1e2b2 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -21,22 +21,7 @@
endif
endif
-nlohmann_json_dep = dependency(
- 'nlohmann_json',
- required: false,
- version: '>=3.11.2',
- include_type: 'system',
-)
-if not nlohmann_json_dep.found()
- nlohmann_proj = subproject('nlohmann_json', required: true)
- nlohmann_json_dep = nlohmann_proj.get_variable('nlohmann_json_dep')
-endif
-
-valijson_dep = dependency('valijson', required: false)
-if not valijson_dep.found()
- valijson_proj = cmake.subproject('valijson')
- valijson_dep = valijson_proj.get_variable('valijson_dep')
-endif
+jsonc_daccord = dependency('jsoncdac')
test_sources = ['test-utils.cpp', 'base64_test.cpp']
@@ -50,13 +35,12 @@
include_directories: include_directories(test_include_dirs),
cpp_args: '-fpermissive',
dependencies: [
+ json_c_dep,
+ jsonc_daccord,
libcper_parse_dep,
libcper_generate_dep,
- json_c_dep,
gtest,
gmock,
- nlohmann_json_dep,
- valijson_dep,
],
)
test('test-cper-tests', cper_tests)
@@ -81,13 +65,7 @@
cpp_args: fuzz_args,
c_args: fuzz_args,
link_args: fuzz_args,
- dependencies: [
- json_c_dep,
- gtest,
- gmock,
- nlohmann_json_dep,
- valijson_dep,
- ],
+ dependencies: [json_c_dep, jsonc_daccord, gtest, gmock],
)
test(
fuzzer_test,
diff --git a/tests/test-utils.cpp b/tests/test-utils.cpp
index 11d8a02..e4d79d3 100644
--- a/tests/test-utils.cpp
+++ b/tests/test-utils.cpp
@@ -7,47 +7,54 @@
#include <cstdio>
#include <cstdlib>
#include <fstream>
+#include <map>
#include <filesystem>
+#include <vector>
+#include <algorithm>
#include "test-utils.hpp"
#include <libcper/BaseTypes.h>
#include <libcper/generator/cper-generate.h>
+extern "C" {
+#include <jsoncdaccord.h>
+#include <json.h>
+#include <libcper/log.h>
+}
+
namespace fs = std::filesystem;
// Objects that have mutually exclusive fields (and thereforce can't have both
// required at the same time) can be added to this list.
// Truly optional properties that shouldn't be added to "required" field for
// validating the entire schema with validationbits=1
-const static std::map<std::string, std::vector<std::string> >
- optional_properties_map = {
- { "./sections/cper-cxl-protocol.json",
- { "capabilityStructure", "deviceSerial" } },
- { "./sections/cper-cxl-component.json",
- { "cxlComponentEventLog" } },
- { "./sections/cper-ia32x64-processor.json",
- { "addressSpace", "errorType", "participationType",
- "timedOut", "level", "operation", "preciseIP",
- "restartableIP", "overflow", "uncorrected",
- "transactionType" } },
- // Several PCIe properties are dependent on the device capability
- // version and whether the device is running in Flit-Mode.
- // All of these properties are optional.
- { "./sections/cper-pcie.json",
- { "device_capabilities2", "device_status2", "device_control2",
- "link_capabilities2", "link_status2", "link_control2",
- "slot_capabilities2", "slot_status2", "slot_control2" } },
- };
+// In most cases making sure examples set all valid bits is preferable to adding to this list
+const static std::vector<std::string> optional_props = {
+ { // Some sections don't parse header correctly?
+ "header",
-nlohmann::json loadJson(const char *filePath)
-{
- std::ifstream file(filePath);
- if (!file.is_open()) {
- std::cerr << "Failed to open file: " << filePath << std::endl;
- }
- nlohmann::json out = nlohmann::json::parse(file, nullptr, false);
- return out;
-}
+ // Each section is optional
+ "GenericProcessor", "Ia32x64Processor", "ArmProcessor", "Memory",
+ "Memory2", "Pcie", "PciBus", "PciComponent", "Firmware",
+ "GenericDmar", "VtdDmar", "IommuDmar", "CcixPer", "CxlProtocol",
+ "CxlComponent", "Nvidia", "Ampere", "Unknown",
+
+ // CXL? might have a bug?
+ "partitionID",
+
+ // CXL protocol
+ "capabilityStructure", "deviceSerial",
+
+ // CXL component
+ "cxlComponentEventLog", "addressSpace", "errorType",
+ "participationType", "timedOut", "level", "operation", "preciseIP",
+ "restartableIP", "overflow", "uncorrected", "transactionType",
+
+ // PCIe AER
+ "addressSpace", "errorType", "participationType", "timedOut", "level",
+ "operation", "preciseIP", "restartableIP", "overflow", "uncorrected",
+ "transactionType" }
+};
//Returns a ready-for-use memory stream containing a CPER record with the given sections inside.
FILE *generate_record_memstream(const char **types, UINT16 num_types,
@@ -72,161 +79,151 @@
return fmemopen(*buf, *buf_size, "r");
}
-void iterate_make_required_props(nlohmann::json &jsonSchema,
- std::vector<std::string> &optional_props)
+int iterate_make_required_props(json_object *jsonSchema, bool all_valid_bits)
{
- //id
- const auto it_id = jsonSchema.find("$id");
- if (it_id != jsonSchema.end()) {
- auto id_strptr = it_id->get_ptr<const std::string *>();
- std::string id_str = *id_strptr;
- if (id_str.find("header") != std::string::npos ||
- id_str.find("section-descriptor") != std::string::npos) {
- return;
+ //properties
+ json_object *properties =
+ json_object_object_get(jsonSchema, "properties");
+
+ if (properties != nullptr) {
+ json_object *requrired_arr = json_object_new_array();
+
+ json_object_object_foreach(properties, property_name,
+ property_value)
+ {
+ bool add_to_required = true;
+ const auto it_find_opt_prop = std::ranges::find(
+ optional_props, property_name);
+ if (it_find_opt_prop != optional_props.end()) {
+ add_to_required = false;
+ }
+
+ if (add_to_required) {
+ //Add to list if property is not optional
+ json_object_array_add(
+ requrired_arr,
+ json_object_new_string(property_name));
+ }
+ }
+
+ json_object_object_foreach(properties, property_name2,
+ property_value2)
+ {
+ (void)property_name2;
+ if (iterate_make_required_props(property_value2,
+ all_valid_bits) < 0) {
+ return -1;
+ }
+ }
+
+ if (all_valid_bits) {
+ json_object_object_add(jsonSchema, "required",
+ requrired_arr);
+ }
+ //json_object_put(requrired_arr);
+ }
+
+ // ref
+ json_object *ref = json_object_object_get(jsonSchema, "$ref");
+ if (ref != nullptr) {
+ const char *ref_str = json_object_get_string(ref);
+ if (ref_str != nullptr) {
+ std::string ref_path = LIBCPER_JSON_SPEC;
+ // remove the leading .
+ ref_path += std::string(ref_str).substr(1);
+ json_object *ref_obj =
+ json_object_from_file(ref_path.c_str());
+ if (ref_obj == nullptr) {
+ printf("Failed to parse file: %s\n",
+ ref_path.c_str());
+ return -1;
+ }
+
+ if (iterate_make_required_props(ref_obj,
+ all_valid_bits) < 0) {
+ json_object_put(ref_obj);
+ return -1;
+ }
+
+ json_object_object_foreach(ref_obj, key, val)
+ {
+ json_object_object_add(jsonSchema, key,
+ json_object_get(val));
+ }
+ json_object_object_del(jsonSchema, "$ref");
+
+ json_object_put(ref_obj);
}
}
+
//oneOf
- const auto it_oneof = jsonSchema.find("oneOf");
- if (it_oneof != jsonSchema.end()) {
- //Iterate over oneOf properties
- for (auto &oneOfProp : *it_oneof) {
- iterate_make_required_props(oneOfProp, optional_props);
+ const json_object *oneOf = json_object_object_get(jsonSchema, "oneOf");
+ if (oneOf != nullptr) {
+ size_t num_elements = json_object_array_length(oneOf);
+
+ for (size_t i = 0; i < num_elements; i++) {
+ json_object *obj = json_object_array_get_idx(oneOf, i);
+ if (iterate_make_required_props(obj, all_valid_bits) <
+ 0) {
+ return -1;
+ }
}
}
//items
- const auto it_items = jsonSchema.find("items");
- if (it_items != jsonSchema.end()) {
- iterate_make_required_props(*it_items, optional_props);
- }
- //required
- const auto it_req = jsonSchema.find("required");
- if (it_req == jsonSchema.end()) {
- return;
- }
-
- //properties
- const auto it_prop = jsonSchema.find("properties");
- if (it_prop == jsonSchema.end()) {
- return;
- }
- nlohmann::json &propertyFields = *it_prop;
- nlohmann::json::array_t property_list;
- if (propertyFields.is_object()) {
- for (auto &[key, value] : propertyFields.items()) {
- const auto it_find_opt_prop =
- std::find(optional_props.begin(),
- optional_props.end(), key);
- if (it_find_opt_prop == optional_props.end()) {
- //Add to list if property is not optional
- property_list.push_back(key);
+ const json_object *items = json_object_object_get(jsonSchema, "items");
+ if (items != nullptr) {
+ json_object_object_foreach(items, key, val)
+ {
+ (void)key;
+ if (iterate_make_required_props(val, all_valid_bits) <
+ 0) {
+ return -1;
}
-
- iterate_make_required_props(value, optional_props);
}
}
- *it_req = property_list;
+ return 1;
}
-// Document loader callback function
-const nlohmann::json *documentLoader(const std::string &uri,
- AddRequiredProps add_required_props)
+int schema_validate_from_file(json_object *to_test, int single_section,
+ int all_valid_bits)
{
- // Load the schema from a file
- std::unique_ptr<nlohmann::json> ref_schema =
- std::make_unique<nlohmann::json>();
- *ref_schema = loadJson(uri.c_str());
- if (ref_schema->is_discarded()) {
- std::cerr << "Could not open schema file: " << uri << std::endl;
- }
- if (add_required_props == AddRequiredProps::YES) {
- std::vector<std::string> opt = {};
- const auto it_optional_file = optional_properties_map.find(uri);
- if (it_optional_file != optional_properties_map.end()) {
- opt = it_optional_file->second;
- }
- iterate_make_required_props(*ref_schema, opt);
- }
-
- return ref_schema.release();
-}
-
-// Document release callback function
-void documentRelease(const nlohmann::json *adapter)
-{
- delete adapter; // Free the adapter memory
-}
-
-std::unique_ptr<valijson::Schema>
-load_schema(AddRequiredProps add_required_props, int single_section)
-{
- // Load the schema
- fs::path pathObj(LIBCPER_JSON_SPEC);
-
+ const char *schema_file;
if (single_section) {
- pathObj /= "cper-json-section-log.json";
+ schema_file = "cper-json-section-log.json";
} else {
- pathObj /= "cper-json-full-log.json";
- }
- nlohmann::json schema_root = loadJson(pathObj.c_str());
- fs::path base_path(LIBCPER_JSON_SPEC);
- try {
- fs::current_path(base_path);
- // std::cout << "Changed directory to: " << fs::current_path()
- // << std::endl;
- } catch (const fs::filesystem_error &e) {
- std::cerr << "Filesystem error: " << e.what() << std::endl;
+ schema_file = "cper-json-full-log.json";
}
- // Parse the json schema into an internal schema format
- std::unique_ptr<valijson::Schema> schema =
- std::make_unique<valijson::Schema>();
- valijson::SchemaParser parser;
- valijson::adapters::NlohmannJsonAdapter schemaDocumentAdapter(
- schema_root);
+ std::string schema_path = LIBCPER_JSON_SPEC;
+ schema_path += "/";
+ schema_path += schema_file;
- // Set up callbacks for resolving external references
- try {
- parser.populateSchema(
- schemaDocumentAdapter, *schema,
- [add_required_props](const std::string &uri) {
- return documentLoader(uri, add_required_props);
- },
- documentRelease);
- } catch (std::exception &e) {
- std::cerr << "Failed to parse schema: " << e.what()
- << std::endl;
- }
- return schema;
-}
-
-int schema_validate_from_file(const valijson::Schema &schema,
- nlohmann::json &jsonData,
- std::string &error_message)
-{
- // Perform validation
- valijson::Validator validator(valijson::Validator::kStrongTypes);
- valijson::ValidationResults results;
- valijson::adapters::NlohmannJsonAdapter targetDocumentAdapter(jsonData);
- if (!validator.validate(schema, targetDocumentAdapter, &results)) {
- std::cerr << "Validation failed." << std::endl;
- valijson::ValidationResults::Error error;
- unsigned int errorNum = 1;
- while (results.popError(error)) {
- std::string context;
- for (const std::string &str : error.context) {
- context += str;
- }
-
- std::cout << "Error #" << errorNum << '\n'
- << " context: " << context << '\n'
- << " desc: " << error.description << '\n';
- ++errorNum;
- }
+ json_object *schema = json_object_from_file(schema_path.c_str());
+ if (schema == nullptr) {
+ cper_print_log("Could not parse schema file: %s", schema_file);
return 0;
}
- error_message = "Schema validation successful";
- return 1;
+ if (iterate_make_required_props(schema, all_valid_bits) < 0) {
+ printf("Failed to make required props\n");
+ json_object_put(schema);
+ return -1;
+ }
+
+ int err = jdac_validate(to_test, schema);
+ if (err == JDAC_ERR_VALID) {
+ printf("validation ok\n");
+ json_object_put(schema);
+ return 1;
+ }
+ printf("validate failed %d: %s\n", err, jdac_errorstr(err));
+
+ printf("schema: \n%s\n",
+ json_object_to_json_string_ext(schema, JSON_C_TO_STRING_PRETTY));
+ printf("to_test: \n%s\n", json_object_to_json_string_ext(
+ to_test, JSON_C_TO_STRING_PRETTY));
+ json_object_put(schema);
+ return 0;
}
diff --git a/tests/test-utils.hpp b/tests/test-utils.hpp
index ec5f064..3b1d061 100644
--- a/tests/test-utils.hpp
+++ b/tests/test-utils.hpp
@@ -1,17 +1,10 @@
#ifndef CPER_IR_TEST_UTILS_H
#define CPER_IR_TEST_UTILS_H
-#include <valijson/adapters/nlohmann_json_adapter.hpp>
-#include <valijson/schema.hpp>
-#include <valijson/schema_parser.hpp>
-#include <valijson/validator.hpp>
-#include <nlohmann/json.hpp>
-
-extern "C" {
#include <stdio.h>
#include <libcper/BaseTypes.h>
#include <libcper/generator/sections/gen-section.h>
-}
+#include <json.h>
// Controls whether required properties are added to the majority of property
// definitions. This is useful for unit tests that are validating JSON where
@@ -23,13 +16,7 @@
int single_section,
GEN_VALID_BITS_TEST_TYPE validBitsType);
-std::unique_ptr<valijson::Schema>
-load_schema(AddRequiredProps add_required_props, int single_section);
-
-int schema_validate_from_file(const valijson::Schema &schema,
- nlohmann::json &jsonData,
- std::string &error_message);
-
-nlohmann::json loadJson(const char *filePath);
+int schema_validate_from_file(json_object *to_test, int single_section,
+ int all_valid_bits);
#endif