| /* | 
 |  * Licensed to the Apache Software Foundation (ASF) under one | 
 |  * or more contributor license agreements. See the NOTICE file | 
 |  * distributed with this work for additional information | 
 |  * regarding copyright ownership. The ASF licenses this file | 
 |  * to you under the Apache License, Version 2.0 (the | 
 |  * 'License'); you may not use this file except in compliance | 
 |  * with the License. You may obtain a copy of the License at | 
 |  * | 
 |  *   http://www.apache.org/licenses/LICENSE-2.0 | 
 |  * | 
 |  * Unless required by applicable law or agreed to in writing, | 
 |  * software distributed under the License is distributed on an | 
 |  * 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 |  * KIND, either express or implied. See the License for the | 
 |  * specific language governing permissions and limitations | 
 |  * under the License. | 
 |  */ | 
 |  | 
 |  // This is the Node.js test driver for the standard Apache Thrift | 
 |  // test service. The driver invokes every function defined in the | 
 |  // Thrift Test service with a representative range of parameters. | 
 |  // | 
 |  // The ThriftTestDriver function requires a client object | 
 |  // connected to a server hosting the Thrift Test service and | 
 |  // supports an optional callback function which is called with | 
 |  // a status message when the test is complete. | 
 |  | 
 | var assert = require('assert'); | 
 | var ttypes = require('./gen-nodejs/ThriftTest_types'); | 
 | var Int64 = require('node-int64'); | 
 | var testCases = require('./test-cases'); | 
 |  | 
 | exports.ThriftTestDriver = function(client, callback) { | 
 |  | 
 |   function makeAsserter(assertionFn) { | 
 |     return function(c) { | 
 |       var fnName = c[0]; | 
 |       var expected = c[1]; | 
 |       client[fnName](expected, function(err, actual) { | 
 |         assert(!err); | 
 |         assertionFn(actual, expected); | 
 |       }) | 
 |     }; | 
 |   } | 
 |  | 
 |   testCases.simple.forEach(makeAsserter(assert.equal)); | 
 |   testCases.deep.forEach(makeAsserter(assert.deepEqual)); | 
 |  | 
 |   client.testStruct(testCases.out, function(err, response) { | 
 |     assert(!err); | 
 |     checkRecursively(testCases.out, response); | 
 |   }); | 
 |  | 
 |   client.testNest(testCases.out2, function(err, response) { | 
 |     assert(!err); | 
 |     checkRecursively(testCases.out2, response); | 
 |   }); | 
 |  | 
 |   client.testInsanity(testCases.crazy, function(err, response) { | 
 |     assert(!err); | 
 |     checkRecursively(testCases.insanity, response); | 
 |   }); | 
 |  | 
 |   client.testException('TException', function(err, response) { | 
 |     assert(!err); | 
 |     assert(!response); | 
 |   }); | 
 |  | 
 |   client.testException('Xception', function(err, response) { | 
 |     assert(!response); | 
 |     assert.equal(err.errorCode, 1001); | 
 |     assert.equal('Xception', err.message); | 
 |   }); | 
 |  | 
 |   client.testException('no Exception', function(err, response) { | 
 |     assert(!err); | 
 |     assert.equal(undefined, response); //void | 
 |   }); | 
 |  | 
 |   client.testOneway(0, function(err, response) { | 
 |     assert(false); //should not answer | 
 |   }); | 
 |  | 
 |   checkOffByOne(function(done) { | 
 |     client.testI32(-1, function(err, response) { | 
 |       assert(!err); | 
 |       assert.equal(-1, response); | 
 |       done(); | 
 |     }); | 
 |   }, callback); | 
 |  | 
 | }; | 
 |  | 
 | exports.ThriftTestDriverPromise = function(client, callback) { | 
 |  | 
 |   function makeAsserter(assertionFn) { | 
 |     return function(c) { | 
 |       var fnName = c[0]; | 
 |       var expected = c[1]; | 
 |       client[fnName](expected) | 
 |         .then(function(actual) { | 
 |           assert.equal(actual, expected); | 
 |         }) | 
 |         .fail(failTest); | 
 |     }; | 
 |   } | 
 |  | 
 |   testCases.simple.forEach(makeAsserter(assert.equal)); | 
 |   testCases.deep.forEach(makeAsserter(assert.deepEqual)); | 
 |  | 
 |   client.testStruct(testCases.out) | 
 |     .then(function(response) { | 
 |       checkRecursivelyP(testCases.out, response); | 
 |     }) | 
 |     .fail(failTest); | 
 |  | 
 |   client.testNest(testCases.out2) | 
 |     .then(function(response) { | 
 |       checkRecursivelyP(testCases.out2, response); | 
 |     }) | 
 |     .fail(failTest); | 
 |  | 
 |   client.testInsanity(testCases.crazy) | 
 |     .then(function(response) { | 
 |       checkRecursivelyP(testCases.insanity, response); | 
 |     }) | 
 |     .fail(failTest); | 
 |  | 
 |   client.testException('TException') | 
 |     .then(failTest); | 
 |  | 
 |   client.testException('Xception') | 
 |     .then(function(response) { | 
 |       assert.equal(err.errorCode, 1001); | 
 |       assert.equal('Xception', err.message); | 
 |     }) | 
 |     .fail(failTest); | 
 |  | 
 |   client.testException('no Exception') | 
 |     .then(function(response) { | 
 |       assert.equal(undefined, response); //void | 
 |     }) | 
 |     .fail(failTest); | 
 |  | 
 |   client.testOneway(0, failTest); //should not answer | 
 |  | 
 |   checkOffByOne(function(done) { | 
 |     client.testI32(-1) | 
 |       .then(function(response) { | 
 |           assert.equal(-1, response); | 
 |           done(); | 
 |       }) | 
 |       .fail(function() { | 
 |         assert(false); | 
 |       }); | 
 |   }, callback); | 
 |  | 
 | }; | 
 |  | 
 |  | 
 | // Helper Functions | 
 | // ========================================================= | 
 |  | 
 | function failTest() { | 
 |   assert(false); | 
 | } | 
 |  | 
 | // This is the version of checkRecursively that was in the vanilla callback | 
 | // version of test_driver. | 
 | function checkRecursively(map1, map2) { | 
 |   if (typeof map1 !== 'function' && typeof map2 !== 'function') { | 
 |     if (!map1 || typeof map1 !== 'object') { | 
 |       //Handle int64 types (which use node-int64 in Node.js JavaScript) | 
 |       if ((typeof map1 === "number") && (typeof map2 === "object") && | 
 |           (map2.buffer) && (map2.buffer instanceof Buffer) && (map2.buffer.length === 8)) { | 
 |         var n = new Int64(map2.buffer); | 
 |         assert.equal(map1, n.toNumber()); | 
 |       } else { | 
 |         assert.equal(map1, map2); | 
 |       } | 
 |     } else { | 
 |       for (var key in map1) { | 
 |         checkRecursively(map1[key], map2[key]); | 
 |       } | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | // This is the version of checkRecursively that was in the promise version of | 
 | // test_driver. | 
 | // deepEqual doesn't work with fields using node-int64 | 
 | function checkRecursivelyP(map1, map2) { | 
 |   if (typeof map1 !== 'function' && typeof map2 !== 'function') { | 
 |     if (!map1 || typeof map1 !== 'object') { | 
 |         assert.equal(map1, map2); | 
 |     } else { | 
 |       for (var key in map1) { | 
 |         checkRecursivelyP(map1[key], map2[key]); | 
 |       } | 
 |     } | 
 |   } | 
 | } | 
 |  | 
 | function checkOffByOne(done, callback) { | 
 |  | 
 |   var retry_limit = 30; | 
 |   var retry_interval = 100; | 
 |   var test_complete = false; | 
 |   var retrys = 0; | 
 |  | 
 |   /** | 
 |    * redo a simple test after the oneway to make sure we aren't "off by one" -- | 
 |    * if the server treated oneway void like normal void, this next test will | 
 |    * fail since it will get the void confirmation rather than the correct | 
 |    * result. In this circumstance, the client will throw the exception: | 
 |    * | 
 |    * Because this is the last test against the server, when it completes | 
 |    * the entire suite is complete by definition (the tests run serially). | 
 |    */ | 
 |   done(function() { | 
 |     test_complete = true; | 
 |   }); | 
 |  | 
 |   //We wait up to retry_limit * retry_interval for the test suite to complete | 
 |   function TestForCompletion() { | 
 |     if(test_complete && callback) { | 
 |       callback("Server successfully tested!"); | 
 |     } else { | 
 |       if (++retrys < retry_limit) { | 
 |         setTimeout(TestForCompletion, retry_interval); | 
 |       } else if (callback) { | 
 |         callback("Server test failed to complete after " + | 
 |                  (retry_limit * retry_interval / 1000) + " seconds"); | 
 |       } | 
 |     } | 
 |   } | 
 |  | 
 |   setTimeout(TestForCompletion, retry_interval); | 
 | } |