mirror of
https://github.com/sorenisanerd/gotty.git
synced 2024-11-10 07:44:25 +00:00
c66ae7b2e4
Launch an Xspice and run: echo -ne "\033]844;127.0.0.1;9876\007" This will launch a SPiCE client connecting to 127.0.0.1:9876. Still need to add all the security stuff and generally be more defensive in the implementation.
180 lines
7.0 KiB
JavaScript
180 lines
7.0 KiB
JavaScript
suite('SpiceChannel', function() {
|
|
var sut, socketQ, toRestore, packetReassembler, config;
|
|
|
|
setup(function() {
|
|
wdi.Debug.debug = false; //disable debugging, it slows tests
|
|
config = {
|
|
protocol: 'ws',
|
|
host: 'localhost',
|
|
port: 8000,
|
|
vmHost: 'localhost',
|
|
vmPort: 5900,
|
|
type: 'spice',
|
|
token: 'sdfjgsd8f'
|
|
};
|
|
socketQ = new wdi.SocketQueue();
|
|
packetReassembler = wdi.ReassemblerFactory.getPacketReassembler(socketQ);
|
|
sut = new wdi.SpiceChannel({socketQ: socketQ, packetReassembler: packetReassembler});
|
|
toRestore = [];
|
|
});
|
|
|
|
teardown(function() {
|
|
toRestore.forEach(function(item) {
|
|
item.restore();
|
|
});
|
|
});
|
|
|
|
suite('Networking', function() {
|
|
|
|
test('When open event it sends SpiceLinkInit', function() {
|
|
var header = new wdi.SpiceLinkHeader({magic:1363428690, major_version:2, minor_version:2, size:22}).marshall();
|
|
var body = new wdi.SpiceLinkMess({
|
|
connection_id:0,
|
|
channel_type:1,
|
|
caps_offset:18,
|
|
num_common_caps: 1,
|
|
common_caps: (1 << wdi.SpiceVars.SPICE_COMMON_CAP_MINI_HEADER)
|
|
}).marshall();
|
|
var args = header.concat(body);
|
|
var packetOut;
|
|
var stub = sinon.stub(socketQ, 'send', function(packet) {
|
|
packetOut = packet;
|
|
});
|
|
toRestore.push(stub);
|
|
socketQ.fire('open');
|
|
assert.deepEqual(packetOut, args, 'The packet is not a RedLinkMess or some parameter is incorrect');
|
|
});
|
|
|
|
test('When close event it disconnects socketQueue', function() {
|
|
var mock = sinon.mock(socketQ);
|
|
var expectation = mock.expects('disconnect').once();
|
|
toRestore.push(mock);
|
|
socketQ.fire('close');
|
|
expectation.verify();
|
|
});
|
|
|
|
test('When error event it disconnects socketQueue', function() {
|
|
var mock = sinon.mock(socketQ);
|
|
var expectation = mock.expects('disconnect').once();
|
|
toRestore.push(mock);
|
|
socketQ.fire('close');
|
|
expectation.verify();
|
|
});
|
|
|
|
test.skip('When packetComplete event containing spicePacket fires message with packet', function() {
|
|
var header = [1, 0, 9, 0, 0, 0]
|
|
var body = [0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
var arr = header.concat(body);
|
|
var expectedData = new wdi.RawMessage({status: 'spicePacket', data: arr}), obtainedData;
|
|
sut.addListener('message', function(e) {
|
|
obtainedData = e[1];
|
|
}, this);
|
|
|
|
toRestore.push(sinon.stub(wdi.PacketLinkFactory, "extract"));
|
|
|
|
packetReassembler.fire('packetComplete', expectedData);
|
|
|
|
assert.equal(body.length, obtainedData.header.size, 'The data doesn\'t match');
|
|
});
|
|
|
|
test('When packetComplete event containing reply sends response', function() {
|
|
var redLinkReply = [82,69,68,81,2,0,0,0,2,0,0,0,186,0,0,0,0,0,0,0,48,129,159,48,13,6,9,42,134,72,134,247,13,1,1,1,5,0,3,129,141,0,48,129,137,2,129,129,0,222,245,236,144,74,241,132,122,250,245,13,59,69,38,226,122,250,73,31,214,203,27,154,16,6,11,91,88,125,158,197,150,32,60,201,138,249,22,59,109,232,64,42,46,79,170,248,239,172,142,240,63,83,130,221,21,207,83,210,112,82,20,214,169,219,27,129,45,241,13,172,228,208,196,200,24,89,163,38,186,139,96,5,24,108,57,9,223,217,215,106,89,118,215,245,214,71,139,141,1,186,111,61,88,37,155,65,65,121,220,133,237,190,114,198,66,62,125,133,62,214,132,69,164,190,184,169,39,2,3,1,0,1,1,0,0,0,1,0,0,0,178,0,0,0,11,0,0,0,18,0,0,0];
|
|
var packet = new wdi.RawMessage({status: 'reply', data: redLinkReply});
|
|
var mock = sinon.mock(socketQ);
|
|
var expectation = mock.expects('send').once();
|
|
toRestore.push(mock);
|
|
packetReassembler.fire('packetComplete', packet);
|
|
expectation.verify();
|
|
});
|
|
|
|
test('When packetComplete event containing errorCode 0 in main channel sends response', function () {
|
|
var errorCode = [0, 0, 0, 0];
|
|
var packet = new wdi.RawMessage({status: 'errorCode', data: errorCode});
|
|
var mock = sinon.mock(socketQ);
|
|
var expectation = mock.expects('send').once();
|
|
toRestore.push(mock);
|
|
packetReassembler.fire('packetComplete', packet);
|
|
expectation.verify();
|
|
});
|
|
|
|
test('When packetComplete event containing errorCode not 0 throws exception', function () {
|
|
var errorCode = [1, 0, 0, 0];
|
|
var packet = new wdi.RawMessage({status: 'errorCode', data: errorCode});
|
|
assert.throws(function () {
|
|
packetReassembler.fire('packetComplete', packet);
|
|
});
|
|
});
|
|
|
|
test('When packetComplete event containing errorCode 0 in display channel sends response', function () {
|
|
var errorCode = [0, 0, 0, 0];
|
|
sut.channel = wdi.SpiceVars.SPICE_CHANNEL_DISPLAY;
|
|
var packet = new wdi.RawMessage({status: 'errorCode', data: errorCode});
|
|
var mock = sinon.mock(socketQ);
|
|
var expectation = mock.expects('send').once();
|
|
toRestore.push(mock);
|
|
packetReassembler.fire('packetComplete', packet);
|
|
expectation.verify();
|
|
});
|
|
|
|
test('When packetComplete event containing errorCode 0 fires channelConnected event', function () {
|
|
var errorCode = [0, 0, 0, 0];
|
|
var packet = new wdi.RawMessage({status: 'errorCode', data: errorCode});
|
|
sinon.stub(socketQ, 'send', function () {});
|
|
|
|
var fired = false;
|
|
sut.addListener('channelConnected', function (e) {
|
|
fired = true;
|
|
}, this);
|
|
|
|
packetReassembler.fire('packetComplete', packet);
|
|
assert.equal(fired, true);
|
|
});
|
|
|
|
});
|
|
|
|
suite.skip('#getRawSpiceMessage', function () {
|
|
test('returns a valid rawSpiceMessage', function () {
|
|
var data = [1, 0, 9, 0, 0, 0, 0,0,0,0,0,0,0,0,0];
|
|
toRestore.push(sinon.stub(wdi.PacketLinkFactory, "extract"));
|
|
var rsm = sut.getRawSpiceMessage(data);
|
|
assert.equal(rsm.header.type, 1, "The header is not valid");
|
|
});
|
|
});
|
|
|
|
suite('#connection', function() {
|
|
|
|
test('connect should call socketQ connect with host and port if they are present', function() {
|
|
var expectedString = config['protocol'] + '://' + config['host'] + ':' + config['port'] + '/websockify/host/' + config['vmHost'] + '/port/' + config['vmPort'] + '/type/' + config['type'];
|
|
var mock = sinon.mock(socketQ);
|
|
var stub = sinon.stub(packetReassembler, 'start');
|
|
var expectation = mock.expects('connect').once().withArgs(expectedString);
|
|
sut.connect(config);
|
|
expectation.verify();
|
|
});
|
|
|
|
test('connect should call socketQ connect with destInfoToken if destHost and destPort are NOT present', function() {
|
|
var tokenedConfig = {
|
|
protocol: 'ws',
|
|
host: 'localhost',
|
|
port: 8000,
|
|
vmInfoToken: 'token-token-token',
|
|
type: 'spice',
|
|
token: 'sdfjgsd8f'
|
|
};
|
|
var expectedString = tokenedConfig['protocol'] + '://' + tokenedConfig['host'] + ':' + tokenedConfig['port'] + '/websockify/destInfoToken/' + tokenedConfig['vmInfoToken'] + '/type/' + tokenedConfig['type'];
|
|
var mock = sinon.mock(socketQ);
|
|
var stub = sinon.stub(packetReassembler, 'start');
|
|
var expectation = mock.expects('connect').once().withArgs(expectedString);
|
|
sut.connect(tokenedConfig);
|
|
expectation.verify();
|
|
});
|
|
|
|
test('disconnect should call socketQ disconnect', function() {
|
|
var mock = sinon.mock(socketQ);
|
|
var expectation = mock.expects('disconnect').once().withExactArgs();
|
|
sut.disconnect();
|
|
expectation.verify();
|
|
});
|
|
});
|
|
});
|