Merge
[c11concurrency-benchmarks.git] / silo / masstree / msgpacktest.cc
1 #include "msgpack.hh"
2 using namespace lcdf;
3
4 enum { status_ok, status_error, status_incomplete };
5
6 __attribute__((noreturn))
7 static void test_error(const char* file, int line,
8                        const char* data, int len,
9                        String division, String message) {
10     std::cerr << file << ":" << line << " ("
11               << String(data, data + len).printable() << ")"
12               << (division ? " " : "") << division << ": "
13               << message << "\n";
14     exit(1);
15 }
16
17 static void onetest(const char* file, int line,
18                     const char* data, int len,
19                     String division, const char* take, int expected_take,
20                     const char* unparse, int status,
21                     msgpack::streaming_parser& a) {
22     if (expected_take >= 0 && take != data + expected_take)
23         test_error(file, line, data, len, division, "accept took " + String(take - data) + " chars, expected " + String(expected_take));
24
25     if (status == status_ok && !a.success())
26         test_error(file, line, data, len, division, "accept not done");
27     if (status == status_error && !a.error())
28         test_error(file, line, data, len, division, "accept not error");
29     if (status == status_incomplete && a.done())
30         test_error(file, line, data, len, division, "accept not incomplete");
31
32     if (unparse && a.result().unparse() != unparse)
33         test_error(file, line, data, len, division, "result was " + a.result().unparse() + "\n\texpected " + String(unparse));
34 }
35
36 static void test(const char* file, int line,
37                  const char* data, int len, int expected_take,
38                  const char* unparse, int status = status_ok) {
39     assert(expected_take <= len);
40
41     msgpack::streaming_parser a;
42     const char* take;
43     take = a.consume(data, data + len);
44     onetest(file, line, data, len, "", take, expected_take, unparse, status, a);
45
46     if (len > 1) {
47         a.reset();
48         take = data;
49         while (take != data + len) {
50             const char* x = a.consume(take, take + 1);
51             if (x != take + (take < data + expected_take))
52                 test_error(file, line, data, len, "by 1s", "accept took unusual amount after " + String(x - data));
53             ++take;
54         }
55         onetest(file, line, data, len, "by 1s", take, -1, unparse, status, a);
56     }
57 }
58
59 #define TEST(...) test(__FILE__, __LINE__, ## __VA_ARGS__)
60
61 void check_correctness() {
62     TEST("\0", 1, 1, "0");
63     TEST("\xFF  ", 3, 1, "-1");
64     TEST("\xC0  ", 3, 1, "null");
65     TEST("\xC2  ", 3, 1, "false");
66     TEST("\xC3  ", 3, 1, "true");
67     TEST("\xD0\xEE", 2, 2, "-18");
68     TEST("\x81\xA7" "compact\xC3", 11, 10, "{\"compact\":true}");
69     TEST("\x81\x00\x81\xA7" "compact\xC3", 13, 12, "{\"0\":{\"compact\":true}}");
70     TEST("\x82\x00\x81\xA7" "compact\xC3\xA1" "a\xC2", 16, 15, "{\"0\":{\"compact\":true},\"a\":false}");
71     TEST("\x93\x00\x01\x02", 5, 4, "[0,1,2]");
72     TEST("\x90     ", 5, 1, "[]");
73     TEST("\xDC\x00\x00     ", 5, 3, "[]");
74     TEST("\224\002\322\000\001\242\321\262p|00356|1000000000\245?!?#*\225\001\322\000\001\242\322\242t|\242t}\332\000Rt|<user_id:5>|<time:10>|<poster_id:5> s|<user_id>|<poster_id> p|<poster_id>|<time>",
75          130, 32, "[2,107217,\"p|00356|1000000000\",\"?!?#*\"]", status_ok);
76     TEST("\xCF\x80\0\0\0\0\0\0\0", 9, 9, "9223372036854775808");
77
78     {
79         msgpack::streaming_parser a;
80         Json j = Json::array(0, 0, 0);
81         swap(j, a.result());
82         a.reset();
83         a.consume("\x91\xC2", 2);
84         assert(a.success() && a.result().unparse() == "[false]");
85         a.reset();
86         a.consume("\xC0", 1);
87         assert(a.success() && a.result().unparse() == "null");
88         a.reset();
89         a.consume("\x82\xA7" "compact\xC3\x00\x00", 12);
90         assert(a.success() && a.result().unparse() == "{\"compact\":true,\"0\":0}");
91         a.reset();
92         a.consume("\x82\xA7" "compact\xC3\x00\x00", 12);
93         assert(a.success() && a.result().unparse() == "{\"compact\":true,\"0\":0}");
94     }
95
96     {
97         StringAccum sa;
98         msgpack::unparser<StringAccum> up(sa);
99         up.clear();
100         up << -32;
101         assert(sa.take_string() == "\xE0");
102         up.clear();
103         up << -33;
104         assert(sa.take_string() == "\xD0\xDF");
105         up.clear();
106         up << 127;
107         assert(sa.take_string() == "\x7F");
108         up.clear();
109         up << 128;
110         assert(sa.take_string() == String("\xD1\x00\x80", 3));
111         up << -32768;
112         assert(sa.take_string() == String("\xD1\x80\x00", 3));
113         up << -32769;
114         assert(sa.take_string() == String("\xD2\xFF\xFF\x7F\xFF", 5));
115     }
116
117     {
118         StringAccum sa;
119         msgpack::unparser<StringAccum> up(sa);
120         up.clear();
121         up << msgpack::array(2) << Json((uint64_t) 1 << 63)
122            << Json((int64_t) 1 << 63);
123         String result = sa.take_string();
124         TEST(result.c_str(), result.length(), result.length(),
125              "[9223372036854775808,-9223372036854775808]");
126     }
127
128     std::cout << "All tests pass!\n";
129 }
130
131 Json __attribute__((noinline)) parse_json(const char* first, const char* last) {
132     return Json::parse(first, last);
133 }
134
135 Json __attribute__((noinline)) parse_json(const String& str) {
136     return Json::parse(str);
137 }
138
139 static const char sample_json[] = "{\"name\": \"Deborah Estrin\", \"email\": \"estrin@usc.edu\", \"affiliation\": \"University of Southern California\", \"roles\": [\"pc\"]}";
140
141 static const char sample_msgpack[] = "\204\244name\256Deborah Estrin\245email\256estrin@usc.edu\253affiliation\331!University of Southern California\245roles\221\242pc";
142
143 static int parse_json_loop_size = 10000000;
144
145 void parse_json_loop_1() {
146     int total_size = 0;
147     const char* sample_json_end = sample_json + strlen(sample_json);
148     for (int i = 0; i != parse_json_loop_size; ++i) {
149         Json j = Json::parse(sample_json, sample_json_end);
150         total_size += j.size();
151     }
152     assert(total_size == 4 * parse_json_loop_size);
153 }
154
155 void parse_json_loop_2() {
156     int total_size = 0;
157     const char* sample_json_end = sample_json + strlen(sample_json);
158     for (int i = 0; i != parse_json_loop_size; ++i) {
159         Json j = Json::parse(String(sample_json, sample_json_end));
160         total_size += j.size();
161     }
162     assert(total_size == 4 * parse_json_loop_size);
163 }
164
165 void parse_json_loop_3() {
166     int total_size = 0;
167     String sample_json_str(sample_json);
168     for (int i = 0; i != parse_json_loop_size; ++i) {
169         Json j = Json::parse(sample_json_str);
170         total_size += j.size();
171     }
172     assert(total_size == 4 * parse_json_loop_size);
173 }
174
175 void parse_msgpack_loop_1() {
176     int total_size = 0;
177     const char* sample_msgpack_end = sample_msgpack + strlen(sample_msgpack);
178     for (int i = 0; i != parse_json_loop_size; ++i) {
179         Json j = msgpack::parse(sample_msgpack, sample_msgpack_end);
180         total_size += j.size();
181     }
182     assert(total_size == 4 * parse_json_loop_size);
183 }
184
185 void parse_msgpack_loop_2() {
186     int total_size = 0;
187     const char* sample_msgpack_end = sample_msgpack + strlen(sample_msgpack);
188     for (int i = 0; i != parse_json_loop_size; ++i) {
189         Json j = msgpack::parse(String(sample_msgpack, sample_msgpack_end));
190         total_size += j.size();
191     }
192     assert(total_size == 4 * parse_json_loop_size);
193 }
194
195 void parse_msgpack_loop_3() {
196     int total_size = 0;
197     String sample_msgpack_str(sample_msgpack);
198     for (int i = 0; i != parse_json_loop_size; ++i) {
199         Json j = msgpack::parse(sample_msgpack_str);
200         total_size += j.size();
201     }
202     assert(total_size == 4 * parse_json_loop_size);
203 }
204
205 int main(int argc, char** argv) {
206     (void) argc, (void) argv;
207
208     check_correctness();
209 }