Skip to content

Commit 2574aa3

Browse files
committed
Add tests for exec.
1 parent 135a94d commit 2574aa3

File tree

2 files changed

+117
-4
lines changed

2 files changed

+117
-4
lines changed

node-client/src/exec.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import stream = require('stream');
33
import ws = require('websocket');
44

55
import { KubeConfig } from './config';
6-
import { WebSocketHandler } from './web-socket-handler';
6+
import { WebSocketHandler, WebSocketInterface } from './web-socket-handler';
77

88
export class Exec {
9-
public 'handler': WebSocketHandler;
9+
public 'handler': WebSocketInterface;
1010

11-
public constructor(config: KubeConfig) {
12-
this.handler = new WebSocketHandler(config);
11+
public constructor(config: KubeConfig, wsInterface?: WebSocketInterface) {
12+
if (wsInterface) {
13+
this.handler = wsInterface;
14+
} else {
15+
this.handler = new WebSocketHandler(config);
16+
}
1317
}
1418

1519
// TODO: make command an array and support multiple args

node-client/src/exec_test.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { expect } from 'chai';
2+
import { ReadableStreamBuffer, WritableStreamBuffer } from 'stream-buffers';
3+
import { anyFunction, capture, instance, mock, verify, when } from 'ts-mockito';
4+
import ws = require('websocket');
5+
6+
import { KubeConfig } from './config';
7+
import { Exec } from './exec';
8+
import { WebSocketHandler, WebSocketInterface } from './web-socket-handler';
9+
10+
describe('Exec', () => {
11+
describe('basic', () => {
12+
it('should correctly exec to a url', async () => {
13+
const kc = new KubeConfig();
14+
const fakeWebSocket: WebSocketInterface = mock(WebSocketHandler);
15+
const exec = new Exec(kc, instance(fakeWebSocket));
16+
const osStream = new WritableStreamBuffer();
17+
const errStream = new WritableStreamBuffer();
18+
const isStream = new ReadableStreamBuffer();
19+
20+
const namespace = 'somenamespace';
21+
const pod = 'somepod';
22+
const container = 'container';
23+
const cmd = 'command';
24+
const path = `/api/v1/namespaces/${namespace}/pods/${pod}/exec`;
25+
26+
await exec.exec(
27+
namespace, pod, container, cmd, osStream, errStream, isStream, false);
28+
let args = `stdout=true&stderr=true&stdin=true&tty=false&command=${cmd}&container=${container}`;
29+
verify(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).called();
30+
31+
await exec.exec(
32+
namespace, pod, container, cmd, null, errStream, isStream, false);
33+
args = `stdout=false&stderr=true&stdin=true&tty=false&command=${cmd}&container=${container}`;
34+
verify(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).called();
35+
36+
await exec.exec(
37+
namespace, pod, container, cmd, null, null, isStream, false);
38+
args = `stdout=false&stderr=false&stdin=true&tty=false&command=${cmd}&container=${container}`;
39+
verify(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).called();
40+
41+
await exec.exec(
42+
namespace, pod, container, cmd, null, null, null, false);
43+
args = `stdout=false&stderr=false&stdin=false&tty=false&command=${cmd}&container=${container}`;
44+
verify(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).called();
45+
46+
await exec.exec(
47+
namespace, pod, container, cmd, null, errStream, isStream, true);
48+
args = `stdout=false&stderr=true&stdin=true&tty=true&command=${cmd}&container=${container}`;
49+
verify(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).called();
50+
});
51+
52+
it('should correctly attach to streams', async () => {
53+
const kc = new KubeConfig();
54+
const fakeWebSocket: WebSocketInterface = mock(WebSocketHandler);
55+
const exec = new Exec(kc, instance(fakeWebSocket));
56+
const osStream = new WritableStreamBuffer();
57+
const errStream = new WritableStreamBuffer();
58+
const isStream = new ReadableStreamBuffer();
59+
60+
const namespace = 'somenamespace';
61+
const pod = 'somepod';
62+
const container = 'somecontainer';
63+
const cmd = 'command';
64+
65+
const path = `/api/v1/namespaces/${namespace}/pods/${pod}/exec`;
66+
const args = `stdout=true&stderr=true&stdin=true&tty=false&command=${cmd}&container=${container}`;
67+
68+
const fakeConn: ws.connection = mock(ws.connection);
69+
when(fakeWebSocket.connect(`${path}?${args}`, null, anyFunction())).thenResolve(fakeConn);
70+
71+
await exec.exec(
72+
namespace, pod, container, cmd, osStream, errStream, isStream, false);
73+
74+
const [, , outputFn] = capture(fakeWebSocket.connect).last();
75+
76+
/* tslint:disable:no-unused-expression */
77+
expect(outputFn).to.not.be.null;
78+
79+
// this is redundant but needed for the compiler, sigh...
80+
if (!outputFn) {
81+
return;
82+
}
83+
84+
let buffer = Buffer.alloc(1024, 10);
85+
86+
outputFn(WebSocketHandler.StdoutStream, buffer);
87+
expect(osStream.size()).to.equal(1024);
88+
let buff = osStream.getContents() as Buffer;
89+
for (let i = 0; i < 1024; i++) {
90+
expect(buff[i]).to.equal(10);
91+
}
92+
93+
buffer = Buffer.alloc(1024, 20);
94+
outputFn(WebSocketHandler.StderrStream, buffer);
95+
expect(errStream.size()).to.equal(1024);
96+
buff = errStream.getContents() as Buffer;
97+
for (let i = 0; i < 1024; i++) {
98+
expect(buff[i]).to.equal(20);
99+
}
100+
101+
const msg = 'This is test data';
102+
isStream.put(msg);
103+
verify(fakeConn.send(msg));
104+
105+
isStream.stop();
106+
verify(fakeConn.close());
107+
});
108+
});
109+
});

0 commit comments

Comments
 (0)