Refactor mocking

This commit is contained in:
Lars Gohr
2019-10-28 20:37:57 +01:00
parent 720c02a9ea
commit 691aa852ae
4 changed files with 187 additions and 184 deletions

View File

@@ -12,7 +12,7 @@ ENTRYPOINT ["/entrypoint.sh"]
FROM runtime as testEnv FROM runtime as testEnv
RUN apk add --no-cache coreutils bats ncurses RUN apk add --no-cache coreutils bats ncurses
ADD test.bats /test.bats ADD test.bats /test.bats
ADD stub.sh /usr/local/bin/docker ADD mock.sh /usr/local/bin/docker
ADD mock.sh /usr/bin/date ADD mock.sh /usr/bin/date
RUN /test.bats RUN /test.bats

19
mock.sh
View File

@@ -1,5 +1,18 @@
#!/bin/sh #!/bin/bash
if [ ! -z "${MOCK_DATE}" ]; then binary="$0"
echo "${MOCK_DATE}" parameters="$@"
echo "${binary} ${parameters}" >> mockCalledWith
function mockShouldFail() {
[ "${MOCK_RETURNS[${binary}]}" = "_${parameters}" ]
}
source mockReturns
if [ ! -z "${MOCK_RETURNS[${binary}]}" ]; then
if mockShouldFail ; then
exit 1
fi
echo ${MOCK_RETURNS[${binary}]}
fi fi
exit 0 exit 0

View File

@@ -1,7 +0,0 @@
#!/bin/sh
parameters="$@"
echo "Called $0 ${parameters}"
if [ "${MOCK_ERROR_CONDITION}" = "${parameters}" ]; then
exit 1
fi
exit 0

343
test.bats
View File

@@ -1,6 +1,12 @@
#!/usr/bin/env bats #!/usr/bin/env bats
setup(){ setup(){
cat /dev/null >| mockCalledWith
declare -A -p MOCK_RETURNS=(
['/usr/local/bin/docker']=""
) > mockReturns
export GITHUB_REF='refs/heads/master' export GITHUB_REF='refs/heads/master'
export INPUT_USERNAME='USERNAME' export INPUT_USERNAME='USERNAME'
export INPUT_PASSWORD='PASSWORD' export INPUT_PASSWORD='PASSWORD'
@@ -23,14 +29,13 @@ teardown() {
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::latest"
Called /usr/local/bin/docker build -t my/repository:latest .
Called /usr/local/bin/docker push my/repository:latest expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::latest /usr/local/bin/docker build -t my/repository:latest .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:latest
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "it pushes branch as name of the branch" { @test "it pushes branch as name of the branch" {
@@ -38,14 +43,13 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::myBranch"
Called /usr/local/bin/docker build -t my/repository:myBranch .
Called /usr/local/bin/docker push my/repository:myBranch expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::myBranch /usr/local/bin/docker build -t my/repository:myBranch .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:myBranch
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "it converts dashes in branch to hyphens" { @test "it converts dashes in branch to hyphens" {
@@ -53,14 +57,13 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::myBranch-withDash"
Called /usr/local/bin/docker build -t my/repository:myBranch-withDash .
Called /usr/local/bin/docker push my/repository:myBranch-withDash expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::myBranch-withDash /usr/local/bin/docker build -t my/repository:myBranch-withDash .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:myBranch-withDash
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "it pushes tags to latest" { @test "it pushes tags to latest" {
@@ -68,14 +71,13 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::latest"
Called /usr/local/bin/docker build -t my/repository:latest .
Called /usr/local/bin/docker push my/repository:latest expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::latest /usr/local/bin/docker build -t my/repository:latest .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:latest
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "with tag names it pushes tags using the name" { @test "with tag names it pushes tags using the name" {
@@ -84,14 +86,13 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::myRelease"
Called /usr/local/bin/docker build -t my/repository:myRelease .
Called /usr/local/bin/docker push my/repository:myRelease expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::myRelease /usr/local/bin/docker build -t my/repository:myRelease .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:myRelease
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "it pushes specific Dockerfile to latest" { @test "it pushes specific Dockerfile to latest" {
@@ -99,54 +100,57 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh export GITHUB_REF='refs/heads/master' run /entrypoint.sh export GITHUB_REF='refs/heads/master'
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::latest"
Called /usr/local/bin/docker build -f MyDockerFileName -t my/repository:latest .
Called /usr/local/bin/docker push my/repository:latest expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::latest /usr/local/bin/docker build -f MyDockerFileName -t my/repository:latest .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:latest
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "it pushes a snapshot by sha and date in addition" { @test "it pushes a snapshot by sha and date in addition" {
export INPUT_SNAPSHOT='true' export INPUT_SNAPSHOT='true'
export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7' export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7'
export MOCK_DATE='197001010101'
declare -A -p MOCK_RETURNS=(
['/usr/local/bin/docker']=""
['/usr/bin/date']="197001010101"
) > mockReturns
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker build -t my/repository:latest -t my/repository:19700101010112169e .
Called /usr/local/bin/docker push my/repository:latest
Called /usr/local/bin/docker push my/repository:19700101010112169e
::set-output name=snapshot-tag::19700101010112169e ::set-output name=snapshot-tag::19700101010112169e
::set-output name=tag::latest ::set-output name=tag::latest"
Called /usr/local/bin/docker logout"
echo $output expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
[ "$output" = "$expected" ] /usr/bin/date +%Y%m%d%H%M%S
/usr/local/bin/docker build -t my/repository:latest -t my/repository:19700101010112169e .
/usr/local/bin/docker push my/repository:latest
/usr/local/bin/docker push my/repository:19700101010112169e
/usr/local/bin/docker logout"
} }
@test "it caches image from former build and uses it for snapshot" { @test "it caches image from former build and uses it for snapshot" {
export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7' export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7'
export MOCK_DATE='197001010101'
export INPUT_SNAPSHOT='true' export INPUT_SNAPSHOT='true'
export INPUT_CACHE='true' export INPUT_CACHE='true'
declare -A -p MOCK_RETURNS=(
['/usr/local/bin/docker']=""
['/usr/bin/date']="197001010101"
) > mockReturns
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker login -u USERNAME --password-stdin /usr/local/bin/docker pull my/repository:latest
Called /usr/local/bin/docker pull my/repository:latest /usr/bin/date +%Y%m%d%H%M%S
Called /usr/local/bin/docker build --cache-from my/repository:latest -t my/repository:latest -t my/repository:19700101010112169e . /usr/local/bin/docker build --cache-from my/repository:latest -t my/repository:latest -t my/repository:19700101010112169e .
Called /usr/local/bin/docker push my/repository:latest /usr/local/bin/docker push my/repository:latest
Called /usr/local/bin/docker push my/repository:19700101010112169e /usr/local/bin/docker push my/repository:19700101010112169e
::set-output name=snapshot-tag::19700101010112169e /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it does not use the cache for building when pulling the former image failed" { @test "it does not use the cache for building when pulling the former image failed" {
@@ -154,110 +158,98 @@ Called /usr/local/bin/docker logout"
export MOCK_DATE='197001010101' export MOCK_DATE='197001010101'
export INPUT_SNAPSHOT='true' export INPUT_SNAPSHOT='true'
export INPUT_CACHE='true' export INPUT_CACHE='true'
export MOCK_ERROR_CONDITION='pull my/repository:latest'
declare -A -p MOCK_RETURNS=(
['/usr/local/bin/docker']="_pull my/repository:latest" # errors when pulled
['/usr/bin/date']="197001010101"
) > mockReturns
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker login -u USERNAME --password-stdin /usr/local/bin/docker pull my/repository:latest
Called /usr/local/bin/docker pull my/repository:latest /usr/bin/date +%Y%m%d%H%M%S
Called /usr/local/bin/docker build -t my/repository:latest -t my/repository:19700101010112169e . /usr/local/bin/docker build -t my/repository:latest -t my/repository:19700101010112169e .
Called /usr/local/bin/docker push my/repository:latest /usr/local/bin/docker push my/repository:latest
Called /usr/local/bin/docker push my/repository:19700101010112169e /usr/local/bin/docker push my/repository:19700101010112169e
::set-output name=snapshot-tag::19700101010112169e /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it pushes branch by sha and date with specific Dockerfile" { @test "it pushes branch by sha and date with specific Dockerfile" {
export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7' export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7'
export MOCK_DATE='197001010101'
export INPUT_SNAPSHOT='true' export INPUT_SNAPSHOT='true'
export INPUT_DOCKERFILE='MyDockerFileName' export INPUT_DOCKERFILE='MyDockerFileName'
declare -A -p MOCK_RETURNS=(
['/usr/local/bin/docker']=""
['/usr/bin/date']="197001010101"
) > mockReturns
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker login -u USERNAME --password-stdin /usr/bin/date +%Y%m%d%H%M%S
Called /usr/local/bin/docker build -f MyDockerFileName -t my/repository:latest -t my/repository:19700101010112169e . /usr/local/bin/docker build -f MyDockerFileName -t my/repository:latest -t my/repository:19700101010112169e .
Called /usr/local/bin/docker push my/repository:latest /usr/local/bin/docker push my/repository:latest
Called /usr/local/bin/docker push my/repository:19700101010112169e /usr/local/bin/docker push my/repository:19700101010112169e
::set-output name=snapshot-tag::19700101010112169e /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it caches image from former build and uses it for snapshot with specific Dockerfile" { @test "it caches image from former build and uses it for snapshot with specific Dockerfile" {
export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7' export GITHUB_SHA='12169ed809255604e557a82617264e9c373faca7'
export MOCK_DATE='197001010101'
export INPUT_SNAPSHOT='true' export INPUT_SNAPSHOT='true'
export INPUT_CACHE='true' export INPUT_CACHE='true'
export INPUT_DOCKERFILE='MyDockerFileName' export INPUT_DOCKERFILE='MyDockerFileName'
declare -A -p MOCK_RETURNS=(
['/usr/local/bin/docker']=""
['/usr/bin/date']="197001010101"
) > mockReturns
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker login -u USERNAME --password-stdin /usr/local/bin/docker pull my/repository:latest
Called /usr/local/bin/docker pull my/repository:latest /usr/bin/date +%Y%m%d%H%M%S
Called /usr/local/bin/docker build -f MyDockerFileName --cache-from my/repository:latest -t my/repository:latest -t my/repository:19700101010112169e . /usr/local/bin/docker build -f MyDockerFileName --cache-from my/repository:latest -t my/repository:latest -t my/repository:19700101010112169e .
Called /usr/local/bin/docker push my/repository:latest /usr/local/bin/docker push my/repository:latest
Called /usr/local/bin/docker push my/repository:19700101010112169e /usr/local/bin/docker push my/repository:19700101010112169e
::set-output name=snapshot-tag::19700101010112169e /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it pushes to another registry and adds the reference" { @test "it pushes to another registry and adds the hostname" {
export INPUT_REGISTRY='my.Registry.io' export INPUT_REGISTRY='my.Registry.io'
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin my.Registry.io
Called /usr/local/bin/docker login -u USERNAME --password-stdin my.Registry.io /usr/local/bin/docker build -t my.Registry.io/my/repository:latest .
Called /usr/local/bin/docker build -t my.Registry.io/my/repository:latest . /usr/local/bin/docker push my.Registry.io/my/repository:latest
Called /usr/local/bin/docker push my.Registry.io/my/repository:latest /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it pushes to another registry and is ok when the reference is already present" { @test "it pushes to another registry and is ok when the hostname is already present" {
export INPUT_REGISTRY='my.Registry.io' export INPUT_REGISTRY='my.Registry.io'
export INPUT_NAME='my.Registry.io/my/repository' export INPUT_NAME='my.Registry.io/my/repository'
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin my.Registry.io
Called /usr/local/bin/docker login -u USERNAME --password-stdin my.Registry.io /usr/local/bin/docker build -t my.Registry.io/my/repository:latest .
Called /usr/local/bin/docker build -t my.Registry.io/my/repository:latest . /usr/local/bin/docker push my.Registry.io/my/repository:latest
Called /usr/local/bin/docker push my.Registry.io/my/repository:latest /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it pushes to another registry and removes the protocol from the reference" { @test "it pushes to another registry and removes the protocol from the hostname" {
export INPUT_REGISTRY='https://my.Registry.io' export INPUT_REGISTRY='https://my.Registry.io'
export INPUT_NAME='my/repository' export INPUT_NAME='my/repository'
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin https://my.Registry.io
Called /usr/local/bin/docker login -u USERNAME --password-stdin https://my.Registry.io /usr/local/bin/docker build -t my.Registry.io/my/repository:latest .
Called /usr/local/bin/docker build -t my.Registry.io/my/repository:latest . /usr/local/bin/docker push my.Registry.io/my/repository:latest
Called /usr/local/bin/docker push my.Registry.io/my/repository:latest /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it caches the image from a former build" { @test "it caches the image from a former build" {
@@ -265,15 +257,11 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker login -u USERNAME --password-stdin /usr/local/bin/docker pull my/repository:latest
Called /usr/local/bin/docker pull my/repository:latest /usr/local/bin/docker build --cache-from my/repository:latest -t my/repository:latest .
Called /usr/local/bin/docker build --cache-from my/repository:latest -t my/repository:latest . /usr/local/bin/docker push my/repository:latest
Called /usr/local/bin/docker push my/repository:latest /usr/local/bin/docker logout"
::set-output name=tag::latest
Called /usr/local/bin/docker logout"
echo $output
[ "$output" = "$expected" ]
} }
@test "it pushes pull requests when configured" { @test "it pushes pull requests when configured" {
@@ -283,14 +271,13 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::12169ed809255604e557a82617264e9c373faca7"
Called /usr/local/bin/docker build -t my/repository:12169ed809255604e557a82617264e9c373faca7 .
Called /usr/local/bin/docker push my/repository:12169ed809255604e557a82617264e9c373faca7 expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::12169ed809255604e557a82617264e9c373faca7 /usr/local/bin/docker build -t my/repository:12169ed809255604e557a82617264e9c373faca7 .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:12169ed809255604e557a82617264e9c373faca7
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "it pushes to the tag if configured in the name" { @test "it pushes to the tag if configured in the name" {
@@ -298,14 +285,13 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin ::set-output name=tag::custom-tag"
Called /usr/local/bin/docker build -t my/repository:custom-tag .
Called /usr/local/bin/docker push my/repository:custom-tag expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
::set-output name=tag::custom-tag /usr/local/bin/docker build -t my/repository:custom-tag .
Called /usr/local/bin/docker logout" /usr/local/bin/docker push my/repository:custom-tag
echo $output /usr/local/bin/docker logout"
[ "$output" = "$expected" ]
} }
@test "it uses buildargs for building, if configured" { @test "it uses buildargs for building, if configured" {
@@ -313,16 +299,15 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin
::add-mask::MY_FIRST ::add-mask::MY_FIRST
::add-mask::MY_SECOND ::add-mask::MY_SECOND
Called /usr/local/bin/docker build --build-arg MY_FIRST --build-arg MY_SECOND -t my/repository:latest . ::set-output name=tag::latest"
Called /usr/local/bin/docker push my/repository:latest
::set-output name=tag::latest expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker logout" /usr/local/bin/docker build --build-arg MY_FIRST --build-arg MY_SECOND -t my/repository:latest .
echo $output /usr/local/bin/docker push my/repository:latest
[ "$output" = "$expected" ] /usr/local/bin/docker logout"
} }
@test "it uses buildargs for a single variable" { @test "it uses buildargs for a single variable" {
@@ -330,15 +315,14 @@ Called /usr/local/bin/docker logout"
run /entrypoint.sh run /entrypoint.sh
local expected=" expectStdOut "
Called /usr/local/bin/docker login -u USERNAME --password-stdin
::add-mask::MY_ONLY ::add-mask::MY_ONLY
Called /usr/local/bin/docker build --build-arg MY_ONLY -t my/repository:latest . ::set-output name=tag::latest"
Called /usr/local/bin/docker push my/repository:latest
::set-output name=tag::latest expectMockCalled "/usr/local/bin/docker login -u USERNAME --password-stdin
Called /usr/local/bin/docker logout" /usr/local/bin/docker build --build-arg MY_ONLY -t my/repository:latest .
echo $output /usr/local/bin/docker push my/repository:latest
[ "$output" = "$expected" ] /usr/local/bin/docker logout"
} }
@test "it errors when with.name was not set" { @test "it errors when with.name was not set" {
@@ -381,3 +365,16 @@ Called /usr/local/bin/docker logout"
[ "$status" -eq 2 ] [ "$status" -eq 2 ]
} }
function expectStdOut() {
echo "Expected: |$1|
Got: |$output|"
[ "$output" = "$1" ]
}
function expectMockCalled() {
local mockCalledWith=$(cat mockCalledWith)
echo "Expected: |$1|
Got: |$mockCalledWith|"
[ "$mockCalledWith" = "$1" ]
}