blob: 9f2b894e5fabaa6fa8bbac330da661d59615fc40 [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
29var assert = require('assert');
30var ttypes = require('./gen-nodejs/ThriftTest_types');
31var Int64 = require('node-int64');
32var testCases = require('./test-cases');
33
34exports.ThriftTestDriver = function(client, callback) {
35
36 function makeAsserter(assertionFn) {
37 return function(c) {
38 var fnName = c[0];
39 var expected = c[1];
40 client[fnName](expected, function(err, actual) {
41 assert(!err);
42 assertionFn(actual, expected);
43 })
44 };
45 }
46
47 testCases.simple.forEach(makeAsserter(assert.equal));
48 testCases.deep.forEach(makeAsserter(assert.deepEqual));
49
50 client.testStruct(testCases.out, function(err, response) {
51 assert(!err);
52 checkRecursively(testCases.out, response);
53 });
54
55 client.testNest(testCases.out2, function(err, response) {
56 assert(!err);
57 checkRecursively(testCases.out2, response);
58 });
59
60 client.testInsanity(testCases.crazy, function(err, response) {
61 assert(!err);
62 checkRecursively(testCases.insanity, response);
63 });
64
65 client.testException('TException', function(err, response) {
66 assert(!err);
67 assert(!response);
68 });
69
70 client.testException('Xception', function(err, response) {
71 assert(!response);
72 assert.equal(err.errorCode, 1001);
73 assert.equal('Xception', err.message);
74 });
75
76 client.testException('no Exception', function(err, response) {
77 assert(!err);
78 assert.equal(undefined, response); //void
79 });
80
81 client.testOneway(0, function(err, response) {
82 assert(false); //should not answer
83 });
84
85 checkOffByOne(function(done) {
86 client.testI32(-1, function(err, response) {
87 assert(!err);
88 assert.equal(-1, response);
89 done();
90 });
91 }, callback);
92
93};
94
95exports.ThriftTestDriverPromise = function(client, callback) {
96
97 function makeAsserter(assertionFn) {
98 return function(c) {
99 var fnName = c[0];
100 var expected = c[1];
101 client[fnName](expected)
102 .then(function(actual) {
103 assert.equal(actual, expected);
104 })
105 .fail(failTest);
106 };
107 }
108
109 testCases.simple.forEach(makeAsserter(assert.equal));
110 testCases.deep.forEach(makeAsserter(assert.deepEqual));
111
112 client.testStruct(testCases.out)
113 .then(function(response) {
114 checkRecursivelyP(testCases.out, response);
115 })
116 .fail(failTest);
117
118 client.testNest(testCases.out2)
119 .then(function(response) {
120 checkRecursivelyP(testCases.out2, response);
121 })
122 .fail(failTest);
123
124 client.testInsanity(testCases.crazy)
125 .then(function(response) {
126 checkRecursivelyP(testCases.insanity, response);
127 })
128 .fail(failTest);
129
130 client.testException('TException')
131 .then(failTest);
132
133 client.testException('Xception')
134 .then(function(response) {
135 assert.equal(err.errorCode, 1001);
136 assert.equal('Xception', err.message);
137 })
138 .fail(failTest);
139
140 client.testException('no Exception')
141 .then(function(response) {
142 assert.equal(undefined, response); //void
143 })
144 .fail(failTest);
145
146 client.testOneway(0, failTest); //should not answer
147
148 checkOffByOne(function(done) {
149 client.testI32(-1)
150 .then(function(response) {
151 assert.equal(-1, response);
152 done();
153 })
154 .fail(function() {
155 assert(false);
156 });
157 }, callback);
158
159};
160
161
162// Helper Functions
163// =========================================================
164
165function failTest() {
166 assert(false);
167}
168
169// This is the version of checkRecursively that was in the vanilla callback
170// version of test_driver.
171function checkRecursively(map1, map2) {
172 if (typeof map1 !== 'function' && typeof map2 !== 'function') {
173 if (!map1 || typeof map1 !== 'object') {
174 //Handle int64 types (which use node-int64 in Node.js JavaScript)
175 if ((typeof map1 === "number") && (typeof map2 === "object") &&
176 (map2.buffer) && (map2.buffer instanceof Buffer) && (map2.buffer.length === 8)) {
177 var n = new Int64(map2.buffer);
178 assert.equal(map1, n.toNumber());
179 } else {
180 assert.equal(map1, map2);
181 }
182 } else {
183 for (var key in map1) {
184 checkRecursively(map1[key], map2[key]);
185 }
186 }
187 }
188}
189
190// This is the version of checkRecursively that was in the promise version of
191// test_driver.
192// deepEqual doesn't work with fields using node-int64
193function checkRecursivelyP(map1, map2) {
194 if (typeof map1 !== 'function' && typeof map2 !== 'function') {
195 if (!map1 || typeof map1 !== 'object') {
196 assert.equal(map1, map2);
197 } else {
198 for (var key in map1) {
199 checkRecursivelyP(map1[key], map2[key]);
200 }
201 }
202 }
203}
204
205function checkOffByOne(done, callback) {
206
207 var retry_limit = 30;
208 var retry_interval = 100;
209 var test_complete = false;
210 var retrys = 0;
211
212 /**
213 * redo a simple test after the oneway to make sure we aren't "off by one" --
214 * if the server treated oneway void like normal void, this next test will
215 * fail since it will get the void confirmation rather than the correct
216 * result. In this circumstance, the client will throw the exception:
217 *
218 * Because this is the last test against the server, when it completes
219 * the entire suite is complete by definition (the tests run serially).
220 */
221 done(function() {
222 test_complete = true;
223 });
224
225 //We wait up to retry_limit * retry_interval for the test suite to complete
226 function TestForCompletion() {
227 if(test_complete && callback) {
228 callback("Server successfully tested!");
229 } else {
230 if (++retrys < retry_limit) {
231 setTimeout(TestForCompletion, retry_interval);
232 } else if (callback) {
233 callback("Server test failed to complete after " +
234 (retry_limit * retry_interval / 1000) + " seconds");
235 }
236 }
237 }
238
239 setTimeout(TestForCompletion, retry_interval);
240}