teraslice 2.11.0 → 2.12.1

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 -94
  118. package/service.js +0 -0
@@ -0,0 +1,455 @@
1
+ import { V1Deployment, V1Job, V1Pod, V1ReplicaSet, V1Service } from '@kubernetes/client-node';
2
+ import nock from 'nock';
3
+ import { debugLogger } from '@terascope/job-components';
4
+ import { K8s } from '../../../../../../../../src/lib/cluster/services/cluster/backends/kubernetesV2/k8s.js';
5
+ const logger = debugLogger('k8s-v2-spec');
6
+ const _url = 'http://mock.kube.api';
7
+ // const _url = 'https://192.168.99.100:8443';
8
+ describe('k8s', () => {
9
+ let k8s;
10
+ const job = Object.assign(new V1Job(), {
11
+ apiVersion: '1.0.0',
12
+ kind: 'Job',
13
+ metadata: {
14
+ labels: {
15
+ 'app.kubernetes.io/name': 'teraslice'
16
+ },
17
+ name: 'testJob1',
18
+ uid: 'uid1'
19
+ },
20
+ spec: {
21
+ template: {
22
+ metadata: {
23
+ labels: {
24
+ 'app.kubernetes.io/name': 'teraslice'
25
+ },
26
+ },
27
+ spec: {
28
+ containers: [{
29
+ volumeMounts: []
30
+ }],
31
+ volumes: []
32
+ }
33
+ },
34
+ selector: {
35
+ matchLabels: {
36
+ 'app.kubernetes.io/component': 'execution_controller'
37
+ }
38
+ }
39
+ }
40
+ });
41
+ const testPod1 = Object.assign(new V1Pod(), {
42
+ apiVersion: 'v1',
43
+ kind: 'Pod',
44
+ metadata: { name: 'testPod1' },
45
+ status: {}
46
+ });
47
+ const testPod2 = Object.assign(new V1Pod(), {
48
+ apiVersion: 'v1',
49
+ kind: 'Pod',
50
+ metadata: { name: 'testPod2' },
51
+ status: {}
52
+ });
53
+ const service = Object.assign(new V1Service(), {
54
+ kind: 'Service',
55
+ metadata: {
56
+ name: 'service1'
57
+ },
58
+ spec: {
59
+ selector: {
60
+ 'app.kubernetes.io/component': 'execution_controller'
61
+ },
62
+ ports: [
63
+ { port: 45680 }
64
+ ]
65
+ }
66
+ });
67
+ const deployment = Object.assign(new V1Deployment(), {
68
+ apiVersion: 'v1',
69
+ kind: 'Deployment',
70
+ metadata: {
71
+ labels: {
72
+ 'app.kubernetes.io/name': 'teraslice'
73
+ },
74
+ name: 'dname'
75
+ },
76
+ spec: {
77
+ replicas: 5,
78
+ template: {
79
+ metadata: {
80
+ labels: {
81
+ 'app.kubernetes.io/name': 'teraslice'
82
+ },
83
+ },
84
+ spec: {
85
+ volumes: [{ name: 'volume1' }],
86
+ containers: [{
87
+ volumeMounts: [],
88
+ }]
89
+ }
90
+ },
91
+ selector: {}
92
+ },
93
+ status: {}
94
+ });
95
+ const replicaSet = Object.assign(new V1ReplicaSet(), {
96
+ kind: 'ReplicaSet',
97
+ metadata: {
98
+ name: 'replicaset1'
99
+ },
100
+ status: {}
101
+ });
102
+ const status = {
103
+ apiVersion: 'v1',
104
+ details: {
105
+ group: 'batch',
106
+ kind: 'jobs',
107
+ name: 'testJob1',
108
+ uid: 'f29935a1-9f36-4104-a840-f6534d7f2ef8'
109
+ },
110
+ kind: 'Status',
111
+ status: 'Success'
112
+ };
113
+ beforeEach(async () => {
114
+ nock(_url)
115
+ .get('/api/v1/namespaces')
116
+ .reply(200, {
117
+ kind: 'NamespaceList',
118
+ apiVersion: 'v1',
119
+ metadata: {
120
+ selfLink: '/api/v1/namespaces',
121
+ resourceVersion: '1961000'
122
+ },
123
+ items: [
124
+ {
125
+ metadata: {
126
+ name: 'default'
127
+ }
128
+ }
129
+ ]
130
+ });
131
+ const clientConfig = {
132
+ clusters: [{
133
+ name: 'cluster',
134
+ server: _url,
135
+ skipTLSVerify: true
136
+ }],
137
+ users: [{
138
+ name: 'admin',
139
+ password: 'fakepass'
140
+ }],
141
+ contexts: [{
142
+ name: 'context',
143
+ user: 'user',
144
+ cluster: 'cluster'
145
+ }],
146
+ currentContext: 'context'
147
+ };
148
+ k8s = new K8s(logger, clientConfig, null, 1, 1);
149
+ });
150
+ afterEach(() => {
151
+ nock.cleanAll();
152
+ });
153
+ it('can get the "default" namespace', async () => {
154
+ const namespaces = await k8s.getNamespaces();
155
+ expect(namespaces.items[0].metadata?.name).toEqual('default');
156
+ });
157
+ describe('->list', () => {
158
+ it('can get PodList', async () => {
159
+ nock(_url)
160
+ .get('/api/v1/namespaces/default/pods')
161
+ .query({ labelSelector: 'app=teraslice' })
162
+ .reply(200, {
163
+ kind: 'PodList',
164
+ items: [testPod1]
165
+ });
166
+ const pods = await k8s.list('app=teraslice', 'pods');
167
+ expect(pods.kind).toEqual('PodList');
168
+ });
169
+ it('can get ServiceList', async () => {
170
+ nock(_url)
171
+ .get('/api/v1/namespaces/default/services')
172
+ .query({ labelSelector: 'app=teraslice' })
173
+ .reply(200, {
174
+ kind: 'ServiceList',
175
+ items: [service]
176
+ });
177
+ const pods = await k8s.list('app=teraslice', 'services');
178
+ expect(pods.kind).toEqual('ServiceList');
179
+ });
180
+ it('can get DeploymentList', async () => {
181
+ nock(_url)
182
+ .get('/apis/apps/v1/namespaces/default/deployments')
183
+ .query({ labelSelector: 'app=teraslice' })
184
+ .reply(200, {
185
+ kind: 'DeploymentList',
186
+ items: [deployment]
187
+ });
188
+ const deployments = await k8s.list('app=teraslice', 'deployments');
189
+ expect(deployments.kind).toEqual('DeploymentList');
190
+ });
191
+ it('can get JobList', async () => {
192
+ nock(_url)
193
+ .get('/apis/batch/v1/namespaces/default/jobs')
194
+ .query({ labelSelector: 'app=teraslice' })
195
+ .reply(200, {
196
+ kind: 'JobList',
197
+ items: [job]
198
+ });
199
+ const jobs = await k8s.list('app=teraslice', 'jobs');
200
+ expect(jobs.kind).toEqual('JobList');
201
+ });
202
+ it('can get ReplicaSetList', async () => {
203
+ nock(_url)
204
+ .get('/apis/apps/v1/namespaces/default/replicasets')
205
+ .query({ labelSelector: 'app=teraslice' })
206
+ .reply(200, {
207
+ kind: 'ReplicaSetList',
208
+ items: [replicaSet]
209
+ });
210
+ const jobs = await k8s.list('app=teraslice', 'replicasets');
211
+ expect(jobs.kind).toEqual('ReplicaSetList');
212
+ });
213
+ });
214
+ describe('->nonEmptyList', () => {
215
+ it('can get list with one item', async () => {
216
+ nock(_url)
217
+ .get('/apis/batch/v1/namespaces/default/jobs')
218
+ .query({ labelSelector: 'app=teraslice' })
219
+ .reply(200, {
220
+ kind: 'JobList',
221
+ items: [job]
222
+ });
223
+ const jobs = await k8s.nonEmptyJobList('app=teraslice');
224
+ expect(jobs.items[0]).toEqual(job);
225
+ });
226
+ it('throws with an empty list', async () => {
227
+ nock(_url)
228
+ .get('/apis/batch/v1/namespaces/default/jobs')
229
+ .query({ labelSelector: 'app=teraslice' })
230
+ .reply(200, {
231
+ kind: 'JobList',
232
+ items: []
233
+ });
234
+ await expect(k8s.nonEmptyJobList('app=teraslice'))
235
+ .rejects.toThrow('Teraslice job matching the following selector was not found: app=teraslice (retriable)');
236
+ });
237
+ });
238
+ describe('->post', () => {
239
+ it('can post a deployment', async () => {
240
+ nock(_url, { encodedQueryParams: true })
241
+ .post('/apis/apps/v1/namespaces/default/deployments')
242
+ .reply(201, deployment);
243
+ const response = await k8s.post(deployment);
244
+ expect(response.kind).toEqual('Deployment');
245
+ });
246
+ it('can post a job', async () => {
247
+ nock(_url, { encodedQueryParams: true })
248
+ .post('/apis/batch/v1/namespaces/default/jobs')
249
+ .reply(201, job);
250
+ const response = await k8s.post(job);
251
+ expect(response.kind).toEqual('Job');
252
+ });
253
+ it('can post a pod', async () => {
254
+ nock(_url, { encodedQueryParams: true })
255
+ .post('/api/v1/namespaces/default/pods')
256
+ .reply(201, testPod1);
257
+ const response = await k8s.post(testPod1);
258
+ expect(response.kind).toEqual('Pod');
259
+ });
260
+ it('can post a replicaSet', async () => {
261
+ nock(_url, { encodedQueryParams: true })
262
+ .post('/apis/apps/v1/namespaces/default/replicasets')
263
+ .reply(201, replicaSet);
264
+ const response = await k8s.post(replicaSet);
265
+ expect(response.kind).toEqual('ReplicaSet');
266
+ });
267
+ it('can post a service', async () => {
268
+ nock(_url, { encodedQueryParams: true })
269
+ .post('/api/v1/namespaces/default/services')
270
+ .reply(201, service);
271
+ const response = await k8s.post(service);
272
+ expect(response.kind).toEqual('Service');
273
+ });
274
+ });
275
+ describe('->patch', () => {
276
+ it('can patch a deployment by name', async () => {
277
+ nock(_url, { encodedQueryParams: true })
278
+ .patch('/apis/apps/v1/namespaces/default/deployments/test1')
279
+ .reply(204, {});
280
+ const response = await k8s.patch({ name: 'testName' }, 'test1');
281
+ expect(response).toEqual({});
282
+ });
283
+ it('will throw on a reponse code >= 400', async () => {
284
+ nock(_url)
285
+ .patch('/apis/apps/v1/namespaces/default/deployments/bad-response')
286
+ .replyWithError({ statusCode: 400 })
287
+ .patch('/apis/apps/v1/namespaces/default/deployments/bad-response')
288
+ .replyWithError({ statusCode: 400 })
289
+ .patch('/apis/apps/v1/namespaces/default/deployments/bad-response')
290
+ .replyWithError({ statusCode: 400 });
291
+ await expect(k8s.patch({ name: 'bad-response' }, 'bad-response'))
292
+ .rejects.toThrow('Request k8s.patch with name: bad-response failed with: TSError: {"statusCode":400}');
293
+ });
294
+ });
295
+ describe('->delete', () => {
296
+ it('will throw if name is undefined', async () => {
297
+ await expect(k8s.delete(undefined, 'deployments'))
298
+ .rejects.toThrow('Name of resource to delete must be specified. Received: "undefined".');
299
+ });
300
+ it('will throw if name is an empty string', async () => {
301
+ await expect(k8s.delete('', 'deployments'))
302
+ .rejects.toThrow('Name of resource to delete must be specified. Received: "".');
303
+ });
304
+ it('can delete a deployment by name', async () => {
305
+ nock(_url)
306
+ .delete('/apis/apps/v1/namespaces/default/deployments/test1')
307
+ .reply(200, {});
308
+ const response = await k8s.delete('test1', 'deployments');
309
+ expect(response).toEqual({});
310
+ });
311
+ it('can delete a service by name', async () => {
312
+ nock(_url)
313
+ .delete('/api/v1/namespaces/default/services/test1')
314
+ .reply(200, {});
315
+ const response = await k8s.delete('test1', 'services');
316
+ expect(response).toEqual({});
317
+ });
318
+ it('can delete a job by name', async () => {
319
+ nock(_url)
320
+ .delete('/apis/batch/v1/namespaces/default/jobs/test1')
321
+ .reply(200, {});
322
+ const response = await k8s.delete('test1', 'jobs');
323
+ expect(response).toEqual({});
324
+ });
325
+ it('can delete a pod by name', async () => {
326
+ nock(_url)
327
+ .delete('/api/v1/namespaces/default/pods/test1')
328
+ .reply(200, {});
329
+ const response = await k8s.delete('test1', 'pods');
330
+ expect(response).toEqual({});
331
+ });
332
+ it('can delete a replicaset by name', async () => {
333
+ nock(_url)
334
+ .delete('/apis/apps/v1/namespaces/default/replicasets/test1')
335
+ .reply(200, {});
336
+ const response = await k8s.delete('test1', 'replicasets');
337
+ expect(response).toEqual({});
338
+ });
339
+ it('will throw on a reponse code >= 400, excluding 404', async () => {
340
+ nock(_url)
341
+ .delete('/api/v1/namespaces/default/pods/bad-response')
342
+ .replyWithError({ statusCode: 400 })
343
+ .delete('/api/v1/namespaces/default/pods/bad-response')
344
+ .replyWithError({ statusCode: 400 })
345
+ .delete('/api/v1/namespaces/default/pods/bad-response')
346
+ .replyWithError({ statusCode: 400 });
347
+ await expect(k8s.delete('bad-response', 'pods'))
348
+ .rejects.toThrow('Request k8s.delete with name: bad-response failed with: TSError: {"statusCode":400}');
349
+ });
350
+ it('will succeed on a 404 response code', async () => {
351
+ const notFoundResponse = {
352
+ body: {
353
+ kind: 'Status',
354
+ apiVersion: 'v1',
355
+ metadata: {},
356
+ status: 'Failure',
357
+ message: 'pods "non-existent" not found',
358
+ reason: 'NotFound',
359
+ details: { name: 'non-existent', kind: 'pods' },
360
+ code: 404
361
+ },
362
+ statusCode: 404
363
+ };
364
+ nock(_url)
365
+ .delete('/api/v1/namespaces/default/pods/non-existent')
366
+ .replyWithError(notFoundResponse);
367
+ const response = await k8s.delete('non-existent', 'pods');
368
+ expect(response).toEqual(notFoundResponse.body);
369
+ });
370
+ });
371
+ describe('->_deletObjByExId', () => {
372
+ it('can delete a single object', async () => {
373
+ nock(_url)
374
+ .get('/apis/batch/v1/namespaces/default/jobs')
375
+ .query({ labelSelector: /app\.kubernetes\.io\/component=execution_controller,teraslice\.terascope\.io\/exId=.*/ })
376
+ .reply(200, {
377
+ kind: 'JobList',
378
+ items: [job]
379
+ });
380
+ nock(_url)
381
+ .delete('/apis/batch/v1/namespaces/default/jobs/testJob1')
382
+ .reply(200, status);
383
+ const response = await k8s._deleteObjByExId('testJob1', 'execution_controller', 'jobs');
384
+ expect(response).toEqual([expect.objectContaining(status)]);
385
+ });
386
+ it('can delete a multiple objects', async () => {
387
+ nock(_url)
388
+ .get('/api/v1/namespaces/default/pods')
389
+ .query({ labelSelector: /app\.kubernetes\.io\/component=worker,teraslice\.terascope\.io\/exId=.*/ })
390
+ .reply(200, {
391
+ kind: 'PodList',
392
+ items: [testPod1, testPod2]
393
+ })
394
+ .delete('/api/v1/namespaces/default/pods/testPod1')
395
+ .reply(200, testPod1)
396
+ .delete('/api/v1/namespaces/default/pods/testPod2')
397
+ .reply(200, testPod2);
398
+ const response = await k8s._deleteObjByExId('testPods', 'worker', 'pods');
399
+ expect(response).toEqual([
400
+ expect.objectContaining(testPod1),
401
+ expect.objectContaining(testPod2)
402
+ ]);
403
+ });
404
+ });
405
+ describe('->scaleExecution', () => {
406
+ let scope;
407
+ beforeEach(() => {
408
+ deployment.spec.replicas = 5;
409
+ scope = nock(_url)
410
+ .get('/apis/apps/v1/namespaces/default/deployments')
411
+ .query({ labelSelector: /app\.kubernetes\.io\/component=worker,teraslice\.terascope\.io\/exId=.*/ })
412
+ .reply(200, {
413
+ kind: 'DeploymentList',
414
+ items: [deployment]
415
+ });
416
+ });
417
+ it('can set nodes to a deployment to 2', async () => {
418
+ deployment.spec.replicas = 2;
419
+ scope.patch('/apis/apps/v1/namespaces/default/deployments/dname', [
420
+ {
421
+ op: 'replace',
422
+ path: '/spec/replicas',
423
+ value: 2
424
+ }
425
+ ]).reply(200, deployment);
426
+ const response = await k8s.scaleExecution('abcde1234', 2, 'set');
427
+ expect(response.spec?.replicas).toEqual(2);
428
+ });
429
+ it('can add 2 nodes to a deployment with 5 to get 7', async () => {
430
+ deployment.spec.replicas = 7;
431
+ scope.patch('/apis/apps/v1/namespaces/default/deployments/dname', [
432
+ {
433
+ op: 'replace',
434
+ path: '/spec/replicas',
435
+ value: 7
436
+ }
437
+ ]).reply(200, deployment);
438
+ const response = await k8s.scaleExecution('abcde1234', 2, 'add');
439
+ expect(response.spec?.replicas).toEqual(7);
440
+ });
441
+ it('can remove 2 nodes from a deployment with 5 to get 3', async () => {
442
+ deployment.spec.replicas = 3;
443
+ scope.patch('/apis/apps/v1/namespaces/default/deployments/dname', [
444
+ {
445
+ op: 'replace',
446
+ path: '/spec/replicas',
447
+ value: 3
448
+ }
449
+ ]).reply(200, deployment);
450
+ const response = await k8s.scaleExecution('abcde1234', 2, 'remove');
451
+ expect(response.spec?.replicas).toEqual(3);
452
+ });
453
+ });
454
+ });
455
+ //# sourceMappingURL=k8s-v2-spec.js.map