teraslice 2.10.0 → 2.12.0

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 (118) hide show
  1. package/dist/src/interfaces.js +12 -0
  2. package/dist/src/lib/cluster/cluster_master.js +246 -0
  3. package/dist/src/lib/cluster/node_master.js +355 -0
  4. package/dist/src/lib/cluster/services/api.js +663 -0
  5. package/dist/src/lib/cluster/services/assets.js +226 -0
  6. package/dist/src/lib/cluster/services/cluster/backends/kubernetes/index.js +192 -0
  7. package/dist/src/lib/cluster/services/cluster/backends/kubernetes/k8s.js +481 -0
  8. package/dist/src/lib/cluster/services/cluster/backends/kubernetes/k8sResource.js +414 -0
  9. package/dist/src/lib/cluster/services/cluster/backends/kubernetes/k8sState.js +59 -0
  10. package/dist/src/lib/cluster/services/cluster/backends/kubernetes/utils.js +43 -0
  11. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/index.js +192 -0
  12. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/interfaces.js +2 -0
  13. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8s.js +423 -0
  14. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sDeploymentResource.js +60 -0
  15. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sJobResource.js +55 -0
  16. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sResource.js +359 -0
  17. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sServiceResource.js +37 -0
  18. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sState.js +60 -0
  19. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/utils.js +170 -0
  20. package/dist/src/lib/cluster/services/cluster/backends/native/dispatch.js +13 -0
  21. package/dist/src/lib/cluster/services/cluster/backends/native/index.js +526 -0
  22. package/dist/src/lib/cluster/services/cluster/backends/native/messaging.js +547 -0
  23. package/dist/src/lib/cluster/services/cluster/backends/state-utils.js +26 -0
  24. package/dist/src/lib/cluster/services/cluster/index.js +17 -0
  25. package/dist/src/lib/cluster/services/execution.js +435 -0
  26. package/dist/src/lib/cluster/services/index.js +6 -0
  27. package/dist/src/lib/cluster/services/interfaces.js +2 -0
  28. package/dist/src/lib/cluster/services/jobs.js +454 -0
  29. package/dist/src/lib/config/default-sysconfig.js +26 -0
  30. package/dist/src/lib/config/index.js +22 -0
  31. package/dist/src/lib/config/schemas/system.js +360 -0
  32. package/dist/src/lib/storage/analytics.js +86 -0
  33. package/dist/src/lib/storage/assets.js +401 -0
  34. package/dist/src/lib/storage/backends/elasticsearch_store.js +494 -0
  35. package/dist/src/lib/storage/backends/mappings/analytics.js +50 -0
  36. package/dist/src/lib/storage/backends/mappings/asset.js +41 -0
  37. package/dist/src/lib/storage/backends/mappings/ex.js +62 -0
  38. package/dist/src/lib/storage/backends/mappings/job.js +38 -0
  39. package/dist/src/lib/storage/backends/mappings/state.js +38 -0
  40. package/dist/src/lib/storage/backends/s3_store.js +237 -0
  41. package/dist/src/lib/storage/execution.js +300 -0
  42. package/dist/src/lib/storage/index.js +7 -0
  43. package/dist/src/lib/storage/jobs.js +81 -0
  44. package/dist/src/lib/storage/state.js +255 -0
  45. package/dist/src/lib/utils/api_utils.js +157 -0
  46. package/dist/src/lib/utils/asset_utils.js +94 -0
  47. package/dist/src/lib/utils/date_utils.js +52 -0
  48. package/dist/src/lib/utils/encoding_utils.js +27 -0
  49. package/dist/src/lib/utils/events.js +4 -0
  50. package/dist/src/lib/utils/file_utils.js +124 -0
  51. package/dist/src/lib/utils/id_utils.js +15 -0
  52. package/dist/src/lib/utils/port_utils.js +32 -0
  53. package/dist/src/lib/workers/assets/index.js +3 -0
  54. package/dist/src/lib/workers/assets/loader-executable.js +40 -0
  55. package/dist/src/lib/workers/assets/loader.js +73 -0
  56. package/dist/src/lib/workers/assets/spawn.js +55 -0
  57. package/dist/src/lib/workers/context/execution-context.js +12 -0
  58. package/dist/src/lib/workers/context/terafoundation-context.js +8 -0
  59. package/dist/src/lib/workers/execution-controller/execution-analytics.js +188 -0
  60. package/dist/src/lib/workers/execution-controller/index.js +1024 -0
  61. package/dist/src/lib/workers/execution-controller/recovery.js +151 -0
  62. package/dist/src/lib/workers/execution-controller/scheduler.js +390 -0
  63. package/dist/src/lib/workers/execution-controller/slice-analytics.js +96 -0
  64. package/dist/src/lib/workers/helpers/job.js +80 -0
  65. package/dist/src/lib/workers/helpers/op-analytics.js +22 -0
  66. package/dist/src/lib/workers/helpers/terafoundation.js +34 -0
  67. package/dist/src/lib/workers/helpers/worker-shutdown.js +169 -0
  68. package/dist/src/lib/workers/metrics/index.js +108 -0
  69. package/dist/src/lib/workers/worker/index.js +378 -0
  70. package/dist/src/lib/workers/worker/slice.js +122 -0
  71. package/dist/test/config/schemas/system_schema-spec.js +37 -0
  72. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/k8s-spec.js +316 -0
  73. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/k8sResource-spec.js +795 -0
  74. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/k8sState-multicluster-spec.js +67 -0
  75. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/k8sState-spec.js +84 -0
  76. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/utils-spec.js +132 -0
  77. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8s-v2-spec.js +455 -0
  78. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sResource-v2-spec.js +818 -0
  79. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-multicluster-v2-spec.js +67 -0
  80. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-v2-spec.js +84 -0
  81. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/utils-v2-spec.js +320 -0
  82. package/dist/test/lib/cluster/services/cluster/backends/state-utils-spec.js +37 -0
  83. package/dist/test/node_master-spec.js +188 -0
  84. package/dist/test/services/api-spec.js +80 -0
  85. package/dist/test/services/assets-spec.js +158 -0
  86. package/dist/test/services/messaging-spec.js +440 -0
  87. package/dist/test/storage/assets_storage-spec.js +95 -0
  88. package/dist/test/storage/s3_store-spec.js +138 -0
  89. package/dist/test/test.config.js +8 -0
  90. package/dist/test/test.setup.js +6 -0
  91. package/dist/test/utils/api_utils-spec.js +86 -0
  92. package/dist/test/utils/asset_utils-spec.js +141 -0
  93. package/dist/test/utils/elastic_utils-spec.js +25 -0
  94. package/dist/test/workers/execution-controller/execution-controller-spec.js +371 -0
  95. package/dist/test/workers/execution-controller/execution-special-test-cases-spec.js +520 -0
  96. package/dist/test/workers/execution-controller/execution-test-cases-spec.js +338 -0
  97. package/dist/test/workers/execution-controller/recovery-spec.js +160 -0
  98. package/dist/test/workers/execution-controller/scheduler-spec.js +249 -0
  99. package/dist/test/workers/execution-controller/slice-analytics-spec.js +121 -0
  100. package/dist/test/workers/fixtures/ops/example-op/processor.js +20 -0
  101. package/dist/test/workers/fixtures/ops/example-op/schema.js +19 -0
  102. package/dist/test/workers/fixtures/ops/example-reader/fetcher.js +20 -0
  103. package/dist/test/workers/fixtures/ops/example-reader/schema.js +41 -0
  104. package/dist/test/workers/fixtures/ops/example-reader/slicer.js +37 -0
  105. package/dist/test/workers/fixtures/ops/new-op/processor.js +29 -0
  106. package/dist/test/workers/fixtures/ops/new-op/schema.js +18 -0
  107. package/dist/test/workers/fixtures/ops/new-reader/fetcher.js +19 -0
  108. package/dist/test/workers/fixtures/ops/new-reader/schema.js +23 -0
  109. package/dist/test/workers/fixtures/ops/new-reader/slicer.js +13 -0
  110. package/dist/test/workers/helpers/configs.js +130 -0
  111. package/dist/test/workers/helpers/execution-controller-helper.js +49 -0
  112. package/dist/test/workers/helpers/index.js +5 -0
  113. package/dist/test/workers/helpers/test-context.js +210 -0
  114. package/dist/test/workers/helpers/zip-directory.js +25 -0
  115. package/dist/test/workers/worker/slice-spec.js +333 -0
  116. package/dist/test/workers/worker/worker-spec.js +356 -0
  117. package/package.json +94 -93
  118. package/service.js +0 -0
@@ -0,0 +1,130 @@
1
+ import path from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+ import { withoutNil } from '@terascope/utils';
4
+ // @ts-expect-error
5
+ import Chance from 'chance';
6
+ import { newId } from '../../../src/lib/utils/id_utils.js';
7
+ const { SEARCH_TEST_HOST } = process.env;
8
+ const dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const opsPath = path.join(dirname, '..', 'fixtures', 'ops');
10
+ const chance = new Chance();
11
+ const newConfig = (options = {}) => {
12
+ const { newOps } = options;
13
+ let { operations } = options;
14
+ if (operations == null) {
15
+ if (newOps) {
16
+ operations = [
17
+ withoutNil({
18
+ _op: path.join(opsPath, 'new-reader'),
19
+ countPerSlicer: options.countPerSlicer
20
+ }),
21
+ withoutNil({
22
+ _op: path.join(opsPath, 'new-op'),
23
+ failOnSliceRetry: options.failOnSliceRetry || false
24
+ }),
25
+ {
26
+ _op: 'noop'
27
+ }
28
+ ];
29
+ }
30
+ else {
31
+ operations = [
32
+ withoutNil({
33
+ _op: path.join(opsPath, 'example-reader'),
34
+ exampleProp: 321,
35
+ updateMetadata: options.updateMetadata,
36
+ errorAt: options.readerErrorAt,
37
+ results: options.readerResults,
38
+ slicerResults: options.slicerResults,
39
+ slicerErrorAt: options.slicerErrorAt,
40
+ slicerQueueLength: options.slicerQueueLength
41
+ }),
42
+ withoutNil({
43
+ _op: path.join(opsPath, 'example-op'),
44
+ exampleProp: 123,
45
+ errorAt: options.opErrorAt,
46
+ results: options.opResults
47
+ })
48
+ ];
49
+ }
50
+ }
51
+ const { analytics = false, maxRetries = 0, slicerPort = 0, lifecycle = 'once', assets = [], workers = 1, slicers = 1, autorecover = false, recoveredExecution, recoveredSliceType, probationWindow = 5000, log_level } = options;
52
+ return {
53
+ name: chance.name({ middle: true }),
54
+ slicers,
55
+ workers,
56
+ assets,
57
+ analytics,
58
+ lifecycle,
59
+ max_retries: maxRetries,
60
+ operations,
61
+ autorecover,
62
+ performance_metrics: false,
63
+ recovered_execution: recoveredExecution,
64
+ recovered_slice_type: recoveredSliceType,
65
+ ex_id: newId('ex-id', true),
66
+ job_id: newId('job-id', true),
67
+ node_id: newId('node-id', true),
68
+ slicer_port: slicerPort,
69
+ slicer_hostname: 'localhost',
70
+ probation_window: probationWindow,
71
+ log_level
72
+ };
73
+ };
74
+ const newSysConfig = (options) => {
75
+ const { clusterName = 'test-teraslice-cluster', timeout = 3000, actionTimeout = 2000, shutdownTimeout = 4000, assetDir, clusterMasterPort, log_level_terafoundation = 'info', } = options;
76
+ return {
77
+ terafoundation: {
78
+ environment: 'development',
79
+ log_level: log_level_terafoundation,
80
+ connectors: {
81
+ 'elasticsearch-next': {
82
+ default: {
83
+ node: [SEARCH_TEST_HOST],
84
+ requestTimeout: timeout,
85
+ deadTimeout: timeout
86
+ }
87
+ }
88
+ }
89
+ },
90
+ teraslice: {
91
+ assets_directory: assetDir,
92
+ shutdown_timeout: shutdownTimeout,
93
+ action_timeout: actionTimeout,
94
+ network_latency_buffer: 100,
95
+ slicer_timeout: timeout,
96
+ slicer_allocation_attempts: 3,
97
+ node_state_interval: timeout,
98
+ node_disconnect_timeout: timeout,
99
+ worker_disconnect_timeout: timeout,
100
+ analytics_rate: 100,
101
+ name: clusterName,
102
+ master_hostname: 'localhost',
103
+ port: clusterMasterPort,
104
+ index_settings: {
105
+ analytics: {
106
+ number_of_shards: 1,
107
+ number_of_replicas: 0
108
+ },
109
+ assets: {
110
+ number_of_shards: 1,
111
+ number_of_replicas: 0
112
+ },
113
+ jobs: {
114
+ number_of_shards: 1,
115
+ number_of_replicas: 0
116
+ },
117
+ execution: {
118
+ number_of_shards: 1,
119
+ number_of_replicas: 0
120
+ },
121
+ state: {
122
+ number_of_shards: 1,
123
+ number_of_replicas: 0
124
+ }
125
+ }
126
+ }
127
+ };
128
+ };
129
+ export { opsPath, newConfig, newSysConfig };
130
+ //# sourceMappingURL=configs.js.map
@@ -0,0 +1,49 @@
1
+ import { pDelay, pDefer } from '@terascope/utils';
2
+ export function makeShutdownEarlyFn({ exController, enabled = false }) {
3
+ let shutdownErr = {
4
+ message: 'Shutdown never triggered'
5
+ };
6
+ let alreadyCalled = false;
7
+ const deferred = pDefer();
8
+ const catchShutdown = async () => {
9
+ if (alreadyCalled)
10
+ return;
11
+ alreadyCalled = true;
12
+ shutdownErr.message = 'Shutdown trigger but did not error';
13
+ try {
14
+ await exController.shutdown();
15
+ }
16
+ catch (err) {
17
+ shutdownErr = err;
18
+ }
19
+ deferred.resolve();
20
+ };
21
+ return {
22
+ error: () => shutdownErr,
23
+ wait: async () => {
24
+ if (!enabled)
25
+ return;
26
+ await deferred.promise;
27
+ },
28
+ shutdown: async () => {
29
+ if (!enabled)
30
+ return;
31
+ await pDelay(100);
32
+ catchShutdown();
33
+ await pDelay(100);
34
+ }
35
+ };
36
+ }
37
+ export function getTestCases(testCases) {
38
+ const onlyCases = testCases.filter((ts) => ts[1].only);
39
+ if (onlyCases.length > 0) {
40
+ console.warn('[WARNING]: test cases includes a "only" property, make sure to remove this before committing');
41
+ return onlyCases;
42
+ }
43
+ const cases = testCases.filter((ts) => !ts[1].only);
44
+ if (cases.length !== testCases.length) {
45
+ console.warn('[WARNING]: test cases includes a "skip" property, make sure to remove this before committing');
46
+ }
47
+ return cases;
48
+ }
49
+ //# sourceMappingURL=execution-controller-helper.js.map
@@ -0,0 +1,5 @@
1
+ import { TestContext } from './test-context';
2
+ import { newId } from '../../../src/lib/utils/id_utils.js';
3
+ import { newConfig, newSysConfig, opsPath } from './configs';
4
+ export { newConfig, opsPath, newId, newSysConfig, TestContext };
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,210 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'node:path';
3
+ import { createTempDirSync, cleanupTempDirs } from 'jest-fixtures';
4
+ import { newTestSlice } from '@terascope/job-components';
5
+ import { get, pWhile } from '@terascope/utils';
6
+ import { ClusterMaster } from '@terascope/teraslice-messaging';
7
+ import { AssetsStorage, StateStorage, AnalyticsStorage, ExecutionStorage, JobsStorage } from '../../../src/lib/storage/index.js';
8
+ import { initializeTestExecution } from '../../../src/lib/workers/helpers/job.js';
9
+ import { makeTerafoundationContext } from '../../../src/lib/workers/context/terafoundation-context.js';
10
+ import { makeExecutionContext } from '../../../src/lib/workers/context/execution-context.js';
11
+ import { newId } from '../../../src/lib/utils/id_utils.js';
12
+ import { findPort } from '../../../src/lib/utils/port_utils.js';
13
+ import { newConfig, newSysConfig } from './configs.js';
14
+ import { zipDirectory } from './zip-directory.js';
15
+ import { TERASLICE_CLUSTER_NAME } from '../../test.config.js';
16
+ const tmpAssetDir = createTempDirSync();
17
+ const clusterName = `${TERASLICE_CLUSTER_NAME}`;
18
+ export class TestContext {
19
+ setupId;
20
+ assetDir;
21
+ sysconfig;
22
+ config;
23
+ context;
24
+ clean = false;
25
+ nodeId;
26
+ exId;
27
+ jobId;
28
+ events;
29
+ _cleanupFns = [];
30
+ executionContext;
31
+ assignment;
32
+ clusterMaster;
33
+ _stores = {};
34
+ cleanups = {};
35
+ constructor(options = {}) {
36
+ const { clusterMasterPort, shutdownTimeout, actionTimeout, timeout, log_level_terafoundation } = options;
37
+ this.setupId = newId('setup', true);
38
+ this.assetDir = tmpAssetDir;
39
+ this.sysconfig = newSysConfig({
40
+ clusterName,
41
+ assetDir: this.assetDir,
42
+ clusterMasterPort,
43
+ actionTimeout,
44
+ timeout,
45
+ shutdownTimeout,
46
+ log_level_terafoundation
47
+ });
48
+ this.config = newConfig(options);
49
+ this.cleanups[this.setupId] = () => this.cleanup();
50
+ this.assignment = options.assignment || 'worker';
51
+ }
52
+ // make sure we cleanup if any test fails to cleanup properly
53
+ async cleanupAll(withEs = false) {
54
+ const count = Object.keys(this.cleanups).length;
55
+ if (!count)
56
+ return;
57
+ const fns = Object.keys(this.cleanups).map(async (name) => {
58
+ const fn = this.cleanups[name];
59
+ try {
60
+ await fn();
61
+ }
62
+ catch (err) {
63
+ console.error(`Failed to cleanup ${name}`, err);
64
+ }
65
+ delete this.cleanups[name];
66
+ });
67
+ await Promise.all(fns);
68
+ try {
69
+ cleanupTempDirs();
70
+ }
71
+ catch (err) {
72
+ console.error(err);
73
+ }
74
+ if (withEs && Object.keys(this._stores).length) {
75
+ try {
76
+ await Promise.all(Object.values(this._stores).map((store) => store.shutdown(true)));
77
+ }
78
+ catch (err) {
79
+ console.error(err);
80
+ }
81
+ }
82
+ }
83
+ async waitForCleanup() {
84
+ return pWhile(async () => !Object.keys(this.cleanups).length, {
85
+ name: 'Test Context',
86
+ timeoutMs: 3000
87
+ });
88
+ }
89
+ async initialize(makeItReal = false, initOptions = {}) {
90
+ this.context = await makeTerafoundationContext({ sysconfig: this.sysconfig });
91
+ this.context.assignment = this.assignment;
92
+ this.events = this.context.apis.foundation.getSystemEvents();
93
+ if (makeItReal) {
94
+ await Promise.all([
95
+ this.addJobStore(),
96
+ this.addExStore(),
97
+ this.addStateStore()
98
+ ]);
99
+ const { ex } = await initializeTestExecution(Object.assign({
100
+ context: this.context,
101
+ config: this.config,
102
+ stores: this._stores,
103
+ }, initOptions));
104
+ this.config = ex;
105
+ }
106
+ this.executionContext = await makeExecutionContext(this.context, this.config);
107
+ // @ts-expect-error
108
+ this.nodeId = this.executionContext.config.node_id;
109
+ this.exId = this.executionContext.config.ex_id;
110
+ this.jobId = this.executionContext.config.job_id;
111
+ }
112
+ get stores() {
113
+ return this._stores;
114
+ }
115
+ async addClusterMaster() {
116
+ if (this.clusterMaster)
117
+ return this.clusterMaster;
118
+ const port = await findPort();
119
+ const networkLatencyBuffer = get(this.context, 'sysconfig.teraslice.network_latency_buffer');
120
+ const actionTimeout = get(this.context, 'sysconfig.teraslice.action_timeout');
121
+ const nodeDisconnectTimeout = get(this.context, 'sysconfig.teraslice.node_disconnect_timeout');
122
+ this.clusterMaster = new ClusterMaster.Server({
123
+ port,
124
+ networkLatencyBuffer,
125
+ actionTimeout,
126
+ nodeDisconnectTimeout
127
+ });
128
+ await this.clusterMaster.start();
129
+ this.context.sysconfig.teraslice.port = port;
130
+ this.attachCleanup(() => this.clusterMaster.shutdown());
131
+ return this.clusterMaster;
132
+ }
133
+ attachCleanup(fn) {
134
+ this._cleanupFns.push(fn);
135
+ }
136
+ async saveAsset(assetDir, cleanup) {
137
+ await this.addAssetStore();
138
+ const exists = await fs.pathExists(assetDir);
139
+ if (!exists) {
140
+ const err = new Error(`Asset Directory ${assetDir} does not exist`);
141
+ throw err;
142
+ }
143
+ const assetZip = await zipDirectory(assetDir);
144
+ if (!this._stores.assetsStorage) {
145
+ throw new Error('Assets storage is not setup');
146
+ }
147
+ const { assetId } = await this._stores.assetsStorage.save(assetZip);
148
+ if (cleanup) {
149
+ await fs.remove(path.join(this.assetDir, assetId));
150
+ }
151
+ return assetId;
152
+ }
153
+ async newSlice() {
154
+ const sliceConfig = newTestSlice({ request: { example: 'slice-data' } });
155
+ await this.addStateStore();
156
+ await this._stores.stateStorage.createState(this.exId, sliceConfig, 'start');
157
+ return sliceConfig;
158
+ }
159
+ async addAssetStore() {
160
+ if (this._stores.assetsStorage) {
161
+ return this._stores.assetsStorage;
162
+ }
163
+ this._stores.assetsStorage = new AssetsStorage(this.context);
164
+ await this._stores.assetsStorage.initialize();
165
+ delete this.context.apis.assets;
166
+ return this._stores.assetsStorage;
167
+ }
168
+ async addStateStore() {
169
+ if (this._stores.stateStorage) {
170
+ return this._stores.stateStorage;
171
+ }
172
+ this._stores.stateStorage = new StateStorage(this.context);
173
+ await this._stores.stateStorage.initialize();
174
+ return this._stores.stateStorage;
175
+ }
176
+ async addAnalyticsStore() {
177
+ if (this._stores.analyticsStorage) {
178
+ return this._stores.analyticsStorage;
179
+ }
180
+ this._stores.analyticsStorage = new AnalyticsStorage(this.context);
181
+ await this._stores.analyticsStorage.initialize();
182
+ return this._stores.analyticsStorage;
183
+ }
184
+ async addJobStore() {
185
+ if (this._stores.jobsStorage) {
186
+ return this._stores.jobsStorage;
187
+ }
188
+ this._stores.jobsStorage = new JobsStorage(this.context);
189
+ await this._stores.jobsStorage.initialize();
190
+ return this._stores.jobsStorage;
191
+ }
192
+ async addExStore() {
193
+ if (this._stores.executionStorage) {
194
+ return this._stores.executionStorage;
195
+ }
196
+ this._stores.executionStorage = new ExecutionStorage(this.context);
197
+ await this._stores.executionStorage.initialize();
198
+ return this._stores.executionStorage;
199
+ }
200
+ async cleanup() {
201
+ if (this.clean)
202
+ return;
203
+ await Promise.all(this._cleanupFns.map((fn) => fn()));
204
+ this._cleanupFns.length = 0;
205
+ this.events.removeAllListeners();
206
+ delete this.cleanups[this.setupId];
207
+ this.clean = true;
208
+ }
209
+ }
210
+ //# sourceMappingURL=test-context.js.map
@@ -0,0 +1,25 @@
1
+ import path from 'node:path';
2
+ import { random } from '@terascope/utils';
3
+ // @ts-expect-error
4
+ import BufferStreams from 'bufferstreams';
5
+ import archiver from 'archiver';
6
+ import { newId } from '../../../src/lib/utils/id_utils.js';
7
+ export function zipDirectory(dir) {
8
+ return new Promise((resolve, reject) => {
9
+ const archive = archiver('zip', { zlib: { level: 9 } });
10
+ archive.append(JSON.stringify({
11
+ name: path.basename(dir),
12
+ version: `${random(0, 100)}.${random(0, 100)}.${random(0, 100)}`,
13
+ someProp: newId()
14
+ }, null, 4), { name: 'asset.json' });
15
+ archive.pipe(new BufferStreams((err, buf) => {
16
+ if (err) {
17
+ reject(err);
18
+ return;
19
+ }
20
+ resolve(buf);
21
+ }));
22
+ archive.directory(dir, 'asset').finalize();
23
+ });
24
+ }
25
+ //# sourceMappingURL=zip-directory.js.map