Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/85 bats test #86

Merged
merged 3 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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