eadb91e734
This closes #8727, thanks to @jfcantu for the suggestion. The CLI implementation of exec already has a 10-second heartbeat so this mirrors that: https://github.com/hashicorp/nomad/blob/v0.12.3/api/allocations.go#L161-L173
202 lines
4.7 KiB
JavaScript
202 lines
4.7 KiB
JavaScript
import ExecSocketXtermAdapter from 'nomad-ui/utils/classes/exec-socket-xterm-adapter';
|
|
import { setupRenderingTest } from 'ember-qunit';
|
|
import { module, test } from 'qunit';
|
|
import { render, settled } from '@ember/test-helpers';
|
|
import hbs from 'htmlbars-inline-precompile';
|
|
import { Terminal } from 'xterm';
|
|
import { HEARTBEAT_INTERVAL } from 'nomad-ui/utils/classes/exec-socket-xterm-adapter';
|
|
import sinon from 'sinon';
|
|
|
|
module('Integration | Utility | exec-socket-xterm-adapter', function(hooks) {
|
|
setupRenderingTest(hooks);
|
|
|
|
test('initiating socket sends authentication handshake', async function(assert) {
|
|
let done = assert.async();
|
|
|
|
let terminal = new Terminal();
|
|
this.set('terminal', terminal);
|
|
|
|
await render(hbs`
|
|
<ExecTerminal @terminal={{terminal}} />
|
|
`);
|
|
|
|
await settled();
|
|
|
|
let firstMessage = true;
|
|
let mockSocket = new Object({
|
|
send(message) {
|
|
if (firstMessage) {
|
|
firstMessage = false;
|
|
assert.deepEqual(message, JSON.stringify({ version: 1, auth_token: 'mysecrettoken' }));
|
|
mockSocket.onclose();
|
|
done();
|
|
}
|
|
},
|
|
});
|
|
|
|
new ExecSocketXtermAdapter(terminal, mockSocket, 'mysecrettoken');
|
|
|
|
mockSocket.onopen();
|
|
|
|
await settled();
|
|
});
|
|
|
|
test('initiating socket sends authentication handshake even if unauthenticated', async function(assert) {
|
|
let done = assert.async();
|
|
|
|
let terminal = new Terminal();
|
|
this.set('terminal', terminal);
|
|
|
|
await render(hbs`
|
|
<ExecTerminal @terminal={{terminal}} />
|
|
`);
|
|
|
|
await settled();
|
|
|
|
let firstMessage = true;
|
|
let mockSocket = new Object({
|
|
send(message) {
|
|
if (firstMessage) {
|
|
firstMessage = false;
|
|
assert.deepEqual(message, JSON.stringify({ version: 1, auth_token: '' }));
|
|
mockSocket.onclose();
|
|
done();
|
|
}
|
|
},
|
|
});
|
|
|
|
new ExecSocketXtermAdapter(terminal, mockSocket, null);
|
|
|
|
mockSocket.onopen();
|
|
|
|
await settled();
|
|
});
|
|
|
|
test('a heartbeat is sent periodically', async function(assert) {
|
|
let done = assert.async();
|
|
|
|
const clock = sinon.useFakeTimers({
|
|
now: new Date(),
|
|
shouldAdvanceTime: true,
|
|
});
|
|
|
|
let terminal = new Terminal();
|
|
this.set('terminal', terminal);
|
|
|
|
await render(hbs`
|
|
<ExecTerminal @terminal={{terminal}} />
|
|
`);
|
|
|
|
await settled();
|
|
|
|
let mockSocket = new Object({
|
|
send(message) {
|
|
if (!message.includes('version') && !message.includes('tty_size')) {
|
|
assert.deepEqual(message, JSON.stringify({}));
|
|
clock.restore();
|
|
mockSocket.onclose();
|
|
done();
|
|
}
|
|
},
|
|
});
|
|
|
|
new ExecSocketXtermAdapter(terminal, mockSocket, null);
|
|
mockSocket.onopen();
|
|
await settled();
|
|
clock.tick(HEARTBEAT_INTERVAL);
|
|
});
|
|
|
|
test('resizing the window passes a resize message through the socket', async function(assert) {
|
|
let done = assert.async();
|
|
|
|
let terminal = new Terminal();
|
|
this.set('terminal', terminal);
|
|
|
|
await render(hbs`
|
|
<ExecTerminal @terminal={{terminal}} />
|
|
`);
|
|
|
|
await settled();
|
|
|
|
let mockSocket = new Object({
|
|
send(message) {
|
|
assert.deepEqual(
|
|
message,
|
|
JSON.stringify({ tty_size: { width: terminal.cols, height: terminal.rows } })
|
|
);
|
|
mockSocket.onclose();
|
|
done();
|
|
},
|
|
});
|
|
|
|
new ExecSocketXtermAdapter(terminal, mockSocket, '');
|
|
|
|
window.dispatchEvent(new Event('resize'));
|
|
|
|
await settled();
|
|
});
|
|
|
|
test('stdout frames without data are ignored', async function(assert) {
|
|
assert.expect(0);
|
|
|
|
let terminal = new Terminal();
|
|
this.set('terminal', terminal);
|
|
|
|
await render(hbs`
|
|
<ExecTerminal @terminal={{terminal}} />
|
|
`);
|
|
|
|
await settled();
|
|
|
|
let mockSocket = new Object({
|
|
send() {},
|
|
});
|
|
|
|
new ExecSocketXtermAdapter(terminal, mockSocket, '');
|
|
|
|
mockSocket.onmessage({
|
|
data: '{"stdout":{"exited":"true"}}',
|
|
});
|
|
|
|
await settled();
|
|
mockSocket.onclose();
|
|
});
|
|
|
|
test('stderr frames are ignored', async function(assert) {
|
|
let terminal = new Terminal();
|
|
this.set('terminal', terminal);
|
|
|
|
await render(hbs`
|
|
<ExecTerminal @terminal={{terminal}} />
|
|
`);
|
|
|
|
await settled();
|
|
|
|
let mockSocket = new Object({
|
|
send() {},
|
|
});
|
|
|
|
new ExecSocketXtermAdapter(terminal, mockSocket, '');
|
|
|
|
mockSocket.onmessage({
|
|
data: '{"stdout":{"data":"c2gtMy4yIPCfpbMk"}}',
|
|
});
|
|
|
|
mockSocket.onmessage({
|
|
data: '{"stderr":{"data":"c2gtMy4yIPCfpbMk"}}',
|
|
});
|
|
|
|
await settled();
|
|
|
|
assert.equal(
|
|
terminal.buffer.active
|
|
.getLine(0)
|
|
.translateToString()
|
|
.trim(),
|
|
'sh-3.2 🥳$'
|
|
);
|
|
|
|
mockSocket.onclose();
|
|
});
|
|
});
|