From 7eba48f8b832ec16465565f210e659a9f822e5b3 Mon Sep 17 00:00:00 2001 From: Christina Ying Wang Date: Wed, 14 Jun 2023 19:50:26 -0700 Subject: [PATCH] Improve tests surrounding Engine-host race patch See: #2170 Change-type: patch Signed-off-by: Christina Ying Wang --- .../compose/application-manager.spec.ts | 483 ++++++++++++------ test/unit/compose/app.spec.ts | 159 +++--- 2 files changed, 406 insertions(+), 236 deletions(-) diff --git a/test/integration/compose/application-manager.spec.ts b/test/integration/compose/application-manager.spec.ts index 71444d1a..745521fd 100644 --- a/test/integration/compose/application-manager.spec.ts +++ b/test/integration/compose/application-manager.spec.ts @@ -1424,20 +1424,19 @@ describe('compose/application-manager', () => { // In this case, the Supervisor needs to wait a grace period for the Engine to start the container, and if this does not occur, the Supervisor // deduces the existence of this race condition and generates another start step after a delay (SECONDS_TO_WAIT_FOR_START). describe('handling Engine restart policy inaction when host resource required by container is delayed in creation', () => { - // Time 61 seconds ago - const date61SecondsAgo = new Date(); - date61SecondsAgo.setSeconds(date61SecondsAgo.getSeconds() - 61); + const SECONDS_TO_WAIT_FOR_START = 30; + const newer = SECONDS_TO_WAIT_FOR_START - 2; + const older = SECONDS_TO_WAIT_FOR_START + 2; - // Time 59 seconds ago - const date50SecondsAgo = new Date(); - date50SecondsAgo.setSeconds(date50SecondsAgo.getSeconds() - 50); + const getTimeNSecondsAgo = (date: Date, seconds: number) => { + const newDate = new Date(date); + newDate.setSeconds(newDate.getSeconds() - seconds); + return newDate; + }; - // TODO: We need to be able to start a service with restart policy "no" if that service did not start at all due to - // the host resource race condition described above. However, this is harder to parse as the containers do not include - // the proper metadata for this. The last resort would be parsing the error message that caused the container to exit. - it('should not infer any steps for a service with a status of "exited" if restart policy is "no" or "on-failure"', async () => { + it('should not infer any steps for a service with a status of "exited" if restart policy is "no"', async () => { // Conditions: - // - restart: "no" || "on-failure" + // - restart: "no" // - status: "exited" const targetApps = createApps( { @@ -1456,20 +1455,6 @@ describe('compose/application-manager', () => { restart: 'no', }, }), - await createService({ - image: 'image-3', - serviceName: 'three', - composition: { - restart: 'on-failure', - }, - }), - await createService({ - image: 'image-4', - serviceName: 'four', - composition: { - restart: 'on-failure', - }, - }), ], networks: [DEFAULT_NETWORK], }, @@ -1490,8 +1475,7 @@ describe('compose/application-manager', () => { { state: { status: 'exited', - // Should not generate noop if exited within SECONDS_TO_WAIT_FOR_START - createdAt: date50SecondsAgo, + createdAt: getTimeNSecondsAgo(new Date(), newer), }, }, ), @@ -1506,40 +1490,7 @@ describe('compose/application-manager', () => { { state: { status: 'exited', - // Should not generate start if exited more than SECONDS_TO_WAIT_FOR_START ago - createdAt: date61SecondsAgo, - }, - }, - ), - await createService( - { - image: 'image-3', - serviceName: 'three', - composition: { - restart: 'on-failure', - }, - }, - { - state: { - status: 'exited', - // Should not generate noop if exited within SECONDS_TO_WAIT_FOR_START - createdAt: date50SecondsAgo, - }, - }, - ), - await createService( - { - image: 'image-4', - serviceName: 'four', - composition: { - restart: 'on-failure', - }, - }, - { - state: { - status: 'exited', - // Should not generate start if exited more than SECONDS_TO_WAIT_FOR_START ago - createdAt: date61SecondsAgo, + createdAt: getTimeNSecondsAgo(new Date(), older), }, }, ), @@ -1554,14 +1505,6 @@ describe('compose/application-manager', () => { name: 'image-2', serviceName: 'two', }), - createImage({ - name: 'image-3', - serviceName: 'three', - }), - createImage({ - name: 'image-4', - serviceName: 'four', - }), ], }); @@ -1578,36 +1521,41 @@ describe('compose/application-manager', () => { expect(steps).to.have.lengthOf(0); }); - it('should infer a noop step for a service that was created <= SECONDS_TO_WAIT_FOR_START ago with status of "exited" if restart policy is "always" or "unless-stopped"', async () => { - // Conditions: - // - restart: "always" || "unless-stopped" - // - status: "exited" - // - createdAt: <= SECONDS_TO_WAIT_FOR_START ago - const targetApps = createApps( - { - services: [ - await createService({ - image: 'image-1', - serviceName: 'one', - composition: { - restart: 'always', - }, - }), - await createService({ - image: 'image-2', - serviceName: 'two', - composition: { - restart: 'unless-stopped', - }, - }), - ], - networks: [DEFAULT_NETWORK], - }, - true, - ); + describe('restart policy "on-failure"', () => { + it('should not infer any steps for a service that exited with code 0', async () => { + // Conditions: + // - restart: "on-failure" + // - status: "exited" + // - exitCode: 0 + const targetApps = createApps( + { + services: [ + await createService({ + image: 'image-1', + serviceName: 'one', + composition: { + restart: 'on-failure', + }, + }), + await createService({ + image: 'image-2', + serviceName: 'two', + composition: { + restart: 'on-failure', + }, + }), + ], + networks: [DEFAULT_NETWORK], + }, + true, + ); - const { currentApps, availableImages, downloading, containerIdsByAppId } = - createCurrentState({ + const { + currentApps, + availableImages, + downloading, + containerIdsByAppId, + } = createCurrentState({ services: [ await createService( { @@ -1615,13 +1563,14 @@ describe('compose/application-manager', () => { serviceName: 'one', running: false, composition: { - restart: 'always', + restart: 'on-failure', }, }, { state: { status: 'exited', - createdAt: date50SecondsAgo, + exitCode: 0, + createdAt: getTimeNSecondsAgo(new Date(), newer), }, }, ), @@ -1631,13 +1580,14 @@ describe('compose/application-manager', () => { serviceName: 'two', running: false, composition: { - restart: 'unless-stopped', + restart: 'on-failure', }, }, { state: { status: 'exited', - createdAt: date50SecondsAgo, + exitCode: 0, + createdAt: getTimeNSecondsAgo(new Date(), older), }, }, ), @@ -1655,49 +1605,189 @@ describe('compose/application-manager', () => { ], }); - const [noopStep1, noopStep2, ...nextSteps] = - await applicationManager.inferNextSteps(currentApps, targetApps, { - downloading, + const [...steps] = await applicationManager.inferNextSteps( + currentApps, + targetApps, + { + downloading, + availableImages, + containerIdsByAppId, + }, + ); + + expect(steps).to.have.lengthOf(0); + }); + + it('should infer a noop step for a service that was created <= SECONDS_TO_WAIT_FOR_START ago and exited non-zero', async () => { + // Conditions: + // - restart: "on-failure" + // - status: "exited" + // - exitCode: non-zero + // - createdAt: <= SECONDS_TO_WAIT_FOR_START + const targetApps = createApps( + { + services: [ + await createService({ + image: 'image-1', + serviceName: 'one', + composition: { + restart: 'on-failure', + }, + }), + ], + networks: [DEFAULT_NETWORK], + }, + true, + ); + + const { + currentApps, availableImages, + downloading, containerIdsByAppId, + } = createCurrentState({ + services: [ + await createService( + { + image: 'image-1', + serviceName: 'one', + running: false, + composition: { + restart: 'on-failure', + }, + }, + { + state: { + status: 'exited', + exitCode: 1, + createdAt: getTimeNSecondsAgo(new Date(), newer), + }, + }, + ), + ], + networks: [DEFAULT_NETWORK], + images: [ + createImage({ + name: 'image-1', + serviceName: 'one', + }), + ], }); - expect(noopStep1).to.have.property('action').that.equals('noop'); - expect(noopStep2).to.have.property('action').that.equals('noop'); + const [noopStep, ...nextSteps] = + await applicationManager.inferNextSteps(currentApps, targetApps, { + downloading, + availableImages, + containerIdsByAppId, + }); - expect(nextSteps).to.have.lengthOf(0); + expect(noopStep).to.have.property('action').that.equals('noop'); + expect(nextSteps).to.have.lengthOf(0); + }); + + it('should infer a start step for a service that was created > SECONDS_TO_WAIT_FOR_START ago and exited non-zero', async () => { + // Conditions: + // - restart: "on-failure" + // - status: "exited" + // - exitCode: non-zero\ + // - createdAt: > SECONDS_TO_WAIT_FOR_START + const targetApps = createApps( + { + services: [ + await createService({ + image: 'image-1', + serviceName: 'one', + composition: { + restart: 'on-failure', + }, + }), + ], + networks: [DEFAULT_NETWORK], + }, + true, + ); + + const { + currentApps, + availableImages, + downloading, + containerIdsByAppId, + } = createCurrentState({ + services: [ + await createService( + { + image: 'image-1', + serviceName: 'one', + running: false, + composition: { + restart: 'on-failure', + }, + }, + { + state: { + status: 'exited', + exitCode: 1, + createdAt: getTimeNSecondsAgo(new Date(), older), + }, + }, + ), + ], + networks: [DEFAULT_NETWORK], + images: [ + createImage({ + name: 'image-1', + serviceName: 'one', + }), + ], + }); + + const [startStep, ...nextSteps] = + await applicationManager.inferNextSteps(currentApps, targetApps, { + downloading, + availableImages, + containerIdsByAppId, + }); + + expect(startStep).to.have.property('action').that.equals('start'); + expect(nextSteps).to.have.lengthOf(0); + }); }); - it('should infer a start step for a service that was created > SECONDS_TO_WAIT_FOR_START ago with status of "exited" if restart policy is "always" or "unless-stopped"', async () => { - // Conditions: - // - restart: "always" || "unless-stopped" - // - status: "exited" - // - createdAt: > SECONDS_TO_WAIT_FOR_START ago - const targetApps = createApps( - { - services: [ - await createService({ - image: 'image-1', - serviceName: 'one', - composition: { - restart: 'always', - }, - }), - await createService({ - image: 'image-2', - serviceName: 'two', - composition: { - restart: 'unless-stopped', - }, - }), - ], - networks: [DEFAULT_NETWORK], - }, - true, - ); + describe('restart policy "always" or "unless-stopped"', () => { + it('should infer a noop step for a service that was created <= SECONDS_TO_WAIT_FOR_START ago with status of "exited"', async () => { + // Conditions: + // - restart: "always" || "unless-stopped" + // - status: "exited" + // - createdAt: <= SECONDS_TO_WAIT_FOR_START ago + const targetApps = createApps( + { + services: [ + await createService({ + image: 'image-1', + serviceName: 'one', + composition: { + restart: 'always', + }, + }), + await createService({ + image: 'image-2', + serviceName: 'two', + composition: { + restart: 'unless-stopped', + }, + }), + ], + networks: [DEFAULT_NETWORK], + }, + true, + ); - const { currentApps, availableImages, downloading, containerIdsByAppId } = - createCurrentState({ + const { + currentApps, + availableImages, + downloading, + containerIdsByAppId, + } = createCurrentState({ services: [ await createService( { @@ -1711,7 +1801,7 @@ describe('compose/application-manager', () => { { state: { status: 'exited', - createdAt: date61SecondsAgo, + createdAt: getTimeNSecondsAgo(new Date(), newer), }, }, ), @@ -1727,7 +1817,7 @@ describe('compose/application-manager', () => { { state: { status: 'exited', - createdAt: date61SecondsAgo, + createdAt: getTimeNSecondsAgo(new Date(), newer), }, }, ), @@ -1745,21 +1835,116 @@ describe('compose/application-manager', () => { ], }); - const [startStep1, startStep2, ...nextSteps] = - await applicationManager.inferNextSteps(currentApps, targetApps, { - downloading, + const [noopStep1, noopStep2, ...nextSteps] = + await applicationManager.inferNextSteps(currentApps, targetApps, { + downloading, + availableImages, + containerIdsByAppId, + }); + + expect(noopStep1).to.have.property('action').that.equals('noop'); + expect(noopStep2).to.have.property('action').that.equals('noop'); + + expect(nextSteps).to.have.lengthOf(0); + }); + + it('should infer a start step for a service that was created > SECONDS_TO_WAIT_FOR_START ago with status of "exited"', async () => { + // Conditions: + // - restart: "always" || "unless-stopped" + // - status: "exited" + // - createdAt: > SECONDS_TO_WAIT_FOR_START ago + const targetApps = createApps( + { + services: [ + await createService({ + image: 'image-1', + serviceName: 'one', + composition: { + restart: 'always', + }, + }), + await createService({ + image: 'image-2', + serviceName: 'two', + composition: { + restart: 'unless-stopped', + }, + }), + ], + networks: [DEFAULT_NETWORK], + }, + true, + ); + + const { + currentApps, availableImages, + downloading, containerIdsByAppId, + } = createCurrentState({ + services: [ + await createService( + { + image: 'image-1', + serviceName: 'one', + running: false, + composition: { + restart: 'always', + }, + }, + { + state: { + status: 'exited', + createdAt: getTimeNSecondsAgo(new Date(), older), + }, + }, + ), + await createService( + { + image: 'image-2', + serviceName: 'two', + running: false, + composition: { + restart: 'unless-stopped', + }, + }, + { + state: { + status: 'exited', + createdAt: getTimeNSecondsAgo(new Date(), older), + }, + }, + ), + ], + networks: [DEFAULT_NETWORK], + images: [ + createImage({ + name: 'image-1', + serviceName: 'one', + }), + createImage({ + name: 'image-2', + serviceName: 'two', + }), + ], }); - [startStep1, startStep2].forEach((step) => { - expect(step).to.have.property('action').that.equals('start'); - expect(step) - .to.have.property('target') - .that.has.property('serviceName') - .that.is.oneOf(['one', 'two']); + const [startStep1, startStep2, ...nextSteps] = + await applicationManager.inferNextSteps(currentApps, targetApps, { + downloading, + availableImages, + containerIdsByAppId, + }); + + [startStep1, startStep2].forEach((step) => { + expect(step).to.have.property('action').that.equals('start'); + expect(step) + .to.have.property('target') + .that.has.property('serviceName') + .that.is.oneOf(['one', 'two']); + }); + expect(nextSteps).to.have.lengthOf(0); }); - expect(nextSteps).to.have.lengthOf(0); }); }); }); diff --git a/test/unit/compose/app.spec.ts b/test/unit/compose/app.spec.ts index b6e17fa8..a068d4bf 100644 --- a/test/unit/compose/app.spec.ts +++ b/test/unit/compose/app.spec.ts @@ -111,7 +111,7 @@ const defaultNetwork = Network.fromComposeObject('default', 1, 'appuuid', {}); describe('compose/app', () => { describe('volume state behavior', () => { - it('should correctly infer a volume create step', async () => { + it('should correctly infer a volume create step', () => { // Setup current and target apps const current = createApp(); const target = createApp({ @@ -120,7 +120,7 @@ describe('compose/app', () => { }); // Calculate the steps - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); // Check that a createVolume step has been created const [createVolumeStep] = expectSteps('createVolume', steps); @@ -129,7 +129,7 @@ describe('compose/app', () => { .that.deep.includes({ name: 'test-volume' }); }); - it('should correctly infer more than one volume create step', async () => { + it('should correctly infer more than one volume create step', () => { const current = createApp(); const target = createApp({ volumes: [ @@ -139,7 +139,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); // Check that 2 createVolume steps are found const createVolumeSteps = expectSteps('createVolume', steps, 2); @@ -160,7 +160,7 @@ describe('compose/app', () => { }); // We don't remove volumes until the end - it('should not infer a volume remove step when the app is still referenced', async () => { + it('should not infer a volume remove step when the app is still referenced', () => { const current = createApp({ volumes: [ Volume.fromComposeObject('test-volume', 1, 'deadbeef'), @@ -172,11 +172,11 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); expectNoStep('removeVolume', steps); }); - it('should correctly infer volume recreation steps', async () => { + it('should correctly infer volume recreation steps', () => { const current = createApp({ volumes: [Volume.fromComposeObject('test-volume', 1, 'deadbeef')], }); @@ -190,7 +190,7 @@ describe('compose/app', () => { }); // First step should create a volume removal step - const stepsForRemoval = await current.nextStepsForAppUpdate( + const stepsForRemoval = current.nextStepsForAppUpdate( defaultContext, target, ); @@ -212,7 +212,7 @@ describe('compose/app', () => { }); // This test is extra since we have already tested that the volume gets created - const stepsForCreation = await intermediate.nextStepsForAppUpdate( + const stepsForCreation = intermediate.nextStepsForAppUpdate( defaultContext, target, ); @@ -254,7 +254,7 @@ describe('compose/app', () => { }); // Calculate steps - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [killStep] = expectSteps('kill', steps); expect(killStep) @@ -294,7 +294,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); expectNoStep('kill', steps); }); @@ -333,7 +333,7 @@ describe('compose/app', () => { }); // Step 1: kill - const steps = await current.nextStepsForAppUpdate( + const steps = current.nextStepsForAppUpdate( contextWithImages, intermediateTarget, ); @@ -341,7 +341,7 @@ describe('compose/app', () => { // Step 2: noop (service is stopping) service.status = 'Stopping'; - const secondStageSteps = await current.nextStepsForAppUpdate( + const secondStageSteps = current.nextStepsForAppUpdate( contextWithImages, intermediateTarget, ); @@ -355,7 +355,7 @@ describe('compose/app', () => { volumes: [volume], }); expect( - await currentWithServiceRemoved.nextStepsForAppUpdate( + currentWithServiceRemoved.nextStepsForAppUpdate( contextWithImages, intermediateTarget, ), @@ -377,7 +377,7 @@ describe('compose/app', () => { isTarget: true, }); const recreateVolumeSteps = - await currentWithVolumesRemoved.nextStepsForAppUpdate( + currentWithVolumesRemoved.nextStepsForAppUpdate( contextWithImages, target, ); @@ -393,7 +393,7 @@ describe('compose/app', () => { }); const createServiceSteps = - await currentWithVolumeRecreated.nextStepsForAppUpdate( + currentWithVolumeRecreated.nextStepsForAppUpdate( contextWithImages, target, ); @@ -402,14 +402,14 @@ describe('compose/app', () => { }); describe('network state behavior', () => { - it('should correctly infer a network create step', async () => { + it('should correctly infer a network create step', () => { const current = createApp({ networks: [] }); const target = createApp({ networks: [Network.fromComposeObject('default', 1, 'deadbeef', {})], isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [createNetworkStep] = expectSteps('createNetwork', steps); expect(createNetworkStep).to.have.property('target').that.deep.includes({ @@ -417,7 +417,7 @@ describe('compose/app', () => { }); }); - it('should correctly infer a network remove step', async () => { + it('should correctly infer a network remove step', () => { const current = createApp({ networks: [ Network.fromComposeObject('test-network', 1, 'deadbeef', {}), @@ -425,7 +425,7 @@ describe('compose/app', () => { }); const target = createApp({ networks: [], isTarget: true }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [removeNetworkStep] = expectSteps('removeNetwork', steps); @@ -434,7 +434,7 @@ describe('compose/app', () => { }); }); - it('should correctly remove default duplicate networks', async () => { + it('should correctly remove default duplicate networks', () => { const current = createApp({ networks: [defaultNetwork, defaultNetwork], }); @@ -443,7 +443,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [removeNetworkStep] = expectSteps('removeNetwork', steps); @@ -452,7 +452,7 @@ describe('compose/app', () => { }); }); - it('should correctly remove duplicate networks', async () => { + it('should correctly remove duplicate networks', () => { const current = createApp({ networks: [ Network.fromComposeObject('test-network', 1, 'deadbeef', {}), @@ -468,7 +468,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [removeNetworkStep] = expectSteps('removeNetwork', steps); @@ -477,7 +477,7 @@ describe('compose/app', () => { }); }); - it('should ignore the duplicates if there are changes already', async () => { + it('should ignore the duplicates if there are changes already', () => { const current = createApp({ networks: [ Network.fromComposeObject('test-network', 1, 'deadbeef', {}), @@ -494,7 +494,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [removeNetworkStep] = expectSteps('removeNetwork', steps); expect(removeNetworkStep).to.have.property('current').that.deep.includes({ @@ -534,7 +534,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [removeNetworkStep] = expectSteps('kill', steps); @@ -543,7 +543,7 @@ describe('compose/app', () => { }); }); - it('should correctly infer more than one network removal step', async () => { + it('should correctly infer more than one network removal step', () => { const current = createApp({ networks: [ Network.fromComposeObject('test-network', 1, 'deadbeef', {}), @@ -553,7 +553,7 @@ describe('compose/app', () => { }); const target = createApp({ networks: [], isTarget: true }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [first, second] = expectSteps('removeNetwork', steps, 2); @@ -565,7 +565,7 @@ describe('compose/app', () => { }); }); - it('should correctly infer a network recreation step', async () => { + it('should correctly infer a network recreation step', () => { const current = createApp({ networks: [ Network.fromComposeObject('test-network', 1, 'deadbeef', {}), @@ -580,7 +580,7 @@ describe('compose/app', () => { isTarget: true, }); - const stepsForRemoval = await current.nextStepsForAppUpdate( + const stepsForRemoval = current.nextStepsForAppUpdate( defaultContext, target, ); @@ -595,7 +595,7 @@ describe('compose/app', () => { networks: [], }); - const stepsForCreation = await intermediate.nextStepsForAppUpdate( + const stepsForCreation = intermediate.nextStepsForAppUpdate( defaultContext, target, ); @@ -641,7 +641,7 @@ describe('compose/app', () => { const availableImages = [createImage({ appUuid: 'deadbeef' })]; - const steps = await current.nextStepsForAppUpdate( + const steps = current.nextStepsForAppUpdate( { ...defaultContext, availableImages }, target, ); @@ -674,7 +674,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [killStep] = expectSteps('kill', steps); expect(killStep) @@ -730,7 +730,7 @@ describe('compose/app', () => { createImage({ appId: 1, serviceName: 'two', name: 'alpine' }), ]; - const steps = await current.nextStepsForAppUpdate( + const steps = current.nextStepsForAppUpdate( { ...defaultContext, availableImages }, target, ); @@ -793,7 +793,7 @@ describe('compose/app', () => { createImage({ appId: 1, serviceName: 'two', name: 'alpine' }), ]; - const steps = await current.nextStepsForAppUpdate( + const steps = current.nextStepsForAppUpdate( { ...defaultContext, availableImages }, target, ); @@ -808,11 +808,11 @@ describe('compose/app', () => { expectNoStep('removeNetwork', steps); }); - it('should create the default network if it does not exist', async () => { + it('should create the default network if it does not exist', () => { const current = createApp({ networks: [] }); const target = createApp({ networks: [], isTarget: true }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); // A default network should always be created const [createNetworkStep] = expectSteps('createNetwork', steps); @@ -821,13 +821,13 @@ describe('compose/app', () => { .that.deep.includes({ name: 'default' }); }); - it('should not create the default network if it already exists', async () => { + it('should not create the default network if it already exists', () => { const current = createApp({ networks: [Network.fromComposeObject('default', 1, 'deadbeef', {})], }); const target = createApp({ networks: [], isTarget: true }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); // The network should not be created again expectNoStep('createNetwork', steps); @@ -854,7 +854,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [createNetworkStep] = expectSteps('createNetwork', steps); expect(createNetworkStep) @@ -883,7 +883,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [createNetworkStep] = expectSteps('createNetwork', steps); expect(createNetworkStep) @@ -892,11 +892,11 @@ describe('compose/app', () => { .that.deep.includes({ configOnly: false }); }); - it('should create a config-only network if there are no services in the app', async () => { + it('should create a config-only network if there are no services in the app', () => { const current = createApp({}); const target = createApp({ isTarget: true }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [createNetworkStep] = expectSteps('createNetwork', steps); expect(createNetworkStep) @@ -921,7 +921,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [killStep] = expectSteps('kill', steps); expect(killStep) .to.have.property('current') @@ -939,7 +939,7 @@ describe('compose/app', () => { }); const target = createApp({ services: [], isTarget: true }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); expectSteps('noop', steps); // Kill was already emitted for this service @@ -959,7 +959,7 @@ describe('compose/app', () => { services: [await createService({ serviceName: 'main', running: true })], }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); expectSteps('noop', steps); }); @@ -977,7 +977,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [removeStep] = expectSteps('remove', steps); expect(removeStep) @@ -996,7 +996,7 @@ describe('compose/app', () => { }); const target = createApp({ services: [], isTarget: true }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [removeStep] = expectSteps('remove', steps); expect(removeStep) @@ -1013,7 +1013,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate( + const steps = current.nextStepsForAppUpdate( { ...defaultContext, ...{ downloading: ['main-image'] } }, target, ); @@ -1034,7 +1034,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [updateMetadataStep] = expectSteps('updateMetadata', steps); expect(updateMetadataStep) @@ -1057,7 +1057,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [stopStep] = expectSteps('stop', steps); expect(stopStep) .to.have.property('current') @@ -1086,7 +1086,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); expectNoStep('start', steps); }); @@ -1118,7 +1118,7 @@ describe('compose/app', () => { }); // should see a 'stop' - const stepsToIntermediate = await current.nextStepsForAppUpdate( + const stepsToIntermediate = current.nextStepsForAppUpdate( contextWithImages, target, ); @@ -1135,7 +1135,7 @@ describe('compose/app', () => { }); // now should see a 'start' - const stepsToTarget = await intermediate.nextStepsForAppUpdate( + const stepsToTarget = intermediate.nextStepsForAppUpdate( contextWithImages, target, ); @@ -1193,7 +1193,7 @@ describe('compose/app', () => { isTarget: true, }); - const stepsToIntermediate = await current.nextStepsForAppUpdate( + const stepsToIntermediate = current.nextStepsForAppUpdate( contextWithImages, target, ); @@ -1216,7 +1216,7 @@ describe('compose/app', () => { }); // we should now see a start for the 'main' service... - const stepsToTarget = await intermediate.nextStepsForAppUpdate( + const stepsToTarget = intermediate.nextStepsForAppUpdate( { ...contextWithImages, ...{ containerIds: { dep: 'dep-id' } } }, target, ); @@ -1248,10 +1248,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate( - contextWithImages, - target, - ); + const steps = current.nextStepsForAppUpdate(contextWithImages, target); // There should be no steps since the engine manages restart policy for stopped containers expect(steps.length).to.equal(0); @@ -1295,7 +1292,7 @@ describe('compose/app', () => { isTarget: true, }); - const stepsToIntermediate = await current.nextStepsForAppUpdate( + const stepsToIntermediate = current.nextStepsForAppUpdate( contextWithImages, target, ); @@ -1311,7 +1308,7 @@ describe('compose/app', () => { networks: [defaultNetwork], }); - const stepsToTarget = await intermediate.nextStepsForAppUpdate( + const stepsToTarget = intermediate.nextStepsForAppUpdate( contextWithImages, target, ); @@ -1382,10 +1379,7 @@ describe('compose/app', () => { }); // No kill steps should be generated - const steps = await current.nextStepsForAppUpdate( - contextWithImages, - target, - ); + const steps = current.nextStepsForAppUpdate(contextWithImages, target); expectNoStep('kill', steps); }); @@ -1427,7 +1421,7 @@ describe('compose/app', () => { isTarget: true, }); - const stepsFirstTry = await current.nextStepsForAppUpdate( + const stepsFirstTry = current.nextStepsForAppUpdate( contextWithImages, target, ); @@ -1438,7 +1432,7 @@ describe('compose/app', () => { .that.deep.includes({ serviceName: 'main' }); // if at first you don't succeed - const stepsSecondTry = await current.nextStepsForAppUpdate( + const stepsSecondTry = current.nextStepsForAppUpdate( contextWithImages, target, ); @@ -1470,7 +1464,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [killStep] = expectSteps('kill', steps); expect(killStep) .to.have.property('current') @@ -1493,7 +1487,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [createNetworkStep] = expectSteps('createNetwork', steps); expect(createNetworkStep) .to.have.property('target') @@ -1534,7 +1528,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); expectSteps('kill', steps, 2); }); @@ -1596,10 +1590,7 @@ describe('compose/app', () => { }); // No kill steps should be generated - const steps = await current.nextStepsForAppUpdate( - contextWithImages, - target, - ); + const steps = current.nextStepsForAppUpdate(contextWithImages, target); expectNoStep('kill', steps); }); @@ -1638,10 +1629,7 @@ describe('compose/app', () => { }); // No kill steps should be generated - const steps = await current.nextStepsForAppUpdate( - contextWithImages, - target, - ); + const steps = current.nextStepsForAppUpdate(contextWithImages, target); expectNoStep('start', steps); }); @@ -1685,10 +1673,7 @@ describe('compose/app', () => { }); // No kill steps should be generated - const steps = await current.nextStepsForAppUpdate( - contextWithImages, - target, - ); + const steps = current.nextStepsForAppUpdate(contextWithImages, target); expectSteps('start', steps, 2); }); }); @@ -1701,7 +1686,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [fetchStep] = expectSteps('fetch', steps); expect(fetchStep) .to.have.property('image') @@ -1723,7 +1708,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate( + const steps = current.nextStepsForAppUpdate( contextWithDownloading, target, ); @@ -1739,7 +1724,7 @@ describe('compose/app', () => { isTarget: true, }); - const steps = await current.nextStepsForAppUpdate(defaultContext, target); + const steps = current.nextStepsForAppUpdate(defaultContext, target); const [fetchStep] = expectSteps('fetch', steps); expect(fetchStep)