add jaeger support, link hot container & req span (#840)

* add jaeger support, link hot container & req span

* adds jaeger support now with FN_JAEGER_URL, there's a simple tutorial in the
operating/metrics.md file now and it's pretty easy to get up and running.
* links a hot request span to a hot container span. when we change this to
sample at a lower ratio we'll need to finagle the hot container span to always
sample or something, otherwise we'll hide that info. at least, since we're
sampling at 100% for now if this is flipped on, can see freeze/unfreeze etc.
if they hit. this is useful for debugging. note that zipkin's exporter does
not follow the link at all, hence jaeger... and they're backed by the Cloud
Empire now (CNCF) so we'll probably use it anyway.

* vendor: add thrift for jaeger
This commit is contained in:
Reed Allman
2018-03-13 15:57:12 -07:00
committed by GitHub
parent a7347a88b7
commit 9eaf824398
2953 changed files with 2334535 additions and 35 deletions

View File

@@ -0,0 +1,137 @@
/*
* 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.
*/
var test = require('tape');
var binary = require('thrift/binary');
var cases = {
"Should read signed byte": function(assert){
assert.equal(1, binary.readByte(0x01));
assert.equal(-1, binary.readByte(0xFF));
assert.equal(127, binary.readByte(0x7F));
assert.equal(-128, binary.readByte(0x80));
assert.end();
},
"Should write byte": function(assert){
//Protocol simply writes to the buffer. Nothing to test.. yet.
assert.ok(true);
assert.end();
},
"Should read I16": function(assert) {
assert.equal(0, binary.readI16([0x00, 0x00]));
assert.equal(1, binary.readI16([0x00, 0x01]));
assert.equal(-1, binary.readI16([0xff, 0xff]));
// Min I16
assert.equal(-32768, binary.readI16([0x80, 0x00]));
// Max I16
assert.equal(32767, binary.readI16([0x7f, 0xff]));
assert.end();
},
"Should write I16": function(assert) {
assert.deepEqual([0x00, 0x00], binary.writeI16([], 0));
assert.deepEqual([0x00, 0x01], binary.writeI16([], 1));
assert.deepEqual([0xff, 0xff], binary.writeI16([], -1));
// Min I16
assert.deepEqual([0x80, 0x00], binary.writeI16([], -32768));
// Max I16
assert.deepEqual([0x7f, 0xff], binary.writeI16([], 32767));
assert.end();
},
"Should read I32": function(assert) {
assert.equal(0, binary.readI32([0x00, 0x00, 0x00, 0x00]));
assert.equal(1, binary.readI32([0x00, 0x00, 0x00, 0x01]));
assert.equal(-1, binary.readI32([0xff, 0xff, 0xff, 0xff]));
// Min I32
assert.equal(-2147483648, binary.readI32([0x80, 0x00, 0x00, 0x00]));
// Max I32
assert.equal(2147483647, binary.readI32([0x7f, 0xff, 0xff, 0xff]));
assert.end();
},
"Should write I32": function(assert) {
assert.deepEqual([0x00, 0x00, 0x00, 0x00], binary.writeI32([], 0));
assert.deepEqual([0x00, 0x00, 0x00, 0x01], binary.writeI32([], 1));
assert.deepEqual([0xff, 0xff, 0xff, 0xff], binary.writeI32([], -1));
// Min I32
assert.deepEqual([0x80, 0x00, 0x00, 0x00], binary.writeI32([], -2147483648));
// Max I32
assert.deepEqual([0x7f, 0xff, 0xff, 0xff], binary.writeI32([], 2147483647));
assert.end();
},
"Should read doubles": function(assert) {
assert.equal(0, binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
assert.equal(0, binary.readDouble([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
assert.equal(1, binary.readDouble([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
assert.equal(2, binary.readDouble([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
assert.equal(-2, binary.readDouble([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
assert.equal(Math.PI, binary.readDouble([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18]))
assert.equal(Infinity, binary.readDouble([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
assert.equal(-Infinity, binary.readDouble([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
assert.ok(isNaN(binary.readDouble([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])))
assert.equal(1/3, binary.readDouble([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55]))
// Min subnormal positive double
assert.equal(4.9406564584124654e-324, binary.readDouble([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]))
// Min normal positive double
assert.equal(2.2250738585072014e-308, binary.readDouble([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
// Max positive double
assert.equal(1.7976931348623157e308, binary.readDouble([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))
assert.end();
},
"Should write doubles": function(assert) {
assert.deepEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 0));
assert.deepEqual([0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 1));
assert.deepEqual([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2));
assert.deepEqual([0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -2));
assert.deepEqual([0x40, 0x9, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18], binary.writeDouble([], Math.PI));
assert.deepEqual([0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], Infinity));
assert.deepEqual([0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], -Infinity));
assert.deepEqual([0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], NaN));
assert.deepEqual([0x3f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55], binary.writeDouble([], 1/3));
// Min subnormal positive double
assert.deepEqual([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01], binary.writeDouble([], 4.9406564584124654e-324));
// Min normal positive double
assert.deepEqual([0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], binary.writeDouble([], 2.2250738585072014e-308));
// Max positive double
assert.deepEqual([0x7f, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], binary.writeDouble([], 1.7976931348623157e308));
assert.end();
}
};
Object.keys(cases).forEach(function(caseName) {
test(caseName, cases[caseName]);
});

View File

@@ -0,0 +1,45 @@
/*
* 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.
*/
var assert = require('assert');
var thrift = require('thrift');
var helpers = require('./helpers');
var ThriftTest = require('./gen-nodejs/ThriftTest');
var ThriftTestDriver = require('./test_driver').ThriftTestDriver;
// createXHRConnection createWSConnection
var connection = thrift.createXHRConnection("localhost", 9090, {
transport: helpers.transports['buffered'],
protocol: helpers.protocols['json'],
path: '/test'
});
connection.on('error', function(err) {
assert(false, err);
});
// Uncomment the following line to start a websockets connection
// connection.open();
// createWSClient createXHRClient
var client = thrift.createXHRClient(ThriftTest, connection);
ThriftTestDriver(client, function (status) {
console.log('Browser:', status);
});

View File

@@ -0,0 +1,7 @@
server.crt AND server.key ARE PROVIDED FOR TEST PURPOSE AND SHOULD *NEVER* BE USED IN PRODUCTION
Origin of the test key and cert is the folder test/keys of Apache Thrift source code distribution
We need copies for npm deployment

View File

@@ -0,0 +1,136 @@
#!/usr/bin/env node
/*
* 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.
*/
var fs = require('fs');
var assert = require('assert');
var thrift = require('thrift');
var helpers = require('./helpers');
var ThriftTest = require('./gen-nodejs/ThriftTest');
var ThriftTestDriver = require('./test_driver').ThriftTestDriver;
var ThriftTestDriverPromise = require('./test_driver').ThriftTestDriverPromise;
var SecondService = require('./gen-nodejs/SecondService');
var ttypes = require('./gen-nodejs/ThriftTest_types');
var program = require('commander');
program
.option('-p, --protocol <protocol>', 'Set thrift protocol (binary|compact|json) [protocol]')
.option('-t, --transport <transport>', 'Set thrift transport (buffered|framed|http) [transport]')
.option('--port <port>', 'Set thrift server port number to connect', 9090)
.option('--host <host>', 'Set thrift server host to connect', 'localhost')
.option('--ssl', 'use SSL transport')
.option('--promise', 'test with promise style functions')
.option('-t, --type <type>', 'Select server type (http|multiplex|tcp|websocket)', 'tcp')
.parse(process.argv);
var host = program.host;
var port = program.port;
var type = program.type;
var ssl = program.ssl;
var promise = program.promise;
/* for compatibility with cross test invocation for http transport testing */
if (program.transport === 'http') {
program.transport = 'buffered';
type = 'http';
}
var options = {
transport: helpers.transports[program.transport],
protocol: helpers.protocols[program.protocol]
};
if (type === 'http' || type === 'websocket') {
options.path = '/test';
}
if (type === 'http') {
options.headers = {"Connection": "close"};
}
if (ssl) {
if (type === 'tcp' || type === 'multiplex') {
options.rejectUnauthorized = false;
} else if (type === 'http') {
options.nodeOptions = { rejectUnauthorized: false };
options.https = true;
} else if (type === 'websocket') {
options.wsOptions = { rejectUnauthorized: false };
options.secure = true;
}
}
var connection;
var client;
var testDriver = promise ? ThriftTestDriverPromise : ThriftTestDriver;
if (type === 'tcp' || type === 'multiplex') {
connection = ssl ?
thrift.createSSLConnection(host, port, options) :
thrift.createConnection(host, port, options);
} else if (type === 'http') {
connection = thrift.createHttpConnection(host, port, options);
} else if (type === 'websocket') {
connection = thrift.createWSConnection(host, port, options);
connection.open();
}
connection.on('error', function(err) {
assert(false, err);
});
if (type === 'tcp') {
client = thrift.createClient(ThriftTest, connection);
runTests();
} else if (type === 'multiplex') {
var mp = new thrift.Multiplexer();
client = mp.createClient("ThriftTest", ThriftTest, connection);
secondclient = mp.createClient("SecondService", SecondService, connection);
connection.on('connect', function() {
secondclient.secondtestString("Test", function(err, response) {
assert(!err);
assert.equal("testString(\"Test\")", response);
});
runTests();
});
} else if (type === 'http') {
client = thrift.createHttpClient(ThriftTest, connection);
runTests();
} else if (type === 'websocket') {
client = thrift.createWSClient(ThriftTest, connection);
runTests();
}
function runTests() {
testDriver(client, function (status) {
console.log(status);
if (type !== 'http' && type !== 'websocket') {
connection.end();
}
if (type !== 'multiplex') {
process.exit(0);
}
});
}
exports.expressoTest = function() {};

View File

@@ -0,0 +1,333 @@
/*
* 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.
*/
var ttypes = require('./gen-nodejs/JsDeepConstructorTest_types');
var thrift = require('thrift');
var test = require('tape');
var bufferEquals = require('buffer-equals');
function serializeBinary(data) {
var buff;
var transport = new thrift.TBufferedTransport(null, function(msg){
buff = msg;
});
var prot = new thrift.TBinaryProtocol(transport);
data.write(prot);
prot.flush();
return buff;
}
function deserializeBinary(serialized, type) {
var t = new thrift.TFramedTransport(serialized);
var p = new thrift.TBinaryProtocol(t);
var data = new type();
data.read(p);
return data;
}
function serializeJSON(data) {
var buff;
var transport = new thrift.TBufferedTransport(null, function(msg){
buff = msg;
});
var protocol = new thrift.TJSONProtocol(transport);
protocol.writeMessageBegin("", 0, 0);
data.write(protocol);
protocol.writeMessageEnd();
protocol.flush();
return buff;
}
function deserializeJSON(serialized, type) {
var transport = new thrift.TFramedTransport(serialized);
var protocol = new thrift.TJSONProtocol(transport);
protocol.readMessageBegin();
var data = new type();
data.read(protocol);
protocol.readMessageEnd();
return data;
}
function createThriftObj() {
return new ttypes.Complex({
struct_field: new ttypes.Simple({value: 'a'}),
struct_list_field: [
new ttypes.Simple({value: 'b'}),
new ttypes.Simple({value: 'c'}),
],
struct_set_field: [
new ttypes.Simple({value: 'd'}),
new ttypes.Simple({value: 'e'}),
],
struct_map_field: {
A: new ttypes.Simple({value: 'f'}),
B: new ttypes.Simple({value: 'g'})
},
struct_nested_containers_field: [
[
{
C: [
new ttypes.Simple({value: 'h'}),
new ttypes.Simple({value: 'i'})
]
}
]
],
struct_nested_containers_field2: {
D: [
{
DA: new ttypes.Simple({value: 'j'})
},
{
DB: new ttypes.Simple({value: 'k'})
}
]
},
list_of_list_field: [
['l00', 'l01', 'l02'],
['l10', 'l11', 'l12'],
['l20', 'l21', 'l22'],
],
list_of_list_of_list_field: [
[['m000', 'm001', 'm002'], ['m010', 'm011', 'm012'], ['m020', 'm021', 'm022']],
[['m100', 'm101', 'm102'], ['m110', 'm111', 'm112'], ['m120', 'm121', 'm122']],
[['m200', 'm201', 'm202'], ['m210', 'm211', 'm212'], ['m220', 'm221', 'm222']],
],
});
}
function createJsObj() {
return {
struct_field: {value: 'a'},
struct_list_field: [
{value: 'b'},
{value: 'c'},
],
struct_set_field: [
{value: 'd'},
{value: 'e'},
],
struct_map_field: {
A: {value: 'f'},
B: {value: 'g'}
},
struct_nested_containers_field: [
[
{
C: [
{value: 'h'},
{value: 'i'}
]
}
]
],
struct_nested_containers_field2: {
D: [
{
DA: {value: 'j'}
},
{
DB: {value: 'k'}
}
]
},
list_of_list_field: [
['l00', 'l01', 'l02'],
['l10', 'l11', 'l12'],
['l20', 'l21', 'l22'],
],
list_of_list_of_list_field: [
[['m000', 'm001', 'm002'], ['m010', 'm011', 'm012'], ['m020', 'm021', 'm022']],
[['m100', 'm101', 'm102'], ['m110', 'm111', 'm112'], ['m120', 'm121', 'm122']],
[['m200', 'm201', 'm202'], ['m210', 'm211', 'm212'], ['m220', 'm221', 'm222']],
],
};
}
function assertValues(obj, assert) {
assert.equals(obj.struct_field.value, 'a');
assert.equals(obj.struct_list_field[0].value, 'b');
assert.equals(obj.struct_list_field[1].value, 'c');
assert.equals(obj.struct_set_field[0].value, 'd');
assert.equals(obj.struct_set_field[1].value, 'e');
assert.equals(obj.struct_map_field.A.value, 'f');
assert.equals(obj.struct_map_field.B.value, 'g');
assert.equals(obj.struct_nested_containers_field[0][0].C[0].value, 'h');
assert.equals(obj.struct_nested_containers_field[0][0].C[1].value, 'i');
assert.equals(obj.struct_nested_containers_field2.D[0].DA.value, 'j');
assert.equals(obj.struct_nested_containers_field2.D[1].DB.value, 'k');
assert.equals(obj.list_of_list_field[0][0], 'l00');
assert.equals(obj.list_of_list_field[0][1], 'l01');
assert.equals(obj.list_of_list_field[0][2], 'l02');
assert.equals(obj.list_of_list_field[1][0], 'l10');
assert.equals(obj.list_of_list_field[1][1], 'l11');
assert.equals(obj.list_of_list_field[1][2], 'l12');
assert.equals(obj.list_of_list_field[2][0], 'l20');
assert.equals(obj.list_of_list_field[2][1], 'l21');
assert.equals(obj.list_of_list_field[2][2], 'l22');
assert.equals(obj.list_of_list_of_list_field[0][0][0], 'm000');
assert.equals(obj.list_of_list_of_list_field[0][0][1], 'm001');
assert.equals(obj.list_of_list_of_list_field[0][0][2], 'm002');
assert.equals(obj.list_of_list_of_list_field[0][1][0], 'm010');
assert.equals(obj.list_of_list_of_list_field[0][1][1], 'm011');
assert.equals(obj.list_of_list_of_list_field[0][1][2], 'm012');
assert.equals(obj.list_of_list_of_list_field[0][2][0], 'm020');
assert.equals(obj.list_of_list_of_list_field[0][2][1], 'm021');
assert.equals(obj.list_of_list_of_list_field[0][2][2], 'm022');
assert.equals(obj.list_of_list_of_list_field[1][0][0], 'm100');
assert.equals(obj.list_of_list_of_list_field[1][0][1], 'm101');
assert.equals(obj.list_of_list_of_list_field[1][0][2], 'm102');
assert.equals(obj.list_of_list_of_list_field[1][1][0], 'm110');
assert.equals(obj.list_of_list_of_list_field[1][1][1], 'm111');
assert.equals(obj.list_of_list_of_list_field[1][1][2], 'm112');
assert.equals(obj.list_of_list_of_list_field[1][2][0], 'm120');
assert.equals(obj.list_of_list_of_list_field[1][2][1], 'm121');
assert.equals(obj.list_of_list_of_list_field[1][2][2], 'm122');
assert.equals(obj.list_of_list_of_list_field[2][0][0], 'm200');
assert.equals(obj.list_of_list_of_list_field[2][0][1], 'm201');
assert.equals(obj.list_of_list_of_list_field[2][0][2], 'm202');
assert.equals(obj.list_of_list_of_list_field[2][1][0], 'm210');
assert.equals(obj.list_of_list_of_list_field[2][1][1], 'm211');
assert.equals(obj.list_of_list_of_list_field[2][1][2], 'm212');
assert.equals(obj.list_of_list_of_list_field[2][2][0], 'm220');
assert.equals(obj.list_of_list_of_list_field[2][2][1], 'm221');
assert.equals(obj.list_of_list_of_list_field[2][2][2], 'm222');
}
function createTestCases(serialize, deserialize) {
var cases = {
"Serialize/deserialize should return equal object": function(assert){
var tObj = createThriftObj();
var received = deserialize(serialize(tObj), ttypes.Complex);
assert.ok(tObj !== received, 'not the same object');
assert.deepEqual(tObj, received);
assert.end();
},
"Nested structs and containers initialized from plain js objects should serialize same as if initialized from thrift objects": function(assert) {
var tObj1 = createThriftObj();
var tObj2 = new ttypes.Complex(createJsObj());
assertValues(tObj2, assert);
var s1 = serialize(tObj1);
var s2 = serialize(tObj2);
assert.ok(bufferEquals(s1, s2));
assert.end();
},
"Modifications to args object should not affect constructed Thrift object": function (assert) {
var args = createJsObj();
assertValues(args, assert);
var tObj = new ttypes.Complex(args);
assertValues(tObj, assert);
args.struct_field.value = 'ZZZ';
args.struct_list_field[0].value = 'ZZZ';
args.struct_list_field[1].value = 'ZZZ';
args.struct_set_field[0].value = 'ZZZ';
args.struct_set_field[1].value = 'ZZZ';
args.struct_map_field.A.value = 'ZZZ';
args.struct_map_field.B.value = 'ZZZ';
args.struct_nested_containers_field[0][0].C[0] = 'ZZZ';
args.struct_nested_containers_field[0][0].C[1] = 'ZZZ';
args.struct_nested_containers_field2.D[0].DA = 'ZZZ';
args.struct_nested_containers_field2.D[0].DB = 'ZZZ';
assertValues(tObj, assert);
assert.end();
},
"nulls are ok": function(assert) {
var tObj = new ttypes.Complex({
struct_field: null,
struct_list_field: null,
struct_set_field: null,
struct_map_field: null,
struct_nested_containers_field: null,
struct_nested_containers_field2: null
});
var received = deserialize(serialize(tObj), ttypes.Complex);
assert.strictEqual(tObj.struct_field, null);
assert.ok(tObj !== received);
assert.deepEqual(tObj, received);
assert.end();
},
"Can make list with objects": function(assert) {
var tObj = new ttypes.ComplexList({
"struct_list_field": [new ttypes.Complex({})]
});
var innerObj = tObj.struct_list_field[0];
assert.ok(innerObj instanceof ttypes.Complex)
assert.strictEqual(innerObj.struct_field, null);
assert.strictEqual(innerObj.struct_list_field, null);
assert.strictEqual(innerObj.struct_set_field, null);
assert.strictEqual(innerObj.struct_map_field, null);
assert.strictEqual(innerObj.struct_nested_containers_field, null);
assert.strictEqual(innerObj.struct_nested_containers_field2, null);
assert.end();
}
};
return cases;
}
function run(name, cases){
Object.keys(cases).forEach(function(caseName) {
test(name + ': ' + caseName, cases[caseName]);
});
}
run('binary', createTestCases(serializeBinary, deserializeBinary));
run('json', createTestCases(serializeJSON, deserializeJSON));

View File

@@ -0,0 +1,74 @@
/*
* 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.
*/
'use strict';
var test = require('tape');
var thrift = require('../lib/thrift/thrift.js');
var InputBufferUnderrunError = require('../lib/thrift/input_buffer_underrun_error');
test('TApplicationException', function t(assert) {
var e = new thrift.TApplicationException(1, 'foo');
assert.ok(e instanceof thrift.TApplicationException, 'is instanceof TApplicationException');
assert.ok(e instanceof thrift.TException, 'is instanceof TException');
assert.ok(e instanceof Error, 'is instanceof Error');
assert.equal(typeof e.stack, 'string', 'has stack trace');
assert.ok(/^TApplicationException: foo/.test(e.stack), 'Stack trace has correct error name and message');
assert.ok(e.stack.indexOf('test/exceptions.js:7:11') !== -1, 'stack trace starts on correct line and column');
assert.equal(e.name, 'TApplicationException', 'has function name TApplicationException');
assert.equal(e.message, 'foo', 'has error message "foo"');
assert.equal(e.type, 1, 'has type 1');
assert.end();
});
test('TException', function t(assert) {
var e = new thrift.TException('foo');
assert.ok(e instanceof thrift.TException, 'is instanceof TException');
assert.ok(e instanceof Error, 'is instanceof Error');
assert.equal(typeof e.stack, 'string', 'has stack trace');
assert.ok(/^TException: foo/.test(e.stack), 'Stack trace has correct error name and message');
assert.ok(e.stack.indexOf('test/exceptions.js:21:11') !== -1, 'stack trace starts on correct line and column');
assert.equal(e.name, 'TException', 'has function name TException');
assert.equal(e.message, 'foo', 'has error message "foo"');
assert.end();
});
test('TProtocolException', function t(assert) {
var e = new thrift.TProtocolException(1, 'foo');
assert.ok(e instanceof thrift.TProtocolException, 'is instanceof TProtocolException');
assert.ok(e instanceof Error, 'is instanceof Error');
assert.equal(typeof e.stack, 'string', 'has stack trace');
assert.ok(/^TProtocolException: foo/.test(e.stack), 'Stack trace has correct error name and message');
assert.ok(e.stack.indexOf('test/exceptions.js:33:11') !== -1, 'stack trace starts on correct line and column');
assert.equal(e.name, 'TProtocolException', 'has function name TProtocolException');
assert.equal(e.message, 'foo', 'has error message "foo"');
assert.equal(e.type, 1, 'has type 1');
assert.end();
});
test('InputBufferUnderrunError', function t(assert) {
var e = new InputBufferUnderrunError('foo');
assert.ok(e instanceof InputBufferUnderrunError, 'is instanceof InputBufferUnderrunError');
assert.ok(e instanceof Error, 'is instanceof Error');
assert.equal(typeof e.stack, 'string', 'has stack trace');
assert.ok(/^InputBufferUnderrunError: foo/.test(e.stack), 'Stack trace has correct error name and message');
assert.ok(e.stack.indexOf('test/exceptions.js:46:11') !== -1, 'stack trace starts on correct line and column');
assert.equal(e.name, 'InputBufferUnderrunError', 'has function name InputBufferUnderrunError');
assert.equal(e.message, 'foo', 'has error message "foo"');
assert.end();
});

View File

@@ -0,0 +1,32 @@
/*
* 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.
*/
'use strict';
var thrift = require('../lib/thrift');
module.exports.transports = {
'buffered': thrift.TBufferedTransport,
'framed': thrift.TFramedTransport
};
module.exports.protocols = {
'json': thrift.TJSONProtocol,
'binary': thrift.TBinaryProtocol,
'compact': thrift.TCompactProtocol
};

View File

@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIENzCCAx+gAwIBAgIJAOYfYfw7NCOcMA0GCSqGSIb3DQEBBQUAMIGxMQswCQYD
VQQGEwJVUzERMA8GA1UECAwITWFyeWxhbmQxFDASBgNVBAcMC0ZvcmVzdCBIaWxs
MScwJQYDVQQKDB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xFjAUBgNV
BAsMDUFwYWNoZSBUaHJpZnQxEjAQBgNVBAMMCWxvY2FsaG9zdDEkMCIGCSqGSIb3
DQEJARYVZGV2QHRocmlmdC5hcGFjaGUub3JnMB4XDTE0MDQwNzE4NTgwMFoXDTIy
MDYyNDE4NTgwMFowgbExCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNYXJ5bGFuZDEU
MBIGA1UEBwwLRm9yZXN0IEhpbGwxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29mdHdh
cmUgRm91bmRhdGlvbjEWMBQGA1UECwwNQXBhY2hlIFRocmlmdDESMBAGA1UEAwwJ
bG9jYWxob3N0MSQwIgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0LmFwYWNoZS5vcmcw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqE9TE9wEXp5LRtLQVDSGQ
GV78+7ZtP/I/ZaJ6Q6ZGlfxDFvZjFF73seNhAvlKlYm/jflIHYLnNOCySN8I2Xw6
L9MbC+jvwkEKfQo4eDoxZnOZjNF5J1/lZtBeOowMkhhzBMH1Rds351/HjKNg6ZKg
2Cldd0j7HbDtEixOLgLbPRpBcaYrLrNMasf3Hal+x8/b8ue28x93HSQBGmZmMIUw
AinEu/fNP4lLGl/0kZb76TnyRpYSPYojtS6CnkH+QLYnsRREXJYwD1Xku62LipkX
wCkRTnZ5nUsDMX6FPKgjQFQCWDXG/N096+PRUQAChhrXsJ+gF3NqWtDmtrhVQF4n
AgMBAAGjUDBOMB0GA1UdDgQWBBQo8v0wzQPx3EEexJPGlxPK1PpgKjAfBgNVHSME
GDAWgBQo8v0wzQPx3EEexJPGlxPK1PpgKjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
DQEBBQUAA4IBAQBGFRiJslcX0aJkwZpzTwSUdgcfKbpvNEbCNtVohfQVTI4a/oN5
U+yqDZJg3vOaOuiAZqyHcIlZ8qyesCgRN314Tl4/JQ++CW8mKj1meTgo5YFxcZYm
T9vsI3C+Nzn84DINgI9mx6yktIt3QOKZRDpzyPkUzxsyJ8J427DaimDrjTR+fTwD
1Dh09xeeMnSa5zeV1HEDyJTqCXutLetwQ/IyfmMBhIx+nvB5f67pz/m+Dv6V0r3I
p4HCcdnDUDGJbfqtoqsAATQQWO+WWuswB6mOhDbvPTxhRpZq6AkgWqv4S+u3M2GO
r5p9FrBgavAw5bKO54C0oQKpN/5fta5l6Ws0
-----END CERTIFICATE-----

View File

@@ -0,0 +1,106 @@
#!/usr/bin/env node
/*
* 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.
*/
var fs = require('fs');
var path = require('path');
var thrift = require('../lib/thrift');
var program = require('commander');
var helpers = require('./helpers');
var ThriftTest = require('./gen-nodejs/ThriftTest');
var SecondService = require('./gen-nodejs/SecondService');
var ThriftTestHandler = require('./test_handler').AsyncThriftTestHandler;
var ThriftTestHandlerPromise = require('./test_handler').SyncThriftTestHandler;
var ttypes = require('./gen-nodejs/ThriftTest_types');
program
.option('-p, --protocol <protocol>', 'Set thrift protocol (binary|compact|json)', 'binary')
.option('-t, --transport <transport>', 'Set thrift transport (buffered|framed|http)', 'buffered')
.option('--ssl', 'use ssl transport')
.option('--port <port>', 'Set thrift server port', 9090)
.option('--promise', 'test with promise style functions')
.option('-t, --type <type>', 'Select server type (http|multiplex|tcp|websocket)', 'tcp')
.parse(process.argv);
var port = program.port;
var type = program.type;
var ssl = program.ssl;
var promise = program.promise;
var handler = program.promise ? ThriftTestHandler : ThriftTestHandlerPromise;
if (program.transport === 'http') {
program.transport = 'buffered';
type = 'http';
}
var options = {
transport: helpers.transports[program.transport],
protocol: helpers.protocols[program.protocol]
};
if (type === 'http' || type ==='websocket') {
options.handler = handler;
options.processor = ThriftTest;
options = {
services: { "/test": options },
cors: {
'*': true
}
}
}
if (type === 'multiplex') {
var SecondServiceHandler = {
secondtestString: function(thing, result) {
console.log('testString("' + thing + '")');
result(null, 'testString("' + thing + '")');
}
};
var processor = new thrift.MultiplexedProcessor();
processor.registerProcessor("ThriftTest",
new ThriftTest.Processor(ThriftTestHandler));
processor.registerProcessor("SecondService",
new SecondService.Processor(SecondServiceHandler));
}
if (ssl) {
options.tls = {
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
};
}
var server;
if (type === 'tcp') {
server = thrift.createServer(ThriftTest, handler, options);
} else if (type === 'multiplex') {
server = thrift.createMultiplexServer(processor, options);
} else if (type === 'http' || type === 'websocket') {
server = thrift.createWebServer(options);
}
server.listen(port);

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCqE9TE9wEXp5LR
tLQVDSGQGV78+7ZtP/I/ZaJ6Q6ZGlfxDFvZjFF73seNhAvlKlYm/jflIHYLnNOCy
SN8I2Xw6L9MbC+jvwkEKfQo4eDoxZnOZjNF5J1/lZtBeOowMkhhzBMH1Rds351/H
jKNg6ZKg2Cldd0j7HbDtEixOLgLbPRpBcaYrLrNMasf3Hal+x8/b8ue28x93HSQB
GmZmMIUwAinEu/fNP4lLGl/0kZb76TnyRpYSPYojtS6CnkH+QLYnsRREXJYwD1Xk
u62LipkXwCkRTnZ5nUsDMX6FPKgjQFQCWDXG/N096+PRUQAChhrXsJ+gF3NqWtDm
trhVQF4nAgMBAAECggEAW/y52YYW6ypROGbZ94DQpFV0kLO7qT8q0Ksxw5sPNaIt
fEPRIymDa8ikyHWJS5Oxmw84wo5jnJV26jaLmwe2Lupq7Xf1lqej8f5LJtuv7cQR
xfzp1vM65KJFFJHp6WqjGqJ6HSSZOpVDsnQYcXQjQCdpyAmaSWd3p+FqYSZ1mQmD
bFNI7jqpczWSZhTdotQ7p7Hn9TVCehflP3yGIB3bQ+wCcCB85dOBz201L+YgaIck
Sz43A4NvWaQIRLRDw7s9GW4jY5T0Jv282WIeAlVpVxLIwu48r4R4yGTIx9Ydowvq
57+Y5iPPjAXxu0V9t00oS3bYxDaKh2DUfc/5zowq8QKBgQDYNVPXmaG0aIH4vjQ9
7fRdw/UDkYcQbn6CnglQOu77/S8ogQzpKCVJgJgkZNqOVtQMEPzekGEcLTbje1gU
8Bky2k+PL9UwbFy0emnOVh4rqrNXHsRvJcehNT/PRb5hjF3MUMFV/0iD4b+naFaE
jrSWiZ2ZXj2qfwAK52GFbtOuBQKBgQDJYQuGiY0r22E4waJmCSKczoBT3cwlVzWj
V2ljgA9RHLNTVkvNNYQLGu2qngFrtwpeaSnsMDerVG4wKAQWyCnYzxVrlnC4uDrJ
HXuFEltBWi9Ffbgfsnd3749AT0oBP1NT2tMleguyf5DFgjCR3VRJLdrVaaZ8row/
LqKcFMqnOwKBgB+OIO99l7E584Y3VG6ZdSneOLtNmRXX2pT7tcZE465ZdHGH7Dd3
SYHhx9K/+Xn+yDH+pLli/xlarAEldmSP6k2WuTfftlC78AfTOfAId5zN7CDR9791
Fx67I9X/itq33tS8EIuZl57P6uXm/4GXRloWOa8xpvRkVsBApuYPl8t1AoGATQDS
y2sllDObBXzlgGbV2WgNIgSZ311toTv3jJiXQsjauW8yJRHln+l4H9mzaWDgkiFc
ang1kUoDqF5k0eFQPxtQcYdhKwEnWWfwp33RbzfxA32DPnubuzzbZhfrkHaKgnIW
cyor9uFYlm2l7ODZLfJez2RKyTplXnOSsmQw6akCgYAz3dj9Hskyj+HVJ+ht1OcE
c7ai/ESkSA7Vajp0tjJp0EKjW/zq8DvUSXOtcdnJgkKycFluLwbmnaN4txBds1C1
Qr8Rt2sUCCBNZe1L6DHe3XBdbkJe9sgZVNTjtUSQrzy8UhvsCqG4YWeCu07Szcbc
rdPUV9/uQkdx8VrShxlD8A==
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,163 @@
/*
* 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.
*/
'use strict';
var ttypes = require('./gen-nodejs/ThriftTest_types');
var Int64 = require('node-int64');
//all Languages in UTF-8
/*jshint -W100 */
var stringTest = module.exports.stringTest = "Afrikaans, Alemannisch, Aragonés, العربية, مصرى, " +
"Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška, " +
"Беларуская, Беларуская (тарашкевіца), Български, Bamanankan, " +
"বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн, " +
"Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg, " +
"Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English, " +
"Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt, " +
"Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego, " +
"Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski, " +
"Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia, " +
"Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa, " +
"ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар, " +
"Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino, " +
"Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa " +
"Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa " +
"Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, " +
"Norsk (nynorsk), Norsk (bokmål), Nouormand, Diné bizaad, " +
"Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو, " +
"Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română, " +
"Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple " +
"English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk, " +
"Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog, " +
"Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük, " +
"Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文, " +
"Bân-lâm-gú, 粵語";
/*jshint +W100 */
var specialCharacters = module.exports.specialCharacters = 'quote: \" backslash:' +
' forwardslash-escaped: \/ ' +
' backspace: \b formfeed: \f newline: \n return: \r tab: ' +
' now-all-of-them-together: "\\\/\b\n\r\t' +
' now-a-bunch-of-junk: !@#$%&()(&%$#{}{}<><><' +
' char-to-test-json-parsing: ]] \"]] \\" }}}{ [[[ ';
var mapTestInput = module.exports.mapTestInput = {
"a":"123", "a b":"with spaces ", "same":"same", "0":"numeric key",
"longValue":stringTest, stringTest:"long key"
};
var simple = [
['testVoid', undefined],
['testString', 'Test'],
['testString', ''],
['testString', stringTest],
['testString', specialCharacters],
['testBool', true],
['testBool', false],
['testByte', 1],
['testByte', 0],
['testByte', -1],
['testByte', -127],
['testI32', -1],
['testDouble', -5.2098523],
['testDouble', 7.012052175215044],
['testEnum', ttypes.Numberz.ONE],
['testI64', 5],
['testI64', -5],
['testI64', 734359738368],
['testI64', -734359738368],
['testI64', new Int64(new Buffer([0, 0x20, 0, 0, 0, 0, 0, 1]))], // 2^53+1
['testI64', new Int64(
new Buffer([0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]))], // -2^53-1
['testTypedef', 69]
]
var mapout = {};
for (var i = 0; i < 5; ++i) {
mapout[i] = i-10;
}
var deep = [
['testList', [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]],
];
var deepUnordered = [
['testMap', mapout],
['testSet', [1,2,3]],
['testStringMap', mapTestInput]
];
var out = new ttypes.Xtruct({
string_thing: 'Zero',
byte_thing: 1,
i32_thing: -3,
i64_thing: 1000000
});
var out2 = new ttypes.Xtruct2();
out2.byte_thing = 1;
out2.struct_thing = out;
out2.i32_thing = 5;
var crazy = new ttypes.Insanity({
"userMap":{ "5":5, "8":8 },
"xtructs":[new ttypes.Xtruct({
"string_thing":"Goodbye4",
"byte_thing":4,
"i32_thing":4,
"i64_thing":4
}), new ttypes.Xtruct({
"string_thing":"Hello2",
"byte_thing":2,
"i32_thing":2,
"i64_thing":2
})]
});
var crazy2 = new ttypes.Insanity({
"userMap":{ "5":5, "8":8 },
"xtructs":[{
"string_thing":"Goodbye4",
"byte_thing":4,
"i32_thing":4,
"i64_thing":4
}, {
"string_thing":"Hello2",
"byte_thing":2,
"i32_thing":2,
"i64_thing":2
}]
});
var insanity = {
"1":{ "2": crazy, "3": crazy },
"2":{ "6":{ "userMap":{}, "xtructs":[] } }
};
module.exports.simple = simple;
module.exports.deep = deep;
module.exports.deepUnordered = deepUnordered;
module.exports.out = out;
module.exports.out2 = out2;
module.exports.crazy = crazy;
module.exports.crazy2 = crazy2;
module.exports.insanity = insanity;

108
vendor/git.apache.org/thrift.git/lib/nodejs/test/testAll.sh generated vendored Executable file
View File

@@ -0,0 +1,108 @@
#! /bin/sh
# 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.
if [ -n "${1}" ]; then
COVER=${1};
fi
DIR="$( cd "$( dirname "$0" )" && pwd )"
ISTANBUL="$DIR/../../../node_modules/istanbul/lib/cli.js"
RUNBROWSER="$DIR/../../../node_modules/run-browser/bin/cli.js"
REPORT_PREFIX="${DIR}/../coverage/report"
COUNT=0
export NODE_PATH="${DIR}:${DIR}/../lib:${NODE_PATH}"
testServer()
{
echo " Testing $1 Client/Server with protocol $2 and transport $3 $4";
RET=0
if [ -n "${COVER}" ]; then
${ISTANBUL} cover ${DIR}/server.js --dir ${REPORT_PREFIX}${COUNT} --handle-sigint -- --type $1 -p $2 -t $3 $4 &
COUNT=$((COUNT+1))
else
node ${DIR}/server.js --type $1 -p $2 -t $3 $4 &
fi
SERVERPID=$!
sleep 0.1
if [ -n "${COVER}" ]; then
${ISTANBUL} cover ${DIR}/client.js --dir ${REPORT_PREFIX}${COUNT} -- --type $1 -p $2 -t $3 $4 || RET=1
COUNT=$((COUNT+1))
else
node ${DIR}/client.js --type $1 -p $2 -t $3 $4 || RET=1
fi
kill -2 $SERVERPID || RET=1
wait $SERVERPID
return $RET
}
testBrowser()
{
echo " Testing browser client with http server with json protocol and buffered transport";
RET=0
node ${DIR}/server.js --type http -p json -t buffered &
SERVERPID=$!
sleep 1
${RUNBROWSER} ${DIR}/browser_client.js --phantom || RET=1
kill -2 $SERVERPID || RET=1
return $RET
}
TESTOK=0
#generating thrift code
${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node ${DIR}/../../../test/ThriftTest.thrift
${DIR}/../../../compiler/cpp/thrift -o ${DIR} --gen js:node ${DIR}/../../../test/JsDeepConstructorTest.thrift
#unit tests
node ${DIR}/binary.test.js || TESTOK=1
node ${DIR}/deep-constructor.test.js || TESTOK=1
#integration tests
for type in tcp multiplex websocket http
do
for protocol in compact binary json
do
for transport in buffered framed
do
testServer $type $protocol $transport || TESTOK=1
testServer $type $protocol $transport --ssl || TESTOK=1
testServer $type $protocol $transport --promise || TESTOK=1
done
done
done
# XHR only until phantomjs 2 is released.
# testBrowser
if [ -n "${COVER}" ]; then
${ISTANBUL} report --dir "${DIR}/../coverage" --include "${DIR}/../coverage/report*/coverage.json" lcov cobertura html
rm -r ${DIR}/../coverage/report*/*
rmdir ${DIR}/../coverage/report*
fi
exit $TESTOK

View File

@@ -0,0 +1,327 @@
/*
* 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 test = require('tape');
//var assert = require('assert');
var ttypes = require('./gen-nodejs/ThriftTest_types');
var TException = require('thrift').Thrift.TException;
var Int64 = require('node-int64');
var testCases = require('./test-cases');
exports.ThriftTestDriver = function(client, callback) {
test('NodeJS Style Callback Client Tests', function(assert) {
var checkRecursively = makeRecursiveCheck(assert);
function makeAsserter(assertionFn) {
return function(c) {
var fnName = c[0];
var expected = c[1];
client[fnName](expected, function(err, actual) {
assert.error(err, fnName + ': no callback error');
assertionFn(actual, expected, fnName);
})
};
}
testCases.simple.forEach(makeAsserter(function(a, e, m){
if (a instanceof Int64) {
var e64 = e instanceof Int64 ? e : new Int64(e);
assert.deepEqual(a.buffer, e64.buffer, m);
} else {
assert.equal(a, e, m);
}
}));
testCases.deep.forEach(makeAsserter(assert.deepEqual));
testCases.deepUnordered.forEach(makeAsserter(makeUnorderedDeepEqual(assert)));
var arr = [];
for (var i = 0; i < 256; ++i) {
arr[i] = 255 - i;
}
var buf = new Buffer(arr);
client.testBinary(buf, function(err, response) {
assert.error(err, 'testBinary: no callback error');
assert.equal(response.length, 256, 'testBinary');
assert.deepEqual(response, buf, 'testBinary(Buffer)');
});
var buf = new Buffer(arr);
client.testBinary(buf.toString('binary'), function(err, response) {
assert.error(err, 'testBinary: no callback error');
assert.equal(response.length, 256, 'testBinary');
assert.deepEqual(response, buf, 'testBinary(string)');
});
client.testMapMap(42, function(err, response) {
var expected = {
"4": {"1":1, "2":2, "3":3, "4":4},
"-4": {"-4":-4, "-3":-3, "-2":-2, "-1":-1}
};
assert.error(err, 'testMapMap: no callback error');
assert.deepEqual(expected, response, 'testMapMap');
});
client.testStruct(testCases.out, function(err, response) {
assert.error(err, 'testStruct: no callback error');
checkRecursively(testCases.out, response, 'testStruct');
});
client.testNest(testCases.out2, function(err, response) {
assert.error(err, 'testNest: no callback error');
checkRecursively(testCases.out2, response, 'testNest');
});
client.testInsanity(testCases.crazy, function(err, response) {
assert.error(err, 'testInsanity: no callback error');
checkRecursively(testCases.insanity, response, 'testInsanity');
});
client.testInsanity(testCases.crazy2, function(err, response) {
assert.error(err, 'testInsanity2: no callback error');
checkRecursively(testCases.insanity, response, 'testInsanity2');
});
client.testException('TException', function(err, response) {
assert.ok(err instanceof TException, 'testException: correct error type');
assert.ok(!response, 'testException: no response');
});
client.testException('Xception', function(err, response) {
assert.ok(err instanceof ttypes.Xception, 'testException: correct error type');
assert.ok(!response, 'testException: no response');
assert.equal(err.errorCode, 1001, 'testException: correct error code');
assert.equal('Xception', err.message, 'testException: correct error message');
});
client.testException('no Exception', function(err, response) {
assert.error(err, 'testException: no callback error');
assert.ok(!response, 'testException: no response');
});
client.testOneway(0, function(err, response) {
assert.fail('testOneway should not answer');
});
checkOffByOne(function(done) {
client.testI32(-1, function(err, response) {
assert.error(err, 'checkOffByOne: no callback error');
assert.equal(-1, response);
assert.end();
done();
});
}, callback);
});
};
exports.ThriftTestDriverPromise = function(client, callback) {
test('Q Promise Client Tests', function(assert) {
var checkRecursively = makeRecursiveCheck(assert);
function fail(msg) {
return function() {
assert.fail(msg);
}
}
function makeAsserter(assertionFn) {
return function(c) {
var fnName = c[0];
var expected = c[1];
client[fnName](expected)
.then(function(actual) {
assertionFn(actual, expected, fnName);
})
.fail(fail('fnName'));
};
}
testCases.simple.forEach(makeAsserter(function(a, e, m){
if (a instanceof Int64) {
var e64 = e instanceof Int64 ? e : new Int64(e);
assert.deepEqual(a.buffer, e64.buffer, m);
} else {
assert.equal(a, e, m);
}
}));
testCases.deep.forEach(makeAsserter(assert.deepEqual));
testCases.deepUnordered.forEach(makeAsserter(makeUnorderedDeepEqual(assert)));
client.testStruct(testCases.out)
.then(function(response) {
checkRecursively(testCases.out, response, 'testStruct');
})
.fail(fail('testStruct'));
client.testNest(testCases.out2)
.then(function(response) {
checkRecursively(testCases.out2, response, 'testNest');
})
.fail(fail('testNest'));
client.testInsanity(testCases.crazy)
.then(function(response) {
checkRecursively(testCases.insanity, response, 'testInsanity');
})
.fail(fail('testInsanity'));
client.testInsanity(testCases.crazy2)
.then(function(response) {
checkRecursively(testCases.insanity, response, 'testInsanity2');
})
.fail(fail('testInsanity2'));
client.testException('TException')
.then(function(response) {
fail('testException: TException');
})
.fail(function(err) {
assert.ok(err instanceof TException);
});
client.testException('Xception')
.then(function(response) {
fail('testException: Xception');
})
.fail(function(err) {
assert.ok(err instanceof ttypes.Xception);
assert.equal(err.errorCode, 1001);
assert.equal('Xception', err.message);
});
client.testException('no Exception')
.then(function(response) {
assert.equal(undefined, response); //void
})
.fail(fail('testException'));
client.testOneway(0, fail('testOneway: should not answer'));
checkOffByOne(function(done) {
client.testI32(-1)
.then(function(response) {
assert.equal(-1, response);
assert.end();
done();
})
.fail(fail('checkOffByOne'));
}, callback);
});
};
// Helper Functions
// =========================================================
function makeRecursiveCheck(assert) {
return function (map1, map2, msg) {
var equal = true;
var equal = checkRecursively(map1, map2);
assert.ok(equal, msg);
// deepEqual doesn't work with fields using node-int64
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);
return map1 === n.toNumber();
} else {
return map1 == map2;
}
} else {
return Object.keys(map1).every(function(key) {
return checkRecursively(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);
}
function makeUnorderedDeepEqual(assert) {
return function(actual, expected, name) {
assert.equal(actual.length, expected.length, name);
for (var k in actual) {
var found = false;
for (var k2 in expected) {
if (actual[k] === expected[k2]) {
found = true;
}
}
if (!found) {
assert.fail('Unexpected value ' + actual[k] + ' with key ' + k);
}
}
};
}

View File

@@ -0,0 +1,227 @@
/*
* 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 server side Node test handler for the standard
// Apache Thrift test service.
var ttypes = require('./gen-nodejs/ThriftTest_types');
var TException = require('thrift').Thrift.TException;
function makeSyncHandler(label) {
return function(thing) {
//console.log(label + '(\'' + thing + '\')');
return thing;
}
}
var syncHandlers = {
testVoid: testVoid,
testMapMap: testMapMap,
testInsanity: testInsanity,
testMulti: testMulti,
testException: testException,
testMultiException: testMultiException,
testOneway: testOneway
};
function makeAsyncHandler(label) {
return function(thing, result) {
thing = syncHandlers[label](thing);
result(null, thing);
}
}
var asyncHandlers = {
testVoid: testVoidAsync,
testMulti: testMultiAsync,
testException: testExceptionAsync,
testMultiException: testMultiExceptionAsync,
testOneway: testOnewayAsync
};
var identityHandlers = [
'testString',
'testBool',
'testByte',
'testI32',
'testI64',
'testDouble',
'testBinary',
'testStruct',
'testNest',
'testMap',
'testStringMap',
'testSet',
'testList',
'testEnum',
'testTypedef'
];
function testVoid() {
//console.log('testVoid()');
}
function testVoidAsync(result) {
result(testVoid());
}
function testMapMap(hello) {
//console.log('testMapMap(' + hello + ')');
var mapmap = [];
var pos = [];
var neg = [];
for (var i = 1; i < 5; i++) {
pos[i] = i;
neg[-i] = -i;
}
mapmap[4] = pos;
mapmap[-4] = neg;
return mapmap;
}
function testInsanity(argument) {
//console.log('testInsanity(');
//console.log(argument);
//console.log(')');
var first_map = [];
var second_map = [];
first_map[ttypes.Numberz.TWO] = argument;
first_map[ttypes.Numberz.THREE] = argument;
var looney = new ttypes.Insanity();
second_map[ttypes.Numberz.SIX] = looney;
var insane = [];
insane[1] = first_map;
insane[2] = second_map;
//console.log('insane result:');
//console.log(insane);
return insane;
}
function testMulti(arg0, arg1, arg2, arg3, arg4, arg5) {
//console.log('testMulti()');
var hello = new ttypes.Xtruct();
hello.string_thing = 'Hello2';
hello.byte_thing = arg0;
hello.i32_thing = arg1;
hello.i64_thing = arg2;
return hello;
}
function testMultiAsync(arg0, arg1, arg2, arg3, arg4, arg5, result) {
var hello = testMulti(arg0, arg1, arg2, arg3, arg4, arg5);
result(null, hello);
}
function testException(arg) {
//console.log('testException('+arg+')');
if (arg === 'Xception') {
var x = new ttypes.Xception();
x.errorCode = 1001;
x.message = arg;
throw x;
} else if (arg === 'TException') {
throw new TException(arg);
} else {
return;
}
}
function testExceptionAsync(arg, result) {
//console.log('testException('+arg+')');
if (arg === 'Xception') {
var x = new ttypes.Xception();
x.errorCode = 1001;
x.message = arg;
result(x);
} else if (arg === 'TException') {
result(new TException(arg));
} else {
result(null);
}
}
function testMultiException(arg0, arg1) {
//console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
if (arg0 === ('Xception')) {
var x = new ttypes.Xception();
x.errorCode = 1001;
x.message = 'This is an Xception';
throw x;
} else if (arg0 === ('Xception2')) {
var x2 = new ttypes.Xception2();
x2.errorCode = 2002;
x2.struct_thing = new ttypes.Xtruct();
x2.struct_thing.string_thing = 'This is an Xception2';
throw x2;
}
var res = new ttypes.Xtruct();
res.string_thing = arg1;
return res;
}
function testMultiExceptionAsync(arg0, arg1, result) {
//console.log('testMultiException(' + arg0 + ', ' + arg1 + ')');
if (arg0 === ('Xception')) {
var x = new ttypes.Xception();
x.errorCode = 1001;
x.message = 'This is an Xception';
result(x);
} else if (arg0 === ('Xception2')) {
var x2 = new ttypes.Xception2();
x2.errorCode = 2002;
x2.struct_thing = new ttypes.Xtruct();
x2.struct_thing.string_thing = 'This is an Xception2';
result(x2);
} else {
var res = new ttypes.Xtruct();
res.string_thing = arg1;
result(null, res);
}
}
function testOneway(sleepFor) {
//console.log('testOneway(' + sleepFor + ') => JavaScript (like Rust) never sleeps!');
}
function testOnewayAsync(sleepFor, result) {
testOneway(sleepFor);
}
identityHandlers.forEach(function(label) {
syncHandlers[label] = makeSyncHandler(label);
asyncHandlers[label] = makeAsyncHandler(label);
});
['testMapMap', 'testInsanity'].forEach(function(label) {
asyncHandlers[label] = makeAsyncHandler(label);
});
exports.ThriftTestHandler = asyncHandlers;
exports.AsyncThriftTestHandler = asyncHandlers;
exports.SyncThriftTestHandler = asyncHandlers;