From aab315b97b9c22ff9b175212d6226ef445c7c58d Mon Sep 17 00:00:00 2001 From: Ajinkya Date: Thu, 6 Jun 2019 19:19:32 +0530 Subject: [PATCH 1/2] Adding DockerV2 L0 tests --- Tasks/DockerV2/Tests/L0.ts | 444 ++++++++++++++++++++++++++++- Tasks/DockerV2/Tests/TestSetup.ts | 225 +++++++++++++++ Tasks/DockerV2/Tests/TestShared.ts | 56 ++++ Tasks/DockerV2/task.json | 2 +- Tasks/DockerV2/task.loc.json | 2 +- 5 files changed, 726 insertions(+), 3 deletions(-) create mode 100644 Tasks/DockerV2/Tests/TestSetup.ts create mode 100644 Tasks/DockerV2/Tests/TestShared.ts diff --git a/Tasks/DockerV2/Tests/L0.ts b/Tasks/DockerV2/Tests/L0.ts index 46a7fdcde743..5f43f13d5b58 100644 --- a/Tasks/DockerV2/Tests/L0.ts +++ b/Tasks/DockerV2/Tests/L0.ts @@ -1,18 +1,460 @@ +import * as path from "path"; import * as assert from "assert"; +import * as ttm from "vsts-task-lib/mock-test"; import * as tl from "vsts-task-lib/task"; import * as dockerCommandUtils from "docker-common/dockercommandutils"; +import * as shared from "./TestShared"; describe("DockerV2 Suite", function () { - this.timeout(10000); + this.timeout(30000); if (!tl.osType().match(/^Win/)) { return; } before((done) => { + process.env[shared.TestEnvVars.operatingSystem] = tl.osType().match(/^Win/) ? shared.OperatingSystems.Windows : shared.OperatingSystems.Other; done(); }); + + beforeEach(() => { + delete process.env[shared.TestEnvVars.containerRegistry]; + delete process.env[shared.TestEnvVars.repository]; + delete process.env[shared.TestEnvVars.command]; + delete process.env[shared.TestEnvVars.dockerFile]; + delete process.env[shared.TestEnvVars.buildContext]; + delete process.env[shared.TestEnvVars.tags]; + delete process.env[shared.TestEnvVars.arguments]; + }); + + after(function () { + }); + + // Docker build tests begin + it('Runs successfully for docker build', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Runs successfully for docker build when registry other than Docker hub is used', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "acrendpoint"; + process.env[shared.TestEnvVars.repository] = "testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testacr.azurecr.io/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Runs successfully for docker build without containerRegistry and repository inputs', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Docker build should honour Dockerfile input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + process.env[shared.TestEnvVars.dockerFile] = shared.formatPath("a/w/meta/Dockerfile"); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/meta/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Docker build should honour buildContext input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + process.env[shared.TestEnvVars.buildContext] = shared.formatPath("a/w/context"); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w/context")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Docker build should work correctly with multiple tags', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + process.env[shared.TestEnvVars.tags] = "tag1\ntag2\ntag3"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:tag1 -t testuser/testrepo:tag2 -t testuser/testrepo:tag3 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Docker build should honour arguments input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + process.env[shared.TestEnvVars.arguments] = "--rm --queit"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} --rm --queit -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Docker build should honour multiline arguments input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + process.env[shared.TestEnvVars.arguments] = "--rm\n--queit"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} --rm --queit -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + + it('Docker build should ensure that the image name follows the Docker naming conventions', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "Test User/TEST repo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); + // Docker build tests end + + // Docker push tests begin + it('Runs successfully for docker push', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.push; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 2, 'should have invoked tool two times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Runs successfully for docker push when registry other than Docker hub is used', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "acrendpoint"; + process.env[shared.TestEnvVars.repository] = "testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.push; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 2, 'should have invoked tool two times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker push testacr.azurecr.io/testrepo:11`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testacr.azurecr.io/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker push should work with multiple tags', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.push; + process.env[shared.TestEnvVars.tags] = "tag1\ntag2\ntag3"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 6, 'should have invoked tool six times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag1`) != -1, "docker push should have pushed tag1"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag2`) != -1, "docker push should have pushed tag2"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag3`) != -1, "docker push should have pushed tag3"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag1`) != -1, "docker history should be invoked for the image"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag2`) != -1, "docker history should be invoked for the image"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag3`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker push should honour arguments input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.push; + process.env[shared.TestEnvVars.arguments] = "--disable-content-trust --arg2"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 2, 'should have invoked tool two times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11 --disable-content-trust --arg2`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker push should honour multiline arguments input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.push; + process.env[shared.TestEnvVars.arguments] = "--disable-content-trust\n--arg2"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 2, 'should have invoked tool two times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11 --disable-content-trust --arg2`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker push should work with multiple tags and honour multiline arguments input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.push; + process.env[shared.TestEnvVars.tags] = "tag1\ntag2\ntag3"; + process.env[shared.TestEnvVars.arguments] = "--disable-content-trust\n--arg2"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 6, 'should have invoked tool six times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag1 --disable-content-trust --arg2`) != -1, "docker push should have pushed tag1 with correct arguments"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag2 --disable-content-trust --arg2`) != -1, "docker push should have pushed tag2 with correct arguments"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag3 --disable-content-trust --arg2`) != -1, "docker push should have pushed tag2 with correct arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag1`) != -1, "docker history should be invoked for the image"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag2`) != -1, "docker history should be invoked for the image"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag3`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker push should ensure that the image name follows the Docker naming conventions', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "Test User/TEST repo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.push; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 2, 'should have invoked tool two times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + // Docker push tests end + + // Docker buildAndPush tests begin + it('Runs successfully for docker buildAndPush', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 3, 'should have invoked tool three times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker buildAndPush should honour Dockerfile input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.dockerFile] = shared.formatPath("a/w/meta/Dockerfile"); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 3, 'should have invoked tool three times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/meta/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker buildAndPush should honour buildContext input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.buildContext] = shared.formatPath("a/w/context"); + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 3, 'should have invoked tool three times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w/context")}`) != -1, "docker build should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker buildAndPush should work correctly with multiple tags', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.tags] = "tag1\ntag2\ntag3"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 7, 'should have invoked tool seven times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:tag1 -t testuser/testrepo:tag2 -t testuser/testrepo:tag3 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag1`) != -1, "docker push should have pushed tag1"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag2`) != -1, "docker push should have pushed tag2"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:tag3`) != -1, "docker push should have pushed tag3"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag1`) != -1, "docker history should be invoked for the image"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag2`) != -1, "docker history should be invoked for the image"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag3`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + + it('Docker buildAndPush should ignore arguments input', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.arguments] = "--rm --queit"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 3, 'should have invoked tool three times. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker push testuser/testrepo:11`) != -1, "docker push should run with expected arguments"); + assert(tr.stdout.indexOf(`[command]docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`) != -1, "docker history should be invoked for the image"); + console.log(tr.stderr); + done(); + }); + // Docker buildAndPush tests end + + // Docker general command tests begin + it('Runs successfully for docker images', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.command] = shared.CommandTypes.images; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker images`) != -1, "docker should be invoked"); + console.log(tr.stderr); + done(); + }); + + it('Runs successfully for docker images with arguments', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.command] = shared.CommandTypes.images; + process.env[shared.TestEnvVars.arguments] = "--all --digests"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker images --all --digests`) != -1, "docker should be invoked with the correct arguments"); + console.log(tr.stderr); + done(); + }); + + it('Runs successfully for docker images with multiline arguments', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.command] = shared.CommandTypes.images; + process.env[shared.TestEnvVars.arguments] = "--all\n--digests"; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker images --all --digests`) != -1, "docker should be invoked with the correct arguments"); + console.log(tr.stderr); + done(); + }); + // Docker general command tests end + // Other tests it("extractSizeInBytes should return correctly", (done: MochaDone) => { console.log("TestCaseName: extractSizeInBytes should return correctly"); diff --git a/Tasks/DockerV2/Tests/TestSetup.ts b/Tasks/DockerV2/Tests/TestSetup.ts new file mode 100644 index 000000000000..68c3cfe1679a --- /dev/null +++ b/Tasks/DockerV2/Tests/TestSetup.ts @@ -0,0 +1,225 @@ +import ma = require('vsts-task-lib/mock-answer'); +import tmrm = require('vsts-task-lib/mock-run'); +import path = require('path'); +import * as shared from './TestShared'; + +const DefaultBuildContext: string = shared.formatPath("a/w/**"); +const DefaultDockerFileInput = shared.formatPath("a/w/**/Dockerfile"); +const DefaultWorkingDirectory: string = shared.formatPath("a/w"); +const DockerfilePath: string = shared.formatPath("a/w/Dockerfile"); +const DockerfilePath2: string = shared.formatPath("a/w/meta/Dockerfile"); +const BuildContextPath: string = shared.formatPath("a/w"); +const BuildContextPath2: string = shared.formatPath("a/w/meta"); +const BuildContextPath3: string = shared.formatPath("a/w/context"); +const Dockerfile: string = `FROM ubuntu\nCMD ["echo","Hello World!"]` + +let taskPath = path.join(__dirname, '..', 'docker.js'); +let tr: tmrm.TaskMockRunner = new tmrm.TaskMockRunner(taskPath); + +tr.setInput('containerRegistry', process.env[shared.TestEnvVars.containerRegistry] || ""); +tr.setInput('repository', process.env[shared.TestEnvVars.repository] || ""); +tr.setInput('command', process.env[shared.TestEnvVars.command] || "buildAndPush"); +tr.setInput('Dockerfile', process.env[shared.TestEnvVars.dockerFile] || DefaultDockerFileInput); +tr.setInput('buildContext', process.env[shared.TestEnvVars.buildContext] || DefaultBuildContext); +tr.setInput('tags', process.env[shared.TestEnvVars.tags] || "11"); +tr.setInput('arguments', process.env[shared.TestEnvVars.arguments] || ""); + +console.log("Inputs have been set"); + +process.env["RELEASE_RELEASENAME"] = "Release-1"; +process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = DefaultWorkingDirectory; +process.env["SYSTEM_HOSTTYPE"] = process.env[shared.TestEnvVars.hostType] || "build"; +process.env["SYSTEM_SERVERTYPE"] = "hosted"; +process.env["ENDPOINT_AUTH_dockerhubendpoint"] = "{\"parameters\":{\"username\":\"testuser\", \"password\":\"regpassword\", \"email\":\"testuser1@microsoft.com\",\"registry\":\"https://index.docker.io/v1/\"},\"scheme\":\"UsernamePassword\"}"; +process.env["ENDPOINT_AUTH_acrendpoint"] = "{\"parameters\":{\"username\":\"testacr\", \"password\":\"acrpassword\",\"registry\":\"https://testacr.azurecr.io/\"},\"scheme\":\"UsernamePassword\"}"; + +// Set variables used for common labels +process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = shared.SharedValues.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI; +process.env["SYSTEM_TEAMPROJECT"] = shared.SharedValues.SYSTEM_TEAMPROJECT; + +// Set variables used for build labels +process.env["BUILD_REPOSITORY_NAME"] = shared.SharedValues.BUILD_REPOSITORY_NAME; +process.env["BUILD_REPOSITORY_URI"] = shared.SharedValues.BUILD_REPOSITORY_URI; +process.env["BUILD_SOURCEBRANCHNAME"] = shared.SharedValues.BUILD_SOURCEBRANCHNAME; +process.env["BUILD_SOURCEVERSION"] = shared.SharedValues.BUILD_SOURCEVERSION; +process.env["BUILD_DEFINITIONNAME"] = shared.SharedValues.BUILD_DEFINITIONNAME; +process.env["BUILD_BUILDNUMBER"] = shared.SharedValues.BUILD_BUILDNUMBER; +process.env["BUILD_BUILDURI"] = shared.SharedValues.BUILD_BUILDURI; + +// Set variables used for release labels +process.env["RELEASE_DEFINITIONNAME"] = shared.SharedValues.RELEASE_DEFINITIONNAME; +process.env["RELEASE_RELEASEID"] = shared.SharedValues.RELEASE_RELEASEID; +process.env["RELEASE_RELEASEWEBURL"] = shared.SharedValues.RELEASE_RELEASEWEBURL; + +// provide answers for task mock +let a = { + "which": { + "docker": "docker" + }, + "checkPath": { + "docker": true + }, + "exist": { + "docker": true + }, + "exec": { + "docker push test/test:2" : { + "code": 0, + "stdout": "successfully pushed test/test:2 image" + }, + "docker run --rm test/test:2" : { + "code": 0, + "stdout": "successfully ran test/test:2 image" + }, + "docker run --rm -m 2GB test/test:2": { + "code": 0, + "stdout": "successfully ran test/test:2 image" + }, + "docker pull test/test:2": { + "code": 0, + "stdout": "successfully pulled test/test:2 image" + } + }, + "find": {} +}; + +// Add extra answer definitions that need to be dynamically generated +a.exist[DockerfilePath] = true; +a.exist[DockerfilePath2] = true; + +a.find[`${DefaultWorkingDirectory}`] = [ + `${DockerfilePath}` +] + +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${BuildContextPath}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} -t testacr.azurecr.io/testrepo:11 ${BuildContextPath}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} ${BuildContextPath}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker build -f ${DockerfilePath2} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${BuildContextPath2}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:11 ${BuildContextPath3}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} -t testuser/testrepo:tag1 -t testuser/testrepo:tag2 -t testuser/testrepo:tag3 ${BuildContextPath}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} --rm --queit -t testuser/testrepo:11 ${BuildContextPath}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} --rm --queit -t testuser/testrepo:11 ${BuildContextPath}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + +a.exec[`docker push testuser/testrepo:11`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:11." +}; + +a.exec[`docker push testacr.azurecr.io/testrepo:11`] = { + "code": 0, + "stdout": "successfully pushed testacr.azurecr.io/testrepo:11." +}; + +a.exec[`docker push testuser/testrepo:tag1`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:tag1." +}; + +a.exec[`docker push testuser/testrepo:tag2`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:tag2." +}; + +a.exec[`docker push testuser/testrepo:tag3`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:tag3." +}; + +a.exec[`docker push testuser/testrepo:11 --disable-content-trust --arg2`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:11 with arguments --disable-content-trust --arg2." +}; + +a.exec[`docker push testuser/testrepo:tag1 --disable-content-trust --arg2`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:tag1 with arguments --disable-content-trust --arg2." +}; + +a.exec[`docker push testuser/testrepo:tag2 --disable-content-trust --arg2`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:tag2 with arguments --disable-content-trust --arg2." +}; + +a.exec[`docker push testuser/testrepo:tag3 --disable-content-trust --arg2`] = { + "code": 0, + "stdout": "successfully pushed testuser/testrepo:tag3 with arguments --disable-content-trust --arg2." +}; + +a.exec[`docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:11`] = { + "code": 0, + "stdout": "" +}; + +a.exec[`docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag1`] = { + "code": 0, + "stdout": "" +}; + +a.exec[`docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag2`] = { + "code": 0, + "stdout": "" +}; + +a.exec[`docker history --format createdAt:{{.CreatedAt}}; layerSize:{{.Size}}; createdBy:{{.CreatedBy}} --no-trunc testuser/testrepo:tag3`] = { + "code": 0, + "stdout": "" +}; + +a.exec[`docker images`] = { + "code": 0, + "stdout": "Listed images successfully." +}; + +a.exec[`docker images --all --digests`] = { + "code": 0, + "stdout": "Listed images successfully with args --all --digests." +}; + +tr.setAnswers(a); + +// Create mock for fs module +let fs = require('fs'); +let fsClone = Object.assign({}, fs); +fsClone.readFileSync = function(filePath, options) { + switch (filePath) { + case DockerfilePath: + case DockerfilePath2: + return Dockerfile; + default: + return fs.readFileSync(filePath, options); + } +}; +tr.registerMock('fs', fsClone); + +tr.run(); \ No newline at end of file diff --git a/Tasks/DockerV2/Tests/TestShared.ts b/Tasks/DockerV2/Tests/TestShared.ts new file mode 100644 index 000000000000..df92d5e4b255 --- /dev/null +++ b/Tasks/DockerV2/Tests/TestShared.ts @@ -0,0 +1,56 @@ +export let TestEnvVars = { + operatingSystem: "__operating_system__", + hostType: "__hostType__", + containerRegistry: "__containerRegistry__", + repository: "__repository__", + command: "__command__", + dockerFile: "__dockerFile__", + buildContext: "__buildContext__", + tags: "__tags__", + arguments: "__arguments__" +}; + +export let OperatingSystems = { + Windows: "Windows", + Other: "Other" +}; + +export let CommandTypes = { + buildAndPush: "buildAndPush", + build: "build", + push: "push", + images: "images" +}; + +export let SharedValues = { + SYSTEM_TEAMFOUNDATIONCOLLECTIONURI: "https://dev.azure.com/abc", + SYSTEM_TEAMPROJECT: "testproj", + BUILD_REPOSITORY_NAME: "testrepo", + BUILD_REPOSITORY_URI: "https://dev.azure.com/abc/testrepo", + BUILD_SOURCEBRANCHNAME: "master", + BUILD_SOURCEVERSION: "521747298a3790fde1710f3aa2d03b55020575aa", + BUILD_DEFINITIONNAME: "testBD", + BUILD_BUILDNUMBER: "11", + BUILD_BUILDURI: "vstfs:///Build/Build/11", + RELEASE_DEFINITIONNAME: "testRD", + RELEASE_RELEASEID: "21", + RELEASE_RELEASEWEBURL: "https://dev.azure.com/abc/testrepo/_release?releaseId=21&_a=release-summary", + containerRegistry: "dockerhubendpoint" +} + +export let DockerCommandArgs = { + BuildLabels: `--label com.azure.dev.image.system.teamfoundationcollectionuri=${SharedValues.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI} --label com.azure.dev.image.system.teamproject=${SharedValues.SYSTEM_TEAMPROJECT} --label com.azure.dev.image.build.repository.name=${SharedValues.BUILD_REPOSITORY_NAME} --label com.azure.dev.image.build.repository.uri=${SharedValues.BUILD_REPOSITORY_URI} --label com.azure.dev.image.build.sourcebranchname=${SharedValues.BUILD_SOURCEBRANCHNAME} --label com.azure.dev.image.build.sourceversion=${SharedValues.BUILD_SOURCEVERSION} --label com.azure.dev.image.build.definitionname=${SharedValues.BUILD_DEFINITIONNAME} --label com.azure.dev.image.build.buildnumber=${SharedValues.BUILD_BUILDNUMBER} --label com.azure.dev.image.build.builduri=${SharedValues.BUILD_BUILDURI}`, + ReleaseLabels: `--label com.azure.dev.image.system.teamfoundationcollectionuri=${SharedValues.SYSTEM_TEAMFOUNDATIONCOLLECTIONURI} --label com.azure.dev.image.system.teamproject=${SharedValues.SYSTEM_TEAMPROJECT} --label com.azure.dev.image.release.definitionname=${SharedValues.RELEASE_DEFINITIONNAME} --label com.azure.dev.image.release.releaseid=${SharedValues.RELEASE_RELEASEID} --label com.azure.dev.image.release.releaseweburl=${SharedValues.RELEASE_RELEASEWEBURL}` +} + +/** + * Formats the given path to be appropriate for the operating system. + * @param canonicalPath A non-rooted path using a forward slash (/) as a directory separator. + */ +export function formatPath(canonicalPath: string) { + if (process.env[TestEnvVars.operatingSystem] === OperatingSystems.Windows) { + return "F:\\" + canonicalPath.replace(/\//g, '\\'); + } else { + return "/" + canonicalPath; + } +}; \ No newline at end of file diff --git a/Tasks/DockerV2/task.json b/Tasks/DockerV2/task.json index 2fa65e5f71c6..7009d4caa35d 100644 --- a/Tasks/DockerV2/task.json +++ b/Tasks/DockerV2/task.json @@ -14,7 +14,7 @@ "version": { "Major": 2, "Minor": 154, - "Patch": 0 + "Patch": 1 }, "demands": [], "releaseNotes": "Simplified the task YAML by:
 - Removing the Container registry type input
 - Removing complex inputs as they can be passed as arguments to the command.", diff --git a/Tasks/DockerV2/task.loc.json b/Tasks/DockerV2/task.loc.json index 4438179865c6..76eef23055be 100644 --- a/Tasks/DockerV2/task.loc.json +++ b/Tasks/DockerV2/task.loc.json @@ -14,7 +14,7 @@ "version": { "Major": 2, "Minor": 154, - "Patch": 0 + "Patch": 1 }, "demands": [], "releaseNotes": "ms-resource:loc.releaseNotes", From 74727f3a5210118ee602289917026dfbfe919eca Mon Sep 17 00:00:00 2001 From: Ajinkya Date: Tue, 11 Jun 2019 16:23:28 +0530 Subject: [PATCH 2/2] Adding test for release labels --- Tasks/DockerV2/Tests/L0.ts | 18 ++++++++++++++++++ Tasks/DockerV2/Tests/TestSetup.ts | 11 ++++++++--- Tasks/DockerV2/Tests/TestShared.ts | 5 +++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Tasks/DockerV2/Tests/L0.ts b/Tasks/DockerV2/Tests/L0.ts index 5f43f13d5b58..8a5d0fcf0200 100644 --- a/Tasks/DockerV2/Tests/L0.ts +++ b/Tasks/DockerV2/Tests/L0.ts @@ -18,6 +18,7 @@ describe("DockerV2 Suite", function () { }); beforeEach(() => { + delete process.env[shared.TestEnvVars.hostType]; delete process.env[shared.TestEnvVars.containerRegistry]; delete process.env[shared.TestEnvVars.repository]; delete process.env[shared.TestEnvVars.command]; @@ -46,6 +47,23 @@ describe("DockerV2 Suite", function () { console.log(tr.stderr); done(); }); + + it('Runs successfully for docker build with release labels', (done:MochaDone) => { + let tp = path.join(__dirname, 'TestSetup.js'); + process.env[shared.TestEnvVars.containerRegistry] = "dockerhubendpoint"; + process.env[shared.TestEnvVars.repository] = "testuser/testrepo"; + process.env[shared.TestEnvVars.command] = shared.CommandTypes.build; + process.env[shared.TestEnvVars.hostType] = shared.HostTypes.release; + let tr : ttm.MockTestRunner = new ttm.MockTestRunner(tp); + tr.run(); + + assert(tr.invokedToolCount == 1, 'should have invoked tool one time. actual: ' + tr.invokedToolCount); + assert(tr.stderr.length == 0 || tr.errorIssues.length, 'should not have written to stderr'); + assert(tr.succeeded, 'task should have succeeded'); + assert(tr.stdout.indexOf(`[command]docker build -f ${shared.formatPath("a/w/Dockerfile")} ${shared.DockerCommandArgs.ReleaseLabels} -t testuser/testrepo:11 ${shared.formatPath("a/w")}`) != -1, "docker build should run with expected arguments"); + console.log(tr.stderr); + done(); + }); it('Runs successfully for docker build when registry other than Docker hub is used', (done:MochaDone) => { let tp = path.join(__dirname, 'TestSetup.js'); diff --git a/Tasks/DockerV2/Tests/TestSetup.ts b/Tasks/DockerV2/Tests/TestSetup.ts index 68c3cfe1679a..b5373df99079 100644 --- a/Tasks/DockerV2/Tests/TestSetup.ts +++ b/Tasks/DockerV2/Tests/TestSetup.ts @@ -28,7 +28,7 @@ console.log("Inputs have been set"); process.env["RELEASE_RELEASENAME"] = "Release-1"; process.env["SYSTEM_DEFAULTWORKINGDIRECTORY"] = DefaultWorkingDirectory; -process.env["SYSTEM_HOSTTYPE"] = process.env[shared.TestEnvVars.hostType] || "build"; +process.env["SYSTEM_HOSTTYPE"] = process.env[shared.TestEnvVars.hostType] || shared.HostTypes.build; process.env["SYSTEM_SERVERTYPE"] = "hosted"; process.env["ENDPOINT_AUTH_dockerhubendpoint"] = "{\"parameters\":{\"username\":\"testuser\", \"password\":\"regpassword\", \"email\":\"testuser1@microsoft.com\",\"registry\":\"https://index.docker.io/v1/\"},\"scheme\":\"UsernamePassword\"}"; process.env["ENDPOINT_AUTH_acrendpoint"] = "{\"parameters\":{\"username\":\"testacr\", \"password\":\"acrpassword\",\"registry\":\"https://testacr.azurecr.io/\"},\"scheme\":\"UsernamePassword\"}"; @@ -38,7 +38,7 @@ process.env["SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"] = shared.SharedValues.SYSTEM_T process.env["SYSTEM_TEAMPROJECT"] = shared.SharedValues.SYSTEM_TEAMPROJECT; // Set variables used for build labels -process.env["BUILD_REPOSITORY_NAME"] = shared.SharedValues.BUILD_REPOSITORY_NAME; +process.env["BUILD_REPOSITORY_NAME"] = process.env["SYSTEM_HOSTTYPE"] == shared.HostTypes.build ? shared.SharedValues.BUILD_REPOSITORY_NAME : ""; process.env["BUILD_REPOSITORY_URI"] = shared.SharedValues.BUILD_REPOSITORY_URI; process.env["BUILD_SOURCEBRANCHNAME"] = shared.SharedValues.BUILD_SOURCEBRANCHNAME; process.env["BUILD_SOURCEVERSION"] = shared.SharedValues.BUILD_SOURCEVERSION; @@ -96,6 +96,11 @@ a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels "stdout": "successfully built image and tagged testuser/testrepo:11." }; +a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.ReleaseLabels} -t testuser/testrepo:11 ${BuildContextPath}`] = { + "code": 0, + "stdout": "successfully built image and tagged testuser/testrepo:11." +}; + a.exec[`docker build -f ${DockerfilePath} ${shared.DockerCommandArgs.BuildLabels} -t testacr.azurecr.io/testrepo:11 ${BuildContextPath}`] = { "code": 0, "stdout": "successfully built image and tagged testuser/testrepo:11." @@ -208,7 +213,7 @@ a.exec[`docker images --all --digests`] = { tr.setAnswers(a); -// Create mock for fs module +// Create mock for fs module. Required to make the base image name extraction (push command) work. let fs = require('fs'); let fsClone = Object.assign({}, fs); fsClone.readFileSync = function(filePath, options) { diff --git a/Tasks/DockerV2/Tests/TestShared.ts b/Tasks/DockerV2/Tests/TestShared.ts index df92d5e4b255..1244ee45fbcb 100644 --- a/Tasks/DockerV2/Tests/TestShared.ts +++ b/Tasks/DockerV2/Tests/TestShared.ts @@ -15,6 +15,11 @@ export let OperatingSystems = { Other: "Other" }; +export let HostTypes ={ + build: "build", + release: "release" +} + export let CommandTypes = { buildAndPush: "buildAndPush", build: "build",