Skip to content

Commit

Permalink
Merge pull request #86 from cloudogu/feature/85_bats_test
Browse files Browse the repository at this point in the history
Feature/85 bats test
  • Loading branch information
nhinze23 committed Oct 6, 2022
2 parents 45c0559 + 35ced96 commit c8e8198
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
- 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
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down
13 changes: 13 additions & 0 deletions docs/development/development_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
42 changes: 42 additions & 0 deletions src/com/cloudogu/ces/cesbuildlib/Bats.groovy
Original file line number Diff line number Diff line change
@@ -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'
}
}
}
97 changes: 97 additions & 0 deletions test/com/cloudogu/ces/cesbuildlib/BatsTest.groovy
Original file line number Diff line number Diff line change
@@ -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<Object>() {
@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<Object>() {
@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())
}
}
8 changes: 6 additions & 2 deletions test/com/cloudogu/ces/cesbuildlib/ScriptMock.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class ScriptMock {
List<String> allActualArgs = new LinkedList<>()
List<String> actualEcho = new LinkedList<>()

LinkedHashMap<Object,Object> actualJUnitFlags = new LinkedHashMap<>()

List<String> actualShMapArgs = new LinkedList<>()

List<Map<String, String>> writeFileParams = new LinkedList<>()
Expand Down Expand Up @@ -54,9 +56,11 @@ class ScriptMock {
return getReturnValueFor(args)
}

String sh(Map<String, Object> args) {
def script = args.get('script')
void junit(LinkedHashMap<Object,Object> map = [:]) {
actualJUnitFlags = map
}

String sh(Map<String, Object> args) {
actualShMapArgs.add(args.script.toString())
allActualArgs.add(args.script.toString())

Expand Down

0 comments on commit c8e8198

Please sign in to comment.