-
Notifications
You must be signed in to change notification settings - Fork 1
/
test.js
319 lines (274 loc) · 8.62 KB
/
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
const {suite, test, before, after} = require('mocha');
suite('trying client', () => {
var DockerClient = require('../src/client.js');
var DockerServer = require('docker-exec-websocket-server').DockerExecServer;
var assert = require('assert');
var Docker = require('dockerode');
var fs = require('fs');
var http = require('http');
var fs = require('fs');
var sleep = require('./sleep');
var poll = require('./poll');
const PORT = 60171;
const DOCKER_SOCKET = '/var/run/docker.sock';
// Test that we have a docker socket
if (!fs.statSync(DOCKER_SOCKET).isSocket()) {
throw new Error('Are you sure the docker is running?');
}
// Setup docker container we can play with
var dockerServer, dockerServer2, container;
before(async() => {
var docker = new Docker({socketPath: DOCKER_SOCKET});
await docker.pull('ubuntu');
await poll(async () => {
// Create docker container
container = await docker.createContainer({
Image: 'ubuntu',
Cmd: ['sleep', '600']
});
}, 40, 500);
// Start the container
await container.start();
// Start server
var server = http.createServer();
await new Promise(accept => server.listen(PORT, accept));
// Docker docket socket server
dockerServer = new DockerServer({
server: server,
containerId: container.id,
path: '/a',
});
//another server to do the connection limit tests
var server2 = http.createServer();
await new Promise(accept => server2.listen(8082, accept));
dockerServer2 = new DockerServer({
server: server2,
containerId: container.id,
path: '/a',
maxSessions: 1,
});
});
// Clean up after docker container
after(async() => {
dockerServer.close();
dockerServer2.close();
await container.remove({v: true, force: true});
});
/*test('docker exec true', async () => {
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: false,
command: ['sh', '-c', 'true'],
});
// Execute command
await client.execute();
// Wait for termination
var code = await new Promise((accept, reject) => {
client.on('exit', accept);
client.on('error', reject);
});
assert(code === 0, 'Expected exit code to be zero');
client.close();
});
test('docker exec echo test', async () => {
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: false,
command: ['echo', 'test'],
});
// Execute command
await client.execute();
// Read bytes from stdout
var data = [];
client.stdout.on('data', buf => data.push(buf));
// Wait for termination
var code = await new Promise((accept, reject) => {
client.on('exit', accept);
client.on('error', reject);
});
assert(code === 0, 'Expected exit code to be zero');
// Get all the data we received from stdout
var output = Buffer.concat(data);
// Check that the output is correct
assert(output.toString() == "test\n", 'Expected output === "test\\n"');
client.close();
});*/
test('docker exec wc -c', async () => {
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: false,
command: ['wc', '-c'],
});
// Execute command
await client.execute();
// Write some bytes on stdin to cat, then close stdin
var input = new Uint8Array([97, 98, 99]);
client.stdin.write(new Buffer(input));
client.stdin.end();
// Read bytes from stdout
var stdout = [], stderr = [];
client.stdout.on('data', b => stdout.push(b));
client.stderr.on('data', b => stderr.push(b));
// Wait for termination
var code = await new Promise((accept, reject) => {
client.on('exit', accept);
client.on('error', reject);
});
console.log("Exit code: " + code);
stdout = Buffer.concat(stdout);
stderr = Buffer.concat(stderr);
console.log("stdout: '%s'", stdout.toString());
console.log("stderr: '%s'", stderr.toString());
assert(code === 0, 'Expected exit code to be zero');
client.close();
});
test('cat on server', async () => {
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: false,
command: ['cat', '-E'],
});
await client.execute();
var buf1 = new Uint8Array([0xfa, 0xff, 0x0a]);
client.stdin.write(new Buffer(buf1));
var passed = false;
client.stdout.on('data', (message) => {
var buf = new Buffer([0xfa, 0xff, 0x24, 0x0a]); //0x24 is $ from the -E option
assert(buf.compare(message) === 0, 'message wrong!');
passed = true;
});
await poll(async () => {
assert(passed, 'message not recieved');
}, 40, 500);
client.close();
});
test('exit code', async () => {
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: true,
command: ['/bin/bash'],
});
await client.execute();
client.stdin.write('exit 9\n');
var passed = false;
client.on('exit', (code) => {
assert(code === 9, 'message wrong!');
passed = true;
});
await poll(async () => {
assert(passed, 'exit message not recieved');
}, 40, 500);
client.close();
});
/* test('server pause', async () => {
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: false,
command: 'cat',
});
await client.execute();
client.pause();
var paused = true;
var timer;
client.stdin.write('hello\n');
client.stdout.on('data', (message) => {
assert(!paused, 'message recieved too early');
assert(message.toString() === 'hello\n', 'message recieved was incorrect');
client.close();
clearTimeout(timer);
});
setTimeout(() => {
paused = false;
client.resume();
timer = setTimeout(() => {
throw new Error('message too slow');
}, 500);
}, 500);
});*/
test('connection limit', async () => {
var client = new DockerClient({
url: 'ws://localhost:8082/a',
tty: false,
command: ['cat'],
});
var client2 = new DockerClient({
url: 'ws://localhost:8082/a',
tty: false,
command: ['cat'],
});
await client.execute();
client2.on('error', (errorStr) => {
assert(errorStr.toString() === 'Too many sessions active!');
// client.close();
// TODO: server isn't closed here due to race condition where client2
// isn't finished executing, causing things to be unclosable
// Possible solution: There's no way to cancel execute, so we could
// emit something on end of execute so the close function knows when to close
// That doesn't seem like a very nice solution to me though
});
client2.execute();
});
test('automatic pausing', async () => {
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: false,
command: ['sleep', '3'],
});
await client.execute();
//before the socket opens, the writes will just buffer in memory
// await sleep(1000);
client.strbuf.write(new Buffer(8 * 1024 * 1024 + 1));
// assert(!client.strbuf.write(new Buffer(1)));
var passed = false;
client.on('paused', () => {
passed = true;
});
// similar to above problem, can't close client here
await sleep(1000);
assert(passed, 'did not pause when socket overloaded');
client.close();
});
test('session count', async () => {
var sessionCount;
dockerServer.once('session added', (num) => {
sessionCount = num;
dockerServer.once('session removed', (newnum) => {
assert(num === newnum + 1, 'session count not working properly');
})
})
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: false,
command: ['cat'],
});
await client.execute();
client.close();
});
test('resize', async () => {
//have to give it some time to resize before lsing
var client = new DockerClient({
url: 'ws://localhost:' + PORT + '/a',
tty: true,
command: ['/bin/bash', '-c', 'sleep 3; ls'],
});
await client.execute();
client.resize(25, 1);
var passed = false;
var byteNum = 0;
var buf = new Buffer([0x62, 0x69, 0x6e, 0x0d, 0x0a]);
var res = [];
client.stdout.on('data', (message) => {
res.push(message);
if(!buf.compare(Buffer.concat(res).slice(0, 5))) {
passed = true;
}
else {
assert(Buffer.concat(res).length <= 5, 'message is wrong, not properly resized');
}
});
await poll(async () => {
assert(passed, 'message not received');
}, 40, 500);
client.close();
});
});