Upgrading dependency to Thrift 0.12.0

This commit is contained in:
Renan DelValle 2018-11-27 18:03:50 -08:00
parent 3e4590dcc0
commit 356978cb42
No known key found for this signature in database
GPG key ID: C240AD6D6F443EC9
1302 changed files with 101701 additions and 26784 deletions

View file

@ -15,14 +15,13 @@
# specific language governing permissions and limitations
# under the License.
THRIFT = $(top_builddir)/compiler/cpp/thrift
# We call npm twice to work around npm issues
stubs: $(top_srcdir)/test/ThriftTest.thrift
$(THRIFT) --gen js:node -o test/ $(top_srcdir)/test/ThriftTest.thrift
deps: $(top_srcdir)/package.json
$(NPM) install --no-bin-links $(top_srcdir)/
$(NPM) install $(top_srcdir)/ || $(NPM) install $(top_srcdir)/
all-local: deps

View file

@ -20,6 +20,9 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
## Compatibility
node version 6 or later is required
## Install
@ -35,30 +38,32 @@ You can compile IDL sources for Node.js with the following command:
Here is a Cassandra example:
var thrift = require('thrift'),
Cassandra = require('./gen-nodejs/Cassandra')
ttypes = require('./gen-nodejs/cassandra_types');
```js
var thrift = require('thrift'),
Cassandra = require('./gen-nodejs/Cassandra')
ttypes = require('./gen-nodejs/cassandra_types');
var connection = thrift.createConnection("localhost", 9160),
client = thrift.createClient(Cassandra, connection);
var connection = thrift.createConnection("localhost", 9160),
client = thrift.createClient(Cassandra, connection);
connection.on('error', function(err) {
console.error(err);
});
connection.on('error', function(err) {
console.error(err);
});
client.get_slice("Keyspace", "key", new ttypes.ColumnParent({column_family: "ExampleCF"}), new ttypes.SlicePredicate({slice_range: new ttypes.SliceRange({start: '', finish: ''})}), ttypes.ConsistencyLevel.ONE, function(err, data) {
if (err) {
// handle err
} else {
// data == [ttypes.ColumnOrSuperColumn, ...]
}
connection.end();
});
client.get_slice("Keyspace", "key", new ttypes.ColumnParent({column_family: "ExampleCF"}), new ttypes.SlicePredicate({slice_range: new ttypes.SliceRange({start: '', finish: ''})}), ttypes.ConsistencyLevel.ONE, function(err, data) {
if (err) {
// handle err
} else {
// data == [ttypes.ColumnOrSuperColumn, ...]
}
connection.end();
});
```
<a name="int64"></a>
## Int64
Since JavaScript represents all numbers as doubles, int64 values cannot be accurately represented naturally. To solve this, int64 values in responses will be wrapped with Thirft.Int64 objects. The Int64 implementation used is [broofa/node-int64](https://github.com/broofa/node-int64).
Since JavaScript represents all numbers as doubles, int64 values cannot be accurately represented naturally. To solve this, int64 values in responses will be wrapped with Thrift.Int64 objects. The Int64 implementation used is [broofa/node-int64](https://github.com/broofa/node-int64).
## Client and server examples

View file

@ -7,7 +7,7 @@ from thrift.server import THttpServer
class HelloSvcHandler:
def hello_func(self):
print "Hello Called"
print("Hello Called")
return "hello from Python"
processor = HelloSvc.Processor(HelloSvcHandler())
@ -16,4 +16,3 @@ port = 9090
server = THttpServer.THttpServer(processor, ("localhost", port), protoFactory)
print "Python server running on port " + str(port)
server.serve()

View file

@ -37,6 +37,7 @@ function TBinaryProtocol(trans, strictRead, strictWrite) {
this.trans = trans;
this.strictRead = (strictRead !== undefined ? strictRead : false);
this.strictWrite = (strictWrite !== undefined ? strictWrite : true);
this._seqid = null;
};
TBinaryProtocol.prototype.flush = function() {
@ -54,8 +55,7 @@ TBinaryProtocol.prototype.writeMessageBegin = function(name, type, seqid) {
this.writeI32(seqid);
}
// Record client seqid to find callback again
if (this._seqid) {
// TODO better logging log warning
if (this._seqid !== null) {
log.warning('SeqId already set', { 'name': name });
} else {
this._seqid = seqid;
@ -64,7 +64,7 @@ TBinaryProtocol.prototype.writeMessageBegin = function(name, type, seqid) {
};
TBinaryProtocol.prototype.writeMessageEnd = function() {
if (this._seqid) {
if (this._seqid !== null) {
this._seqid = null;
} else {
log.warning('No seqid to unset');
@ -177,7 +177,6 @@ TBinaryProtocol.prototype.readMessageBegin = function() {
if (sz < 0) {
var version = sz & VERSION_MASK;
if (version != VERSION_1) {
console.log("BAD: " + version);
throw new Thrift.TProtocolException(Thrift.TProtocolExceptionType.BAD_VERSION, "Bad version in readMessageBegin: " + sz);
}
type = sz & TYPE_MASK;

View file

@ -32,3 +32,5 @@ exports.TFramedTransport = require('./framed_transport');
exports.Protocol = exports.TJSONProtocol = require('./json_protocol');
exports.TBinaryProtocol = require('./binary_protocol');
exports.TCompactProtocol = require('./compact_protocol');
exports.Int64 = require('node-int64');

View file

@ -33,6 +33,14 @@ function TBufferedTransport(buffer, callback) {
this.onFlush = callback;
};
TBufferedTransport.prototype.reset = function() {
this.inBuf = new Buffer(this.defaultReadBufferSize);
this.readCursor = 0;
this.writeCursor = 0;
this.outBuffers = [];
this.outCount = 0;
}
TBufferedTransport.receiver = function(callback, seqid) {
var reader = new TBufferedTransport();

View file

@ -249,7 +249,6 @@ TCompactProtocol.prototype.writeMessageBegin = function(name, type, seqid) {
// Record client seqid to find callback again
if (this._seqid) {
// TODO better logging log warning
log.warning('SeqId already set', { 'name': name });
} else {
this._seqid = seqid;

View file

@ -17,10 +17,12 @@
* under the License.
*/
var util = require('util');
var EventEmitter = require("events").EventEmitter;
var EventEmitter = require('events').EventEmitter;
var constants = require('constants');
var net = require('net');
var tls = require('tls');
var thrift = require('./thrift');
var log = require('./log');
var TBufferedTransport = require('./buffered_transport');
var TBinaryProtocol = require('./binary_protocol');
@ -121,7 +123,6 @@ var Connection = exports.Connection = function(stream, options) {
var service_name = self.seqId2Service[header.rseqid];
if (service_name) {
client = self.client[service_name];
delete self.seqId2Service[header.rseqid];
}
/*jshint -W083 */
client._reqs[dummy_seqid] = function(err, success){
@ -129,6 +130,9 @@ var Connection = exports.Connection = function(stream, options) {
var callback = client._reqs[header.rseqid];
delete client._reqs[header.rseqid];
if (service_name) {
delete self.seqId2Service[header.rseqid];
}
if (callback) {
callback(err, success);
}
@ -201,9 +205,7 @@ Connection.prototype.connection_gone = function () {
this.retry_delay = Math.floor(this.retry_delay * this.retry_backoff);
}
if (self._debug) {
console.log("Retry connection in " + this.retry_delay + " ms");
}
log.debug("Retry connection in " + this.retry_delay + " ms");
if (this.max_attempts && this.attempts >= this.max_attempts) {
this.retry_timer = null;
@ -219,9 +221,7 @@ Connection.prototype.connection_gone = function () {
});
this.retry_timer = setTimeout(function () {
if (self._debug) {
console.log("Retrying connection...");
}
log.debug("Retrying connection...");
self.retry_totaltime += self.retry_delay;
@ -232,7 +232,11 @@ Connection.prototype.connection_gone = function () {
return;
}
self.connection.connect(self.port, self.host);
if (self.path !== undefined) {
self.connection.connect(self.path);
} else {
self.connection.connect(self.port, self.host);
}
self.retry_timer = null;
}, this.retry_delay);
};
@ -246,7 +250,20 @@ exports.createConnection = function(host, port, options) {
return connection;
};
exports.createUDSConnection = function(path, options) {
var stream = net.createConnection(path);
var connection = new Connection(stream, options);
connection.path = path;
return connection;
};
exports.createSSLConnection = function(host, port, options) {
if (!('secureProtocol' in options) && !('secureOptions' in options)) {
options.secureProtocol = "SSLv23_method";
options.secureOptions = constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3;
}
var stream = tls.connect(port, host, options);
var connection = new Connection(stream, options);
connection.host = host;
@ -268,20 +285,19 @@ var StdIOConnection = exports.StdIOConnection = function(command, options) {
var self = this;
EventEmitter.call(this);
this._debug = options.debug || false;
this.connection = child.stdin;
this.options = options || {};
this.transport = this.options.transport || TBufferedTransport;
this.protocol = this.options.protocol || TBinaryProtocol;
this.offline_queue = [];
if(this._debug === true){
this.child.stderr.on('data',function(err){
console.log(err.toString(),'CHILD ERROR');
if (log.getLogLevel() === 'debug') {
this.child.stderr.on('data', function (err) {
log.debug(err.toString(), 'CHILD ERROR');
});
this.child.on('exit',function(code,signal){
console.log(code+':'+signal,'CHILD EXITED');
this.child.on('exit', function (code,signal) {
log.debug(code + ':' + signal, 'CHILD EXITED');
});
}

View file

@ -59,8 +59,6 @@ var createClient = require('./create_client');
* Initializes a Thrift HttpConnection instance (use createHttpConnection() rather than
* instantiating directly).
* @constructor
* @param {string} host - The host name or IP to connect to.
* @param {number} port - The TCP port to connect to.
* @param {ConnectOptions} options - The configuration options to use.
* @throws {error} Exceptions other than InputBufferUnderrunError are rethrown
* @event {error} The "error" event is fired when a Node.js error event occurs during
@ -71,15 +69,16 @@ var createClient = require('./create_client');
* semantics implemented over the Node.js http.request() method.
* @see {@link createHttpConnection}
*/
var HttpConnection = exports.HttpConnection = function(host, port, options) {
var HttpConnection = exports.HttpConnection = function(options) {
//Initialize the emitter base object
EventEmitter.call(this);
//Set configuration
var self = this;
this.options = options || {};
this.host = host;
this.port = port;
this.host = this.options.host;
this.port = this.options.port;
this.socketPath = this.options.socketPath;
this.https = this.options.https || false;
this.transport = this.options.transport || TBufferedTransport;
this.protocol = this.options.protocol || TBinaryProtocol;
@ -87,7 +86,8 @@ var HttpConnection = exports.HttpConnection = function(host, port, options) {
//Prepare Node.js options
this.nodeOptions = {
host: this.host,
port: this.port || 80,
port: this.port,
socketPath: this.socketPath,
path: this.options.path || '/',
method: 'POST',
headers: this.options.headers || {},
@ -169,6 +169,10 @@ var HttpConnection = exports.HttpConnection = function(host, port, options) {
var data = [];
var dataLen = 0;
if (response.statusCode !== 200) {
this.emit("error", new THTTPException(response));
}
response.on('error', function (e) {
self.emit("error", e);
});
@ -210,10 +214,13 @@ util.inherits(HttpConnection, EventEmitter);
*/
HttpConnection.prototype.write = function(data) {
var self = this;
self.nodeOptions.headers["Content-length"] = data.length;
var opts = self.nodeOptions;
opts.headers["Content-length"] = data.length;
if (!opts.headers["Content-Type"])
opts.headers["Content-Type"] = "application/x-thrift";
var req = (self.https) ?
https.request(self.nodeOptions, self.responseCallback) :
http.request(self.nodeOptions, self.responseCallback);
https.request(opts, self.responseCallback) :
http.request(opts, self.responseCallback);
req.on('error', function(err) {
self.emit("error", err);
});
@ -231,8 +238,26 @@ HttpConnection.prototype.write = function(data) {
* @see {@link ConnectOptions}
*/
exports.createHttpConnection = function(host, port, options) {
return new HttpConnection(host, port, options);
options.host = host;
options.port = port || 80;
return new HttpConnection(options);
};
exports.createHttpUDSConnection = function(path, options) {
options.socketPath = path;
return new HttpConnection(options);
};
exports.createHttpClient = createClient
function THTTPException(response) {
thrift.TApplicationException.call(this);
Error.captureStackTrace(this, this.constructor);
this.name = this.constructor.name;
this.statusCode = response.statusCode;
this.response = response;
this.type = thrift.TApplicationExceptionType.PROTOCOL_ERROR;
this.message = "Received a response with a bad HTTP status code: " + response.statusCode;
}
util.inherits(THTTPException, thrift.TApplicationException);

View file

@ -18,10 +18,16 @@
*/
exports.Thrift = require('./thrift');
var log = require('./log');
exports.setLogFunc = log.setLogFunc;
exports.setLogLevel = log.setLogLevel;
exports.getLogLevel = log.getLogLevel;
var connection = require('./connection');
exports.Connection = connection.Connection;
exports.createClient = connection.createClient;
exports.createConnection = connection.createConnection;
exports.createUDSConnection = connection.createUDSConnection;
exports.createSSLConnection = connection.createSSLConnection;
exports.createStdIOClient = connection.createStdIOClient;
exports.createStdIOConnection = connection.createStdIOConnection;
@ -29,6 +35,7 @@ exports.createStdIOConnection = connection.createStdIOConnection;
var httpConnection = require('./http_connection');
exports.HttpConnection = httpConnection.HttpConnection;
exports.createHttpConnection = httpConnection.createHttpConnection;
exports.createHttpUDSConnection = httpConnection.createHttpUDSConnection;
exports.createHttpClient = httpConnection.createHttpClient;
var wsConnection = require('./ws_connection');

View file

@ -17,7 +17,6 @@
* under the License.
*/
var log = require('./log');
var Int64 = require('node-int64');
var InputBufferUnderrunError = require('./transport').InputBufferUnderrunError;
var Thrift = require('./thrift');
@ -739,5 +738,65 @@ TJSONProtocol.prototype.getTransport = function() {
* Method to arbitrarily skip over data
*/
TJSONProtocol.prototype.skip = function(type) {
throw new Error('skip not supported yet');
switch (type) {
case Type.STOP:
return;
case Type.BOOL:
this.readBool();
break;
case Type.BYTE:
this.readByte();
break;
case Type.I16:
this.readI16();
break;
case Type.I32:
this.readI32();
break;
case Type.I64:
this.readI64();
break;
case Type.DOUBLE:
this.readDouble();
break;
case Type.STRING:
this.readString();
break;
case Type.STRUCT:
this.readStructBegin();
while (true) {
var r = this.readFieldBegin();
if (r.ftype === Type.STOP) {
break;
}
this.skip(r.ftype);
this.readFieldEnd();
}
this.readStructEnd();
break;
case Type.MAP:
var mapBegin = this.readMapBegin();
for (var i = 0; i < mapBegin.size; ++i) {
this.skip(mapBegin.ktype);
this.skip(mapBegin.vtype);
}
this.readMapEnd();
break;
case Type.SET:
var setBegin = this.readSetBegin();
for (var i2 = 0; i2 < setBegin.size; ++i2) {
this.skip(setBegin.etype);
}
this.readSetEnd();
break;
case Type.LIST:
var listBegin = this.readListBegin();
for (var i3 = 0; i3 < listBegin.size; ++i3) {
this.skip(listBegin.etype);
}
this.readListEnd();
break;
default:
throw new Error("Invalid type: " + type);
}
};

View file

@ -17,10 +17,71 @@
* under the License.
*/
module.exports = {
'info' : function logInfo() {},
'warning' : function logWarning() {},
'error' : function logError() {},
'debug' : function logDebug() {},
'trace' : function logTrace() {}
var util = require('util');
var disabled = function () {};
var logFunc = console.log;
var logLevel = 'error'; // default level
function factory(level) {
return function () {
// better use spread syntax, but due to compatibility,
// use legacy method here.
var args = ['thrift: [' + level + '] '].concat(Array.from(arguments));
return logFunc(util.format.apply(null, args));
};
}
var trace = disabled;
var debug = disabled;
var error = disabled;
var warning = disabled;
var info = disabled;
exports.setLogFunc = function (func) {
logFunc = func;
};
var setLogLevel = exports.setLogLevel = function (level) {
trace = debug = error = warning = info = disabled;
logLevel = level;
switch (logLevel) {
case 'trace':
trace = factory('TRACE');
case 'debug':
debug = factory('DEBUG');
case 'error':
error = factory('ERROR');
case 'warning':
warning = factory('WARN');
case 'info':
info = factory('INFO');
}
};
// set default
setLogLevel(logLevel);
exports.getLogLevel = function () {
return logLevel;
};
exports.trace = function () {
return trace.apply(null, arguments);
};
exports.debug = function () {
return debug.apply(null, arguments);
};
exports.error = function () {
return error.apply(null, arguments);
};
exports.warning = function () {
return warning.apply(null, arguments);
};
exports.info = function () {
return info.apply(null, arguments);
};

View file

@ -52,17 +52,17 @@ Multiplexer.prototype.createClient = function(serviceName, ServiceClient, connec
if (ServiceClient.Client) {
ServiceClient = ServiceClient.Client;
}
var self = this;
ServiceClient.prototype.new_seqid = function() {
self.seqid += 1;
return self.seqid;
};
var writeCb = function(buf, seqid) {
connection.write(buf,seqid);
};
var transport = new connection.transport(undefined, writeCb);
var protocolWrapper = new Wrapper(serviceName, connection.protocol, connection);
var client = new ServiceClient(transport, protocolWrapper);
var self = this;
client.new_seqid = function() {
self.seqid += 1;
return self.seqid;
};
if (typeof connection.client !== 'object') {
connection.client = {};

View file

@ -16,6 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
var constants = require('constants');
var net = require('net');
var tls = require('tls');
@ -87,6 +89,10 @@ exports.createMultiplexServer = function(processor, options) {
}
if (options && options.tls) {
if (!('secureProtocol' in options.tls) && !('secureOptions' in options.tls)) {
options.tls.secureProtocol = "SSLv23_method";
options.tls.secureOptions = constants.SSL_OP_NO_SSLv2 | constants.SSL_OP_NO_SSLv3;
}
return tls.createServer(options.tls, serverImpl);
} else {
return net.createServer(serverImpl);

View file

@ -22,6 +22,7 @@ var url = require("url");
var path = require("path");
var fs = require("fs");
var crypto = require("crypto");
var log = require('./log');
var MultiplexedProcessor = require('./multiplexed_processor').MultiplexedProcessor;
@ -284,7 +285,7 @@ exports.createWebServer = function(options) {
'.jpeg': 'image/jpeg',
'.gif': 'image/gif',
'.png': 'image/png',
  '.svg': 'image/svg+xml'
'.svg': 'image/svg+xml'
};
//Setup all of the services
@ -414,7 +415,15 @@ exports.createWebServer = function(options) {
//Locate the file requested and send it
var uri = url.parse(request.url).pathname;
var filename = path.join(baseDir, uri);
var filename = path.resolve(path.join(baseDir, uri));
//Ensure the basedir path is not able to be escaped
if (filename.indexOf(baseDir) != 0) {
response.writeHead(400, "Invalid request path", {});
response.end();
return;
}
fs.exists(filename, function(exists) {
if(!exists) {
response.writeHead(404);
@ -547,7 +556,7 @@ exports.createWebServer = function(options) {
frame = result.nextFrame;
}
} catch(e) {
console.log("TWebSocketTransport Exception: " + e);
log.error('TWebSocketTransport Exception: ' + e);
socket.destroy();
}
});
@ -556,9 +565,3 @@ exports.createWebServer = function(options) {
//Return the server
return server;
};

View file

@ -17,6 +17,8 @@
* under the License.
*/
var log = require('./log');
module.exports = TWebSocketTransport;
/**
@ -105,7 +107,7 @@ TWebSocketTransport.prototype.__onMessage = function(evt) {
};
TWebSocketTransport.prototype.__onError = function(evt) {
console.log("Thrift WebSocket Error: " + evt.toString());
log.error('websocket: ' + evt.toString());
this.socket.close();
};

View file

@ -1,27 +0,0 @@
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

@ -32,21 +32,29 @@ var ttypes = require('./gen-nodejs/ThriftTest_types');
var program = require('commander');
program
.option('-p, --protocol <protocol>', 'Set thrift protocol (binary|json) [protocol]')
.option('-t, --transport <transport>', 'Set thrift transport (buffered|framed) [transport]')
.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('--domain-socket <path>', 'Set thrift server unix domain socket to connect')
.option('--ssl', 'use SSL transport')
.option('--promise', 'test with promise style functions')
.option('-t, --type <type>', 'Select server type (tcp|multiplex|http)', 'tcp')
.option('-t, --type <type>', 'Select server type (http|multiplex|tcp|websocket)', 'tcp')
.parse(process.argv);
var host = program.host;
var port = program.port;
var domainSocket = program.domainSocket;
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]
@ -77,11 +85,19 @@ var client;
var testDriver = promise ? ThriftTestDriverPromise : ThriftTestDriver;
if (type === 'tcp' || type === 'multiplex') {
connection = ssl ?
thrift.createSSLConnection(host, port, options) :
thrift.createConnection(host, port, options);
if (domainSocket) {
connection = thrift.createUDSConnection(domainSocket, options);
} else {
connection = ssl ?
thrift.createSSLConnection(host, port, options) :
thrift.createConnection(host, port, options);
}
} else if (type === 'http') {
connection = thrift.createHttpConnection(host, port, options);
if (domainSocket) {
connection = thrift.createHttpUDSConnection(domainSocket, options);
} else {
connection = thrift.createHttpConnection(host, port, options);
}
} else if (type === 'websocket') {
connection = thrift.createWSConnection(host, port, options);
connection.open();
@ -102,7 +118,7 @@ if (type === 'tcp') {
connection.on('connect', function() {
secondclient.secondtestString("Test", function(err, response) {
assert(!err);
assert.equal("Test", response);
assert.equal("testString(\"Test\")", response);
});
runTests();

View file

@ -1,3 +1,22 @@
/*
* 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');
@ -286,7 +305,7 @@ function createTestCases(serialize, deserialize) {
"Can make list with objects": function(assert) {
var tObj = new ttypes.ComplexList({
"struct_list_field": [new ttypes.Complex({})]
"struct_list_field": [new ttypes.Complex({})]
});
var innerObj = tObj.struct_list_field[0];
assert.ok(innerObj instanceof ttypes.Complex)

View file

@ -1,3 +1,22 @@
/*
* 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');
@ -17,6 +36,20 @@ test('TApplicationException', function t(assert) {
assert.end();
});
test('unexpected TApplicationException ', function t(assert) {
var e = new thrift.TApplicationException(1, 100);
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: 100/.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, 100, 'has error message 100');
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');

View file

@ -1,3 +1,22 @@
/*
* 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');

View file

@ -32,21 +32,28 @@ var ThriftTestHandlerPromise = require('./test_handler').SyncThriftTestHandler;
var ttypes = require('./gen-nodejs/ThriftTest_types');
program
.option('-p, --protocol <protocol>', 'Set thrift protocol (binary|json|compact)', 'binary')
.option('-t, --transport <transport>', 'Set thrift transport (buffered|framed)', 'buffered')
.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('--domain-socket <path>', 'Set thift server unix domain socket')
.option('--promise', 'test with promise style functions')
.option('-t, --type <type>', 'Select server type (tcp|multiplex|http)', 'tcp')
.option('-t, --type <type>', 'Select server type (http|multiplex|tcp|websocket)', 'tcp')
.parse(process.argv);
var port = program.port;
var domainSocket = program.domainSocket;
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]
@ -67,8 +74,8 @@ if (type === 'http' || type ==='websocket') {
if (type === 'multiplex') {
var SecondServiceHandler = {
secondtestString: function(thing, result) {
console.log('testString(\'' + thing + '\')');
result(null, thing);
console.log('testString("' + thing + '")');
result(null, 'testString("' + thing + '")');
}
};
@ -83,10 +90,12 @@ if (type === 'multiplex') {
}
if (ssl) {
options.tls = {
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
};
if (type === 'tcp' || type === 'multiplex' || type === 'http' || type === 'websocket') {
options.tls = {
key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
};
}
}
var server;
@ -98,4 +107,8 @@ if (type === 'tcp') {
server = thrift.createWebServer(options);
}
server.listen(port);
if (domainSocket) {
server.listen(domainSocket);
} else if (type === 'tcp' || type === 'multiplex' || type === 'http' || type === 'websocket') {
server.listen(port);
}

View file

@ -1,3 +1,22 @@
/*
* 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');

View file

@ -24,7 +24,6 @@ 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"
@ -43,7 +42,7 @@ testServer()
node ${DIR}/server.js --type $1 -p $2 -t $3 $4 &
fi
SERVERPID=$!
sleep 1
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))
@ -51,20 +50,10 @@ testServer()
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
@ -95,8 +84,6 @@ do
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

View file

@ -125,7 +125,8 @@ exports.ThriftTestDriver = function(client, callback) {
});
client.testOneway(0, function(err, response) {
assert.fail('testOneway should not answer');
assert.error(err, 'testOneway: no callback error');
assert.strictEqual(response, undefined, 'testOneway: void response');
});
checkOffByOne(function(done) {
@ -223,7 +224,11 @@ exports.ThriftTestDriverPromise = function(client, callback) {
})
.fail(fail('testException'));
client.testOneway(0, fail('testOneway: should not answer'));
client.testOneway(0)
.then(function(response) {
assert.strictEqual(response, undefined, 'testOneway: void response')
})
.fail(fail('testOneway: should not reject'));
checkOffByOne(function(done) {
client.testI32(-1)