5 #include "rapidjson/schema.h"
10 #define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
12 using namespace rapidjson;
14 template <typename Allocator>
15 static char* ReadFile(const char* filename, Allocator& allocator) {
16 const char *paths[] = {
25 for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); i++) {
26 sprintf(buffer, "%s%s", paths[i], filename);
27 fp = fopen(buffer, "rb");
35 fseek(fp, 0, SEEK_END);
36 size_t length = static_cast<size_t>(ftell(fp));
37 fseek(fp, 0, SEEK_SET);
38 char* json = reinterpret_cast<char*>(allocator.Malloc(length + 1));
39 size_t readLength = fread(json, 1, length, fp);
40 json[readLength] = '\0';
45 class Schema : public PerfTest {
49 virtual void SetUp() {
52 const char* filenames[] = {
53 "additionalItems.json",
54 "additionalProperties.json",
74 "patternProperties.json",
83 char jsonBuffer[65536];
84 MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer));
86 for (size_t i = 0; i < ARRAY_SIZE(filenames); i++) {
87 char filename[FILENAME_MAX];
88 sprintf(filename, "jsonschema/tests/draft4/%s", filenames[i]);
89 char* json = ReadFile(filename, jsonAllocator);
91 printf("json test suite file %s not found", filename);
97 if (d.HasParseError()) {
98 printf("json test suite file %s has parse error", filename);
102 for (Value::ConstValueIterator schemaItr = d.Begin(); schemaItr != d.End(); ++schemaItr) {
103 std::string schemaDescription = (*schemaItr)["description"].GetString();
104 if (IsExcludeTestSuite(schemaDescription))
107 TestSuite* ts = new TestSuite;
108 ts->schema = new SchemaDocument((*schemaItr)["schema"]);
110 const Value& tests = (*schemaItr)["tests"];
111 for (Value::ConstValueIterator testItr = tests.Begin(); testItr != tests.End(); ++testItr) {
112 if (IsExcludeTest(schemaDescription + ", " + (*testItr)["description"].GetString()))
115 Document* d2 = new Document;
116 d2->CopyFrom((*testItr)["data"], d2->GetAllocator());
117 ts->tests.push_back(d2);
119 testSuites.push_back(ts);
124 virtual void TearDown() {
125 PerfTest::TearDown();
126 for (TestSuiteList::const_iterator itr = testSuites.begin(); itr != testSuites.end(); ++itr)
132 // Using the same exclusion in https://github.com/json-schema/JSON-Schema-Test-Suite
133 static bool IsExcludeTestSuite(const std::string& description) {
134 const char* excludeTestSuites[] = {
135 //lost failing these tests
137 "remote ref, containing refs itself",
138 "fragment within remote ref",
139 "ref within remote ref",
140 "change resolution scope",
141 // these below were added to get jsck in the benchmarks)
142 "uniqueItems validation",
147 for (size_t i = 0; i < ARRAY_SIZE(excludeTestSuites); i++)
148 if (excludeTestSuites[i] == description)
153 // Using the same exclusion in https://github.com/json-schema/JSON-Schema-Test-Suite
154 static bool IsExcludeTest(const std::string& description) {
155 const char* excludeTests[] = {
156 //lots of validators fail these
157 "invalid definition, invalid definition schema",
158 "maxLength validation, two supplementary Unicode code points is long enough",
159 "minLength validation, one supplementary Unicode code point is not long enough",
160 //this is to get tv4 in the benchmarks
161 "heterogeneous enum validation, something else is invalid"
164 for (size_t i = 0; i < ARRAY_SIZE(excludeTests); i++)
165 if (excludeTests[i] == description)
170 Schema(const Schema&);
171 Schema& operator=(const Schema&);
174 typedef std::vector<Document*> DocumentList;
177 TestSuite() : schema() {}
180 for (DocumentList::iterator itr = tests.begin(); itr != tests.end(); ++itr)
183 SchemaDocument* schema;
187 typedef std::vector<TestSuite* > TestSuiteList;
188 TestSuiteList testSuites;
191 TEST_F(Schema, TestSuite) {
192 char validatorBuffer[65536];
193 MemoryPoolAllocator<> validatorAllocator(validatorBuffer, sizeof(validatorBuffer));
195 const int trialCount = 100000;
197 clock_t start = clock();
198 for (int i = 0; i < trialCount; i++) {
199 for (TestSuiteList::const_iterator itr = testSuites.begin(); itr != testSuites.end(); ++itr) {
200 const TestSuite& ts = **itr;
201 GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(*ts.schema, &validatorAllocator);
202 for (DocumentList::const_iterator testItr = ts.tests.begin(); testItr != ts.tests.end(); ++testItr) {
204 (*testItr)->Accept(validator);
207 validatorAllocator.Clear();
210 clock_t end = clock();
211 double duration = double(end - start) / CLOCKS_PER_SEC;
212 printf("%d trials in %f s -> %f trials per sec\n", trialCount, duration, trialCount / duration);
213 printf("%d tests per trial\n", testCount / trialCount);