@loadmill/core 0.3.51 → 0.3.52

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 (59) hide show
  1. package/package.json +2 -2
  2. package/src/conf/defaults.ts +0 -25
  3. package/src/conf/extrema.ts +0 -36
  4. package/src/conf/index.ts +0 -95
  5. package/src/conf/notifications.ts +0 -17
  6. package/src/conf/types.ts +0 -100
  7. package/src/conf/validate.ts +0 -559
  8. package/src/distributed-logger-reporter.ts +0 -19
  9. package/src/echo/firehose.ts +0 -64
  10. package/src/echo/index.ts +0 -4
  11. package/src/echo/stats.ts +0 -84
  12. package/src/har/index.ts +0 -81
  13. package/src/multipart-form-data/form-data-utils.ts +0 -81
  14. package/src/multipart-form-data/is-binary-file.ts +0 -206
  15. package/src/multipart-form-data/multipart-text-to-post-form-data.ts +0 -149
  16. package/src/parameters/extractions.ts +0 -53
  17. package/src/parameters/extractors/cheerio-extractor.ts +0 -57
  18. package/src/parameters/extractors/expression-extractor.ts +0 -13
  19. package/src/parameters/extractors/extractor.ts +0 -3
  20. package/src/parameters/extractors/header-extractor.ts +0 -24
  21. package/src/parameters/extractors/index.ts +0 -10
  22. package/src/parameters/extractors/json-path-extractor.ts +0 -63
  23. package/src/parameters/extractors/parametrized-extractor.ts +0 -27
  24. package/src/parameters/extractors/regex-extractor.ts +0 -18
  25. package/src/parameters/extractors/regex-matcher.ts +0 -17
  26. package/src/parameters/extractors/ws-extractor.ts +0 -91
  27. package/src/parameters/generate-random.ts +0 -114
  28. package/src/parameters/index.ts +0 -624
  29. package/src/parameters/json-path-utils.ts +0 -20
  30. package/src/parameters/operators/binary-operator.ts +0 -23
  31. package/src/parameters/operators/index.ts +0 -39
  32. package/src/parameters/parameter-functions/boolean-parameter-functions.ts +0 -24
  33. package/src/parameters/parameter-functions/crypto.ts +0 -55
  34. package/src/parameters/parameter-functions/json-schema.ts +0 -29
  35. package/src/parameters/parameter-functions/numeric-input-parameter-functions.ts +0 -22
  36. package/src/parameters/parameter-functions/numeric-parameter-functions.ts +0 -37
  37. package/src/parameters/parameter-functions/parameter-function-utils.ts +0 -55
  38. package/src/parameters/parameter-functions/parameter-function.ts +0 -7
  39. package/src/parameters/parameter-functions/parameter-functions.ts +0 -54
  40. package/src/parameters/parameter-functions/random-parameter-functions.ts +0 -22
  41. package/src/parameters/parameter-functions/textual-parameter-functions.ts +0 -464
  42. package/src/parameters/parameter-regex-providers.ts +0 -78
  43. package/src/parameters/resolvers/random-parameters-resolver.ts +0 -8
  44. package/src/parameters/type.ts +0 -7
  45. package/src/parameters/value-utils.ts +0 -47
  46. package/src/request/index.ts +0 -526
  47. package/src/schema/json-schema-generator.ts +0 -76
  48. package/test/conf/validate.spec.js +0 -141
  49. package/test/har/is-har.spec.js +0 -33
  50. package/test/multipart-form-data/form-data-utils.spec.ts +0 -142
  51. package/test/multipart-form-data/resources/multipart-form-data-file-text-content.json +0 -5
  52. package/test/parameters/builtin-functions.spec.js +0 -85
  53. package/test/parameters/json-path-utils.spec.ts +0 -50
  54. package/test/parameters/parameter-functions.spec.js +0 -48
  55. package/test/parameters/parameter-utils.spec.js +0 -185
  56. package/test/parameters/regex-functions.spec.ts +0 -57
  57. package/test/parameters/value-utils.spec.js +0 -73
  58. package/test/schema/json-schema-generator.spec.js +0 -227
  59. package/tsconfig.json +0 -9
@@ -1,526 +0,0 @@
1
- import flatMap = require('lodash/flatMap');
2
- import * as uriUtils from '@loadmill/universal/dist/uri-utils';
3
- import { Parameters, parameterUtils } from '../parameters';
4
-
5
- export const DEFAULT_REQUEST_TIMEOUT = 25000;
6
- export const supportedMethods = {
7
- GET: 'GET',
8
- POST: 'POST',
9
- PUT: 'PUT',
10
- DELETE: 'DELETE',
11
- PATCH: 'PATCH',
12
- };
13
- export const ALLOWED_RESPONSE_STATUSES = { SUCCESS: 'SUCCESS', ERROR: 'ERROR', ANY: 'ANY' };
14
-
15
- export type HttpMethod = keyof typeof supportedMethods;
16
- export type HttpResponseStatus = keyof typeof ALLOWED_RESPONSE_STATUSES;
17
-
18
- /**
19
- * This class represents an HTTP request to be performed in the course of a load test.
20
- *
21
- * @property url The URL of the request (parameterizable).
22
- * @property method The HTTP method.
23
- * @property headers An array of headers to add to the request (values parameterizable).
24
- * @property postData The content of the request (text parameterizable).
25
- * @property delay The delay between this request and the previous one in milliseconds. This property is ignored for the first request.
26
- * @property timeout The time to wait for the request to finish in milliseconds.
27
- * @property extract A dictionary of parameter extractions.
28
- * @property assert An array or dictionary of assertions.
29
- * @property expectedStatus The expected status of the http response SUCCESS for 2XX-3XX, ERROR for 4XX-5XX.
30
- */
31
- export class LoadmillRequest implements RequestLike {
32
- auth?: AuthConf;
33
- stopBefore?: string;
34
- skipBefore?: SkipConf;
35
- loop?: LoopConf;
36
-
37
- useCookies?: boolean;
38
- description?: string;
39
- delay?: number | string;
40
- postData?: RequestPostData;
41
- postFormData?: PostFormData;
42
- file?: RequestRawFileData;
43
- cachePenetration?: CachePenetration;
44
-
45
- method: HttpMethod = 'GET';
46
- headers?: LoadmillHeaders[];
47
-
48
- assert?: Assertions;
49
- extract?: Extractions[];
50
- postScript?: string;
51
- disabled?: boolean;
52
- timeout?: number;
53
- expectedStatus?: HttpResponseStatus;
54
- noRedirects?: boolean;
55
-
56
- constructor(public url: string) { }
57
- }
58
-
59
- export function resolveUrl(
60
- url: string,
61
- parameters: Parameters | Parameters[],
62
- onError?
63
- ) {
64
- return uriUtils.withProtocol(
65
- parameterUtils.resolveExpression(url, parameters, onError)
66
- );
67
- }
68
-
69
- /**
70
- * This function should be able to take any object/json and either make a VALID LoadmillRequest out of it
71
- * or fail with a meaningful error message.
72
- */
73
- export function createRequest(from: RequestLike): LoadmillRequest {
74
- const {
75
- url,
76
- delay,
77
- assert,
78
- method,
79
- timeout,
80
- extract,
81
- headers,
82
- postData,
83
- postFormData,
84
- file,
85
- stopBefore,
86
- skipBefore,
87
- loop,
88
- description,
89
- expectedStatus,
90
- postScript,
91
- disabled,
92
- noRedirects,
93
- } = from;
94
-
95
- const request = new LoadmillRequest(url);
96
-
97
- if (method) {
98
- request.method = method;
99
- }
100
-
101
- if (description) {
102
- request.description = description;
103
- }
104
-
105
- if (headers) {
106
- request.headers = toHeaders(headers);
107
- }
108
-
109
- if (postData) {
110
- const text = postData.text;
111
- const mimeType = postData.mimeType;
112
- request.postData = { text, mimeType };
113
- }
114
-
115
- if (postFormData) {
116
- request.postFormData = postFormData;
117
- }
118
-
119
- if (file) {
120
- request.file = file;
121
- }
122
-
123
- if (delay !== null && delay !== undefined) {
124
- request.delay = delay;
125
- }
126
-
127
- if (stopBefore !== undefined) {
128
- request.stopBefore = stopBefore;
129
- }
130
-
131
- if (skipBefore != null) {
132
- const { goTo, negate, condition } = skipBefore;
133
-
134
- request.skipBefore = {
135
- goTo,
136
- condition,
137
- negate: !!negate,
138
- };
139
- }
140
-
141
- if (loop != null) {
142
- const { iterations, assert } = loop;
143
-
144
- const [converted] = toAssertions([assert]);
145
- request.loop = {
146
- assert: converted,
147
- iterations
148
- };
149
- }
150
-
151
- if (timeout != null) {
152
- request.timeout = timeout;
153
- }
154
-
155
- if (extract) {
156
- request.extract = toExtractions(extract);
157
- }
158
-
159
- if (assert) {
160
- request.assert = toAssertions(assert);
161
- }
162
-
163
- if (expectedStatus) {
164
- request.expectedStatus = expectedStatus;
165
- }
166
-
167
- if (postScript !== undefined) {
168
- request.postScript = postScript;
169
- }
170
-
171
- if (disabled !== undefined) {
172
- request.disabled = disabled;
173
- }
174
-
175
- if (noRedirects !== undefined) {
176
- request.noRedirects = noRedirects;
177
- }
178
-
179
- return request;
180
- }
181
-
182
- export function toHeaders(headers: LoadmillHeaders | LoadmillHeaders[]) {
183
- return flatMap<LoadmillHeaders | string, LoadmillHeaders>(
184
- headers as any,
185
- (value: LoadmillHeaders | any, key: number | string) => {
186
- const res = [];
187
- if (typeof key === 'string') {
188
- pushHeader(value, key, res);
189
- } else {
190
- Object.keys(value).map((innerKey: string) => {
191
- const innerValue = value[innerKey];
192
- pushHeader(innerValue, innerKey!, res);
193
- });
194
- }
195
-
196
- return res;
197
- }
198
- );
199
- }
200
-
201
- function toExtractions(extractions: Extractions | Extractions[]) {
202
- if (!Array.isArray(extractions)) {
203
- extractions = [extractions];
204
- }
205
-
206
- return extractions.map(toSingleExtractions);
207
- }
208
-
209
- function toSingleExtractions(extractions: Extractions): Extractions {
210
- const result = {};
211
-
212
- // Arrgh: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/12449
213
- Object.keys(extractions).forEach((name: string) => {
214
- const extraction = extractions[name];
215
- let newExtraction: Extraction = extractions[name];
216
-
217
- if (typeof extraction !== 'string') {
218
- newExtraction = {};
219
- const { header, jQuery, jsonPath, edn, regex, ws } = extraction;
220
-
221
- if (header != null) {
222
- newExtraction.header = header;
223
- }
224
-
225
- if (jQuery != null) {
226
- newExtraction.jQuery =
227
- typeof jQuery === 'string'
228
- ? jQuery
229
- : { query: jQuery.query, attr: jQuery.attr };
230
- }
231
-
232
- if (jsonPath != null) {
233
- newExtraction.jsonPath = jsonPath;
234
- }
235
-
236
- if (edn != null) {
237
- newExtraction.edn = edn;
238
- }
239
-
240
- if (regex != null) {
241
- newExtraction.regex = regex;
242
- }
243
-
244
- if (ws != null) {
245
- newExtraction.ws = ws;
246
- }
247
- }
248
-
249
- result[name] = newExtraction;
250
- });
251
-
252
- return result;
253
- }
254
-
255
- function toAssertions(assertions: Assertions) {
256
- const result: Assertions = [];
257
-
258
- assertions.forEach((assertion: Assertion, key: number) => {
259
- const {
260
- check,
261
- equals,
262
- notEquals,
263
- contains,
264
- notContains,
265
- matches,
266
- falsy,
267
- greater,
268
- lesser,
269
- JSONSchema
270
- } = assertion;
271
-
272
- const converted: Assertion = {
273
- check,
274
- };
275
-
276
- if (equals != null) {
277
- converted.equals = equals;
278
- }
279
-
280
- if (notEquals != null) {
281
- converted.notEquals = notEquals;
282
- }
283
-
284
- if (contains != null) {
285
- converted.contains = contains;
286
- }
287
-
288
- if (notContains != null) {
289
- converted.notContains = notContains;
290
- }
291
-
292
- if (matches != null) {
293
- converted.matches = matches;
294
- }
295
-
296
- if (greater != null) {
297
- converted.greater = greater;
298
- }
299
-
300
- if (lesser != null) {
301
- converted.lesser = lesser;
302
- }
303
-
304
- if (falsy != null && (falsy === 'true' || falsy === true)) {
305
- converted.falsy = true;
306
- }
307
-
308
- if (JSONSchema != null) {
309
- converted.JSONSchema = JSONSchema;
310
- }
311
-
312
- result[key] = converted;
313
- });
314
-
315
- return result;
316
- }
317
-
318
- export function findRequestIndex(requests: RequestLike[], desc: string) {
319
- return requests.findIndex(({ description }) => description === desc);
320
- }
321
-
322
- export function isReservedHeader(lowerName: string) {
323
- return (
324
- lowerName.startsWith('proxy-') ||
325
- (lowerName.startsWith('sec-') && !lowerName.startsWith('sec-websocket')) ||
326
- lowerName === 'accept-charset' ||
327
- lowerName === 'accept-encoding' ||
328
- lowerName === 'access-control-request-headers' ||
329
- lowerName === 'access-control-request-method' ||
330
- lowerName === 'connection' ||
331
- lowerName === 'content-length' ||
332
- lowerName === 'cookie2' ||
333
- lowerName === 'date' ||
334
- lowerName === 'dnt' ||
335
- lowerName === 'expect' ||
336
- lowerName === 'keep-alive' ||
337
- lowerName === 'te' ||
338
- lowerName === 'trailer' ||
339
- lowerName === 'transfer-encoding' ||
340
- lowerName === 'upgrade'
341
- );
342
- }
343
-
344
- function pushHeader(value, name: string, to: object[]) {
345
- to.push(singleton(value, name));
346
- }
347
-
348
- function singleton(value: string, name: string) {
349
- return { [name]: value };
350
- }
351
-
352
- export interface RequestLike {
353
- url: string;
354
-
355
- // currently ignored:
356
- auth?: AuthConf;
357
-
358
- stopBefore?: string;
359
- skipBefore?: SkipConf;
360
- loop?: LoopConf;
361
-
362
- timeout?: number;
363
- assert?: Assertions;
364
- method?: HttpMethod;
365
- description?: string;
366
- delay?: number | string;
367
- postData?: RequestPostData;
368
- postFormData?: PostFormData;
369
- file?: RequestRawFileData;
370
- extract?: Extractions | Extractions[];
371
- headers?: LoadmillHeaders | LoadmillHeaders[];
372
- expectedStatus?: HttpResponseStatus;
373
- parameters?;
374
- postScript?: string;
375
- disabled?: boolean;
376
- noRedirects?: boolean;
377
- }
378
-
379
- export type SkipConf = {
380
- condition: string;
381
- negate?: boolean;
382
- goTo?: string;
383
- };
384
-
385
- export type LoopConf = {
386
- assert: Assertion;
387
- iterations: number;
388
- };
389
-
390
- export type RequestPostData = {
391
- mimeType?: string;
392
- text: string;
393
- };
394
-
395
- export type PostFormData = PostFormDataEntry[];
396
-
397
- export type PostFormDataEntry = {
398
- name: string;
399
- value: string;
400
- fileName?: string;
401
- contentType?: string;
402
- };
403
-
404
- export type RequestRawFileData = {
405
- name: string;
406
- key: string;
407
- signedUrl?: string; // created by aws
408
- };
409
-
410
- export enum BodyTypes {
411
- POST_DATA = 'postData',
412
- FORM_DATA = 'postFormData',
413
- RAW_FILE = 'rawFile',
414
- }
415
-
416
- export type LoadmillHeaders = { [headerName: string]: string };
417
-
418
- export type Extractions = { [parameter: string]: Extraction };
419
-
420
- /**
421
- * This object represents a parameter extraction.
422
- *
423
- * The jQuary expression is evaluated against the response body text using Cheerio.
424
- * The jsonPath expression is evaluated against a superagent-like response object.
425
- * The edn expression is evaluated against a superagent-like response object converted to JSON and then treated like jsonPath.
426
- * If a regular expression is specified as well as a header, jQuery or jsonPath then the expression will be matched against the
427
- * query result, otherwise it is evaluated against the response body text.
428
- *
429
- * It is invalid to submit an empty extraction or one with more than one non-regex query. If the extraction yields a
430
- * `null` result, then the original parameter value will be retained, defaulting to an empty string.
431
- *
432
- * @property header A name of a header whose value will be extracted.
433
- * @property jQuery A jQuery expression to be matched against the response body text.
434
- * @property jsonPath A jsonPath expression to be matched against the response object.
435
- * @property edn A jsonPath expression (yes - jsonPath) to be matched against the EDN response object converted to JSON.
436
- * @property regex A JavaScript regular expression with a capture term, to be matched against the response body text.
437
- */
438
- export type Extraction = string | ExtractionObj;
439
-
440
- export type ExtractionObj = {
441
- regex?: string;
442
- header?: string;
443
- jsonPath?: string;
444
- edn?: string;
445
-
446
- jQuery?:
447
- | string
448
- | {
449
- query: string;
450
- attr?: string;
451
- };
452
- ws?: string;
453
- };
454
-
455
- export type Assertions = Assertion[];
456
-
457
- /**
458
- * This object represents an assertion.
459
- *
460
- * Assertions are made once the request has been fulfilled and all parameters have been extracted.
461
- * All assertions are evaluated, even if some fail.
462
- * If an assertion contains more then one conditions then the conditions are or-ed.
463
- *
464
- * @property check A parameter name to assert the given conditions on.
465
- * @property equals A parametrized expression that asserts to true if its value is equal to `check`.
466
- * @property contains A parametrized expression that asserts to true if its value is contained in `check`.
467
- * @property matches A JavaScript regular expression that asserts to true if `check` matches it.
468
- * @property falsy if true then A parametrized expression that asserts to true if the value of `check` equales false.
469
- * @property greater A parametrized expression that asserts to true if its value is less to `check`.
470
- * @property lesser A parametrized expression that asserts to true if its value is greater to `check`.
471
- */
472
- export interface Assertion {
473
- check: string;
474
- equals?: string;
475
- notEquals?: string;
476
- contains?: string;
477
- notContains?: string;
478
- matches?: string;
479
- falsy?: string | boolean;
480
- greater?: string;
481
- lesser?: string;
482
- JSONSchema?: string;
483
- }
484
-
485
- export interface AuthConf {
486
- user?: string;
487
- password?: string;
488
- }
489
-
490
- export interface CachePenetration {
491
- cacheControl?: string;
492
- mode?: CachePenetrationModes;
493
- }
494
-
495
- export enum CachePenetrationModes {
496
- none = 'none',
497
- def = 'default',
498
- alwaysQuery = 'always-query',
499
- alwaysHeader = 'always-header',
500
- }
501
-
502
- // list of fields in our object we must not change
503
- export const EXCLUDES = [
504
- 'url',
505
- 'method',
506
- 'headers',
507
- 'timeout',
508
- 'postData',
509
- 'text',
510
- 'mimeType',
511
- 'extract',
512
- 'jsonPath',
513
- 'jQuery',
514
- 'regex',
515
- 'header',
516
- 'assert',
517
- 'check',
518
- 'equals',
519
- 'contains',
520
- 'matches',
521
- 'falsy',
522
- 'greater',
523
- 'lesser',
524
- ];
525
-
526
- export const isWSRequest = (url: string) => url.startsWith('ws://') || url.startsWith('wss://');
@@ -1,76 +0,0 @@
1
- import find = require('lodash/find');
2
- import log from '@loadmill/universal/dist/log';
3
- import isEmpty = require('lodash/isEmpty');
4
-
5
- export const generateJSONSchema = (jsObj: any, ignoreKeys: string[] = [], shouldAddNullable: boolean = false): PrimitiveSchema | Schema => {
6
- try {
7
- const schema = _getSchema(jsObj, ignoreKeys, shouldAddNullable);
8
- return schema;
9
- } catch (err) {
10
- _handleError('Error generating JSON Schema', err, jsObj);
11
- }
12
-
13
- return {};
14
- };
15
-
16
- const _getSchema = (obj, ignoreKeys: string[] = [], shouldAddNullable: boolean = false) => {
17
- if (obj == null) {
18
- return shouldAddNullable ? { type: 'object', nullable: true } :{};
19
- }
20
- else if (_isPrimitive(obj)) {
21
- return {
22
- 'type': typeof obj
23
- };
24
- }
25
- else if (Array.isArray(obj)) {
26
- const items: any[] = [];
27
- for (const [, value] of Object.entries(obj)) {
28
- const elementSchema = _getSchema(value, ignoreKeys);
29
- if (!find(items, elementSchema)) {
30
- items.push(elementSchema);
31
- }
32
- }
33
- // The use of 'oneOf' creates a schema that validates the existence of the items but not their order in the array
34
- return {
35
- 'type': 'array',
36
- 'items': isEmpty(items) ? {} : { 'anyOf': items }
37
- };
38
- }
39
- else {
40
- const properties = {};
41
- for (const [key, value] of Object.entries(obj)) {
42
- if (!ignoreKeys.includes(key)) {
43
- properties[key] = _getSchema(value, ignoreKeys);
44
- }
45
- }
46
- return {
47
- 'type': 'object',
48
- properties
49
- };
50
- }
51
- };
52
-
53
- const _isPrimitive = (obj) => Object(obj) !== obj;
54
-
55
- const _handleError = (err, msg, json) => {
56
- log.error(msg, err, json);
57
- throw new Error(msg);
58
- };
59
-
60
- export type Schema = BaseSchema & {
61
- properties?: {
62
- [name: string]: Schema | PrimitiveSchema
63
- }
64
- items?: Schema[] | PrimitiveSchema[]
65
- }
66
-
67
- export type PrimitiveSchema = BaseSchema & {
68
- const?: Primitive
69
- }
70
-
71
- type BaseSchema = {
72
- type?: string
73
- }
74
-
75
- type Primitive = string | number | boolean;
76
-