Electroneum
Loading...
Searching...
No Matches
schematest.cpp
Go to the documentation of this file.
1#include "perftest.h"
2
3#if TEST_RAPIDJSON
4
5#include "rapidjson/schema.h"
6#include <ctime>
7#include <string>
8#include <vector>
9
10#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
11
12using namespace rapidjson;
13
14template <typename Allocator>
15static char* ReadFile(const char* filename, Allocator& allocator) {
16 const char *paths[] = {
17 "",
18 "bin/",
19 "../bin/",
20 "../../bin/",
21 "../../../bin/"
22 };
23 char buffer[1024];
24 FILE *fp = 0;
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");
28 if (fp)
29 break;
30 }
31
32 if (!fp)
33 return 0;
34
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';
41 fclose(fp);
42 return json;
43}
44
45class Schema : public PerfTest {
46public:
47 Schema() {}
48
49 virtual void SetUp() {
50 PerfTest::SetUp();
51
52 const char* filenames[] = {
53 "additionalItems.json",
54 "additionalProperties.json",
55 "allOf.json",
56 "anyOf.json",
57 "default.json",
58 "definitions.json",
59 "dependencies.json",
60 "enum.json",
61 "items.json",
62 "maximum.json",
63 "maxItems.json",
64 "maxLength.json",
65 "maxProperties.json",
66 "minimum.json",
67 "minItems.json",
68 "minLength.json",
69 "minProperties.json",
70 "multipleOf.json",
71 "not.json",
72 "oneOf.json",
73 "pattern.json",
74 "patternProperties.json",
75 "properties.json",
76 "ref.json",
77 "refRemote.json",
78 "required.json",
79 "type.json",
80 "uniqueItems.json"
81 };
82
83 char jsonBuffer[65536];
84 MemoryPoolAllocator<> jsonAllocator(jsonBuffer, sizeof(jsonBuffer));
85
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);
90 if (!json) {
91 printf("json test suite file %s not found", filename);
92 return;
93 }
94
95 Document d;
96 d.Parse(json);
97 if (d.HasParseError()) {
98 printf("json test suite file %s has parse error", filename);
99 return;
100 }
101
102 for (Value::ConstValueIterator schemaItr = d.Begin(); schemaItr != d.End(); ++schemaItr) {
103 std::string schemaDescription = (*schemaItr)["description"].GetString();
104 if (IsExcludeTestSuite(schemaDescription))
105 continue;
106
107 TestSuite* ts = new TestSuite;
108 ts->schema = new SchemaDocument((*schemaItr)["schema"]);
109
110 const Value& tests = (*schemaItr)["tests"];
111 for (Value::ConstValueIterator testItr = tests.Begin(); testItr != tests.End(); ++testItr) {
112 if (IsExcludeTest(schemaDescription + ", " + (*testItr)["description"].GetString()))
113 continue;
114
115 Document* d2 = new Document;
116 d2->CopyFrom((*testItr)["data"], d2->GetAllocator());
117 ts->tests.push_back(d2);
118 }
119 testSuites.push_back(ts);
120 }
121 }
122 }
123
124 virtual void TearDown() {
125 PerfTest::TearDown();
126 for (TestSuiteList::const_iterator itr = testSuites.begin(); itr != testSuites.end(); ++itr)
127 delete *itr;
128 testSuites.clear();
129 }
130
131private:
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
136 "remote ref",
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",
143 "valid definition",
144 "invalid definition"
145 };
146
147 for (size_t i = 0; i < ARRAY_SIZE(excludeTestSuites); i++)
148 if (excludeTestSuites[i] == description)
149 return true;
150 return false;
151 }
152
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"
162 };
163
164 for (size_t i = 0; i < ARRAY_SIZE(excludeTests); i++)
165 if (excludeTests[i] == description)
166 return true;
167 return false;
168 }
169
170 Schema(const Schema&);
171 Schema& operator=(const Schema&);
172
173protected:
174 typedef std::vector<Document*> DocumentList;
175
176 struct TestSuite {
179 delete schema;
180 for (DocumentList::iterator itr = tests.begin(); itr != tests.end(); ++itr)
181 delete *itr;
182 }
185 };
186
187 typedef std::vector<TestSuite* > TestSuiteList;
189};
190
191TEST_F(Schema, TestSuite) {
192 char validatorBuffer[65536];
193 MemoryPoolAllocator<> validatorAllocator(validatorBuffer, sizeof(validatorBuffer));
194
195 const int trialCount = 100000;
196 int testCount = 0;
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;
202 for (DocumentList::const_iterator testItr = ts.tests.begin(); testItr != ts.tests.end(); ++testItr) {
203 validator.Reset();
204 (*testItr)->Accept(validator);
205 testCount++;
206 }
207 validatorAllocator.Clear();
208 }
209 }
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);
214}
215
216#endif
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2418
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition document.h:2394
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion).
Definition document.h:2331
JSON Schema Validator.
Definition schema.h:1765
void Reset()
Reset the internal states.
Definition schema.h:1843
const GenericValue * ConstValueIterator
Definition document.h:586
Default memory allocator used by the parser and DOM.
Definition allocators.h:115
void Clear()
Deallocates all memory chunks, excluding the user-supplied buffer.
Definition allocators.h:158
virtual void SetUp()
std::vector< Document * > DocumentList
std::vector< TestSuite * > TestSuiteList
TestSuiteList testSuites
virtual void TearDown()
Concept for allocating, resizing and freeing memory block.
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition document.h:2116
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:2512
GenericSchemaDocument< Value, CrtAllocator > SchemaDocument
Definition fwd.h:138
#define TEST_F(test_fixture, test_name)
Definition gtest.h:2216
main RapidJSON namespace
#define ARRAY_SIZE(a)
DocumentList tests
SchemaDocument * schema
rapidjson::Document json
Definition transport.cpp:49