teraslice 3.3.0 → 3.3.2

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 (108) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +25 -28
  3. package/dist/src/interfaces.js +0 -12
  4. package/dist/src/lib/cluster/cluster_master.js +0 -246
  5. package/dist/src/lib/cluster/node_master.js +0 -355
  6. package/dist/src/lib/cluster/services/api.js +0 -663
  7. package/dist/src/lib/cluster/services/assets.js +0 -224
  8. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/index.js +0 -192
  9. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/interfaces.js +0 -2
  10. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8s.js +0 -419
  11. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sDeploymentResource.js +0 -60
  12. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sJobResource.js +0 -55
  13. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sResource.js +0 -357
  14. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sServiceResource.js +0 -37
  15. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sState.js +0 -60
  16. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/utils.js +0 -170
  17. package/dist/src/lib/cluster/services/cluster/backends/native/dispatch.js +0 -13
  18. package/dist/src/lib/cluster/services/cluster/backends/native/index.js +0 -526
  19. package/dist/src/lib/cluster/services/cluster/backends/native/messaging.js +0 -548
  20. package/dist/src/lib/cluster/services/cluster/backends/state-utils.js +0 -26
  21. package/dist/src/lib/cluster/services/cluster/index.js +0 -13
  22. package/dist/src/lib/cluster/services/execution.js +0 -435
  23. package/dist/src/lib/cluster/services/index.js +0 -6
  24. package/dist/src/lib/cluster/services/interfaces.js +0 -2
  25. package/dist/src/lib/cluster/services/jobs.js +0 -458
  26. package/dist/src/lib/config/default-sysconfig.js +0 -25
  27. package/dist/src/lib/config/index.js +0 -20
  28. package/dist/src/lib/config/schemas/system.js +0 -360
  29. package/dist/src/lib/storage/analytics.js +0 -86
  30. package/dist/src/lib/storage/assets.js +0 -401
  31. package/dist/src/lib/storage/backends/elasticsearch_store.js +0 -496
  32. package/dist/src/lib/storage/backends/mappings/analytics.js +0 -20
  33. package/dist/src/lib/storage/backends/mappings/asset.js +0 -32
  34. package/dist/src/lib/storage/backends/mappings/ex.js +0 -53
  35. package/dist/src/lib/storage/backends/mappings/job.js +0 -42
  36. package/dist/src/lib/storage/backends/mappings/state.js +0 -16
  37. package/dist/src/lib/storage/backends/s3_store.js +0 -237
  38. package/dist/src/lib/storage/execution.js +0 -302
  39. package/dist/src/lib/storage/index.js +0 -7
  40. package/dist/src/lib/storage/jobs.js +0 -81
  41. package/dist/src/lib/storage/state.js +0 -254
  42. package/dist/src/lib/utils/api_utils.js +0 -128
  43. package/dist/src/lib/utils/asset_utils.js +0 -94
  44. package/dist/src/lib/utils/date_utils.js +0 -52
  45. package/dist/src/lib/utils/encoding_utils.js +0 -27
  46. package/dist/src/lib/utils/events.js +0 -4
  47. package/dist/src/lib/utils/file_utils.js +0 -124
  48. package/dist/src/lib/utils/id_utils.js +0 -15
  49. package/dist/src/lib/utils/port_utils.js +0 -32
  50. package/dist/src/lib/workers/assets/index.js +0 -3
  51. package/dist/src/lib/workers/assets/loader-executable.js +0 -40
  52. package/dist/src/lib/workers/assets/loader.js +0 -73
  53. package/dist/src/lib/workers/assets/spawn.js +0 -55
  54. package/dist/src/lib/workers/context/execution-context.js +0 -12
  55. package/dist/src/lib/workers/context/terafoundation-context.js +0 -8
  56. package/dist/src/lib/workers/execution-controller/execution-analytics.js +0 -188
  57. package/dist/src/lib/workers/execution-controller/index.js +0 -1024
  58. package/dist/src/lib/workers/execution-controller/recovery.js +0 -151
  59. package/dist/src/lib/workers/execution-controller/scheduler.js +0 -390
  60. package/dist/src/lib/workers/execution-controller/slice-analytics.js +0 -96
  61. package/dist/src/lib/workers/helpers/job.js +0 -80
  62. package/dist/src/lib/workers/helpers/op-analytics.js +0 -22
  63. package/dist/src/lib/workers/helpers/terafoundation.js +0 -34
  64. package/dist/src/lib/workers/helpers/worker-shutdown.js +0 -147
  65. package/dist/src/lib/workers/metrics/index.js +0 -108
  66. package/dist/src/lib/workers/worker/index.js +0 -378
  67. package/dist/src/lib/workers/worker/slice.js +0 -122
  68. package/dist/test/config/schemas/system_schema-spec.js +0 -26
  69. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8s-v2-spec.js +0 -458
  70. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sResource-v2-spec.js +0 -818
  71. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-multicluster-v2-spec.js +0 -67
  72. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-v2-spec.js +0 -84
  73. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/utils-v2-spec.js +0 -320
  74. package/dist/test/lib/cluster/services/cluster/backends/state-utils-spec.js +0 -37
  75. package/dist/test/node_master-spec.js +0 -194
  76. package/dist/test/services/api-spec.js +0 -79
  77. package/dist/test/services/assets-spec.js +0 -158
  78. package/dist/test/services/messaging-spec.js +0 -440
  79. package/dist/test/storage/assets_storage-spec.js +0 -95
  80. package/dist/test/storage/s3_store-spec.js +0 -149
  81. package/dist/test/test.config.js +0 -23
  82. package/dist/test/test.setup.js +0 -6
  83. package/dist/test/utils/api_utils-spec.js +0 -25
  84. package/dist/test/utils/asset_utils-spec.js +0 -141
  85. package/dist/test/utils/elastic_utils-spec.js +0 -25
  86. package/dist/test/workers/execution-controller/execution-controller-spec.js +0 -371
  87. package/dist/test/workers/execution-controller/execution-special-test-cases-spec.js +0 -519
  88. package/dist/test/workers/execution-controller/execution-test-cases-spec.js +0 -343
  89. package/dist/test/workers/execution-controller/recovery-spec.js +0 -160
  90. package/dist/test/workers/execution-controller/scheduler-spec.js +0 -249
  91. package/dist/test/workers/execution-controller/slice-analytics-spec.js +0 -121
  92. package/dist/test/workers/fixtures/ops/example-op/processor.js +0 -20
  93. package/dist/test/workers/fixtures/ops/example-op/schema.js +0 -19
  94. package/dist/test/workers/fixtures/ops/example-reader/fetcher.js +0 -20
  95. package/dist/test/workers/fixtures/ops/example-reader/schema.js +0 -41
  96. package/dist/test/workers/fixtures/ops/example-reader/slicer.js +0 -37
  97. package/dist/test/workers/fixtures/ops/new-op/processor.js +0 -29
  98. package/dist/test/workers/fixtures/ops/new-op/schema.js +0 -18
  99. package/dist/test/workers/fixtures/ops/new-reader/fetcher.js +0 -19
  100. package/dist/test/workers/fixtures/ops/new-reader/schema.js +0 -23
  101. package/dist/test/workers/fixtures/ops/new-reader/slicer.js +0 -13
  102. package/dist/test/workers/helpers/configs.js +0 -128
  103. package/dist/test/workers/helpers/execution-controller-helper.js +0 -49
  104. package/dist/test/workers/helpers/index.js +0 -5
  105. package/dist/test/workers/helpers/test-context.js +0 -210
  106. package/dist/test/workers/helpers/zip-directory.js +0 -25
  107. package/dist/test/workers/worker/slice-spec.js +0 -333
  108. package/dist/test/workers/worker/worker-spec.js +0 -356
@@ -1,333 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import { times } from '@terascope/core-utils';
3
- import { SliceExecution } from '../../../src/lib/workers/worker/slice.js';
4
- import { TestContext } from '../helpers/index.js';
5
- describe('Slice', () => {
6
- async function setupSlice(testContext, eventMocks = {}) {
7
- await testContext.initialize();
8
- await testContext.executionContext.initialize();
9
- const [stateStore, analyticsStore] = await Promise.all([
10
- testContext.addStateStore(),
11
- testContext.addAnalyticsStore(),
12
- ]);
13
- const slice = new SliceExecution(testContext.context, testContext.executionContext, stateStore, analyticsStore);
14
- testContext.attachCleanup(() => slice.shutdown());
15
- const sliceConfig = await testContext.newSlice();
16
- await slice.initialize(sliceConfig);
17
- eventMocks['slice:success'] = jest.fn();
18
- eventMocks['slice:finalize'] = jest.fn();
19
- eventMocks['slice:failure'] = jest.fn();
20
- eventMocks['slice:retry'] = jest.fn();
21
- Object.keys(eventMocks).forEach((name) => {
22
- const mock = eventMocks[name];
23
- slice.events.on(name, mock);
24
- });
25
- return slice;
26
- }
27
- describe('with analytics', () => {
28
- describe('when the slice succeeds', () => {
29
- let slice;
30
- let results;
31
- let testContext;
32
- const eventMocks = {};
33
- beforeEach(async () => {
34
- testContext = new TestContext({ analytics: true });
35
- slice = await setupSlice(testContext, eventMocks);
36
- results = await slice.run();
37
- await Promise.all([
38
- slice.stateStorage.refresh(),
39
- slice.analyticsStorage.refresh(),
40
- ]);
41
- });
42
- afterEach(async () => {
43
- await testContext.cleanup();
44
- });
45
- it('should handle the slice correctly', () => {
46
- // should call of the operations
47
- expect(results).toEqual(times(10, () => ({ hi: true })));
48
- // should have the correct analytics data
49
- expect(slice.analyticsData).toBeObject();
50
- expect(slice.analyticsData.memory).toBeArrayOfSize(2);
51
- expect(slice.analyticsData.size).toBeArrayOfSize(2);
52
- expect(slice.analyticsData.time).toBeArrayOfSize(2);
53
- // should call the correct events
54
- expect(eventMocks['slice:success']).toHaveBeenCalledTimes(1);
55
- expect(eventMocks['slice:success']).toHaveBeenCalled();
56
- expect(eventMocks['slice:finalize']).toHaveBeenCalledTimes(1);
57
- expect(eventMocks['slice:finalize']).toHaveBeenCalled();
58
- expect(eventMocks['slice:failure']).not.toHaveBeenCalled();
59
- expect(eventMocks['slice:retry']).not.toHaveBeenCalled();
60
- // should have the correct state storage
61
- const { exId } = slice.executionContext;
62
- const query = `ex_id:${exId} AND state:completed`;
63
- return expect(slice.stateStorage.count(query)).resolves.toEqual(1);
64
- });
65
- });
66
- });
67
- describe('without analytics', () => {
68
- describe('when the slice succeeds', () => {
69
- let slice;
70
- let results;
71
- let testContext;
72
- const eventMocks = {};
73
- beforeEach(async () => {
74
- testContext = new TestContext({ analytics: false });
75
- slice = await setupSlice(testContext, eventMocks);
76
- results = await slice.run();
77
- await Promise.all([
78
- slice.stateStorage.refresh(),
79
- slice.analyticsStorage.refresh(),
80
- ]);
81
- });
82
- afterEach(async () => {
83
- await testContext.cleanup();
84
- });
85
- it('should handle the slice correctly', () => {
86
- // should call all of the operations
87
- expect(results).toEqual(times(10, () => ({ hi: true })));
88
- // should have have the analytics data
89
- expect(slice.analyticsData).toBeUndefined();
90
- // should call the correct events
91
- expect(eventMocks['slice:success']).toHaveBeenCalledTimes(1);
92
- expect(eventMocks['slice:success']).toHaveBeenCalled();
93
- expect(eventMocks['slice:finalize']).toHaveBeenCalledTimes(1);
94
- expect(eventMocks['slice:finalize']).toHaveBeenCalled();
95
- expect(eventMocks['slice:retry']).not.toHaveBeenCalled();
96
- expect(eventMocks['slice:failure']).not.toHaveBeenCalled();
97
- // should have the correct state storage
98
- const { exId } = slice.executionContext;
99
- const query = `ex_id:${exId} AND state:completed`;
100
- return expect(slice.stateStorage.count(query, 0)).resolves.toEqual(1);
101
- });
102
- });
103
- describe('when the slice retries', () => {
104
- let slice;
105
- let results;
106
- let testContext;
107
- const eventMocks = {};
108
- beforeEach(async () => {
109
- testContext = new TestContext({
110
- maxRetries: 3,
111
- analytics: false,
112
- readerErrorAt: [0]
113
- });
114
- slice = await setupSlice(testContext, eventMocks);
115
- results = await slice.run();
116
- await Promise.all([
117
- slice.stateStorage.refresh(),
118
- slice.analyticsStorage.refresh(),
119
- ]);
120
- });
121
- afterEach(async () => {
122
- await testContext.cleanup();
123
- });
124
- it('should handle the slice correctly', () => {
125
- expect(results).toEqual(times(10, () => ({ hi: true })));
126
- // should have have the analytics data
127
- expect(slice.analyticsData).toBeUndefined();
128
- // should call the correct events
129
- expect(eventMocks['slice:retry']).toHaveBeenCalledTimes(1);
130
- expect(eventMocks['slice:retry']).toHaveBeenCalledWith(slice.slice);
131
- expect(eventMocks['slice:success']).toHaveBeenCalledTimes(1);
132
- expect(eventMocks['slice:success']).toHaveBeenCalledWith(slice.slice);
133
- expect(eventMocks['slice:finalize']).toHaveBeenCalledTimes(1);
134
- expect(eventMocks['slice:finalize']).toHaveBeenCalledWith(slice.slice);
135
- expect(eventMocks['slice:failure']).not.toHaveBeenCalled();
136
- // should have the correct state storage
137
- const { exId } = slice.executionContext;
138
- const query = `ex_id:${exId} AND state:completed`;
139
- return expect(slice.stateStorage.count(query, 0)).resolves.toEqual(1);
140
- });
141
- });
142
- describe('when the slice fails to retry', () => {
143
- let slice;
144
- let err;
145
- let testContext;
146
- const eventMocks = {};
147
- beforeEach(async () => {
148
- testContext = new TestContext({
149
- maxRetries: 3,
150
- analytics: false,
151
- newOps: true,
152
- failOnSliceRetry: true
153
- });
154
- slice = await setupSlice(testContext, eventMocks);
155
- try {
156
- await slice.run();
157
- }
158
- catch (_err) {
159
- err = _err;
160
- }
161
- await Promise.all([
162
- slice.stateStorage.refresh(),
163
- slice.analyticsStorage.refresh(),
164
- ]);
165
- });
166
- afterEach(async () => {
167
- await testContext.cleanup();
168
- });
169
- it('should handle the slice correctly', () => {
170
- // should have reject with the error
171
- expect(err).toBeDefined();
172
- const errMsg = err.toString();
173
- expect(errMsg).toInclude('Slice failed to retry');
174
- expect(errMsg).toInclude('I will not allow it');
175
- // should emit the events
176
- expect(eventMocks['slice:retry']).toHaveBeenCalledTimes(1);
177
- expect(eventMocks['slice:retry']).toHaveBeenCalledWith(slice.slice);
178
- expect(eventMocks['slice:failure']).toHaveBeenCalledTimes(1);
179
- expect(eventMocks['slice:failure']).toHaveBeenCalledWith(slice.slice);
180
- expect(eventMocks['slice:success']).not.toHaveBeenCalled();
181
- expect(eventMocks['slice:finalize']).toHaveBeenCalledTimes(1);
182
- expect(eventMocks['slice:finalize']).toHaveBeenCalledWith(slice.slice);
183
- // should have the correct state storage
184
- const { exId } = slice.executionContext;
185
- const query = `ex_id:${exId} AND state:error`;
186
- return expect(slice.stateStorage.count(query, 0)).resolves.toEqual(1);
187
- });
188
- });
189
- describe('when the slice fails', () => {
190
- let slice;
191
- let testContext;
192
- const eventMocks = {};
193
- let err;
194
- beforeEach(async () => {
195
- testContext = new TestContext({
196
- maxRetries: 5,
197
- analytics: false,
198
- opErrorAt: times(6)
199
- });
200
- slice = await setupSlice(testContext, eventMocks);
201
- try {
202
- await slice.run();
203
- }
204
- catch (_err) {
205
- err = _err;
206
- }
207
- await Promise.all([
208
- slice.stateStorage.refresh(),
209
- slice.analyticsStorage.refresh(),
210
- ]);
211
- });
212
- afterEach(async () => {
213
- await testContext.cleanup();
214
- });
215
- it('should handle the slice correctly', () => {
216
- // should have reject with the error
217
- expect(err).toBeDefined();
218
- expect(err.toString()).toStartWith('TSError: Slice failed processing, caused by TSError: Bad news bears');
219
- // should emit the events
220
- expect(eventMocks['slice:retry']).toHaveBeenCalledTimes(5);
221
- expect(eventMocks['slice:retry']).toHaveBeenCalledWith(slice.slice);
222
- expect(eventMocks['slice:failure']).toHaveBeenCalledTimes(1);
223
- expect(eventMocks['slice:failure']).toHaveBeenCalledWith(slice.slice);
224
- expect(eventMocks['slice:success']).not.toHaveBeenCalled();
225
- expect(eventMocks['slice:finalize']).toHaveBeenCalledTimes(1);
226
- expect(eventMocks['slice:finalize']).toHaveBeenCalledWith(slice.slice);
227
- // should have the correct state storage
228
- const { exId } = slice.executionContext;
229
- const query = `ex_id:${exId} AND state:error`;
230
- return expect(slice.stateStorage.count(query, 0)).resolves.toEqual(1);
231
- });
232
- });
233
- describe('when the slice fails with zero retries', () => {
234
- let slice;
235
- let testContext;
236
- const eventMocks = {};
237
- let err;
238
- beforeEach(async () => {
239
- testContext = new TestContext({
240
- maxRetries: 0,
241
- analytics: false,
242
- opErrorAt: times(5)
243
- });
244
- slice = await setupSlice(testContext, eventMocks);
245
- try {
246
- await slice.run();
247
- }
248
- catch (_err) {
249
- err = _err;
250
- }
251
- await Promise.all([
252
- slice.stateStorage.refresh(),
253
- slice.analyticsStorage.refresh(),
254
- ]);
255
- });
256
- afterEach(async () => {
257
- await testContext.cleanup();
258
- });
259
- it('should handle the slice correctly', () => {
260
- // should have reject with the error
261
- expect(err).toBeDefined();
262
- expect(err.toString()).toStartWith('TSError: Slice failed processing, caused by TSError: Bad news bears');
263
- // should emit the events
264
- expect(eventMocks['slice:retry']).not.toHaveBeenCalled();
265
- expect(eventMocks['slice:failure']).toHaveBeenCalledTimes(1);
266
- expect(eventMocks['slice:failure']).toHaveBeenCalledWith(slice.slice);
267
- expect(eventMocks['slice:success']).not.toHaveBeenCalled();
268
- expect(eventMocks['slice:finalize']).toHaveBeenCalledTimes(1);
269
- expect(eventMocks['slice:finalize']).toHaveBeenCalledWith(slice.slice);
270
- // should have the correct state storage
271
- const { exId } = slice.executionContext;
272
- const query = `ex_id:${exId} AND state:error`;
273
- return expect(slice.stateStorage.count(query, 0)).resolves.toEqual(1);
274
- });
275
- });
276
- });
277
- describe('when logging the analytics state', () => {
278
- describe('when given invalid state', () => {
279
- let testContext;
280
- let slice;
281
- beforeEach(async () => {
282
- testContext = new TestContext({ analytics: true });
283
- slice = await setupSlice(testContext);
284
- });
285
- afterEach(async () => {
286
- await testContext.cleanup();
287
- });
288
- it('should not throw an error if given invalid state', async () => {
289
- const data = { should: 'break' };
290
- await expect(slice._logAnalytics(data)).resolves.not.toThrow();
291
- });
292
- });
293
- describe('when the slice is a string', () => {
294
- let testContext;
295
- let slice;
296
- beforeEach(async () => {
297
- testContext = new TestContext({ analytics: true });
298
- slice = await setupSlice(testContext);
299
- slice.slice = 'hello-there';
300
- });
301
- afterEach(async () => {
302
- await testContext.cleanup();
303
- });
304
- it('should handle the case when the slice is a string', async () => {
305
- // TODO: this is not actually testing a string
306
- await expect(slice._logAnalytics({})).resolves.not.toThrow();
307
- });
308
- });
309
- });
310
- describe('when marking an invalid slice', () => {
311
- let testContext;
312
- let slice;
313
- beforeEach(async () => {
314
- testContext = new TestContext();
315
- slice = await setupSlice(testContext);
316
- slice.slice = { should: 'break' };
317
- });
318
- afterEach(async () => {
319
- await testContext.cleanup();
320
- });
321
- it('should throw an error when marking it as failed', async () => {
322
- // @ts-expect-error
323
- await expect(slice._markFailed(new Error('some error'))).rejects.toThrow(/Failure to update error state/);
324
- // @ts-expect-error
325
- await expect(slice._markFailed()).rejects.toThrow(/Failure to update error state/);
326
- });
327
- it('should throw an error when marking it as complete', async () => {
328
- // @ts-expect-error
329
- await expect(slice._markCompleted()).rejects.toThrow(/Failure to update completed state/);
330
- });
331
- });
332
- });
333
- //# sourceMappingURL=slice-spec.js.map
@@ -1,356 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import 'jest-extended';
3
- import { pDelay } from '@terascope/core-utils';
4
- import { ExecutionController } from '@terascope/teraslice-messaging';
5
- import { findPort } from '../../../src/lib/utils/port_utils.js';
6
- import { Worker } from '../../../src/lib/workers/worker/index.js';
7
- import { TestContext } from '../helpers/index.js';
8
- describe('Worker', () => {
9
- async function setupTest(options = {}) {
10
- const slicerPort = await findPort();
11
- options.slicerPort = slicerPort;
12
- const testContext = new TestContext(options);
13
- await testContext.initialize();
14
- const server = new ExecutionController.Server({
15
- port: slicerPort,
16
- networkLatencyBuffer: 0,
17
- actionTimeout: 1000,
18
- workerDisconnectTimeout: 3000
19
- });
20
- testContext.attachCleanup(() => server.shutdown());
21
- await server.start();
22
- const worker = new Worker(testContext.context, testContext.executionContext);
23
- testContext.attachCleanup(() => worker.shutdown());
24
- return { server, worker, testContext };
25
- }
26
- describe('when running forever', () => {
27
- let sliceConfig;
28
- let worker;
29
- let testContext;
30
- let server;
31
- let sliceSuccess;
32
- let sliceFailure;
33
- beforeEach(async () => {
34
- ({ worker, testContext, server } = await setupTest());
35
- await worker.initialize();
36
- sliceConfig = await testContext.newSlice();
37
- server.onClientAvailable(() => {
38
- server.dispatchSlice(sliceConfig, worker.workerId);
39
- });
40
- let shutdownPromise;
41
- server.onSliceSuccess((workerId, _msg) => {
42
- sliceSuccess = _msg;
43
- shutdownPromise = worker.shutdown();
44
- });
45
- server.onSliceFailure((workerId, _msg) => {
46
- sliceFailure = _msg;
47
- shutdownPromise = worker.shutdown();
48
- });
49
- await worker.run();
50
- await shutdownPromise;
51
- });
52
- afterEach(async () => {
53
- await testContext.cleanup();
54
- });
55
- it('should complete the slice', () => {
56
- expect(sliceFailure).toBeNil();
57
- expect(sliceSuccess).toMatchObject({
58
- slice: sliceConfig
59
- });
60
- });
61
- });
62
- describe('when running and the execution controller disconnects', () => {
63
- let sliceConfig;
64
- let worker;
65
- let testContext;
66
- let server;
67
- let sliceSuccess;
68
- let sliceFailure;
69
- beforeEach(async () => {
70
- ({ worker, testContext, server } = await setupTest());
71
- await worker.initialize();
72
- sliceConfig = await testContext.newSlice();
73
- server.onClientAvailable(() => {
74
- server.dispatchSlice(sliceConfig, worker.workerId);
75
- });
76
- let shutdownPromise;
77
- server.onSliceSuccess((workerId, _msg) => {
78
- sliceSuccess = _msg;
79
- setTimeout(async () => {
80
- shutdownPromise = server.shutdown();
81
- });
82
- });
83
- server.onSliceFailure((workerId, _msg) => {
84
- sliceFailure = _msg;
85
- setTimeout(async () => {
86
- shutdownPromise = server.shutdown();
87
- });
88
- });
89
- await worker.run();
90
- await shutdownPromise;
91
- });
92
- afterEach(async () => {
93
- await testContext.cleanup();
94
- });
95
- it('should complete the slice', () => {
96
- expect(sliceFailure).toBeNil();
97
- expect(sliceSuccess).toMatchObject({
98
- slice: sliceConfig
99
- });
100
- });
101
- });
102
- describe('when a slice is sent from the execution controller', () => {
103
- let sliceConfig;
104
- let worker;
105
- let testContext;
106
- let server;
107
- let sliceSuccess;
108
- let sliceFailure;
109
- beforeEach(async () => {
110
- ({ worker, testContext, server } = await setupTest());
111
- await worker.initialize();
112
- sliceConfig = await testContext.newSlice();
113
- server.onClientAvailable(() => {
114
- server.dispatchSlice(sliceConfig, worker.workerId);
115
- });
116
- server.onSliceSuccess((workerId, _msg) => {
117
- sliceSuccess = _msg;
118
- });
119
- server.onSliceFailure((workerId, _msg) => {
120
- sliceFailure = _msg;
121
- });
122
- await worker.runOnce();
123
- // avoid on slice events don't fire immediatley now
124
- await pDelay(0);
125
- });
126
- afterEach(async () => {
127
- await testContext.cleanup();
128
- });
129
- it('should complete the slice', () => {
130
- expect(sliceFailure).toBeNil();
131
- expect(sliceSuccess).toMatchObject({
132
- slice: sliceConfig
133
- });
134
- });
135
- });
136
- describe('when a new slice is not sent right away', () => {
137
- let msg;
138
- let sliceConfig;
139
- let worker;
140
- let testContext;
141
- let server;
142
- let sliceFailure;
143
- let sliceSuccess;
144
- beforeEach(async () => {
145
- ({ worker, testContext, server } = await setupTest());
146
- await worker.initialize();
147
- server.onSliceSuccess((workerId, _msg) => {
148
- sliceSuccess = _msg;
149
- });
150
- server.onSliceFailure((workerId, _msg) => {
151
- sliceFailure = _msg;
152
- });
153
- const msgPromise = server.onceWithTimeout('worker:enqueue');
154
- const workerStart = worker.runOnce();
155
- await pDelay(500);
156
- sliceConfig = await testContext.newSlice();
157
- await server.dispatchSlice(sliceConfig, worker.workerId);
158
- await workerStart;
159
- msg = await msgPromise;
160
- await pDelay(100);
161
- });
162
- afterEach(async () => {
163
- await testContext.cleanup();
164
- });
165
- it('should re-enqueue the worker after receiving the slice complete message', () => {
166
- expect(msg).not.toBeNil();
167
- expect(sliceSuccess).toMatchObject({
168
- slice: sliceConfig
169
- });
170
- expect(sliceFailure).toBeNil();
171
- });
172
- });
173
- describe('when a slice errors', () => {
174
- let worker;
175
- let testContext;
176
- let server;
177
- let sliceFailure;
178
- let sliceSuccess;
179
- let msg;
180
- beforeEach(async () => {
181
- ({ worker, testContext, server } = await setupTest());
182
- await worker.initialize();
183
- const operations = worker.executionContext.getOperations();
184
- for (const op of operations) {
185
- // @ts-expect-error
186
- op.handle = jest.fn().mockRejectedValue(new Error('Bad news bears'));
187
- }
188
- server.onSliceSuccess((workerId, _msg) => {
189
- sliceSuccess = _msg;
190
- });
191
- server.onSliceFailure((workerId, _msg) => {
192
- sliceFailure = _msg;
193
- });
194
- const msgPromise = server.onceWithTimeout('worker:enqueue');
195
- const sliceConfig = await testContext.newSlice();
196
- server.onClientAvailable(() => {
197
- server.dispatchSlice(sliceConfig, worker.workerId);
198
- });
199
- await worker.runOnce();
200
- msg = await msgPromise;
201
- await pDelay(100);
202
- });
203
- afterEach(() => testContext.cleanup());
204
- it('should return send a slice completed message with an error', () => {
205
- expect(sliceSuccess).not.toBeObject();
206
- const errMsg = 'TSError: Slice failed processing, caused by TSError: Bad news bears';
207
- expect(sliceFailure).toBeObject();
208
- expect(sliceFailure.error).toStartWith(errMsg);
209
- expect(msg).not.toBeNil();
210
- });
211
- });
212
- describe('when a slice is in-progress and shutdown is called', () => {
213
- let workerShutdownEvent;
214
- let worker;
215
- let testContext;
216
- let server;
217
- beforeEach(async () => {
218
- ({ worker, testContext, server } = await setupTest());
219
- await worker.initialize();
220
- workerShutdownEvent = jest.fn();
221
- worker.events.once('worker:shutdown', workerShutdownEvent);
222
- worker.context.sysconfig.teraslice.shutdown_timeout = 1000;
223
- // @ts-expect-error
224
- worker.shutdownTimeout = 1000;
225
- // @ts-expect-error
226
- worker.slice.run = jest.fn(async () => pDelay(500));
227
- const sliceConfig = await testContext.newSlice();
228
- server.onClientAvailable(() => {
229
- server.dispatchSlice(sliceConfig, worker.workerId);
230
- });
231
- });
232
- afterEach(async () => {
233
- await testContext.cleanup();
234
- });
235
- it('should not have a shutdown err', async () => {
236
- const promise = server.sendExecutionFinishedToAll(testContext.exId);
237
- await expect(worker.shutdown()).resolves.toBeNil();
238
- expect(workerShutdownEvent).toHaveBeenCalled();
239
- await promise;
240
- });
241
- });
242
- describe('when a slice is in-progress and has to be forced to shutdown', () => {
243
- let shutdownErr;
244
- let worker;
245
- let testContext;
246
- let server;
247
- beforeEach(async () => {
248
- ({ worker, testContext, server } = await setupTest());
249
- await worker.initialize();
250
- worker.context.sysconfig.teraslice.shutdown_timeout = 500;
251
- // @ts-expect-error
252
- worker.shutdownTimeout = 500;
253
- // @ts-expect-error
254
- worker.slice.run = jest.fn(() => pDelay(1000));
255
- const sliceConfig = await testContext.newSlice();
256
- server.onClientAvailable(() => {
257
- server.dispatchSlice(sliceConfig, worker.workerId);
258
- });
259
- let shutdown;
260
- worker.events.once('slice:initialize', () => {
261
- shutdown = worker.shutdown().catch((err) => {
262
- shutdownErr = err;
263
- });
264
- });
265
- await worker.run();
266
- await shutdown;
267
- });
268
- afterEach(() => testContext.cleanup());
269
- it('shutdown should throw an error', () => {
270
- const errMsg = 'Error: Failed to shutdown correctly: Error: Worker shutdown timeout after 0.5 seconds, forcing shutdown';
271
- expect(shutdownErr).not.toBeNil();
272
- expect(shutdownErr.toString()).toStartWith(errMsg);
273
- });
274
- });
275
- describe('when constructed without nothing', () => {
276
- it('should throw an error', () => {
277
- expect(() => {
278
- // @ts-expect-error
279
- new Worker();
280
- }).toThrow();
281
- });
282
- });
283
- describe('when testing shutdown', () => {
284
- let testContext;
285
- let worker;
286
- beforeEach(async () => {
287
- testContext = new TestContext();
288
- await testContext.initialize();
289
- worker = new Worker(testContext.context, testContext.executionContext);
290
- });
291
- afterEach(() => testContext.cleanup());
292
- describe('when not initialized', () => {
293
- it('should resolve', () => expect(worker.shutdown()).resolves.toBeNil());
294
- });
295
- describe('when initialized', () => {
296
- beforeEach(() => {
297
- worker.isInitialized = true;
298
- });
299
- describe('when controller is already being shutdown', () => {
300
- beforeEach(() => {
301
- worker.isShuttingDown = true;
302
- });
303
- it('should resolve when shutdown passes', async () => {
304
- setTimeout(() => {
305
- worker.events.emit('worker:shutdown:complete');
306
- });
307
- await expect(worker.shutdown()).resolves.toBeNil();
308
- });
309
- it('should reject when shutdown fails', async () => {
310
- setTimeout(() => {
311
- worker.events.emit('worker:shutdown:complete', new Error('Uh oh'));
312
- });
313
- await expect(worker.shutdown()).rejects.toThrow('Uh oh');
314
- });
315
- });
316
- describe('when everything errors', () => {
317
- beforeEach(() => {
318
- worker._waitForSliceToFinish = () => Promise.reject(new Error('Slice Finish Error'));
319
- // @ts-expect-error
320
- worker.stateStorage = {
321
- shutdown: () => Promise.reject(new Error('Store Error'))
322
- };
323
- worker.analyticsStorage = {
324
- // @ts-expect-error
325
- shutdown: async () => Promise.resolve(true)
326
- };
327
- // @ts-expect-error
328
- worker.slice = {
329
- flush: () => Promise.reject(new Error('Flush Error')),
330
- shutdown: () => Promise.reject(new Error('Slice Error'))
331
- };
332
- // @ts-expect-error
333
- worker.client = {
334
- shutdown: () => Promise.reject(new Error('Messenger Error'))
335
- };
336
- });
337
- it('should reject with all of the errors', async () => {
338
- expect.hasAssertions();
339
- try {
340
- await worker.shutdown();
341
- }
342
- catch (err) {
343
- const errMsg = err.toString();
344
- expect(errMsg).toStartWith('Error: Failed to shutdown correctly');
345
- expect(errMsg).toInclude('Slice Finish Error');
346
- expect(errMsg).toInclude('Store Error');
347
- expect(errMsg).toInclude('Flush Error');
348
- expect(errMsg).toInclude('Slice Error');
349
- expect(errMsg).toInclude('Messenger Error');
350
- }
351
- });
352
- });
353
- });
354
- });
355
- });
356
- //# sourceMappingURL=worker-spec.js.map