From 260bc47ccd694e530f7118d97f66e4514fb5e1a2 Mon Sep 17 00:00:00 2001 From: Joshua Sprey Date: Wed, 5 Oct 2022 11:33:04 +0200 Subject: [PATCH 1/3] #85 Update documentation about running test in intelli j --- docs/development/development_en.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/development/development_en.md b/docs/development/development_en.md index 06fab42..d64a09c 100644 --- a/docs/development/development_en.md +++ b/docs/development/development_en.md @@ -3,8 +3,21 @@ You need a working Java-11 SDK Run tests with + ```bash ./mvnw test ``` If you want to run tests within IntelliJ you need to use Java 8. + +# Running tests in IntelliJ + +Open Project Structure and set Java 8 as SDK. + +Run + +```bash +./mvnw install +``` + +Then right-click tests in IntelliJ and run. From ca2f635aa8c103a99448779b78919edaf9794238 Mon Sep 17 00:00:00 2001 From: Joshua Sprey Date: Wed, 5 Oct 2022 11:41:28 +0200 Subject: [PATCH 2/3] #85 Add bats wrapper class to support the execution of bats tests. --- CHANGELOG.md | 2 + README.md | 16 +++ src/com/cloudogu/ces/cesbuildlib/Bats.groovy | 42 ++++++++ .../cloudogu/ces/cesbuildlib/BatsTest.groovy | 97 +++++++++++++++++++ .../ces/cesbuildlib/ScriptMock.groovy | 8 +- 5 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 src/com/cloudogu/ces/cesbuildlib/Bats.groovy create mode 100644 test/com/cloudogu/ces/cesbuildlib/BatsTest.groovy diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b53303..daa1804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- [#85] New class `Bats` providing methods to easily execute existing bats (Bash Automated Testing System) tests. ## [1.56.0](https://github.com/cloudogu/ces-build-lib/releases/tag/1.56.0) - 2022-08-25 ### Added diff --git a/README.md b/README.md index cd94868..707d124 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ Jenkins Pipeline Shared library, that contains additional features for Git, Mave - [HttpClient](#httpclient) - [K3d](#k3d) - [DoguRegistry](#doguregistry) +- [Bats](#bats) - [Steps](#steps) - [mailIfStatusChanged](#mailifstatuschanged) - [isPullRequest](#ispullrequest) @@ -1102,6 +1103,21 @@ registry.pushDogu() registry.pushK8sYaml("pathToMyK8sYaml.yaml", "k8s-dogu-operator", "mynamespace", "0.9.0") ``` +# Bats + +`Bats` provides functions to easily execute existing bats tests for a project. + +Example: + +```groovy +Docker docker = new Docker(this) + +stage('Bats Tests') { + Bats bats = new Bats(this, docker) + bats.checkAndExecuteTests() +} +``` + # Makefile `Makefile` provides function regarding the `Makefile` from the current directory. diff --git a/src/com/cloudogu/ces/cesbuildlib/Bats.groovy b/src/com/cloudogu/ces/cesbuildlib/Bats.groovy new file mode 100644 index 0000000..ac80894 --- /dev/null +++ b/src/com/cloudogu/ces/cesbuildlib/Bats.groovy @@ -0,0 +1,42 @@ +package com.cloudogu.ces.cesbuildlib + +/** + * Bats provides functions to easily execute bats tests (bash scripting tests) + */ +class Bats { + private script + private docker + + private static String bats_base_image = "bats_base_image" + private static String bats_custom_image = "bats_custom_image" + private static String bats_tag = "bats_tag" + def defaultSetupConfig = [ + bats_base_image : "bats/bats", + bats_custom_image: "cloudogu/bats", + bats_tag : "1.2.1" + ] + + Bats(script, docker) { + this.script = script + this.docker = docker + } + + void checkAndExecuteTests(config = [:]) { + // Merge default config with the one passed as parameter + config = defaultSetupConfig << config + + script.echo "Executing bats tests with config:" + script.echo "${config}" + def batsImage = docker.build("${config[bats_custom_image]}:${config[bats_tag]}", "--build-arg=BATS_BASE_IMAGE=${config[bats_base_image]} --build-arg=BATS_TAG=${config[bats_tag]} ./build/make/bats") + try { + script.sh "mkdir -p target" + script.sh "mkdir -p testdir" + + batsImage.inside("--entrypoint='' -v ${script.env.WORKSPACE}:/workspace -v ${script.env.WORKSPACE}/testdir:/usr/share/webapps") { + script.sh "make unit-test-shell-ci" + } + } finally { + script.junit allowEmptyResults: true, testResults: 'target/shell_test_reports/*.xml' + } + } +} diff --git a/test/com/cloudogu/ces/cesbuildlib/BatsTest.groovy b/test/com/cloudogu/ces/cesbuildlib/BatsTest.groovy new file mode 100644 index 0000000..b036d19 --- /dev/null +++ b/test/com/cloudogu/ces/cesbuildlib/BatsTest.groovy @@ -0,0 +1,97 @@ +package com.cloudogu.ces.cesbuildlib + +import org.junit.Test +import org.mockito.invocation.InvocationOnMock +import org.mockito.stubbing.Answer + +import static org.assertj.core.api.Assertions.assertThat +import static org.mockito.ArgumentMatchers.any +import static org.mockito.ArgumentMatchers.anyString +import static org.mockito.ArgumentMatchers.eq +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.verify +import static org.mockito.Mockito.when + +class BatsTest extends GroovyTestCase { + + ScriptMock scriptMock = new ScriptMock() + + @Test + void test_Constructor() { + // given + Docker dockerMock = mock(Docker.class) + Docker.Image imageMock = mock(Docker.Image.class) + when(dockerMock.build(anyString(), anyString())).thenReturn(imageMock) + + // when + Bats bats = new Bats(scriptMock, dockerMock) + + // then + assertNotNull(bats) + } + + @Test + void test_checkAndExecuteTests() { + // given + Docker dockerMock = mock(Docker.class) + Docker.Image imageMock = mock(Docker.Image.class) + when(dockerMock.build("cloudogu/bats:1.2.1", "--build-arg=BATS_BASE_IMAGE=bats/bats --build-arg=BATS_TAG=1.2.1 ./build/make/bats")).thenReturn(imageMock) + when(imageMock.inside(anyString(), any())).thenAnswer(new Answer() { + @Override + Object answer(InvocationOnMock invocation) throws Throwable { + Closure closure = invocation.getArgument(1) + closure.call() + } + }) + + Bats bats = new Bats(scriptMock, dockerMock) + + // when + bats.checkAndExecuteTests() + + // then + assertThat(scriptMock.actualEcho[0].trim()).contains("Executing bats tests with config:") + assertThat(scriptMock.actualEcho[1].trim()).contains("[bats_base_image:bats/bats, bats_custom_image:cloudogu/bats, bats_tag:1.2.1]") + + verify(dockerMock).build("cloudogu/bats:1.2.1", "--build-arg=BATS_BASE_IMAGE=bats/bats --build-arg=BATS_TAG=1.2.1 ./build/make/bats") + verify(imageMock).inside(eq("--entrypoint='' -v :/workspace -v /testdir:/usr/share/webapps"), any()) + + assertEquals("true", scriptMock.actualJUnitFlags["allowEmptyResults"].toString()) + assertEquals("target/shell_test_reports/*.xml", scriptMock.actualJUnitFlags["testResults"].toString()) + } + + @Test + void test_checkAndExecuteTests_with_custom_config() { + // given + def defaultSetupConfig = [ + bats_custom_image: "myimage/bats", + bats_tag : "1.4.1" + ] + + Docker dockerMock = mock(Docker.class) + Docker.Image imageMock = mock(Docker.Image.class) + when(dockerMock.build("myimage/bats:1.4.1", "--build-arg=BATS_BASE_IMAGE=bats/bats --build-arg=BATS_TAG=1.4.1 ./build/make/bats")).thenReturn(imageMock) + when(imageMock.inside(anyString(), any())).thenAnswer(new Answer() { + @Override + Object answer(InvocationOnMock invocation) throws Throwable { + Closure closure = invocation.getArgument(1) + closure.call() + } + }) + + Bats bats = new Bats(scriptMock, dockerMock) + + // when + bats.checkAndExecuteTests(defaultSetupConfig) + + // then + assertThat(scriptMock.actualEcho[0].trim()).contains("Executing bats tests with config:") + assertThat(scriptMock.actualEcho[1].trim()).contains("[bats_base_image:bats/bats, bats_custom_image:myimage/bats, bats_tag:1.4.1]") + + verify(dockerMock).build("myimage/bats:1.4.1", "--build-arg=BATS_BASE_IMAGE=bats/bats --build-arg=BATS_TAG=1.4.1 ./build/make/bats") + verify(imageMock).inside(eq("--entrypoint='' -v :/workspace -v /testdir:/usr/share/webapps"), any()) + + assertEquals("true", scriptMock.actualJUnitFlags["allowEmptyResults"].toString()) + assertEquals("target/shell_test_reports/*.xml", scriptMock.actualJUnitFlags["testResults"].toString()) + } +} diff --git a/test/com/cloudogu/ces/cesbuildlib/ScriptMock.groovy b/test/com/cloudogu/ces/cesbuildlib/ScriptMock.groovy index 1fa76a4..7ef1be9 100644 --- a/test/com/cloudogu/ces/cesbuildlib/ScriptMock.groovy +++ b/test/com/cloudogu/ces/cesbuildlib/ScriptMock.groovy @@ -25,6 +25,8 @@ class ScriptMock { List allActualArgs = new LinkedList<>() List actualEcho = new LinkedList<>() + LinkedHashMap actualJUnitFlags = new LinkedHashMap<>() + List actualShMapArgs = new LinkedList<>() List> writeFileParams = new LinkedList<>() @@ -54,9 +56,11 @@ class ScriptMock { return getReturnValueFor(args) } - String sh(Map args) { - def script = args.get('script') + void junit(LinkedHashMap map = [:]) { + actualJUnitFlags = map + } + String sh(Map args) { actualShMapArgs.add(args.script.toString()) allActualArgs.add(args.script.toString()) From 35ced96e4425abfc06faebd336adac92eef211c8 Mon Sep 17 00:00:00 2001 From: Joshua Sprey Date: Thu, 6 Oct 2022 09:11:37 +0200 Subject: [PATCH 3/3] #85 Apply review feedback --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index daa1804..f38deac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added -- [#85] New class `Bats` providing methods to easily execute existing bats (Bash Automated Testing System) tests. +- New class `Bats` providing methods to easily execute existing bats (Bash Automated Testing System) tests. #85 ## [1.56.0](https://github.com/cloudogu/ces-build-lib/releases/tag/1.56.0) - 2022-08-25 ### Added