diff --git a/images/jenkins/tests/controller/main.tf b/images/jenkins/tests/controller/main.tf new file mode 100644 index 0000000000..3cfe589830 --- /dev/null +++ b/images/jenkins/tests/controller/main.tf @@ -0,0 +1,47 @@ +// default values - these get overridden when the resource is called +variable "values" { + type = any + default = { + namespace = "jenkins" + fullnameOverride = "jenkins" + nameOverride = "jenkins" + create_namespace = true + + controller = { + javaOpts = "" + jenkinsOpts = "" + admin = { + createSecret = false + } + installPlugins = false + sidecars = { + configAutoReload = { + enabled = false + } + } + image = { + registry = "cgr.dev" + repository = "chainguard/jenkins" + tag = "latest" + } + } + } +} + +module "helm" { + source = "../../../../tflib/imagetest/helm" + + namespace = "jenkins" + chart = "jenkins" + repo = "https://charts.jenkins.io" + + values = var.values +} + +output "install_cmd" { + value = module.helm.install_cmd +} + +output "release_name" { + value = module.helm.release_name +} diff --git a/images/jenkins/tests/hello-world.sh b/images/jenkins/tests/hello-world.sh new file mode 100755 index 0000000000..410f4e1574 --- /dev/null +++ b/images/jenkins/tests/hello-world.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +# set -euo pipefail + +apk add curl openjdk-21-jre-base + +export JAVA_HOME=/usr/lib/jvm/java-21-openjdk/ + +kubectl port-forward -n jenkins svc/jenkins 8080:8080& +sleep 5 # wait for port-forward to settle +curl -s -O "http://localhost:8080/jnlpJars/jenkins-cli.jar" +mv jenkins-cli.jar /tmp/ + +# define a job +cat /tests/hello-world.xml | \ + $JAVA_HOME/bin/java \ + -jar /tmp/jenkins-cli.jar \ + -s http://127.0.0.1:8080 \ + create-job "Hello world" + +sleep 5 # wait for port-forward to settle + +# run the job +$JAVA_HOME/bin/java \ + -jar /tmp/jenkins-cli.jar \ + -s http://127.0.0.1:8080 build "Hello world" + +sleep 5 # wait for port-forward to settle + +# check job success +STATUS=`$JAVA_HOME/bin/java \ + -jar /tmp/jenkins-cli.jar \ + -s http://127.0.0.1:8080 console "Hello world" |grep 'Finished: SUCCESS'` + diff --git a/images/jenkins/tests/hello-world.xml b/images/jenkins/tests/hello-world.xml new file mode 100644 index 0000000000..0e43b13660 --- /dev/null +++ b/images/jenkins/tests/hello-world.xml @@ -0,0 +1,20 @@ + + + false + + + true + false + false + false + + false + + + echo "Hello world!" + + + + + + diff --git a/images/jenkins/tests/main.tf b/images/jenkins/tests/main.tf index d7d617a7cc..4458ccb469 100644 --- a/images/jenkins/tests/main.tf +++ b/images/jenkins/tests/main.tf @@ -1,19 +1,78 @@ terraform { required_providers { - oci = { source = "chainguard-dev/oci" } + oci = { source = "chainguard-dev/oci" } + imagetest = { source = "chainguard-dev/imagetest" } } } +locals { + namespace = "jenkins" +} + variable "digest" { description = "The image digest to run tests over." } -data "oci_exec_test" "version" { - digest = var.digest - script = "docker run --rm $IMAGE_NAME --version" +data "oci_string" "ref" { input = var.digest } + +data "imagetest_inventory" "this" {} + +resource "imagetest_harness_k3s" "this" { + name = "jenkins" + inventory = data.imagetest_inventory.this + + sandbox = { + mounts = [ + { + source = path.module + destination = "/tests" + } + ] + } } -data "oci_exec_test" "run-tests" { - digest = var.digest - script = "${path.module}/run-tests.sh" +module "helm_controller" { + source = "./controller" + values = { + namespace = local.namespace + fullnameOverride = local.namespace + nameOverride = local.namespace + create_namespace = true + + controller = { + javaOpts = "" + jenkinsOpts = "" + installPlugins = false + admin = { + createSecret = false + } + sidecars = { + configAutoReload = { + enabled = false + } + } + image = { + registry = data.oci_string.ref.registry + repository = data.oci_string.ref.repo + tag = data.oci_string.ref.pseudo_tag + } + } + } } + +resource "imagetest_feature" "this" { + harness = imagetest_harness_k3s.this + name = "jenkins" + description = "Test jenkins functionality" + + steps = [ + { + name = "Install controller", + cmd = module.helm_controller.install_cmd + }, + { + name = "Test running a job", + cmd = "/tests/hello-world.sh" + }, + ] +} \ No newline at end of file diff --git a/images/jenkins/tests/run-tests.sh b/images/jenkins/tests/run-tests.sh deleted file mode 100755 index 4684f24b5b..0000000000 --- a/images/jenkins/tests/run-tests.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -o nounset -o errtrace -o pipefail -x - -CONTAINER_NAME="jenkins-$(uuidgen)" -JENKINS_PORT=${FREE_PORT} - -REQUEST_RETRIES=10 -RETRY_DELAY=15 - -expected_logs=( - "Started all plugins" - "Loaded all jobs" - "Jenkins is fully up and running" -) -missing_logs=() - -# Start Jenkins container and set a trap to ensure it's stopped on exit. -start_container() { - container_id=$(docker run \ - --detach --rm \ - --name "${CONTAINER_NAME}" -p $JENKINS_PORT:8080 \ - --env JAVA_OPTS="-Djenkins.install.runSetupWizard=false" \ - "${IMAGE_NAME}") - - trap "docker stop ${container_id}" EXIT - sleep 10 -} - -# Validate that Jenkins container logs contain expected log messages. -TEST_validate_container_logs() { - for ((i=1; i<=${REQUEST_RETRIES}; i++)); do - local logs=$(docker logs "${container_id}" 2>&1) - local logs_found=true - - # Search the container logs for our expected log lines. - for log in "${expected_logs[@]}"; do - if ! echo "$logs" | grep -Fq "$log"; then - logs_found=false - fi - done - - if $logs_found; then - return 0 - elif [[ $i -lt ${REQUEST_RETRIES} ]]; then - echo "Some expected logs were missing. Retrying in ${RETRY_DELAY} seconds..." - sleep ${RETRY_DELAY} - fi - done - - # After all retries, record the missing logs - for log in "${expected_logs[@]}"; do - if ! echo "${logs}" | grep -Fq "$log"; then - missing_logs+=("${log}") - fi - done - - echo "FAILED: The following log lines where not found:" - printf '%s\n' "${missing_logs[@]}" - exit 1 -} - -# Check that Jenkins responds 200 HTTP status code indicating it's operational. -TEST_http_response() { - for ((i=1; i<=${REQUEST_RETRIES}; i++)); do - if [ $(curl -o /dev/null -s -w "%{http_code}" "http://localhost:${JENKINS_PORT}") -eq 200 ]; then - return 0 - fi - sleep ${RETRY_DELAY} - done - - echo "FAILED: Did not receive 200 HTTP response from Jenkins after ${REQUEST_RETRIES} attempts." - exit 1 -} - -start_container -TEST_validate_container_logs -TEST_http_response