@api-client/core 0.5.25 → 0.5.28
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.
- package/build/browser.d.ts +2 -1
- package/build/browser.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.js.map +1 -1
- package/build/src/events/EventTypes.d.ts +16 -0
- package/build/src/events/EventTypes.js +2 -0
- package/build/src/events/EventTypes.js.map +1 -1
- package/build/src/events/Events.d.ts +16 -0
- package/build/src/events/Events.js +2 -0
- package/build/src/events/Events.js.map +1 -1
- package/build/src/events/transport/TransportEventTypes.d.ts +31 -0
- package/build/src/events/transport/TransportEventTypes.js +36 -0
- package/build/src/events/transport/TransportEventTypes.js.map +1 -0
- package/build/src/events/transport/TransportEvents.d.ts +77 -0
- package/build/src/events/transport/TransportEvents.js +91 -0
- package/build/src/events/transport/TransportEvents.js.map +1 -0
- package/build/src/mocking/ProjectMock.d.ts +2 -0
- package/build/src/mocking/ProjectMock.js +3 -0
- package/build/src/mocking/ProjectMock.js.map +1 -1
- package/build/src/mocking/lib/Url.d.ts +12 -0
- package/build/src/mocking/lib/Url.js +31 -0
- package/build/src/mocking/lib/Url.js.map +1 -0
- package/build/src/models/RequestConfig.d.ts +10 -0
- package/build/src/models/RequestConfig.js +13 -1
- package/build/src/models/RequestConfig.js.map +1 -1
- package/build/src/runtime/http-engine/CoreEngine.js +1 -1
- package/build/src/runtime/http-engine/CoreEngine.js.map +1 -1
- package/build/src/runtime/http-engine/HttpEngine.d.ts +12 -0
- package/build/src/runtime/http-engine/HttpEngine.js +34 -0
- package/build/src/runtime/http-engine/HttpEngine.js.map +1 -1
- package/build/src/runtime/node/InteropInterfaces.d.ts +5 -0
- package/build/src/runtime/node/ProjectParallelRunner.d.ts +20 -0
- package/build/src/runtime/node/ProjectParallelRunner.js +69 -1
- package/build/src/runtime/node/ProjectParallelRunner.js.map +1 -1
- package/build/src/runtime/node/ProjectRequestRunner.d.ts +8 -0
- package/build/src/runtime/node/ProjectRequestRunner.js +19 -0
- package/build/src/runtime/node/ProjectRequestRunner.js.map +1 -1
- package/build/src/runtime/node/ProjectRunner.d.ts +25 -0
- package/build/src/runtime/node/ProjectRunner.js +55 -0
- package/build/src/runtime/node/ProjectRunner.js.map +1 -1
- package/build/src/runtime/node/ProjectRunnerWorker.js +3 -0
- package/build/src/runtime/node/ProjectRunnerWorker.js.map +1 -1
- package/build/src/runtime/node/ProjectSerialRunner.js +3 -0
- package/build/src/runtime/node/ProjectSerialRunner.js.map +1 -1
- package/build/src/runtime/node/RequestFactory.d.ts +6 -0
- package/build/src/runtime/node/RequestFactory.js +10 -1
- package/build/src/runtime/node/RequestFactory.js.map +1 -1
- package/build/src/runtime/node/enums.d.ts +8 -0
- package/build/src/runtime/node/enums.js +10 -0
- package/build/src/runtime/node/enums.js.map +1 -0
- package/package.json +1 -1
- package/src/events/EventTypes.ts +2 -0
- package/src/events/Events.ts +2 -0
- package/src/events/transport/TransportEventTypes.ts +37 -0
- package/src/events/transport/TransportEvents.ts +116 -0
- package/src/mocking/ProjectMock.ts +3 -0
- package/src/mocking/lib/Url.ts +35 -0
- package/src/models/RequestConfig.ts +19 -1
- package/src/runtime/http-engine/CoreEngine.ts +1 -1
- package/src/runtime/http-engine/HttpEngine.ts +39 -0
- package/src/runtime/node/InteropInterfaces.ts +6 -0
- package/src/runtime/node/ProjectParallelRunner.ts +75 -1
- package/src/runtime/node/ProjectRequestRunner.ts +22 -0
- package/src/runtime/node/ProjectRunner.ts +63 -0
- package/src/runtime/node/ProjectRunnerWorker.ts +3 -0
- package/src/runtime/node/ProjectSerialRunner.ts +3 -2
- package/src/runtime/node/RequestFactory.ts +11 -1
- package/src/runtime/node/enums.ts +8 -0
|
@@ -59,6 +59,12 @@ export interface IRequestBaseConfig {
|
|
|
59
59
|
* Whether the processor should validate certificates.
|
|
60
60
|
*/
|
|
61
61
|
validateCertificates?: boolean;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Optional signal from an `AbortController`.
|
|
65
|
+
* This is populated only when executing a request. This value is opaque for the data store.
|
|
66
|
+
*/
|
|
67
|
+
signal?: AbortSignal;
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
/**
|
|
@@ -150,6 +156,12 @@ export class RequestConfig {
|
|
|
150
156
|
*/
|
|
151
157
|
sentMessageLimit?: number;
|
|
152
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Optional signal from an `AbortController`.
|
|
161
|
+
* This is populated only when executing a request. This value is opaque for the data store.
|
|
162
|
+
*/
|
|
163
|
+
signal?: AbortSignal;
|
|
164
|
+
|
|
153
165
|
static withDefaults(): RequestConfig {
|
|
154
166
|
return new RequestConfig({
|
|
155
167
|
kind: Kind,
|
|
@@ -209,7 +221,7 @@ export class RequestConfig {
|
|
|
209
221
|
new(init: IRequestConfig): void {
|
|
210
222
|
const {
|
|
211
223
|
enabled, followRedirects, ignoreSessionCookies, validateCertificates, defaultHeaders, timeout, hosts, variables,
|
|
212
|
-
defaultAccept, defaultUserAgent, proxy, proxyPassword, proxyUsername, sentMessageLimit,
|
|
224
|
+
defaultAccept, defaultUserAgent, proxy, proxyPassword, proxyUsername, sentMessageLimit, signal,
|
|
213
225
|
} = init;
|
|
214
226
|
this.kind = Kind;
|
|
215
227
|
if (typeof enabled === 'boolean') {
|
|
@@ -282,6 +294,11 @@ export class RequestConfig {
|
|
|
282
294
|
} else {
|
|
283
295
|
this.sentMessageLimit = undefined;
|
|
284
296
|
}
|
|
297
|
+
if (signal) {
|
|
298
|
+
this.signal = signal;
|
|
299
|
+
} else {
|
|
300
|
+
this.signal = undefined;
|
|
301
|
+
}
|
|
285
302
|
}
|
|
286
303
|
|
|
287
304
|
toJSON(): IRequestConfig {
|
|
@@ -310,6 +327,7 @@ export class RequestConfig {
|
|
|
310
327
|
if (Array.isArray(this.variables)) {
|
|
311
328
|
result.variables = this.variables.map(i => i.toJSON());
|
|
312
329
|
}
|
|
330
|
+
// DO NOT put the `signal` here.
|
|
313
331
|
return result;
|
|
314
332
|
}
|
|
315
333
|
}
|
|
@@ -191,6 +191,31 @@ export abstract class HttpEngine extends EventEmitter {
|
|
|
191
191
|
protected mainRejecter?: (err: SerializableError) => void;
|
|
192
192
|
[mainPromiseSymbol]?: Promise<IRequestLog>;
|
|
193
193
|
|
|
194
|
+
protected _signal?: AbortSignal;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* The abort signal to set on this request.
|
|
198
|
+
* Aborts the request when the signal fires.
|
|
199
|
+
* @type {(AbortSignal | undefined)}
|
|
200
|
+
*/
|
|
201
|
+
get signal(): AbortSignal | undefined {
|
|
202
|
+
return this._signal;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
set signal(value: AbortSignal | undefined) {
|
|
206
|
+
const old = this._signal;
|
|
207
|
+
if (old === value) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
this._signal = value;
|
|
211
|
+
if (old) {
|
|
212
|
+
old.removeEventListener('abort', this._abortHandler);
|
|
213
|
+
}
|
|
214
|
+
if (value) {
|
|
215
|
+
value.addEventListener('abort', this._abortHandler);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
194
219
|
constructor(request: IHttpRequest, opts: HttpEngineOptions = {}) {
|
|
195
220
|
super();
|
|
196
221
|
this.request = new HttpRequest({ ...request });
|
|
@@ -199,6 +224,11 @@ export abstract class HttpEngine extends EventEmitter {
|
|
|
199
224
|
this.sentRequest = new SentRequest({ ...request, startTime: Date.now() });
|
|
200
225
|
this.uri = this.readUrl(request.url);
|
|
201
226
|
this.hostHeader = RequestUtils.getHostHeader(request.url);
|
|
227
|
+
|
|
228
|
+
this._abortHandler = this._abortHandler.bind(this);
|
|
229
|
+
if (opts.signal) {
|
|
230
|
+
this.signal = opts.signal;
|
|
231
|
+
}
|
|
202
232
|
}
|
|
203
233
|
|
|
204
234
|
/**
|
|
@@ -245,6 +275,15 @@ export abstract class HttpEngine extends EventEmitter {
|
|
|
245
275
|
this.socket = undefined;
|
|
246
276
|
}
|
|
247
277
|
|
|
278
|
+
/**
|
|
279
|
+
* Handler for the `abort` event on the `AbortSignal`.
|
|
280
|
+
*/
|
|
281
|
+
protected _abortHandler(): void {
|
|
282
|
+
const e = new SerializableError('Request aborted', 3);
|
|
283
|
+
this._errorRequest(e);
|
|
284
|
+
this.abort();
|
|
285
|
+
}
|
|
286
|
+
|
|
248
287
|
/**
|
|
249
288
|
* Sends the request.
|
|
250
289
|
*/
|
|
@@ -118,4 +118,10 @@ export interface IProjectRunnerOptions {
|
|
|
118
118
|
* When not set it does not read system variables.
|
|
119
119
|
*/
|
|
120
120
|
variables?: boolean | string[] | Record<string, string>;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Optional signal from an `AbortController`.
|
|
124
|
+
* It aborts the execution when the ``abort` event is dispatched.
|
|
125
|
+
*/
|
|
126
|
+
signal?: AbortSignal;
|
|
121
127
|
}
|
|
@@ -5,6 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
import { HttpProject } from '../../models/HttpProject.js';
|
|
6
6
|
import { IProjectExecutionLog, IProjectExecutionIteration } from '../reporters/Reporter.js';
|
|
7
7
|
import { BaseRunner } from './BaseRunner.js';
|
|
8
|
+
import { State } from './enums.js';
|
|
8
9
|
import { IProjectParallelRunnerOptions, IProjectParallelWorkerOptions } from './InteropInterfaces.js'
|
|
9
10
|
|
|
10
11
|
const numCPUs = cpus().length;
|
|
@@ -74,9 +75,13 @@ export class ProjectParallelRunner extends BaseRunner {
|
|
|
74
75
|
constructor(project: HttpProject, opts: IProjectParallelRunnerOptions = {}) {
|
|
75
76
|
super();
|
|
76
77
|
this.project = project;
|
|
77
|
-
this.options = opts
|
|
78
|
+
this.options = opts;
|
|
78
79
|
|
|
79
80
|
this._exitHandler = this._exitHandler.bind(this);
|
|
81
|
+
this._abortHandler = this._abortHandler.bind(this);
|
|
82
|
+
if (opts.signal) {
|
|
83
|
+
this.signal = opts.signal;
|
|
84
|
+
}
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
execute(): Promise<IProjectExecutionLog> {
|
|
@@ -87,7 +92,70 @@ export class ProjectParallelRunner extends BaseRunner {
|
|
|
87
92
|
});
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
protected _state: State = State.Idle;
|
|
96
|
+
|
|
97
|
+
get state(): State {
|
|
98
|
+
return this._state;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
protected _signal?: AbortSignal;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The abort signal to set on this request.
|
|
105
|
+
* Aborts the request when the signal fires.
|
|
106
|
+
* @type {(AbortSignal | undefined)}
|
|
107
|
+
*/
|
|
108
|
+
get signal(): AbortSignal | undefined {
|
|
109
|
+
return this._signal;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
set signal(value: AbortSignal | undefined) {
|
|
113
|
+
const old = this._signal;
|
|
114
|
+
if (old === value) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
this._signal = value;
|
|
118
|
+
if (old) {
|
|
119
|
+
old.removeEventListener('abort', this._abortHandler);
|
|
120
|
+
}
|
|
121
|
+
if (value) {
|
|
122
|
+
value.addEventListener('abort', this._abortHandler);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Aborts the current run.
|
|
128
|
+
* The promise returned by the `execute()` method will reject if not yet resolved.
|
|
129
|
+
*/
|
|
130
|
+
abort(): void {
|
|
131
|
+
this._state = State.Aborted;
|
|
132
|
+
const { workers } = this;
|
|
133
|
+
workers.forEach((info) => {
|
|
134
|
+
if (info.status !== 'error') {
|
|
135
|
+
try {
|
|
136
|
+
info.worker.destroy();
|
|
137
|
+
} catch (e) {
|
|
138
|
+
// ...
|
|
139
|
+
}
|
|
140
|
+
info.status = 'error';
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
if (this.mainRejecter) {
|
|
144
|
+
this.mainRejecter!(new Error(`The execution has been aborted.`));
|
|
145
|
+
this.mainRejecter = undefined;
|
|
146
|
+
this.mainResolver = undefined;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Handler for the `abort` event on the `AbortSignal`.
|
|
152
|
+
*/
|
|
153
|
+
protected _abortHandler(): void {
|
|
154
|
+
this.abort();
|
|
155
|
+
}
|
|
156
|
+
|
|
90
157
|
private _execute(): void {
|
|
158
|
+
this._state = State.Running as State;
|
|
91
159
|
try {
|
|
92
160
|
cluster.setupPrimary({
|
|
93
161
|
exec: join(__dirname, 'ProjectRunnerWorker.js'),
|
|
@@ -105,6 +173,9 @@ export class ProjectParallelRunner extends BaseRunner {
|
|
|
105
173
|
} catch (e) {
|
|
106
174
|
const cause = e as Error;
|
|
107
175
|
this.mainRejecter!(cause);
|
|
176
|
+
this.mainResolver = undefined
|
|
177
|
+
this.mainRejecter = undefined
|
|
178
|
+
this._state = State.Idle as State;
|
|
108
179
|
}
|
|
109
180
|
}
|
|
110
181
|
|
|
@@ -211,7 +282,10 @@ export class ProjectParallelRunner extends BaseRunner {
|
|
|
211
282
|
this.endTime = Date.now();
|
|
212
283
|
const report = await this.createReport();
|
|
213
284
|
this.mainResolver(report);
|
|
285
|
+
this.mainResolver = undefined
|
|
286
|
+
this.mainRejecter = undefined
|
|
214
287
|
cluster.off('exit', this._exitHandler);
|
|
288
|
+
this._state = State.Idle as State;
|
|
215
289
|
}
|
|
216
290
|
|
|
217
291
|
private setRunError(worker: Worker, message: IWorkerMessage): void {
|
|
@@ -14,6 +14,7 @@ import { VariablesProcessor } from '../variables/VariablesProcessor.js';
|
|
|
14
14
|
import { RequestFactory } from './RequestFactory.js';
|
|
15
15
|
import { EventTypes } from '../../events/EventTypes.js';
|
|
16
16
|
import { ProjectRunnerOptions, ProjectRunnerRunOptions, RunResult } from './InteropInterfaces.js';
|
|
17
|
+
import { State } from './enums.js';
|
|
17
18
|
|
|
18
19
|
export interface ProjectRequestRunner {
|
|
19
20
|
/**
|
|
@@ -62,6 +63,12 @@ export class ProjectRequestRunner extends EventEmitter {
|
|
|
62
63
|
*/
|
|
63
64
|
protected variablesProcessor = new VariablesProcessor();
|
|
64
65
|
|
|
66
|
+
protected _state: State = State.Idle;
|
|
67
|
+
|
|
68
|
+
get state(): State {
|
|
69
|
+
return this._state;
|
|
70
|
+
}
|
|
71
|
+
|
|
65
72
|
constructor(project: HttpProject, opts: ProjectRunnerOptions = {}) {
|
|
66
73
|
super();
|
|
67
74
|
this.project = project;
|
|
@@ -77,15 +84,25 @@ export class ProjectRequestRunner extends EventEmitter {
|
|
|
77
84
|
* @returns A promise with the run result.
|
|
78
85
|
*/
|
|
79
86
|
async run(options?: ProjectRunnerRunOptions): Promise<RunResult[]> {
|
|
87
|
+
this._state = State.Running as State;
|
|
80
88
|
const { project } = this;
|
|
81
89
|
const executed: RunResult[] = [];
|
|
82
90
|
for (const request of project.requestIterator(options)) {
|
|
83
91
|
const info = await this._runItem(request);
|
|
84
92
|
executed.push(info);
|
|
85
93
|
}
|
|
94
|
+
this._state = State.Idle;
|
|
86
95
|
return executed;
|
|
87
96
|
}
|
|
88
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Aborts the current run.
|
|
100
|
+
* The promise returned by the `run()` method will reject if not yet resolved.
|
|
101
|
+
*/
|
|
102
|
+
abort(): void {
|
|
103
|
+
this._state = State.Aborted;
|
|
104
|
+
}
|
|
105
|
+
|
|
89
106
|
/**
|
|
90
107
|
* Allows to iterate over project requests recursively and execute each request
|
|
91
108
|
* in order. The generator yields the `RunResult` for the request.
|
|
@@ -101,13 +118,18 @@ export class ProjectRequestRunner extends EventEmitter {
|
|
|
101
118
|
*/
|
|
102
119
|
async* [Symbol.asyncIterator](): AsyncGenerator<RunResult> {
|
|
103
120
|
const { project } = this;
|
|
121
|
+
this._state = State.Running as State;
|
|
104
122
|
for (const request of project.requestIterator({ recursive: true })) {
|
|
105
123
|
const info = await this._runItem(request);
|
|
106
124
|
yield info;
|
|
107
125
|
}
|
|
126
|
+
this._state = State.Idle;
|
|
108
127
|
}
|
|
109
128
|
|
|
110
129
|
private async _runItem(request: ProjectRequest): Promise<RunResult> {
|
|
130
|
+
if (this._state === State.Aborted) {
|
|
131
|
+
throw new Error(`The execution has been aborted.`);
|
|
132
|
+
}
|
|
111
133
|
const folder = request.getParent();
|
|
112
134
|
const parent = folder || this.project;
|
|
113
135
|
let variables: Record<string, string>;
|
|
@@ -10,6 +10,7 @@ import { IProjectExecutionIteration, IProjectExecutionLog } from '../reporters/R
|
|
|
10
10
|
import { pathExists, readJson } from '../../lib/fs/Fs.js';
|
|
11
11
|
import { BaseRunner } from './BaseRunner.js';
|
|
12
12
|
import { IProjectRunnerOptions } from './InteropInterfaces.js';
|
|
13
|
+
import { State } from './enums.js';
|
|
13
14
|
|
|
14
15
|
type ProjectParent = HttpProject | ProjectFolder;
|
|
15
16
|
|
|
@@ -127,11 +128,48 @@ export abstract class ProjectRunner extends BaseRunner {
|
|
|
127
128
|
*/
|
|
128
129
|
noEmit = false;
|
|
129
130
|
|
|
131
|
+
/**
|
|
132
|
+
* When executing, this is the last user request runner.
|
|
133
|
+
*/
|
|
134
|
+
protected _runner?: ProjectRequestRunner;
|
|
135
|
+
|
|
136
|
+
protected _state: State = State.Idle;
|
|
137
|
+
|
|
138
|
+
get state(): State {
|
|
139
|
+
return this._state;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
protected _signal?: AbortSignal;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The abort signal to set on this request.
|
|
146
|
+
* Aborts the request when the signal fires.
|
|
147
|
+
* @type {(AbortSignal | undefined)}
|
|
148
|
+
*/
|
|
149
|
+
get signal(): AbortSignal | undefined {
|
|
150
|
+
return this._signal;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
set signal(value: AbortSignal | undefined) {
|
|
154
|
+
const old = this._signal;
|
|
155
|
+
if (old === value) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
this._signal = value;
|
|
159
|
+
if (old) {
|
|
160
|
+
old.removeEventListener('abort', this._abortHandler);
|
|
161
|
+
}
|
|
162
|
+
if (value) {
|
|
163
|
+
value.addEventListener('abort', this._abortHandler);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
130
167
|
constructor() {
|
|
131
168
|
super();
|
|
132
169
|
this._requestHandler = this._requestHandler.bind(this);
|
|
133
170
|
this._responseHandler = this._responseHandler.bind(this);
|
|
134
171
|
this._errorHandler = this._errorHandler.bind(this);
|
|
172
|
+
this._abortHandler = this._abortHandler.bind(this);
|
|
135
173
|
}
|
|
136
174
|
|
|
137
175
|
/**
|
|
@@ -152,6 +190,9 @@ export abstract class ProjectRunner extends BaseRunner {
|
|
|
152
190
|
}
|
|
153
191
|
this.root = root;
|
|
154
192
|
this.environment = await this.getEnvironment();
|
|
193
|
+
if (opts.signal) {
|
|
194
|
+
this.signal = opts.signal;
|
|
195
|
+
}
|
|
155
196
|
}
|
|
156
197
|
|
|
157
198
|
/**
|
|
@@ -160,6 +201,24 @@ export abstract class ProjectRunner extends BaseRunner {
|
|
|
160
201
|
*/
|
|
161
202
|
abstract execute(): Promise<IProjectExecutionLog>;
|
|
162
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Aborts the current run.
|
|
206
|
+
* The promise returned by the `execute()` method will reject if not yet resolved.
|
|
207
|
+
*/
|
|
208
|
+
abort(): void {
|
|
209
|
+
this._state = State.Aborted;
|
|
210
|
+
if (this._runner) {
|
|
211
|
+
this._runner.abort();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Handler for the `abort` event on the `AbortSignal`.
|
|
217
|
+
*/
|
|
218
|
+
protected _abortHandler(): void {
|
|
219
|
+
this.abort();
|
|
220
|
+
}
|
|
221
|
+
|
|
163
222
|
/**
|
|
164
223
|
* Creates the report of the execution.
|
|
165
224
|
*/
|
|
@@ -207,6 +266,9 @@ export abstract class ProjectRunner extends BaseRunner {
|
|
|
207
266
|
* Runs the requests from the project as configured.
|
|
208
267
|
*/
|
|
209
268
|
protected async executeIteration(): Promise<void> {
|
|
269
|
+
if (this._state === State.Aborted) {
|
|
270
|
+
throw new Error(`The execution has been aborted.`);
|
|
271
|
+
}
|
|
210
272
|
const { environment, project, options, hasIterations, index, noEmit } = this;
|
|
211
273
|
if (!options || !project) {
|
|
212
274
|
throw new Error(`Run configure() first.`);
|
|
@@ -221,6 +283,7 @@ export abstract class ProjectRunner extends BaseRunner {
|
|
|
221
283
|
eventTarget: this.target,
|
|
222
284
|
variables: this.getSystemVariables(),
|
|
223
285
|
});
|
|
286
|
+
this._runner = runner;
|
|
224
287
|
|
|
225
288
|
runner.on('request', this._requestHandler);
|
|
226
289
|
runner.on('response', this._responseHandler);
|
|
@@ -7,6 +7,7 @@ import { IWorkerMessage } from './ProjectParallelRunner.js';
|
|
|
7
7
|
import { IProjectParallelWorkerOptions } from './InteropInterfaces.js';
|
|
8
8
|
import { sleep } from '../../lib/timers/Timers.js';
|
|
9
9
|
import { ProjectRunner } from './ProjectRunner.js';
|
|
10
|
+
import { State } from './enums.js';
|
|
10
11
|
|
|
11
12
|
class ProjectExeWorker extends ProjectRunner {
|
|
12
13
|
initialize(): void {
|
|
@@ -40,6 +41,7 @@ class ProjectExeWorker extends ProjectRunner {
|
|
|
40
41
|
}
|
|
41
42
|
function unhandledRejection(): void {}
|
|
42
43
|
process.on('unhandledRejection', unhandledRejection);
|
|
44
|
+
this._state = State.Running as State;
|
|
43
45
|
this.startTime = Date.now();
|
|
44
46
|
while (this.remaining > 0) {
|
|
45
47
|
this.remaining--;
|
|
@@ -54,6 +56,7 @@ class ProjectExeWorker extends ProjectRunner {
|
|
|
54
56
|
|
|
55
57
|
const log = await this.createReport();
|
|
56
58
|
process.send!({ cmd: 'result', data: log.iterations });
|
|
59
|
+
this._state = State.Idle as State;
|
|
57
60
|
return log;
|
|
58
61
|
}
|
|
59
62
|
}
|
|
@@ -2,6 +2,7 @@ import { SerializableError } from '../../models/SerializableError.js';
|
|
|
2
2
|
import { sleep } from '../../lib/timers/Timers.js';
|
|
3
3
|
import { ProjectRunner } from './ProjectRunner.js';
|
|
4
4
|
import { IProjectExecutionLog } from '../reporters/Reporter.js';
|
|
5
|
+
import { State } from './enums.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Project runner that runs the requests in the project one-by-one.
|
|
@@ -15,7 +16,7 @@ export class ProjectSerialRunner extends ProjectRunner {
|
|
|
15
16
|
if (!root) {
|
|
16
17
|
throw new SerializableError(`The project runner is not configured.`, 'ECONFIGURE');
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
+
this._state = State.Running as State;
|
|
19
20
|
this.startTime = Date.now();
|
|
20
21
|
while (this.remaining > 0) {
|
|
21
22
|
this.remaining--;
|
|
@@ -29,7 +30,7 @@ export class ProjectSerialRunner extends ProjectRunner {
|
|
|
29
30
|
await sleep(0);
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
+
this._state = State.Idle as State;
|
|
33
34
|
this.endTime = Date.now();
|
|
34
35
|
return this.createReport();
|
|
35
36
|
}
|
|
@@ -73,6 +73,13 @@ export class RequestFactory {
|
|
|
73
73
|
|
|
74
74
|
logger?: Logger;
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* The abort signal to set on this request.
|
|
78
|
+
* Aborts the request when the signal fires.
|
|
79
|
+
* @type {(AbortSignal | undefined)}
|
|
80
|
+
*/
|
|
81
|
+
signal?: AbortSignal;
|
|
82
|
+
|
|
76
83
|
/**
|
|
77
84
|
* Creates an instance from the IRequest object with setting the corresponding variables.
|
|
78
85
|
* @param eventTarget The main events bus.
|
|
@@ -302,7 +309,7 @@ export class RequestFactory {
|
|
|
302
309
|
* Creates a configuration options for the HTTP engine.
|
|
303
310
|
*/
|
|
304
311
|
async prepareEngineConfig(): Promise<HttpEngineOptions> {
|
|
305
|
-
const { certificates, logger } = this;
|
|
312
|
+
const { certificates, logger, signal } = this;
|
|
306
313
|
const auth = await this.readAuthorization();
|
|
307
314
|
const config = await this.readConfig();
|
|
308
315
|
const opts: HttpEngineOptions = {};
|
|
@@ -315,6 +322,9 @@ export class RequestFactory {
|
|
|
315
322
|
if (logger) {
|
|
316
323
|
opts.logger = logger;
|
|
317
324
|
}
|
|
325
|
+
if (signal) {
|
|
326
|
+
opts.signal = signal;
|
|
327
|
+
}
|
|
318
328
|
if (!config || config.enabled === false) {
|
|
319
329
|
return opts;
|
|
320
330
|
}
|