blob: f79baa6d7ec928188e4c731e2471370dc4e88a03 [file] [log] [blame]
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -08001/*
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
Randy Abernethyd8187c52015-02-16 01:25:53 -080029var test = require('tape');
30//var assert = require('assert');
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -080031var ttypes = require('./gen-nodejs/ThriftTest_types');
32var Int64 = require('node-int64');
33var testCases = require('./test-cases');
34
35exports.ThriftTestDriver = function(client, callback) {
36
Randy Abernethyd8187c52015-02-16 01:25:53 -080037 test('NodeJS Style Callback Client Tests', function(assert) {
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -080038
Randy Abernethyd8187c52015-02-16 01:25:53 -080039 var checkRecursively = makeRecursiveCheck(assert);
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -080040
Randy Abernethyd8187c52015-02-16 01:25:53 -080041 function makeAsserter(assertionFn) {
42 return function(c) {
43 var fnName = c[0];
44 var expected = c[1];
45 client[fnName](expected, function(err, actual) {
46 assert.error(err, fnName + ': no callback error');
47 assertionFn(actual, expected, fnName);
48 })
49 };
50 }
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -080051
Randy Abernethyd8187c52015-02-16 01:25:53 -080052 testCases.simple.forEach(makeAsserter(assert.equal));
53 testCases.simpleLoose.forEach(makeAsserter(function(a, e, m){
54 assert.ok(a == e, m);
55 }));
56 testCases.deep.forEach(makeAsserter(assert.deepEqual));
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -080057
Randy Abernethyd8187c52015-02-16 01:25:53 -080058 client.testStruct(testCases.out, function(err, response) {
59 assert.error(err, 'testStruct: no callback error');
60 checkRecursively(testCases.out, response, 'testStruct');
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -080061 });
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -080062
Randy Abernethyd8187c52015-02-16 01:25:53 -080063 client.testNest(testCases.out2, function(err, response) {
64 assert.error(err, 'testNest: no callback error');
65 checkRecursively(testCases.out2, response, 'testNest');
66 });
67
68 client.testInsanity(testCases.crazy, function(err, response) {
69 assert.error(err, 'testInsanity: no callback error');
70 checkRecursively(testCases.insanity, response, 'testInsanity');
71 });
72
73 client.testException('TException', function(err, response) {
74 assert.error(err, 'testException: no callback error');
75 assert.ok(!response, 'testException: no response');
76 });
77
78 client.testException('Xception', function(err, response) {
79 assert.ok(!response, 'testException: no response');
80 assert.equal(err.errorCode, 1001, 'testException: correct error code');
81 assert.equal('Xception', err.message, 'testException: correct error message');
82 });
83
84 client.testException('no Exception', function(err, response) {
85 assert.error(err, 'testException: no callback error');
86 assert.ok(!response, 'testException: no response');
87 });
88
89 client.testOneway(0, function(err, response) {
90 assert.fail('testOneway should not answer');
91 });
92
93 checkOffByOne(function(done) {
94 client.testI32(-1, function(err, response) {
95 assert.error(err, 'checkOffByOne: no callback error');
96 assert.equal(-1, response);
97 assert.end();
98 done();
99 });
100 }, callback);
101
102 });
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800103};
104
105exports.ThriftTestDriverPromise = function(client, callback) {
106
Randy Abernethyd8187c52015-02-16 01:25:53 -0800107 test('Q Promise Client Tests', function(assert) {
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800108
Randy Abernethyd8187c52015-02-16 01:25:53 -0800109 var checkRecursively = makeRecursiveCheck(assert);
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800110
Randy Abernethyd8187c52015-02-16 01:25:53 -0800111 function fail(msg) {
112 return function() {
113 assert.fail(msg);
114 }
115 }
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800116
Randy Abernethyd8187c52015-02-16 01:25:53 -0800117 function makeAsserter(assertionFn) {
118 return function(c) {
119 var fnName = c[0];
120 var expected = c[1];
121 client[fnName](expected)
122 .then(function(actual) {
123 assertionFn(actual, expected, fnName);
124 })
125 .fail(fail('fnName'));
126 };
127 }
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800128
Randy Abernethyd8187c52015-02-16 01:25:53 -0800129 testCases.simple.forEach(makeAsserter(assert.equal));
130 testCases.simpleLoose.forEach(makeAsserter(function(a, e, m){
131 assert.ok(a == e, m);
132 }));
133 testCases.deep.forEach(makeAsserter(assert.deepEqual));
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800134
Randy Abernethyd8187c52015-02-16 01:25:53 -0800135 client.testStruct(testCases.out)
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800136 .then(function(response) {
Randy Abernethyd8187c52015-02-16 01:25:53 -0800137 checkRecursively(testCases.out, response, 'testStruct');
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800138 })
Randy Abernethyd8187c52015-02-16 01:25:53 -0800139 .fail(fail('testStruct'));
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800140
Randy Abernethyd8187c52015-02-16 01:25:53 -0800141 client.testNest(testCases.out2)
142 .then(function(response) {
143 checkRecursively(testCases.out2, response, 'testNest');
144 })
145 .fail(fail('testNest'));
146
147 client.testInsanity(testCases.crazy)
148 .then(function(response) {
149 checkRecursively(testCases.insanity, response, 'testInsanity');
150 })
151 .fail(fail('testInsanity'));
152
153 client.testException('TException')
154 .then(function(response) {
155 assert.ok(!response, 'testException: TException');
156 })
157 .fail(fail('testException: TException'));
158
159 client.testException('Xception')
160 .then(function(response) {
161 assert.ok(!response);
162 })
163 .fail(function(err) {
164 assert.equal(err.errorCode, 1001);
165 assert.equal('Xception', err.message);
166 });
167
168 client.testException('no Exception')
169 .then(function(response) {
170 assert.equal(undefined, response); //void
171 })
172 .fail(fail('testException'));
173
174 client.testOneway(0, fail('testOneway: should not answer'));
175
176 checkOffByOne(function(done) {
177 client.testI32(-1)
178 .then(function(response) {
179 assert.equal(-1, response);
180 assert.end();
181 done();
182 })
183 .fail(fail('checkOffByOne'));
184 }, callback);
185 });
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800186};
187
188
189// Helper Functions
190// =========================================================
191
Randy Abernethyd8187c52015-02-16 01:25:53 -0800192function makeRecursiveCheck(assert) {
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800193
Randy Abernethyd8187c52015-02-16 01:25:53 -0800194 return function (map1, map2, msg) {
195 var equal = true;
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800196
Randy Abernethyd8187c52015-02-16 01:25:53 -0800197 var equal = checkRecursively(map1, map2);
198
199 assert.ok(equal, msg);
200
201 // deepEqual doesn't work with fields using node-int64
202 function checkRecursively(map1, map2) {
203 if (typeof map1 !== 'function' && typeof map2 !== 'function') {
204 if (!map1 || typeof map1 !== 'object') {
205 //Handle int64 types (which use node-int64 in Node.js JavaScript)
206 if ((typeof map1 === "number") && (typeof map2 === "object") &&
207 (map2.buffer) && (map2.buffer instanceof Buffer) && (map2.buffer.length === 8)) {
208 var n = new Int64(map2.buffer);
209 return map1 === n.toNumber();
210 } else {
211 return map1 == map2;
212 }
213 } else {
214 return Object.keys(map1).every(function(key) {
215 return checkRecursively(map1[key], map2[key]);
216 });
217 }
Randy Abernethy3b9ff4d2015-02-16 00:51:24 -0800218 }
219 }
220 }
221}
222
223function checkOffByOne(done, callback) {
224
225 var retry_limit = 30;
226 var retry_interval = 100;
227 var test_complete = false;
228 var retrys = 0;
229
230 /**
231 * redo a simple test after the oneway to make sure we aren't "off by one" --
232 * if the server treated oneway void like normal void, this next test will
233 * fail since it will get the void confirmation rather than the correct
234 * result. In this circumstance, the client will throw the exception:
235 *
236 * Because this is the last test against the server, when it completes
237 * the entire suite is complete by definition (the tests run serially).
238 */
239 done(function() {
240 test_complete = true;
241 });
242
243 //We wait up to retry_limit * retry_interval for the test suite to complete
244 function TestForCompletion() {
245 if(test_complete && callback) {
246 callback("Server successfully tested!");
247 } else {
248 if (++retrys < retry_limit) {
249 setTimeout(TestForCompletion, retry_interval);
250 } else if (callback) {
251 callback("Server test failed to complete after " +
252 (retry_limit * retry_interval / 1000) + " seconds");
253 }
254 }
255 }
256
257 setTimeout(TestForCompletion, retry_interval);
258}