@loadmill/executer 0.1.52 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/parameter-pools.d.ts +3 -0
  2. package/dist/parameter-pools.js +69 -0
  3. package/dist/parameter-pools.js.map +1 -0
  4. package/dist/post-script/post-script-executor.d.ts +12 -2
  5. package/dist/post-script/post-script-executor.js +28 -6
  6. package/dist/post-script/post-script-executor.js.map +1 -1
  7. package/dist/sequence.d.ts +6 -1
  8. package/dist/sequence.js +51 -18
  9. package/dist/sequence.js.map +1 -1
  10. package/dist/single-runner.d.ts +1 -0
  11. package/dist/single-runner.js +4 -1
  12. package/dist/single-runner.js.map +1 -1
  13. package/package.json +3 -3
  14. package/src/asserter.ts +0 -137
  15. package/src/errors.ts +0 -10
  16. package/src/extraction-combiner.ts +0 -110
  17. package/src/failures.ts +0 -79
  18. package/src/message-creators.ts +0 -44
  19. package/src/mill-info.ts +0 -81
  20. package/src/mill-version.ts +0 -7
  21. package/src/post-script/ast-walker/index.ts +0 -160
  22. package/src/post-script/ast-walker/type-guard.ts +0 -73
  23. package/src/post-script/ast-walker/types.ts +0 -35
  24. package/src/post-script/console-log.ts +0 -24
  25. package/src/post-script/parser/acorn-js-parser.ts +0 -8
  26. package/src/post-script/parser/js-parser.ts +0 -22
  27. package/src/post-script/parser/parser.ts +0 -5
  28. package/src/post-script/post-script-executor.ts +0 -93
  29. package/src/post-script/virtual-machine/virtual-machine.ts +0 -15
  30. package/src/post-script/virtual-machine/vm2-virtual-machine.ts +0 -45
  31. package/src/report-types.ts +0 -127
  32. package/src/request-sequence-result.ts +0 -63
  33. package/src/request-stats.ts +0 -20
  34. package/src/res-keeper.ts +0 -53
  35. package/src/sampler.ts +0 -133
  36. package/src/sequence.ts +0 -1115
  37. package/src/single-runner.ts +0 -68
  38. package/src/test-run-event-emitter.ts +0 -25
  39. package/src/utils.ts +0 -8
  40. package/src/work.ts +0 -17
  41. package/src/ws.ts +0 -286
  42. package/test/post-script-console-log.spec.ts +0 -73
  43. package/test/post-script-executor.spec.ts +0 -685
  44. package/tsconfig.json +0 -9
@@ -1,68 +0,0 @@
1
- import superagent from 'superagent';
2
- import { sequence } from './sequence';
3
- import * as envUtils from '@loadmill/universal/dist/env-utils';
4
- import log from '@loadmill/universal/dist/log';
5
- import { AuthConf, LoadmillRequest, CachePenetration } from '@loadmill/core/dist/request';
6
- import { Parameters } from '@loadmill/core/dist/parameters';
7
- import {
8
- ExtendedSequenceResult,
9
- extendSequenceResult,
10
- RequestSequenceResult
11
- } from './request-sequence-result';
12
-
13
- export async function runSingleIterationAndMergeResolved(
14
- conf: ExecutableConf,
15
- ): Promise<ExtendedSequenceResult> {
16
- const result = await runSingleIteration(conf);
17
- return extendSequenceResult(result, conf.requests);
18
- }
19
-
20
- export async function runSingleIteration(
21
- conf: ExecutableConf,
22
- ): Promise<RequestSequenceResult> {
23
- let httpAgent;
24
- if (conf.useCookies && !envUtils.isBrowser()) {
25
- log.debug('Enabling cookies for node client.');
26
-
27
- // todo itay: make leak intentionally possible?
28
- // Unlike in the browser, cookies cannot leak from iteration to iteration:
29
- httpAgent = superagent.agent();
30
- } else {
31
- httpAgent = superagent;
32
- }
33
-
34
- return sequence.execute(
35
- httpAgent,
36
- extendRequests(conf),
37
- conf.parameters,
38
- conf.domainsWhiteList,
39
- conf.increaseResSize
40
- );
41
- }
42
-
43
- function extendRequests({
44
- requests,
45
- auth,
46
- useCookies,
47
- cachePenetration,
48
- }: ExecutableConf) {
49
- return requests.map((req) => ({
50
- ...req,
51
- auth,
52
- useCookies,
53
- cachePenetration,
54
- }));
55
- }
56
-
57
- export interface ExecutableConf {
58
- parameters: Parameters[];
59
- domainsWhiteList: string[];
60
- requests: LoadmillRequest[];
61
- cachePenetration: CachePenetration;
62
-
63
- auth?: AuthConf;
64
- useCookies?: boolean;
65
- useProxy?: boolean;
66
- useStaticIp?: boolean;
67
- increaseResSize?: boolean;
68
- }
@@ -1,25 +0,0 @@
1
- import log from '@loadmill/universal/dist/log';
2
- import { Socket } from 'socket.io-client';
3
-
4
- class TestRunEventsEmitter {
5
- postScript: EventsEmitter;
6
- constructor() {
7
- const warningMsg = ' event emitter callback not assigned';
8
- this.postScript = {
9
- started: () => log.warn('postScript' + warningMsg),
10
- finished: () => log.warn('postScript' + warningMsg),
11
- };
12
- }
13
-
14
- setPostScriptHandlers = (socket: Socket, token: string) => {
15
- this.postScript.started = () => socket.emit(`postscript-started:${token}`);
16
- this.postScript.finished = () => socket.emit(`postscript-finished:${token}`);
17
- }
18
- }
19
-
20
- const testRunEventsEmitter = new TestRunEventsEmitter();
21
- export { testRunEventsEmitter };
22
-
23
- type EventsEmitter = {
24
- [funcName: string]: () => void | Socket;
25
- }
package/src/utils.ts DELETED
@@ -1,8 +0,0 @@
1
- import {
2
- MAX_API_REQUEST_BODY_LENGTH,
3
- MAX_LOAD_REQUEST_BODY_LENGTH
4
- } from '@loadmill/core/dist/conf/extrema';
5
- import * as envUtils from '@loadmill/universal/dist/env-utils';
6
-
7
- export const getMaxRequestBodySize = () =>
8
- envUtils.isBrowser() ? MAX_LOAD_REQUEST_BODY_LENGTH : MAX_API_REQUEST_BODY_LENGTH;
package/src/work.ts DELETED
@@ -1,17 +0,0 @@
1
- import { AuthConf, LoadmillRequest, CachePenetration } from '@loadmill/core/dist/request';
2
- import { TestConfLike } from '@loadmill/core/dist/conf';
3
- import { Parameters } from '@loadmill/core/dist/parameters';
4
-
5
- export interface Work extends TestConfLike {
6
- loadId: string;
7
- duration: number;
8
- iterations: number;
9
- iterationDelay: number;
10
- parameters: Parameters[];
11
- domainsWhiteList: string[];
12
- requests: LoadmillRequest[];
13
- cachePenetration: CachePenetration;
14
-
15
- auth?: AuthConf;
16
- useCookies?: boolean;
17
- }
package/src/ws.ts DELETED
@@ -1,286 +0,0 @@
1
- import WebSocket from 'ws'; // todo should be picked with other option (socketio or non in browser)
2
- import { delay } from '@loadmill/universal/dist/promise-utils';
3
- import log from '@loadmill/universal/dist/log';
4
- import { HttpResponseStatus, LoadmillHeaders } from '@loadmill/core/dist/request';
5
- import { RequestFailuresError } from './errors';
6
- import { ClientRequest, IncomingMessage, IncomingHttpHeaders } from 'http';
7
- import { Socket } from 'net';
8
- declare class WS extends WebSocket {
9
- _req: WSClientRequest | null;
10
- }
11
- declare class WSClientRequest extends ClientRequest {
12
- socket: Socket & { parser: ParserIncomingMessage };
13
- }
14
- declare class ParserIncomingMessage {
15
- incoming: IncomingMessage;
16
- }
17
-
18
-
19
- enum WSState {
20
- CONNECTING,
21
- OPEN,
22
- CLOSING,
23
- CLOSED,
24
- }
25
-
26
- const SWITCHING_PROTOCOLS = 'Switching Protocols';
27
- const WS_CONNECTION_TIMEOUT_MS = 10000;
28
-
29
- export class WSRequest {
30
- private hasErrorOccured?: boolean; // need this otherwise we have race condition between verifyConnectedAndOpen and onError
31
- private ws: WebSocket;
32
- public url: string; // need this for isExpectedStatus function
33
- public expectedStatus: HttpResponseStatus; // need this for isExpectedStatus function
34
-
35
- constructor(
36
- private readonly wsRequestArgs: WSRequestArguments,
37
- private readonly wsHandler: WSSequenceHandler,
38
- private readonly onError: (e: Error) => void,
39
- ) {
40
- this.url = wsRequestArgs.url;
41
- this.expectedStatus = wsRequestArgs.expectedStatus;
42
- }
43
-
44
- /**
45
- * This function is executed when we are ready to send the ws request
46
- * @param cb This callback is being executed after we successfully connected to ws and sent a ws message if there was any
47
- */
48
- async ok(cb: (response: WSResponse) => boolean) {
49
- const response: WSResponse = {
50
- status: undefined,
51
- res: {
52
- statusMessage: undefined,
53
- },
54
- header: {},
55
- req: {},
56
- };
57
-
58
- const existingWS = this.wsHandler.getConnection(this.wsRequestArgs.url);
59
-
60
- existingWS && log.debug(`Existing Connection state ${getConnectionState(existingWS)}`);
61
- if (!existingWS || (existingWS && existingWS.readyState !== WSState.OPEN)) {
62
- await this.addConnection(response);
63
- } else {
64
- this.ws = existingWS;
65
- log.debug('Reusing existing ws connection', this.ws.url);
66
- }
67
-
68
- try {
69
- this.sendMessage();
70
- } catch (e) {
71
- log.error('Failed to send a ws message', e);
72
- }
73
- cb(response);
74
- return { };
75
- }
76
-
77
- private async addConnection(response: WSResponse) {
78
- this.ws = new WebSocket(this.wsRequestArgs.url, undefined, { headers: this.wsRequestArgs.headers });
79
- this.addEventListeners(response);
80
- !this.hasErrorOccured && await this.verifyOpen();
81
- this.wsHandler.storeConnection(this.wsRequestArgs.url, this.ws);
82
- // todo add some debug details for the user to know we created a new connection in this request
83
- }
84
-
85
- private async addEventListeners(response: WSResponse) {
86
- this.addOnErrorListener(response);
87
- this.addOnUpgradeListener(response);
88
- this.addOnOpenListener();
89
- this.addOnMessageListener();
90
- }
91
-
92
- private addOnErrorListener(response: WSResponse) {
93
- this.ws.addEventListener('error', event => {
94
- log.debug('inside addEventListener error');
95
- try {
96
- const target = event.target as WS;
97
- this.updateResponseOnError(target, response);
98
- } catch (e) {
99
- log.error('Got an error inside addEventListener error', e);
100
- }
101
- });
102
-
103
- this.ws.on('error', (e) => {
104
- try {
105
- log.debug('inside on error', e);
106
- this.onError(e);
107
- this.hasErrorOccured = true;
108
- } catch (e) {
109
- log.warn('Failed to handle a ws error', e);
110
- }
111
- try {
112
- log.debug('closing ws');
113
- this.ws.close();
114
- } catch (e) {
115
- log.warn('Failed to close a ws connection', e);
116
- }
117
- });
118
- }
119
-
120
- private updateResponseOnError(ws: WS, response: WSResponse) {
121
- if (ws._req) {
122
- const { statusCode, statusMessage, headers } = ws._req.socket.parser.incoming;
123
- log.debug('Got incoming incoming request', { statusCode, statusMessage, headers });
124
- response.status = statusCode;
125
- response.res.statusMessage = statusMessage;
126
- response.header = headers;
127
- }
128
- }
129
-
130
- private addOnUpgradeListener(response: WSResponse) {
131
- this.ws.on('upgrade', (event) => {
132
- try {
133
- const { statusCode, statusMessage, headers } = event;
134
- log.debug('inside upgrade event', { statusCode, statusMessage, headers });
135
- response.status = statusCode || 101;
136
- response.res.statusMessage = statusMessage || SWITCHING_PROTOCOLS;
137
- response.header = headers as LoadmillHeaders;
138
- } catch (e) {
139
- log.debug('upgrade event err', e);
140
- }
141
- });
142
- }
143
-
144
- private addOnOpenListener() {
145
- this.ws.on('open', () => {
146
- log.debug('inside on open, currently doing nothing here.');
147
- });
148
- }
149
-
150
- private addOnMessageListener() {
151
- this.ws.on('message', (message: any) => {
152
- try {
153
-
154
- const target = Array.isArray(message) ? decode(message) : message;
155
- log.debug('got incoming message', target);
156
-
157
- this.wsHandler.addMessage(target);
158
- } catch (e) {
159
- log.debug('error getting message', e);
160
- }
161
- });
162
- }
163
-
164
- async verifyOpen() {
165
- const readyState = await this.waitForConnectedState(this.wsRequestArgs.timeout);
166
- const connectionDebugMsg = `Connection ${WSState[readyState]}`;
167
- log.debug(connectionDebugMsg);
168
- if (readyState !== WebSocket.OPEN && !this.hasErrorOccured) {
169
- let msg = 'Could not connect to WebSocket address: ';
170
- log.debug(msg, { connectionState: WSState[readyState], url: this.ws.url });
171
- if (readyState === WSState.CONNECTING) {
172
- msg += 'request timeout';
173
- } else { // CLOSING or CLOSED state
174
- msg += connectionDebugMsg;
175
- }
176
- throw new RequestFailuresError(msg);
177
- }
178
- }
179
-
180
- /**
181
- * Waiting for WS connection to go out of CONNECTING state
182
- * @param socket The ws connection object
183
- * @param timeout The timeout in milliseconds for the waiting procedure
184
- * @returns WSState
185
- */
186
- waitForConnectedState = async (timeout: number = WS_CONNECTION_TIMEOUT_MS): Promise<WSState> => {
187
- const WS_CONNECTION_INTERVAL_MS = 100;
188
- if (this.ws.readyState != null && this.ws.readyState !== WebSocket.CONNECTING) {
189
- return this.ws.readyState;
190
- }
191
- else {
192
- const maxIterations = timeout / WS_CONNECTION_INTERVAL_MS;
193
- let i = 0;
194
- while (this.ws.readyState === WebSocket.CONNECTING && i < maxIterations) {
195
- await delay(WS_CONNECTION_INTERVAL_MS);
196
- i++;
197
- }
198
- return this.ws.readyState;
199
- }
200
- };
201
-
202
- private sendMessage() {
203
- log.debug('about to send message', { readyState: WSState[this.ws.readyState] } );
204
-
205
- const { message, mimeType } = this.wsRequestArgs;
206
-
207
- if (this.ws.readyState === WSState.OPEN && message) {
208
- this.ws.send(message, { binary: mimeType === 'binary' });
209
- }
210
-
211
- }
212
-
213
- // need this because the SequenceExecutor expectes a request obj with on func prop
214
- on(_eventName: string, _cb: Function) {
215
- //do nothing
216
- }
217
- }
218
-
219
- export class WSSequenceHandler {
220
- private _connections: { [url: string]: WebSocket };
221
- messages: string[];
222
- constructor() {
223
- this._connections = {};
224
- this.clearMessages();
225
- }
226
-
227
- getConnection(url: string): WebSocket | undefined {
228
- return this._connections[url];
229
- }
230
-
231
- storeConnection(url: string, wsConnection: WebSocket) {
232
- this._connections[url] = wsConnection;
233
- }
234
-
235
- async closeAllConnections() {
236
- try {
237
- log.debug('Closing all ws connections');
238
- for (const connection of Object.values(this._connections)) {
239
- connection.close();
240
- }
241
- } catch (e) {
242
- log.warn('Failed to close all connections', e, { connections: this._connections });
243
- }
244
- }
245
-
246
- getMessages() {
247
- return this.messages;
248
- }
249
-
250
- addMessage(message: string) {
251
- this.messages.push(message);
252
- }
253
-
254
- clearMessages() {
255
- this.messages = [];
256
- }
257
- }
258
-
259
- function getConnectionState(existingWS?: WebSocket) {
260
- return existingWS ? WSState[existingWS.readyState] : null;
261
- }
262
-
263
- function decode(buffer, encoding = 'utf-8') {
264
- const enc = new TextDecoder(encoding);
265
- return enc.decode(new Uint8Array(buffer));
266
- }
267
-
268
- export type WSMimeType = 'binary' | 'text';
269
-
270
- export type WSRequestArguments = {
271
- expectedStatus: HttpResponseStatus;
272
- headers: LoadmillHeaders
273
- message: string;
274
- mimeType: WSMimeType;
275
- timeout: number;
276
- url: string;
277
- };
278
-
279
- export type WSResponse = {
280
- status?: number;
281
- res: {
282
- statusMessage?: string;
283
- };
284
- header: LoadmillHeaders | IncomingHttpHeaders;
285
- req: {};
286
- }
@@ -1,73 +0,0 @@
1
- import { strict as assert } from 'assert';
2
- import { describe, it } from 'mocha';
3
-
4
- import { myConsole, LINE_LIMIT, CONSOLE_LOG_LIMIT } from '../src/post-script/console-log';
5
-
6
- describe('override console.log', () => {
7
-
8
- it('Simple console.log', () => {
9
- myConsole.setStdout([]);
10
- myConsole.log(1);
11
- assert.deepEqual(myConsole.stdout, ['1 ']);
12
- myConsole.setStdout([]);
13
- myConsole.log('a');
14
- assert.deepEqual(myConsole.stdout, ['a ']);
15
- });
16
- it('Empty console.log', () => {
17
- myConsole.setStdout([]);
18
- myConsole.log();
19
- assert.deepEqual(myConsole.stdout, []);
20
- });
21
- it('console.log with empty string', () => {
22
- myConsole.setStdout([]);
23
- myConsole.log('');
24
- assert.deepEqual(myConsole.stdout, [' ']);
25
- });
26
- it('console.log of more than one element in one line', () => {
27
- myConsole.setStdout([]);
28
- myConsole.log(1,2,3,'a','b','c');
29
- assert.deepEqual(myConsole.stdout, ['1 2 3 a b c ']);
30
- });
31
- it('console.log of an object', () => {
32
- myConsole.setStdout([]);
33
- const a = { 'A':1,'B':2 };
34
- myConsole.log(a);
35
- assert.deepEqual(myConsole.stdout, ['{\n "A": 1,\n "B": 2\n} ']);
36
- });
37
- it('console.log of a function', () => {
38
- myConsole.setStdout([]);
39
- const func = () => { };
40
- myConsole.log(func);
41
- assert.deepEqual(myConsole.stdout, ['function () { } ']);
42
- });
43
- it('console.log of an array', () => {
44
- myConsole.setStdout([]);
45
- const a = [1,2,3];
46
- myConsole.log(a);
47
- assert.deepEqual(myConsole.stdout, ['[\n 1,\n 2,\n 3\n] ']);
48
- });
49
- it('console.log of an array that contains objects', () => {
50
- myConsole.setStdout([]);
51
- const a = [1,2,3,{ 'A':1,'B':2 },{ 'C':3,'D':4 }];
52
- myConsole.log(a);
53
- assert.deepEqual(myConsole.stdout, ['[\n 1,\n 2,\n 3,\n {\n "A": 1,\n "B": 2\n },\n {\n "C": 3,\n "D": 4\n }\n] ']);
54
- });
55
- it('check the line limit', () => {
56
- myConsole.setStdout([]);
57
- const a = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
58
- let b = '';
59
- for (let i = 0; i<11; i++) {
60
- b += a;
61
- }
62
- myConsole.log(b);
63
- assert.deepEqual(myConsole.stdout, [b.substring(0, LINE_LIMIT) + '\n...']);
64
- });
65
- it('check the console.log limit', () => {
66
- myConsole.setStdout([]);
67
- const a = 123;
68
- for (let i = 0; i<110; i++) {
69
- myConsole.log(a);
70
- }
71
- assert.equal(myConsole.stdout.length, CONSOLE_LOG_LIMIT);
72
- });
73
- });