]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/nodejs/test/test_driver.js
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / nodejs / test / test_driver.js
CommitLineData
f67539c2
TL
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * 'License'); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20// This is the Node.js test driver for the standard Apache Thrift
21// test service. The driver invokes every function defined in the
22// Thrift Test service with a representative range of parameters.
23//
24// The ThriftTestDriver function requires a client object
25// connected to a server hosting the Thrift Test service and
26// supports an optional callback function which is called with
27// a status message when the test is complete.
28
29const test = require("tape");
30
31const helpers = require("./helpers");
32const ttypes = require(`./${helpers.genPath}/ThriftTest_types`);
33const TException = require("thrift").Thrift.TException;
34const Int64 = require("node-int64");
35const testCases = require("./test-cases");
36
37exports.ThriftTestDriver = function(client, callback) {
38 test(
39 "NodeJS Style Callback Client Tests",
40 { skip: helpers.ecmaMode === "es6" },
41 function(assert) {
42 const checkRecursively = makeRecursiveCheck(assert);
43
44 function makeAsserter(assertionFn) {
45 return function(c) {
46 const fnName = c[0];
47 const expected = c[1];
48 client[fnName](expected, function(err, actual) {
49 assert.error(err, fnName + ": no callback error");
50 assertionFn(actual, expected, fnName);
51 });
52 };
53 }
54
55 testCases.simple.forEach(
56 makeAsserter(function(a, e, m) {
57 if (a instanceof Int64) {
58 const e64 = e instanceof Int64 ? e : new Int64(e);
59 assert.deepEqual(a.buffer, e64.buffer, m);
60 } else {
61 assert.equal(a, e, m);
62 }
63 })
64 );
65 testCases.deep.forEach(makeAsserter(assert.deepEqual));
66 testCases.deepUnordered.forEach(
67 makeAsserter(makeUnorderedDeepEqual(assert))
68 );
69
70 const arr = [];
71 for (let i = 0; i < 256; ++i) {
72 arr[i] = 255 - i;
73 }
74 let buf = new Buffer(arr);
75 client.testBinary(buf, function(err, response) {
76 assert.error(err, "testBinary: no callback error");
77 assert.equal(response.length, 256, "testBinary");
78 assert.deepEqual(response, buf, "testBinary(Buffer)");
79 });
80 buf = new Buffer(arr);
81 client.testBinary(buf.toString("binary"), function(err, response) {
82 assert.error(err, "testBinary: no callback error");
83 assert.equal(response.length, 256, "testBinary");
84 assert.deepEqual(response, buf, "testBinary(string)");
85 });
86
87 client.testMapMap(42, function(err, response) {
88 const expected = {
89 "4": { "1": 1, "2": 2, "3": 3, "4": 4 },
90 "-4": { "-4": -4, "-3": -3, "-2": -2, "-1": -1 }
91 };
92 assert.error(err, "testMapMap: no callback error");
93 assert.deepEqual(expected, response, "testMapMap");
94 });
95
96 client.testStruct(testCases.out, function(err, response) {
97 assert.error(err, "testStruct: no callback error");
98 checkRecursively(testCases.out, response, "testStruct");
99 });
100
101 client.testNest(testCases.out2, function(err, response) {
102 assert.error(err, "testNest: no callback error");
103 checkRecursively(testCases.out2, response, "testNest");
104 });
105
106 client.testInsanity(testCases.crazy, function(err, response) {
107 assert.error(err, "testInsanity: no callback error");
108 checkRecursively(testCases.insanity, response, "testInsanity");
109 });
110
111 client.testInsanity(testCases.crazy2, function(err, response) {
112 assert.error(err, "testInsanity2: no callback error");
113 checkRecursively(testCases.insanity, response, "testInsanity2");
114 });
115
116 client.testException("TException", function(err, response) {
117 assert.ok(
118 err instanceof TException,
119 "testException: correct error type"
120 );
121 assert.ok(!response, "testException: no response");
122 });
123
124 client.testException("Xception", function(err, response) {
125 assert.ok(
126 err instanceof ttypes.Xception,
127 "testException: correct error type"
128 );
129 assert.ok(!response, "testException: no response");
130 assert.equal(err.errorCode, 1001, "testException: correct error code");
131 assert.equal(
132 "Xception",
133 err.message,
134 "testException: correct error message"
135 );
136 });
137
138 client.testException("no Exception", function(err, response) {
139 assert.error(err, "testException: no callback error");
140 assert.ok(!response, "testException: no response");
141 });
142
143 client.testOneway(0, function(err, response) {
144 assert.error(err, "testOneway: no callback error");
145 assert.strictEqual(response, undefined, "testOneway: void response");
146 });
147
148 checkOffByOne(function(done) {
149 client.testI32(-1, function(err, response) {
150 assert.error(err, "checkOffByOne: no callback error");
151 assert.equal(-1, response);
152 assert.end();
153 done();
154 });
155 }, callback);
156 }
157 );
158
159 // ES6 does not support callback style
160 if (helpers.ecmaMode === "es6") {
161 checkOffByOne(done => done(), callback);
162 }
163};
164
165exports.ThriftTestDriverPromise = function(client, callback) {
166 test("Promise Client Tests", function(assert) {
167 const checkRecursively = makeRecursiveCheck(assert);
168
169 function makeAsserter(assertionFn) {
170 return function(c) {
171 const fnName = c[0];
172 const expected = c[1];
173 client[fnName](expected)
174 .then(function(actual) {
175 assertionFn(actual, expected, fnName);
176 })
177 .catch(() => assert.fail("fnName"));
178 };
179 }
180
181 testCases.simple.forEach(
182 makeAsserter(function(a, e, m) {
183 if (a instanceof Int64) {
184 const e64 = e instanceof Int64 ? e : new Int64(e);
185 assert.deepEqual(a.buffer, e64.buffer, m);
186 } else {
187 assert.equal(a, e, m);
188 }
189 })
190 );
191 testCases.deep.forEach(makeAsserter(assert.deepEqual));
192 testCases.deepUnordered.forEach(
193 makeAsserter(makeUnorderedDeepEqual(assert))
194 );
195
196 client
197 .testStruct(testCases.out)
198 .then(function(response) {
199 checkRecursively(testCases.out, response, "testStruct");
200 })
201 .catch(() => assert.fail("testStruct"));
202
203 client
204 .testNest(testCases.out2)
205 .then(function(response) {
206 checkRecursively(testCases.out2, response, "testNest");
207 })
208 .catch(() => assert.fail("testNest"));
209
210 client
211 .testInsanity(testCases.crazy)
212 .then(function(response) {
213 checkRecursively(testCases.insanity, response, "testInsanity");
214 })
215 .catch(() => assert.fail("testInsanity"));
216
217 client
218 .testInsanity(testCases.crazy2)
219 .then(function(response) {
220 checkRecursively(testCases.insanity, response, "testInsanity2");
221 })
222 .catch(() => assert.fail("testInsanity2"));
223
224 client
225 .testException("TException")
226 .then(function() {
227 assert.fail("testException: TException");
228 })
229 .catch(function(err) {
230 assert.ok(err instanceof TException);
231 });
232
233 client
234 .testException("Xception")
235 .then(function() {
236 assert.fail("testException: Xception");
237 })
238 .catch(function(err) {
239 assert.ok(err instanceof ttypes.Xception);
240 assert.equal(err.errorCode, 1001);
241 assert.equal("Xception", err.message);
242 });
243
244 client
245 .testException("no Exception")
246 .then(function(response) {
247 assert.equal(undefined, response); //void
248 })
249 .catch(() => assert.fail("testException"));
250
251 client
252 .testOneway(0)
253 .then(function(response) {
254 assert.strictEqual(response, undefined, "testOneway: void response");
255 })
256 .catch(() => assert.fail("testOneway: should not reject"));
257
258 checkOffByOne(function(done) {
259 client
260 .testI32(-1)
261 .then(function(response) {
262 assert.equal(-1, response);
263 assert.end();
264 done();
265 })
266 .catch(() => assert.fail("checkOffByOne"));
267 }, callback);
268 });
269};
270
271// Helper Functions
272// =========================================================
273
274function makeRecursiveCheck(assert) {
275 return function(map1, map2, msg) {
276 const equal = checkRecursively(map1, map2);
277
278 assert.ok(equal, msg);
279
280 // deepEqual doesn't work with fields using node-int64
281 function checkRecursively(map1, map2) {
282 if (typeof map1 !== "function" && typeof map2 !== "function") {
283 if (!map1 || typeof map1 !== "object") {
284 //Handle int64 types (which use node-int64 in Node.js JavaScript)
285 if (
286 typeof map1 === "number" &&
287 typeof map2 === "object" &&
288 map2.buffer &&
289 map2.buffer instanceof Buffer &&
290 map2.buffer.length === 8
291 ) {
292 const n = new Int64(map2.buffer);
293 return map1 === n.toNumber();
294 } else {
295 return map1 == map2;
296 }
297 } else {
298 return Object.keys(map1).every(function(key) {
299 return checkRecursively(map1[key], map2[key]);
300 });
301 }
302 }
303 }
304 };
305}
306
307function checkOffByOne(done, callback) {
308 const retry_limit = 30;
309 const retry_interval = 100;
310 let test_complete = false;
311 let retrys = 0;
312
313 /**
314 * redo a simple test after the oneway to make sure we aren't "off by one" --
315 * if the server treated oneway void like normal void, this next test will
316 * fail since it will get the void confirmation rather than the correct
317 * result. In this circumstance, the client will throw the exception:
318 *
319 * Because this is the last test against the server, when it completes
320 * the entire suite is complete by definition (the tests run serially).
321 */
322 done(function() {
323 test_complete = true;
324 });
325
326 //We wait up to retry_limit * retry_interval for the test suite to complete
327 function TestForCompletion() {
328 if (test_complete && callback) {
329 callback("Server successfully tested!");
330 } else {
331 if (++retrys < retry_limit) {
332 setTimeout(TestForCompletion, retry_interval);
333 } else if (callback) {
334 callback(
335 "Server test failed to complete after " +
336 (retry_limit * retry_interval) / 1000 +
337 " seconds"
338 );
339 }
340 }
341 }
342
343 setTimeout(TestForCompletion, retry_interval);
344}
345
346function makeUnorderedDeepEqual(assert) {
347 return function(actual, expected, name) {
348 assert.equal(actual.length, expected.length, name);
349 for (const k in actual) {
350 let found = false;
351 for (const k2 in expected) {
352 if (actual[k] === expected[k2]) {
353 found = true;
354 }
355 }
356 if (!found) {
357 assert.fail("Unexpected value " + actual[k] + " with key " + k);
358 }
359 }
360 };
361}