diff --git a/Makefile b/Makefile index 330e0e671d..b71593cf07 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ vendorcheck: ./verify-vendor.sh .PHONY: check -check: cross build_e2e $(HOST_BUILD_DIR)/crc-embedder test cross-lint vendorcheck build_integration +check: cross build_e2e_all $(HOST_BUILD_DIR)/crc-embedder test cross-lint vendorcheck build_integration_all # Start of the actual build targets @@ -178,39 +178,56 @@ clean: clean_docs clean_macos_package clean_windows_msi rm -f $(GOPATH)/bin/crc rm -rf $(RELEASE_DIR) -.PHONY: build_e2e +## e2e building section +.PHONY: build_e2e build_e2e_all containerized_e2e + +## Function to build the e2e binary params: (os, param, binary_name) +e2e_builder = GOOS=$(1) GOARCH=$(2) go test ./test/e2e/ -tags "$(BUILDTAGS)" --ldflags="$(VERSION_VARIABLES)" -c -o $(BUILD_DIR)/$(1)-$(2)/$(3) + build_e2e: $(SOURCES) - GOARCH=amd64 GOOS=linux go test ./test/e2e/ -tags "$(BUILDTAGS)" --ldflags="$(VERSION_VARIABLES)" -c -o $(BUILD_DIR)/linux-amd64/e2e.test - GOARCH=amd64 GOOS=windows go test ./test/e2e/ -tags "$(BUILDTAGS)" --ldflags="$(VERSION_VARIABLES)" -c -o $(BUILD_DIR)/windows-amd64/e2e.test.exe - GOARCH=amd64 GOOS=darwin go test ./test/e2e/ -tags "$(BUILDTAGS)" --ldflags="$(VERSION_VARIABLES)" -c -o $(BUILD_DIR)/macos-amd64/e2e.test - GOARCH=arm64 GOOS=darwin go test ./test/e2e/ -tags "$(BUILDTAGS)" --ldflags="$(VERSION_VARIABLES)" -c -o $(BUILD_DIR)/macos-arm64/e2e.test + $(call e2e_builder,$(GOOS),$(GOARCH),e2e.test) -.PHONY: build_integration -build_integration: $(SOURCES) - GOARCH=amd64 GOOS=linux go test ./test/integration/ -tags "$(BUILDTAGS)" --ldflags="$(VERSION_VARIABLES)" -c -o $(BUILD_DIR)/linux-amd64/integration.test - GOARCH=amd64 GOOS=windows go test -tags "$(BUILDTAGS)" --ldflags="-X $(MODULEPATH)/pkg/crc/version.installerBuild=true $(VERSION_VARIABLES)" ./test/integration/ -c -o $(BUILD_DIR)/windows-amd64/integration.test.exe - GOARCH=amd64 GOOS=darwin go test -tags "$(BUILDTAGS)" --ldflags="-X $(MODULEPATH)/pkg/crc/version.installerBuild=true $(VERSION_VARIABLES)" ./test/integration/ -c -o $(BUILD_DIR)/macos-amd64/integration.test - GOARCH=arm64 GOOS=darwin go test -tags "$(BUILDTAGS)" --ldflags="-X $(MODULEPATH)/pkg/crc/version.installerBuild=true $(VERSION_VARIABLES)" ./test/integration/ -c -o $(BUILD_DIR)/macos-arm64/integration.test +build_e2e_all: $(SOURCES) + $(call e2e_builder,linux,amd64,e2e.test) + $(call e2e_builder,windows,amd64,e2e.test.exe) + $(call e2e_builder,darwin,amd64,e2e.test) + $(call e2e_builder,darwin,arm64,e2e.test) -# Build the container image for e2e -.PHONY: containerized_e2e containerized_e2e: ifndef CRC_E2E_IMG_VERSION CRC_E2E_IMG_VERSION=v$(CRC_VERSION)-$(COMMIT_SHA) endif IMG_E2E = quay.io/crcont/crc-e2e:$(CRC_E2E_IMG_VERSION) containerized_e2e: clean - $(CONTAINER_RUNTIME) build -t $(IMG_E2E) -f images/build-e2e/Dockerfile . + ${CONTAINER_RUNTIME} build -t ${IMG_E2E}-${OS}-${ARCH} -f images/build-e2e/Containerfile --build-arg=OS=${OS} --build-arg=ARCH=${ARCH} . + +## integration building section +.PHONY: build_integration build_integration_all containerized_integration + +## Function to build the integration binary params: (os, param, ldflags, binary_name) +integration_builder = GOOS=$(1) GOARCH=$(2) go test ./test/integration/ -tags "$(BUILDTAGS)" --ldflags="$(3)" -c -o $(BUILD_DIR)/$(1)-$(2)/$(4) + +build_integration: +ILDFLAGS=$(LDFLAGS) +ifneq ($(GOOS), linux) +ILDFLAGS=$(LDFLAGS) -X $(MODULEPATH)/pkg/crc/version.installerBuild=true +endif +build_integration: $(SOURCES) + $(call integration_builder,$(GOOS),$(GOARCH),$(ILDFLAGS),integration.test) + +build_integration_all: $(SOURCES) + $(call integration_builder,linux,amd64,$(LDFLAGS),integration.test) + $(call integration_builder,windows,amd64,$(LDFLAGS) -X $(MODULEPATH)/pkg/crc/version.installerBuild=true,integration.test.exe) + $(call integration_builder,darwin,amd64,$(LDFLAGS) -X $(MODULEPATH)/pkg/crc/version.installerBuild=true,integration.test) + $(call integration_builder,darwin,arm64,$(LDFLAGS) -X $(MODULEPATH)/pkg/crc/version.installerBuild=true,integration.test) -# Build the container image for integration -.PHONY: containerized_integration -containerized_integration: +containerized_integration: ifndef CRC_INTEGRATION_IMG_VERSION CRC_INTEGRATION_IMG_VERSION=v$(CRC_VERSION)-$(COMMIT_SHA) endif IMG_INTEGRATION = quay.io/crcont/crc-integration:$(CRC_INTEGRATION_IMG_VERSION) containerized_integration: clean - $(CONTAINER_RUNTIME) build -t $(IMG_INTEGRATION) -f images/build-integration/Dockerfile . + $(CONTAINER_RUNTIME) build -t $(IMG_INTEGRATION)-${OS}-${ARCH} -f images/build-integration/Containerfile --build-arg=OS=${OS} --build-arg=ARCH=${ARCH} . .PHONY: integration ## Run integration tests in Ginkgo integration: diff --git a/images/build-e2e/Containerfile b/images/build-e2e/Containerfile new file mode 100644 index 0000000000..25160ba121 --- /dev/null +++ b/images/build-e2e/Containerfile @@ -0,0 +1,28 @@ + +FROM registry.access.redhat.com/ubi9/go-toolset:1.20 AS builder + +USER root + +ARG OS +ARG ARCH +WORKDIR /workspace +COPY . . +RUN GOARCH=${ARCH} GOOS=${OS} make build_e2e + +FROM quay.io/rhqp/deliverest:v0.0.6 + +LABEL org.opencontainers.image.authors="CRCQE " + +ARG OS +ARG ARCH + +ENV ASSETS_FOLDER=/opt/crc \ + OS=${OS} \ + ARCH=${ARCH} + +COPY --from=builder /workspace/out/${OS}-${ARCH} ${ASSETS_FOLDER}/bin +COPY --from=builder /workspace/test/e2e/features ${ASSETS_FOLDER}/bin/features +COPY --from=builder /workspace/test/testdata ${ASSETS_FOLDER}/testdata + +COPY images/build-e2e/lib/${OS}/* ${ASSETS_FOLDER}/ + diff --git a/images/build-e2e/Dockerfile b/images/build-e2e/Dockerfile deleted file mode 100644 index 5fc9a01dce..0000000000 --- a/images/build-e2e/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -FROM registry.access.redhat.com/ubi8/go-toolset:1.20 AS builder - -USER root -WORKDIR /workspace -COPY . . -RUN make build_e2e - -FROM registry.access.redhat.com/ubi8/ubi-minimal - -LABEL MAINTAINER "CRC " - -COPY --from=builder /workspace/images/build-e2e/entrypoint.sh /usr/local/bin/ -COPY --from=builder /workspace/out /opt/crc/bin -# Review this when go 1.16 with embed support -COPY --from=builder /workspace/test/e2e/features /opt/crc/features -COPY --from=builder /workspace/test/testdata /opt/crc/testdata - -ENV EPEL https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm - -RUN rpm -ivh ${EPEL} \ - && microdnf --enablerepo=epel install -y openssh-clients sshpass \ - && microdnf clean all - -ENTRYPOINT ["entrypoint.sh"] diff --git a/images/build-e2e/README.md b/images/build-e2e/README.md index 8661619dcf..2ea6754a81 100644 --- a/images/build-e2e/README.md +++ b/images/build-e2e/README.md @@ -1,50 +1,87 @@ # Overview -The container includes the e2e binary for all 3 platforms plus the required resources to run it. +This image contains the e2e suite of tests, and it is intended to run them against a target host, the logic to run the tests remotely is inherit from its base image: [deliverest](https://github.com/adrianriobo/deliverest), each platform and os has its own image. -The container connects through ssh to the target host and copy the right binary for the platform, run e2e tests and pick the results and logs back. +## Run -## Envs +The image version contains the specs about the plaftorm and the arch; then the test customization is made by the command executed within the image; as we can see the cmd should be defined depending on the platform: -**PLATFORM**:*define target platform (windows, macos, linux).* -**ARCH**:*define target arch (amd64, arm64). Default amd64 -**TARGET_HOST**:*dns or ip for the target host.* -**TARGET_HOST_USERNAME**:*username for target host.* -**TARGET_HOST_KEY_PATH**:*private key for user. (Mandatory if not TARGET_HOST_PASSWORD).* -**TARGET_HOST_PASSWORD**:*password for user. (Mandatory if not TARGET_HOST_KEY_PATH).* -**PULL_SECRET_FILE_PATH**: *pull secret file path (local to container).* -**BUNDLE_VERSION**:*(Mandatory if not BUNDLE_LOCATION). Testing agaisnt crc released version bundle version for crc released version.* -**BUNDLE_LOCATION**:*(Mandatory if not BUNDLE_VERSION). When testing crc with custom bundle set the bundle location on target server.* -**RESULTS_PATH**:*(Optional). Path inside container to pick results and logs from e2e execution.* -**RESULTS_FILE**:*(Optional). File name for results xunit results. Default value: e2e.* -**CLEANUP_HOME**:*(Optional). Cleanup crc home folder or keep as it is to run test.* -**E2E_TAG_EXPRESSION**:*(Optional). Define e2e tag expression to select tests. If empty all tests available for the platform will be executed.* +* crc-e2e/run.ps1 ... (windows) +* crc-e2e/run.sh ... (linux/darwin) -## Samples +And the execution is customized by the params addded, available params: + +* bundleLocation When testing a custom bundle we should pass the path on the target host +* e2eTagExpression To set an specific set of tests based on annotations +* targetFolder Name of the folder on the target host under $HOME where all the content will be copied +* junitFilename Name for the junit file with the tests results +* crcMemory Customize memory for the cluster to run the tests + +### Windows amd64 + +```bash +podman run --rm -d --name crc-e2e-windows \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-e2e \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-e2e:v2.34.0-windows-amd64 \ + crc-e2e/run.ps1 -junitFilename crc-e2e-junit.xml +``` + +### Mac arm64 + +```bash +podman run --rm -d --name crc-e2e-darwin \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-e2e \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-e2e:v2.34.0-darwin-arm64 \ + crc-e2e/run.sh -junitFilename crc-e2e-junit.xml +``` + +### Mac amd64 ```bash -# Run e2e on macos platform with ssh key and custom bundle -podman run --rm -it --name crc-e2e \ - -e PLATFORM=macos \ - -e TARGET_HOST=$IP \ - -e TARGET_HOST_USERNAME=$USER \ - -e TARGET_HOST_KEY_PATH=/opt/crc/id_rsa \ - -e PULL_SECRET_FILE_PATH=/opt/crc/pull-secret \ - -e BUNDLE_LOCATION=/bundles/crc_hyperv_4.8.0-rc.3.crcbundle \ - -v $PWD/pull-secret:/opt/crc/pull-secret:Z \ - -v $PWD/id_rsa:/opt/crc/id_rsa:Z \ - -v $PWD/output:/output:Z \ - quay.io/crcont/crc-e2e:v1.29.0-465452f4 - -# Run e2e on windows platform with ssh password and crc released version -podman run --rm -it --name crc-e2e \ - -e PLATFORM=windows \ - -e TARGET_HOST=$IP \ - -e TARGET_HOST_USERNAME=$USER \ - -e TARGET_HOST_PASSWORD=$PASSWORD \ - -e PULL_SECRET_FILE_PATH=/opt/crc/pull-secret \ - -e BUNDLE_VERSION=4.7.18 \ - -v $PWD/pull-secret:/opt/crc/pull-secret:Z \ - -v $PWD/output:/output:Z \ - quay.io/crcont/crc-e2e:v1.29.0-465452f4 +podman run --rm -d --name crc-e2e-darwin \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-e2e \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-e2e:v2.34.0-darwin-amd64 \ + crc-e2e/run.sh -junitFilename crc-e2e-junit.xml ``` + + +### Linux amd64 + +```bash +podman run --rm -d --name crc-e2e-linux \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-e2e \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-e2e:v2.34.0-linux-amd64 \ + crc-e2e/run.sh -junitFilename crc-e2e-junit.xml +``` \ No newline at end of file diff --git a/images/build-e2e/entrypoint.sh b/images/build-e2e/entrypoint.sh deleted file mode 100755 index 96b26ff53a..0000000000 --- a/images/build-e2e/entrypoint.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/bin/sh - -ARCH="${ARCH:-"amd64"}" -# Vars -BINARY=e2e.test -if [[ ${PLATFORM} == 'windows' ]]; then - BINARY=e2e.test.exe -fi -BINARY_PATH="/opt/crc/bin/${PLATFORM}-${ARCH}/${BINARY}" - -# Running options -CLEANUP_HOME="${CLEANUP_HOME:-"true"}" -# e2e tag picking -E2E_TAG_EXPRESSION="${E2E_TAG_EXPRESSION:-""}" -# Review this when go 1.16 with embed support -FEATURES_PATH=/opt/crc/features -TESTDATA_PATH=/opt/crc/testdata - -# Results -RESULTS_PATH="${RESULTS_PATH:-/output}" -# results file name -RESULTS_FILE="${RESULTS_FILE:-"e2e"}" - -if [ "${DEBUG:-}" = "true" ]; then - set -xuo -fi - -# Validate conf -validate=true -[[ -z "${TARGET_HOST+x}" ]] \ - && echo "TARGET_HOST required" \ - && validate=false - -[[ -z "${TARGET_HOST_USERNAME+x}" ]] \ - && echo "TARGET_HOST_USERNAME required" \ - && validate=false - -[[ -z "${TARGET_HOST_KEY_PATH+x}" && -z "${TARGET_HOST_PASSWORD+x}" ]] \ - && echo "TARGET_HOST_KEY_PATH or TARGET_HOST_PASSWORD required" \ - && validate=false - -[[ -z "${PULL_SECRET_FILE_PATH+x}" ]] \ - && echo "PULL_SECRET_FILE_PATH required" \ - && validate=false - -[[ $validate == false ]] && exit 1 - -# Define remote connection -REMOTE="${TARGET_HOST_USERNAME}@${TARGET_HOST}" -if [[ ! -z "${TARGET_HOST_DOMAIN+x}" ]]; then - REMOTE="${TARGET_HOST_USERNAME}@${TARGET_HOST_DOMAIN}@${TARGET_HOST}" -fi - -# Increase ssh connectivity reliability -RELIABLE_CONNECTION='-o ServerAliveInterval=30 -o ServerAliveCountMax=1200' -# Set SCP / SSH command with pass or key -NO_STRICT='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' -if [[ ! -z "${TARGET_HOST_KEY_PATH+x}" ]]; then - SCP="scp -r ${RELIABLE_CONNECTION} ${NO_STRICT} -i ${TARGET_HOST_KEY_PATH}" - SSH="ssh ${RELIABLE_CONNECTION} ${NO_STRICT} -i ${TARGET_HOST_KEY_PATH}" -else - SCP="sshpass -p ${TARGET_HOST_PASSWORD} scp -r ${RELIABLE_CONNECTION} ${NO_STRICT}" \ - SSH="sshpass -p ${TARGET_HOST_PASSWORD} ssh ${RELIABLE_CONNECTION} ${NO_STRICT}" -fi - -echo "Copy resources to target" -# Create execution folder -EXECUTION_FOLDER="/Users/${TARGET_HOST_USERNAME}/crc-e2e" -if [[ ${PLATFORM} == 'linux' ]]; then - EXECUTION_FOLDER="/home/${TARGET_HOST_USERNAME}/crc-e2e" -fi -DATA_FOLDER="${EXECUTION_FOLDER}/out" -if [[ ${PLATFORM} == 'windows' ]]; then - # Todo change for powershell cmdlet - $SSH "${REMOTE}" "powershell.exe -c New-Item -ItemType directory -Path ${EXECUTION_FOLDER}/bin" -else - $SSH "${REMOTE}" "mkdir -p ${EXECUTION_FOLDER}/bin" -fi - -# Copy crc-e2e binary and pull-secret -# Review this when go 1.16 with embed support -$SCP "${BINARY_PATH}" "${REMOTE}:${EXECUTION_FOLDER}/bin" -$SCP "${PULL_SECRET_FILE_PATH}" "${REMOTE}:${EXECUTION_FOLDER}/pull-secret" -$SCP "${FEATURES_PATH}" "${REMOTE}:${EXECUTION_FOLDER}/bin" -# Testdata files -$SCP "${TESTDATA_PATH}" "${REMOTE}:${EXECUTION_FOLDER}" - -echo "Running e2e tests" -# e2e envs -if [[ ${PLATFORM} == 'windows' ]]; then - # BINARY_EXEC="(New-Object -ComObject "Shell.Application").minimizeall(); \$env:SHELL=\"powershell\"; " - BINARY_EXEC="\$env:SHELL=\"powershell\"; " -fi -# e2e running options -if [[ ! -z "${BUNDLE_LOCATION+x}" ]]; then - OPTIONS="--bundle-location=${BUNDLE_LOCATION} " -else - OPTIONS="--bundle-location=\"\" " -fi -if [[ ${PLATFORM} == 'windows' ]]; then - OPTIONS+="--pull-secret-file=C:\\Users\\${TARGET_HOST_USERNAME}\\crc-e2e\\pull-secret " -else - OPTIONS+="--pull-secret-file=${EXECUTION_FOLDER}/pull-secret " -fi -if [[ ${PLATFORM} == 'macos' ]]; then - PLATFORM="darwin" -fi -if [ "${CLEANUP_HOME}" = "false" ]; then - OPTIONS+="--cleanup-home=false " -fi - -TAGS="@${PLATFORM}" -if [ -n "${E2E_TAG_EXPRESSION}" ]; then - TAGS+=" && ${E2E_TAG_EXPRESSION}" -fi -if [[ ${PLATFORM} == 'darwin' ]]; then - OPTIONS+="--godog.tags=\\\"${TAGS}\\\" --godog.format=junit " - BINARY_EXEC+="sudo su - ${TARGET_HOST_USERNAME} -c \"PATH=\$PATH:/usr/local/bin && cd ${EXECUTION_FOLDER}/bin && ./${BINARY} ${OPTIONS} > ${RESULTS_FILE}.results\"" -else - OPTIONS+="--godog.tags=\"${TAGS}\" --godog.format=junit " - BINARY_EXEC+="cd ${EXECUTION_FOLDER}/bin && ./${BINARY} ${OPTIONS} > ${RESULTS_FILE}.results" -fi -# Execute command remote -$SSH ${REMOTE} ${BINARY_EXEC} - -echo "Getting e2e tests results and logs" -# Get results -mkdir -p "${RESULTS_PATH}" -$SCP "${REMOTE}:${EXECUTION_FOLDER}/bin/${RESULTS_FILE}.results" "${RESULTS_PATH}" -$SCP "${REMOTE}:${EXECUTION_FOLDER}/bin/out/test-results" "${RESULTS_PATH}" -# xunit cleanup on results -pushd "${RESULTS_PATH}" -init_line=$(grep -n '' ${RESULTS_FILE}.results | awk '{split($0,n,":"); print n[1]}') -tail -n +$init_line ${RESULTS_FILE}.results > ${RESULTS_FILE}.xml -popd - -echo "Cleanup target" -# Cleanup -$SSH "${REMOTE}" "rm -r ${EXECUTION_FOLDER}" \ No newline at end of file diff --git a/images/build-e2e/lib/darwin/run.sh b/images/build-e2e/lib/darwin/run.sh new file mode 100755 index 0000000000..0b417f56bc --- /dev/null +++ b/images/build-e2e/lib/darwin/run.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Parameters +bundleLocation="" +e2eTagExpression="" +crcMemory="" +targetFolder="crc-e2e" +junitFilename="e2e-junit.xml" +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -bundleLocation) + bundleLocation="$2" + shift + shift + ;; + -e2eTagExpression) + e2eTagExpression="$2" + shift + shift + ;; + -targetFolder) + targetFolder="$2" + shift + shift + ;; + -junitFilename) + junitFilename="$2" + shift + shift + ;; + -crcMemory) + crcMemory="$2" + shift + shift + ;; + *) # unknown option + shift + ;; + esac +done + +# Prepare resuslts folder +mkdir -p $targetFolder/results + +# Run tests +tags="darwin" +if [ ! -z "$e2eTagExpression" ] +then + tags="$tags && $e2eTagExpression" +fi +cd $targetFolder/bin +./e2e.test --bundle-location=$bundleLocation --pull-secret-file="${HOME}/$targetFolder/pull-secret" --cleanup-home=false --crc-memory=$crcMemory --godog.tags="$tags" --godog.format=junit > "${HOME}/$targetFolder/results/e2e.results" + +# Transform results to junit +cd .. +init_line=$(grep -n '' results/e2e.results | awk '{split($0,n,":"); print n[1]}') +tail -n +$init_line results/e2e.results > results/$junitFilename +# Copy logs and diagnose +cp -r bin/out/test-results/* results \ No newline at end of file diff --git a/images/build-e2e/lib/linux/run.sh b/images/build-e2e/lib/linux/run.sh new file mode 100755 index 0000000000..94fe5737da --- /dev/null +++ b/images/build-e2e/lib/linux/run.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Parameters +bundleLocation="" +e2eTagExpression="" +crcMemory="" +targetFolder="crc-e2e" +junitFilename="e2e-junit.xml" +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -bundleLocation) + bundleLocation="$2" + shift + shift + ;; + -e2eTagExpression) + e2eTagExpression="$2" + shift + shift + ;; + -targetFolder) + targetFolder="$2" + shift + shift + ;; + -junitFilename) + junitFilename="$2" + shift + shift + ;; + -crcMemory) + crcMemory="$2" + shift + shift + ;; + *) # unknown option + shift + ;; + esac +done + +# Prepare resuslts folder +mkdir -p $targetFolder/results + +# Run tests +tags="linux" +if [ ! -z "$e2eTagExpression" ] +then + tags="$tags && $e2eTagExpression" +fi +cd $targetFolder/bin +./e2e.test --bundle-location=$bundleLocation --pull-secret-file="${HOME}/$targetFolder/pull-secret" --cleanup-home=false --crc-memory=$crcMemory --godog.tags="$tags" --godog.format=junit > "${HOME}/$targetFolder/results/e2e.results" + +# Transform results to junit +cd .. +init_line=$(grep -n '' results/e2e.results | awk '{split($0,n,":"); print n[1]}') +tail -n +$init_line results/e2e.results > results/$junitFilename +# Copy logs and diagnose +cp -r bin/out/test-results/* results \ No newline at end of file diff --git a/images/build-e2e/lib/windows/run.ps1 b/images/build-e2e/lib/windows/run.ps1 new file mode 100755 index 0000000000..9fd2488538 --- /dev/null +++ b/images/build-e2e/lib/windows/run.ps1 @@ -0,0 +1,35 @@ +param( + [Parameter(HelpMessage='When testing a custom bundle we should pass the paht on the target host')] + $bundleLocation="", + [Parameter(HelpMessage='To set an specific set of tests based on annotations')] + $e2eTagExpression="", + [Parameter(HelpMessage='Name of the folder on the target host under $HOME where all the content will be copied')] + $targetFolder="crc-e2e", + [Parameter(HelpMessage='Name for the junit file with the tests results')] + $junitFilename="e2e-junit.xml", + [Parameter(HelpMessage='Customize memory for the cluster to run the tests')] + $crcMemory="" +) + +# Prepare run e2e +mv $targetFolder/bin/e2e.test $targetFolder/bin/e2e.test.exe + +# Run e2e +$env:PATH="$env:PATH;$env:HOME\$targetFolder\bin;" +$env:SHELL="powershell" +New-Item -ItemType directory -Path "$env:HOME\$targetFolder\results" -Force + +# Run tests +$tags="windows" +if ($e2eTagExpression) { + $tags="$tags && $e2eTagExpression" +} +cd $targetFolder\bin +e2e.test.exe --bundle-location=$bundleLocation --pull-secret-file=$env:HOME\$targetFolder\pull-secret --crc-memory=$crcMemory --cleanup-home=false --godog.tags="$tags" --godog.format=junit > $env:HOME\$targetFolder\results\e2e.results + +# Transform results to junit +cd .. +$r = Select-String -Pattern '' -Path results\e2e.results -list -SimpleMatch | select-object -First 1 +Get-Content results\e2e.results | Select -skip ($r.LineNumber -1) > results\$junitFilename +# Copy logs and diagnose +cp -r bin\out\test-results\* results \ No newline at end of file diff --git a/images/build-integration/Containerfile b/images/build-integration/Containerfile new file mode 100644 index 0000000000..6eda99fd71 --- /dev/null +++ b/images/build-integration/Containerfile @@ -0,0 +1,25 @@ + +FROM registry.access.redhat.com/ubi9/go-toolset:1.20 AS builder + +USER root + +ARG OS +ARG ARCH +WORKDIR /workspace +COPY . . +RUN GOARCH=${ARCH} GOOS=${OS} make build_integration + +FROM quay.io/rhqp/deliverest:v0.0.6 + +LABEL org.opencontainers.image.authors="CRCQE " + +ARG OS +ARG ARCH + +ENV ASSETS_FOLDER=/opt/crc \ + OS=${OS} \ + ARCH=${ARCH} + +COPY --from=builder /workspace/out/${OS}-${ARCH} ${ASSETS_FOLDER}/bin +COPY images/build-integration/lib/${OS}/* ${ASSETS_FOLDER}/ + diff --git a/images/build-integration/Dockerfile b/images/build-integration/Dockerfile deleted file mode 100644 index c4cc717d0a..0000000000 --- a/images/build-integration/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM registry.access.redhat.com/ubi8/go-toolset:1.20 AS builder - -USER root -WORKDIR /workspace -COPY . . -RUN make build_integration - -FROM registry.access.redhat.com/ubi8/ubi-minimal - -LABEL MAINTAINER "CRC " - -COPY --from=builder /workspace/images/build-integration/entrypoint.sh /usr/local/bin/ -COPY --from=builder /workspace/out /opt/crc/bin - -ENV EPEL https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm - -RUN rpm -ivh ${EPEL} \ - && microdnf --enablerepo=epel install -y openssh-clients sshpass \ - && microdnf clean all - -ENTRYPOINT ["entrypoint.sh"] diff --git a/images/build-integration/README.md b/images/build-integration/README.md index 8d2946381a..f1b063aad2 100644 --- a/images/build-integration/README.md +++ b/images/build-integration/README.md @@ -1,44 +1,96 @@ # Overview -The container includes the integration binary for all 3 platforms plus the required resources to run it. +This image contains the integration suite of tests, and it is intended to run them against a target host, the logic to run the tests remotely is inherit from its base image: [deliverest](https://github.com/adrianriobo/deliverest), each platform and os has its own image. -The container connects through ssh to the target host and copy the right binary for the platform, run integration tests and pick the results and logs back. +## Build -## Envs +We should build an image per platform and arch we want to test: -**PLATFORM**:*define target platform (windows, macos, linux).* -**TARGET_HOST**:*dns or ip for the target host.* -**TARGET_HOST_USERNAME**:*username for target host.* -**TARGET_HOST_KEY_PATH**:*private key for user. (Mandatory if not TARGET_HOST_PASSWORD).* -**TARGET_HOST_PASSWORD**:*password for user. (Mandatory if not TARGET_HOST_KEY_PATH).* -**PULL_SECRET_FILE_PATH** pull secret file path (local to container).* -**BUNDLE_LOCATION**:*(Optional). When testing crc with custom bundle set the bundle location on target server.* -**RESULTS_PATH**:*(Optional). Path inside container to pick results and logs from integration execution.* +```bash +CRC_INTEGRATION_IMG_VERSION=v2.35.0-dev OS=windows ARCH=amd64 make containerized_integration +CRC_INTEGRATION_IMG_VERSION=v2.35.0-dev OS=linux ARCH=amd64 make containerized_integration +CRC_INTEGRATION_IMG_VERSION=v2.35.0-dev OS=darwin ARCH=amd64 make containerized_integration +CRC_INTEGRATION_IMG_VERSION=v2.35.0-dev OS=darwin ARCH=arm64 make containerized_integration +``` + +## Run + +The image version contains the specs about the plaftorm and the arch; then the test customization is made by the command executed within the image; as we can see the cmd should be defined depending on the platform: + +* crc-integration/run.ps1 ... (windows) +* crc-integration/run.sh ... (linux/darwin) -## Samples +And the execution is customized by the params addded, available params: + +* bundleLocation When testing a custom bundle we should pass the path on the target host +* targetFolder Name of the folder on the target host under $HOME where all the content will be copied +* junitFilename Name for the junit file with the tests results + +### Windows amd64 ```bash -# Run integration on macos platform with ssh key and custom bundle -podman run --rm -it --name crc-integration \ - -e PLATFORM=macos \ - -e TARGET_HOST=$IP \ - -e TARGET_HOST_USERNAME=$USER \ - -e TARGET_HOST_KEY_PATH=/opt/crc/id_rsa \ - -e PULL_SECRET_FILE_PATH=/opt/crc/pull-secret \ - -e BUNDLE_LOCATION=/bundles/crc_hyperv_4.8.0-rc.3.crcbundle \ - -v $PWD/pull-secret:/opt/crc/pull-secret:Z \ - -v $PWD/id_rsa:/opt/crc/id_rsa:Z \ - -v $PWD/output:/output:Z \ - quay.io/crcont/crc-integration:v1.29.0 - -# Run integration on windows platform with ssh password and crc released version -podman run --rm -it --name crc-integration \ - -e PLATFORM=windows \ - -e TARGET_HOST=$IP \ - -e TARGET_HOST_USERNAME=$USER \ - -e TARGET_HOST_PASSWORD=$PASSWORD \ - -e PULL_SECRET_FILE_PATH=/opt/crc/pull-secret \ - -v $PWD/pull-secret:/opt/crc/pull-secret:Z \ - -v $PWD/output:/output:Z \ - quay.io/crcont/crc-integration:v1.29.0 +podman run --rm -d --name crc-integration-windows \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-integration \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-integration:v2.34.0-windows-amd64 \ + crc-integration/run.ps1 -junitFilename crc-integration-junit.xml ``` + +### Mac arm64 + +```bash +podman run --rm -d --name crc-integration-darwin \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-integration \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-integration:v2.34.0-darwin-arm64 \ + crc-integration/run.sh -junitFilename crc-integration-junit.xml +``` + +### Mac amd64 + +```bash +podman run --rm -d --name crc-integration-darwin \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-integration \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-integration:v2.34.0-darwin-amd64 \ + crc-integration/run.sh -junitFilename crc-integration-junit.xml +``` + + +### Linux amd64 + +```bash +podman run --rm -d --name crc-integration-linux \ + -e TARGET_HOST=XXXX \ + -e TARGET_HOST_USERNAME=XXXX \ + -e TARGET_HOST_KEY_PATH=/data/id_rsa \ + -e TARGET_FOLDER=crc-integration \ + -e TARGET_RESULTS=results \ + -e OUTPUT_FOLDER=/data \ + -e DEBUG=true \ + -v $PWD/pull-secret:/opt/crc/pull-secret:z \ + -v $PWD:/data:z \ + quay.io/crcont/crc-integration:v2.34.0-linux-amd64 \ + crc-integration/run.sh -junitFilename crc-integration-junit.xml +``` \ No newline at end of file diff --git a/images/build-integration/entrypoint.sh b/images/build-integration/entrypoint.sh deleted file mode 100755 index 93b88538fc..0000000000 --- a/images/build-integration/entrypoint.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/sh - -# Vars -ARCH="${ARCH:-"amd64"}" -BINARY=integration.test -if [[ ${PLATFORM} == 'windows' ]]; then - BINARY=integration.test.exe -fi -BINARY_PATH="/opt/crc/bin/${PLATFORM}-${ARCH}/${BINARY}" - -# Results -RESULTS_PATH="${RESULTS_PATH:-/output}" - - -if [ "${DEBUG:-}" = "true" ]; then - set -xuo -fi - -# Validate conf -validate=true -[[ -z "${TARGET_HOST+x}" ]] \ - && echo "TARGET_HOST required" \ - && validate=false - -[[ -z "${TARGET_HOST_USERNAME+x}" ]] \ - && echo "TARGET_HOST_USERNAME required" \ - && validate=false - -[[ -z "${TARGET_HOST_KEY_PATH+x}" && -z "${TARGET_HOST_PASSWORD+x}" ]] \ - && echo "TARGET_HOST_KEY_PATH or TARGET_HOST_PASSWORD required" \ - && validate=false - -[[ -z "${PULL_SECRET_FILE_PATH+x}" ]] \ - && echo "PULL_SECRET_FILE_PATH required" \ - && validate=false - -[[ $validate == false ]] && exit 1 - -# Define remote connection -REMOTE="${TARGET_HOST_USERNAME}@${TARGET_HOST}" -if [[ ! -z "${TARGET_HOST_DOMAIN+x}" ]]; then - REMOTE="${TARGET_HOST_USERNAME}@${TARGET_HOST_DOMAIN}@${TARGET_HOST}" -fi - -# Increase ssh connectivity reliability -RELIABLE_CONNECTION='-o ServerAliveInterval=30 -o ServerAliveCountMax=1200' -# Set SCP / SSH command with pass or key -NO_STRICT='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' -if [[ ! -z "${TARGET_HOST_KEY_PATH+x}" ]]; then - SCP="scp -r ${RELIABLE_CONNECTION} ${NO_STRICT} -i ${TARGET_HOST_KEY_PATH}" - SSH="ssh ${RELIABLE_CONNECTION} ${NO_STRICT} -i ${TARGET_HOST_KEY_PATH}" -else - SCP="sshpass -p ${TARGET_HOST_PASSWORD} scp -r ${RELIABLE_CONNECTION} ${NO_STRICT}" \ - SSH="sshpass -p ${TARGET_HOST_PASSWORD} ssh ${RELIABLE_CONNECTION} ${NO_STRICT}" -fi - -echo "Copy resources to target" -# Create execution folder -EXECUTION_FOLDER="/Users/${TARGET_HOST_USERNAME}/crc-integration" -if [[ ${PLATFORM} == 'linux' ]]; then - EXECUTION_FOLDER="/home/${TARGET_HOST_USERNAME}/crc-integration" -fi -DATA_FOLDER="${EXECUTION_FOLDER}/out" -if [[ ${PLATFORM} == 'windows' ]]; then - # Todo change for powershell cmdlet - $SSH "${REMOTE}" "powershell.exe -c New-Item -ItemType directory -Path ${EXECUTION_FOLDER}/bin" -else - $SSH "${REMOTE}" "mkdir -p ${EXECUTION_FOLDER}/bin" -fi - -# Copy crc-integration binary and pull-secret -$SCP "${BINARY_PATH}" "${REMOTE}:${EXECUTION_FOLDER}/bin" -$SCP "${PULL_SECRET_FILE_PATH}" "${REMOTE}:${EXECUTION_FOLDER}/pull-secret" - -echo "Running integration tests" -# Run integration cmd -# Review when pwsh added as powershell supported -if [[ ${PLATFORM} == 'windows' ]]; then - BINARY_EXEC="cd ${EXECUTION_FOLDER}/bin; " - BINARY_EXEC+="\$env:SHELL='powershell'; " - BINARY_EXEC+="\$env:PULL_SECRET_PATH='${EXECUTION_FOLDER}/pull-secret'; " - if [[ ! -z "${BUNDLE_LOCATION+x}" ]] && [[ -n "${BUNDLE_LOCATION}" ]]; then - BINARY_EXEC+="\$env:BUNDLE_PATH='${BUNDLE_LOCATION}'; " - fi - BINARY_EXEC+="./${BINARY} > integration.results" -else - BINARY_EXEC="cd ${EXECUTION_FOLDER}/bin && " - BINARY_EXEC+="PULL_SECRET_PATH=${EXECUTION_FOLDER}/pull-secret " - if [[ ! -z "${BUNDLE_LOCATION+x}" ]] && [[ -n "${BUNDLE_LOCATION}" ]]; then - BINARY_EXEC+="BUNDLE_PATH=${BUNDLE_LOCATION} " - fi - BINARY_EXEC+="./${BINARY} > integration.results" - if [[ ${PLATFORM} == 'macos' ]]; then - BINARY_EXEC="sudo su - ${TARGET_HOST_USERNAME} -c \"PATH=\$PATH:/usr/local/bin && ${BINARY_EXEC} \"" - fi -fi -# Execute command remote -$SSH "${REMOTE}" "${BINARY_EXEC}" - -echo "Getting integration results and logs" -# Get results -mkdir -p "${RESULTS_PATH}" -$SCP "${REMOTE}:${EXECUTION_FOLDER}/bin/integration.results" "${RESULTS_PATH}" -$SCP "${REMOTE}:${EXECUTION_FOLDER}/bin/out/integration.xml" "${RESULTS_PATH}" - -echo "Cleanup target" -# Clenaup -$SSH "${REMOTE}" "rm -r ${EXECUTION_FOLDER}" \ No newline at end of file diff --git a/images/build-integration/lib/darwin/run.sh b/images/build-integration/lib/darwin/run.sh new file mode 100755 index 0000000000..4665cca7f5 --- /dev/null +++ b/images/build-integration/lib/darwin/run.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Parameters +bundleLocation="" +targetFolder="crc-integration" +junitFilename="integration-junit.xml" +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -bundleLocation) + bundleLocation="$2" + shift + shift + ;; + -targetFolder) + targetFolder="$2" + shift + shift + ;; + -junitFilename) + junitFilename="$2" + shift + shift + ;; + *) # unknown option + shift + ;; + esac +done + +# Prepare resuslts folder +mkdir -p $targetFolder/results + +# Run tests +PATH="$PATH:${HOME}/$targetFolder/bin" +PULL_SECRET_PATH="${HOME}/$targetFolder/pull-secret" +if [ ! -z "$bundleLocation" ] +then + BUNDLE_PATH="$bundleLocation" +fi +cd $targetFolder/bin +. integration.test > integration.results + +# Copy results +cd .. +cp bin/integration.results results/integration.results +cp bin/out/integration.xml results/$junitFilename \ No newline at end of file diff --git a/images/build-integration/lib/linux/run.sh b/images/build-integration/lib/linux/run.sh new file mode 100755 index 0000000000..4665cca7f5 --- /dev/null +++ b/images/build-integration/lib/linux/run.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Parameters +bundleLocation="" +targetFolder="crc-integration" +junitFilename="integration-junit.xml" +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -bundleLocation) + bundleLocation="$2" + shift + shift + ;; + -targetFolder) + targetFolder="$2" + shift + shift + ;; + -junitFilename) + junitFilename="$2" + shift + shift + ;; + *) # unknown option + shift + ;; + esac +done + +# Prepare resuslts folder +mkdir -p $targetFolder/results + +# Run tests +PATH="$PATH:${HOME}/$targetFolder/bin" +PULL_SECRET_PATH="${HOME}/$targetFolder/pull-secret" +if [ ! -z "$bundleLocation" ] +then + BUNDLE_PATH="$bundleLocation" +fi +cd $targetFolder/bin +. integration.test > integration.results + +# Copy results +cd .. +cp bin/integration.results results/integration.results +cp bin/out/integration.xml results/$junitFilename \ No newline at end of file diff --git a/images/build-integration/lib/windows/run.ps1 b/images/build-integration/lib/windows/run.ps1 new file mode 100755 index 0000000000..9c0944b64f --- /dev/null +++ b/images/build-integration/lib/windows/run.ps1 @@ -0,0 +1,30 @@ +param( + [Parameter(HelpMessage='When testing a custom bundle we should pass the paht on the target host')] + $bundleLocation="", + [Parameter(HelpMessage='Name of the folder on the target host under $HOME where all the content will be copied')] + $targetFolder="crc-integration", + [Parameter(HelpMessage='Name for the junit file with the tests results')] + $junitFilename="integration-junit.xml" +) + +# Prepare run e2e +mv $targetFolder/bin/integration.test $targetFolder/bin/integration.test.exe + +# Run e2e +$env:PATH="$env:PATH;$env:HOME\$targetFolder\bin;" +$env:SHELL="powershell" +New-Item -ItemType directory -Path "$env:HOME\$targetFolder\results" -Force + +# Run tests +cd $targetFolder\bin +if ($bundleLocation) { + $env:BUNDLE_PATH="$bundleLocation" +} +# We need to copy the pull-secret to the target folder +$env:PULL_SECRET_PATH="$env:HOME\$targetFolder\pull-secret" +integration.test.exe > integration.results + +# Copy results +cd .. +cp bin\integration.results results\integration.results +cp bin\out\integration.xml results\$junitFilename \ No newline at end of file