Skip to content

Commit

Permalink
Merge pull request #101 from krufab/add_test_and_uniform_code
Browse files Browse the repository at this point in the history
Added tests to the project
  • Loading branch information
oleg-nenashev authored Jan 29, 2020
2 parents 66247d5 + 66471f8 commit 098db9a
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea
bats-core/
37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
ROOT:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

IMAGE_NAME:=jenkins4eval/slave
IMAGE_NAME_AGENT:=jenkins4eval/agent

.PHONY: build
build: build-alpine build-debian build-jdk11

build-alpine:
docker build -t ${IMAGE_NAME}:alpine -t ${IMAGE_NAME_AGENT}:alpine --file Dockerfile-alpine .

build-debian:
docker build -t ${IMAGE_NAME}:test -t ${IMAGE_NAME_AGENT}:test --file Dockerfile .

build-jdk11:
docker build -t ${IMAGE_NAME}:jdk11 -t ${IMAGE_NAME_AGENT}:jdk11 --file Dockerfile-jdk11 .


bats:
# The lastest version is v1.1.0
@if [ ! -d bats-core ]; then git clone /~https://github.com/bats-core/bats-core.git; fi
@git -C bats-core reset --hard c706d1470dd1376687776bbe985ac22d09780327

.PHONY: test
test: test-alpine test-debian test-jdk11

.PHONY: test-alpine
test-alpine: bats
@FLAVOR=alpine bats-core/bin/bats tests/tests.bats

.PHONY: test-debian
test-debian: bats
@bats-core/bin/bats tests/tests.bats

.PHONY: test-jdk11
test-jdk11: bats
@FLAVOR=jdk11 bats-core/bin/bats tests/tests.bats
19 changes: 3 additions & 16 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
#!/bin/bash

set -euxo pipefail
set -e

for dockerfile in Dockerfile*
do
# skip windows build
if [[ $dockerfile == *windows* ]]; then
continue
fi
dockertag=$( echo "$dockerfile" | cut -d ' ' -f 2 )
if [[ "$dockertag" = "$dockerfile" ]]; then
dockertag='latest'
fi
echo "Building $dockerfile => tag=$dockertag"
docker build -f $dockerfile -t jenkins/slave:$dockertag .
docker build -f $dockerfile -t jenkins/agent:$dockertag .
done
make build

echo "Build finished successfully"
make test
58 changes: 58 additions & 0 deletions tests/test_helpers.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env bash

set -eu

# check dependencies
(
type docker &>/dev/null || ( echo "docker is not available"; exit 1 )
)>&2

function printMessage {
echo "# ${*}" >&3
}

# Assert that $1 is the output of a command $2
function assert {
local expected_output
local actual_output
expected_output="${1}"
shift
actual_output=$("${@}")
if ! [[ "${actual_output}" = "${expected_output}" ]]; then
printMessage "Expected: '${expected_output}', actual: '${actual_output}'"
false
fi
}

# Retry a command $1 times until it succeeds. Wait $2 seconds between retries.
function retry {
local attempts
local delay
local i
attempts="${1}"
shift
delay="${1}"
shift

for ((i=0; i < attempts; i++)); do
run "${@}"
if [[ "${status}" -eq 0 ]]; then
return 0
fi
sleep "${delay}"
done

printMessage "Command '${*}' failed $attempts times. Status: ${status}. Output: ${output}"

false
}

function clean_test_container {
docker kill "${AGENT_CONTAINER}" &>/dev/null || :
docker rm -fv "${AGENT_CONTAINER}" &>/dev/null || :
}

function is_agent_container_running {
sleep 1
retry 3 1 assert "true" docker inspect -f '{{.State.Running}}' "${AGENT_CONTAINER}"
}
146 changes: 146 additions & 0 deletions tests/tests.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env bats

DOCKERFILE=Dockerfile
JDK=8
AGENT_IMAGE=jenkins-agent
AGENT_CONTAINER=bats-jenkins-agent

if [[ -z "${FLAVOR}" ]]
then
FLAVOR="debian"
elif [[ "${FLAVOR}" = "jdk11" ]]
then
DOCKERFILE+="-jdk11"
JDK=11
AGENT_IMAGE+=":jdk11"
AGENT_CONTAINER+="-jdk11"
else
DOCKERFILE+="-alpine"
AGENT_IMAGE+=":alpine"
AGENT_CONTAINER+="-alpine"
fi

load test_helpers

clean_test_container

function teardown () {
clean_test_container
}

@test "[${FLAVOR}] build image" {
cd "${BATS_TEST_DIRNAME}"/.. || false
docker build -t "${AGENT_IMAGE}" -f "${DOCKERFILE}" .
}

@test "[${FLAVOR}] checking image metadata" {
local VOLUMES_MAP
VOLUMES_MAP="$(docker inspect -f '{{.Config.Volumes}}' ${AGENT_IMAGE})"

echo "${VOLUMES_MAP}" | grep '/home/jenkins/.jenkins'
echo "${VOLUMES_MAP}" | grep '/home/jenkins/agent'
}

@test "[${FLAVOR}] image has bash and java installed and in the PATH" {
docker run -d -it --name "${AGENT_CONTAINER}" -P "${AGENT_IMAGE}" /bin/sh

is_agent_container_running

run docker exec "${AGENT_CONTAINER}" which bash
[ "${status}" -eq 0 ]
run docker exec "${AGENT_CONTAINER}" bash --version
[ "${status}" -eq 0 ]
run docker exec "${AGENT_CONTAINER}" which java
[ "${status}" -eq 0 ]

if [[ "${JDK}" -eq 8 ]]
then
run docker exec "${AGENT_CONTAINER}" sh -c "
java -version 2>&1 \
| grep -o -E '^openjdk version \"[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+.*\"' \
| grep -o -E '\.[[:digit:]]+\.' \
| grep -o -E '[[:digit:]]+'
"
else
run docker exec "${AGENT_CONTAINER}" sh -c "
java -version 2>&1 \
| grep -o -E '^openjdk version \"[[:digit:]]+\.' \
| grep -o -E '\"[[:digit:]]+\.' \
| grep -o -E '[[:digit:]]+'
"
fi
[ "${JDK}" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" sh -c "printenv | grep AGENT_WORKDIR"
[ "AGENT_WORKDIR=/home/jenkins/agent" = "${output}" ]
}

@test "[${JDK} ${FLAVOR}] check user access to folders" {
docker run -d -it --name "${AGENT_CONTAINER}" -P "${AGENT_IMAGE}" /bin/sh

is_agent_container_running

run docker exec "${AGENT_CONTAINER}" touch /home/jenkins/a
[ "${status}" -eq 0 ]

run docker exec "${AGENT_CONTAINER}" touch /home/jenkins/.jenkins/a
[ "${status}" -eq 0 ]

run docker exec "${AGENT_CONTAINER}" touch /home/jenkins/agent/a
[ "${status}" -eq 0 ]
}

@test "[${JDK} ${FLAVOR}] use build args correctly" {
cd "${BATS_TEST_DIRNAME}"/.. || false

local TEST_VERSION="3.36"
local TEST_USER="test-user"
local TEST_GROUP="test-group"
local TEST_UID=2000
local TEST_GID=3000
local TEST_AGENT_WORKDIR="/home/test-user/something"

docker build \
--build-arg "VERSION=${TEST_VERSION}" \
--build-arg "user=${TEST_USER}" \
--build-arg "group=${TEST_GROUP}" \
--build-arg "uid=${TEST_UID}" \
--build-arg "gid=${TEST_GID}" \
--build-arg "AGENT_WORKDIR=${TEST_AGENT_WORKDIR}" \
-t "${AGENT_IMAGE}" \
-f "${DOCKERFILE}" .

docker run -d -it --name "${AGENT_CONTAINER}" -P "${AGENT_IMAGE}" /bin/sh

is_agent_container_running

run docker exec "${AGENT_CONTAINER}" sh -c "java -cp /usr/share/jenkins/agent.jar hudson.remoting.jnlp.Main -version"
[ "${TEST_VERSION}" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" sh -c "id -u -n ${TEST_USER}"
[ "${TEST_USER}" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" sh -c "id -g -n ${TEST_USER}"
[ "${TEST_GROUP}" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" sh -c "id -u ${TEST_USER}"
[ "${TEST_UID}" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" sh -c "id -g ${TEST_USER}"
[ "${TEST_GID}" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" sh -c "printenv | grep AGENT_WORKDIR"
[ "AGENT_WORKDIR=/home/${TEST_USER}/something" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" sh -c 'stat -c "%U:%G" "${AGENT_WORKDIR}"'
[ "${TEST_USER}:${TEST_GROUP}" = "${lines[0]}" ]

run docker exec "${AGENT_CONTAINER}" touch /home/test-user/a
[ "${status}" -eq 0 ]

run docker exec "${AGENT_CONTAINER}" touch /home/test-user/.jenkins/a
[ "${status}" -eq 0 ]

run docker exec "${AGENT_CONTAINER}" touch /home/test-user/something/a
[ "${status}" -eq 0 ]
}

0 comments on commit 098db9a

Please sign in to comment.