perftest/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 
12 using namespace rapidjson;
13 
14 template <typename Allocator>
15 static 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 
45 class Schema : public PerfTest {
46 public:
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 
131 private:
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 
173 protected:
174  typedef std::vector<Document*> DocumentList;
175 
176  struct TestSuite {
177  TestSuite() : schema() {}
179  delete schema;
180  for (DocumentList::iterator itr = tests.begin(); itr != tests.end(); ++itr)
181  delete *itr;
182  }
184  DocumentList tests;
185  };
186 
187  typedef std::vector<TestSuite* > TestSuiteList;
188  TestSuiteList testSuites;
189 };
190 
191 TEST_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;
201  GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<> >, MemoryPoolAllocator<> > validator(*ts.schema, &validatorAllocator);
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
d
ROSCPP_DECL void start()
JSON schema document.
Definition: fwd.h:136
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:67
void Reset()
Reset the internal states.
Definition: schema.h:1640
static bool IsExcludeTestSuite(const std::string &description)
virtual void SetUp()
void Clear()
Deallocates all memory chunks, excluding the user-supplied buffer.
Definition: allocators.h:145
SchemaDocument * schema
static const char json[]
static char * ReadFile(const char *filename, Allocator &allocator)
#define ARRAY_SIZE(a)
Concept for allocating, resizing and freeing memory block.
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2383
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2477
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2296
main RapidJSON namespace
TEST_F(Schema, TestSuite)
std::vector< Document * > DocumentList
virtual void TearDown()
static bool IsExcludeTest(const std::string &description)
TestSuiteList testSuites
GenericSchemaDocument< Value, CrtAllocator > SchemaDocument
Definition: fwd.h:136
std::vector< TestSuite * > TestSuiteList
JSON Schema Validator.
Definition: fwd.h:145
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:2359


choreo_rapidjson
Author(s):
autogenerated on Thu Jul 18 2019 03:59:09