Skip to content

decentralize osde2e tests #236

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

Closed
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: 1 addition & 1 deletion .ci-operator.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
build_root_image:
name: boilerplate
namespace: openshift
tag: image-v3.0.2
tag: image-v3.0.3
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ updates:
ignore:
- dependency-name: "app-sre/boilerplate"
# don't upgrade boilerplate via these means
- dependency-name: "openshift/origin-operator-registry"
# don't upgrade origin-operator-registry via these means
2 changes: 1 addition & 1 deletion boilerplate/_data/backing-image-tag
Original file line number Diff line number Diff line change
@@ -1 +1 @@
image-v3.0.2
image-v3.0.3
2 changes: 1 addition & 1 deletion boilerplate/_data/last-boilerplate-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f2283ca508e2f9af2e1f1d08e86051aefdad0386
764036b2bf3138ef860fa07d8e0cc017c8cfca43
4 changes: 2 additions & 2 deletions boilerplate/_lib/freeze-check
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ cd $REPO_ROOT
BOILERPLATE_GIT_CLONE="git clone $TMPD" boilerplate/update

# Okay, if anything has changed, that's bad.
if [[ $(git status --porcelain | wc -l) -ne 0 ]]; then
if [[ $(git status --porcelain -- ':!build/Dockerfile*' | wc -l) -ne 0 ]]; then
echo "Your boilerplate is dirty!" >&2
git status --porcelain
git status --porcelain -- ':!build/Dockerfile*'
exit 1
fi

Expand Down
2 changes: 2 additions & 0 deletions boilerplate/generated-includes.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ include boilerplate/_lib/boilerplate.mk
include boilerplate/openshift/golang-osd-operator/csv-generate/csv-generate.mk
include boilerplate/openshift/golang-osd-operator/project.mk
include boilerplate/openshift/golang-osd-operator/standard.mk
include boilerplate/openshift/golang-osd-operator-osde2e/project.mk
include boilerplate/openshift/golang-osd-operator-osde2e/standard.mk
40 changes: 40 additions & 0 deletions boilerplate/openshift/golang-osd-operator-osde2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Conventions for Ginkgo based e2e tests

- [Conventions for Ginkgo based e2e tests](#conventions-for-ginkgo-based-e2e-tests)
- [Consuming](#consuming)
- [`make` targets and functions.](#make-targets-and-functions)
- [E2E Test Harness](#e2e-test-harness)
- [Local Testing](#e2e-harness-local-testing)

## Consuming
Currently, this convention is only intended for OSD operators. To adopt this convention, your `boilerplate/update.cfg` should include:

```
openshift/golang-osd-operator-osde2e
```

## `make` targets and functions.

**Note:** Your repository's main `Makefile` needs to be edited to include the
"nexus makefile include":

```
include boilerplate/generated-includes.mk
```

One of the primary purposes of these `make` targets is to allow you to
standardize your prow and app-sre pipeline configurations using the
following:

### E2e Test Harness

| `make` target | Purpose |
|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `e2e-harness-generate` | Generate scaffolding for an end to end test harness. The `osde2e/` directory is created where the tests and test runner reside. The harness has access to cloud client and addon passthrough secrets within the test job cluster. Add your operator related ginkgo e2e tests under the `osde2e/<operator-name>_tests.go` file. See [this README](https://github.com/openshift/osde2e-example-test-harness/blob/main/README.md#locally-running-this-example) for more details on test harness. |
| `e2e-harness-build`| Compiles ginkgo tests under osde2e/tests and creates the binary to be used by docker image used by osde2e. |
| `e2e-image-build-push` | Builds osde2e test harness image and pushes to operator's quay repo. Image name is defaulted to <operator-image-name>-test-harness. Quay repository must be created beforehand. |

#### E2E Harness Local Testing

Please follow [this README](https://github.com/openshift/osde2e-example-test-harness/blob/main/README.md#locally-running-this-example) to test your e2e harness with Osde2e locally

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#!/usr/bin/env bash

set -e

cmd=${0##*/}

usage() {
cat <<EOF
Usage: $0 OPERATOR_NAME OSDE2E_CONVENTION_DIR

EOF
exit -1
}

OPERATOR_NAME=$1
OSDE2E_CONVENTION_DIR=$2
REPO_ROOT=$(git rev-parse --show-toplevel)
HARNESS_DIR=$REPO_ROOT/osde2e

# Update operator name in templates
export OPERATOR_HYPHEN_NAME=$(echo "$OPERATOR_NAME"| sed 's/-/_/g')
export OPERATOR_PROPER_NAME=$(echo "$OPERATOR_NAME"| sed 's/-/ /g' |awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) substr($i,2) }}1')
export REPLACE_SPECNAME=${OPERATOR_PROPER_NAME} Test Harness
export REPLACE_FUNC=$(echo "$REPLACE_SPECNAME" | sed 's/ //g' )

mkdir $HARNESS_DIR


echo "
# THIS FILE IS GENERATED BY BOILERPLATE. DO NOT EDIT.
FROM registry.ci.openshift.org/openshift/release:golang-1.18 AS builder

ENV PKG=/go/src/github.com/openshift/${OPERATOR_NAME}/
WORKDIR \${PKG}\

COPY . .

FROM registry.access.redhat.com/ubi8/ubi-minimal:latest

COPY ./harness.test harness.test

ENTRYPOINT [ \"/harness.test\" ]" > $HARNESS_DIR/Dockerfile

echo "package osde2etests

import \"github.com/onsi/ginkgo/v2\"

var _ = ginkgo.Describe(\"$OPERATOR_NAME\", func() {
// Add your tests
})
" > ${HARNESS_DIR}/${OPERATOR_HYPHEN_NAME}_tests.go

echo "// THIS FILE IS GENERATED BY BOILERPLATE. DO NOT EDIT.
//go:build integration
// +build integration

package osde2etests

import (
\"path/filepath\"
\"testing\"
. \"github.com/onsi/ginkgo/v2\"
. \"github.com/onsi/gomega\"
)

const (
testResultsDirectory = \"/test-run-results\"
jUnitOutputFilename = \"junit-example-addon.xml\"
)

// Test entrypoint. osde2e runs this as a test suite on test pod.
func Test$REPLACE_FUNC(t *testing.T) {
RegisterFailHandler(Fail)

suiteConfig, reporterConfig := GinkgoConfiguration()
reporterConfig.JUnitReport = filepath.Join(testResultsDirectory, jUnitOutputFilename)
RunSpecs(t, \"$REPLACE_SPECNAME\", suiteConfig, reporterConfig)

}
" > ${HARNESS_DIR}/${OPERATOR_HYPHEN_NAME}_runner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash

set -ev

usage() {
cat <<EOF
Usage: $0 "IMAGE_SPECS"
IMAGE_SPECS is a multiline string where each line has the format:

dockerfile_path image_uri

For example:

# This is the test harness image
./build/Dockerfile quay.io/app-sre/my-wizbang-operator-test-harness:latest


The parameter is mandatory; if only building the catalog image,
specify the empty string.
EOF
exit -1
}

REPO_ROOT=$(git rev-parse --show-toplevel)
source $REPO_ROOT/boilerplate/_lib/common.sh

[[ $# -eq 1 ]] || usage


IMAGE_SPECS="$1"


while read dockerfile_path image_uri junk; do
# Support comment lines
if [[ "$dockerfile_path" == '#'* ]]; then
continue
fi
# Support blank lines
if [[ "$dockerfile_path" == "" ]]; then
continue
fi
if [[ "$junk" != "" ]] && [[ "$junk" != '#'* ]]; then
echo "Invalid image spec: found extra garbage: '$junk'"
exit 1
fi
if ! [[ -f "$dockerfile_path" ]]; then
echo "Invalid image spec: no such dockerfile: '$dockerfile_path'"
exit 1
fi

make IMAGE_URI="${image_uri}" DOCKERFILE_PATH="${dockerfile_path}" container-build-push-one

done <<< "$1"
10 changes: 10 additions & 0 deletions boilerplate/openshift/golang-osd-operator-osde2e/project.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Project specific values
OPERATOR_NAME?=$(shell sed -n 's/.*OperatorName .*"\([^"]*\)".*/\1/p' config/config.go)

HARNESS_IMAGE_REGISTRY?=quay.io
HARNESS_IMAGE_REPOSITORY?=app-sre
HARNESS_IMAGE_NAME?=$(OPERATOR_NAME)-test-harness


REGISTRY_USER?=$(QUAY_USER)
REGISTRY_TOKEN?=$(QUAY_TOKEN)
79 changes: 79 additions & 0 deletions boilerplate/openshift/golang-osd-operator-osde2e/standard.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Validate variables in project.mk exist
ifndef OPERATOR_NAME
$(error OPERATOR_NAME is not set; only operators should consume this convention; check project.mk file)
endif
ifndef HARNESS_IMAGE_REGISTRY
$(error HARNESS_IMAGE_REGISTRY is not set; check project.mk file)
endif
ifndef HARNESS_IMAGE_REPOSITORY
$(error HARNESS_IMAGE_REPOSITORY is not set; check project.mk file)
endif

### Accommodate docker or podman
#
# The docker/podman creds cache needs to be in a location unique to this
# invocation; otherwise it could collide across jenkins jobs. We'll use
# a .docker folder relative to pwd (the repo root).
CONTAINER_ENGINE_CONFIG_DIR = .docker
# But docker and podman use different options to configure it :eyeroll:
# ==> Podman uses --authfile=PATH *after* the `login` subcommand; but
# also accepts REGISTRY_AUTH_FILE from the env. See
# https://www.mankier.com/1/podman-login#Options---authfile=path
export REGISTRY_AUTH_FILE = ${CONTAINER_ENGINE_CONFIG_DIR}/config.json
# If this configuration file doesn't exist, podman will error out. So
# we'll create it if it doesn't exist.
ifeq (,$(wildcard $(REGISTRY_AUTH_FILE)))
$(shell mkdir -p $(CONTAINER_ENGINE_CONFIG_DIR))
$(shell echo '{}' > $(REGISTRY_AUTH_FILE))
endif
# ==> Docker uses --config=PATH *before* (any) subcommand; so we'll glue
# that to the CONTAINER_ENGINE variable itself. (NOTE: I tried half a
# dozen other ways to do this. This was the least ugly one that actually
# works.)
ifndef CONTAINER_ENGINE
CONTAINER_ENGINE=$(shell command -v podman 2>/dev/null || echo docker --config=$(CONTAINER_ENGINE_CONFIG_DIR))
endif

REGISTRY_USER ?=
REGISTRY_TOKEN ?=

# TODO: Figure out how to discover this dynamically
OSDE2E_CONVENTION_DIR := boilerplate/openshift/golang-osd-operator-osde2e

# TODO: figure out how to container-engine-login only once across multiple `make` calls
.PHONY: container-build-push-one
container-build-push-one: container-engine-login
@(if [[ -z "${IMAGE_URI}" ]]; then echo "Must specify IMAGE_URI"; exit 1; fi)
@(if [[ -z "${DOCKERFILE_PATH}" ]]; then echo "Must specify DOCKERFILE_PATH"; exit 1; fi)
${CONTAINER_ENGINE} build --pull -f $(DOCKERFILE_PATH) -t $(IMAGE_URI) .
${CONTAINER_ENGINE} push ${IMAGE_URI}

# log into quay.io
.PHONY: container-engine-login
container-engine-login:
@test "${REGISTRY_USER}" != "" && test "${REGISTRY_TOKEN}" != "" || (echo "REGISTRY_USER and REGISTRY_TOKEN must be defined" && exit 1)
mkdir -p ${CONTAINER_ENGINE_CONFIG_DIR}
@${CONTAINER_ENGINE} login -u="${REGISTRY_USER}" -p="${REGISTRY_TOKEN}" quay.io

######################
# Targets used by osde2e test harness
######################

# create e2e scaffolding
.PHONY: e2e-harness-generate
e2e-harness-generate:
${OSDE2E_CONVENTION_DIR}/e2e-harness-generate.sh $(OPERATOR_NAME) $(OSDE2E_CONVENTION_DIR)

# create binary
.PHONY: e2e-harness-build
e2e-harness-build: GOFLAGS_MOD=-mod=mod
e2e-harness-build: GOENV=GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 GOFLAGS="${GOFLAGS_MOD}"
e2e-harness-build:
go mod tidy
${GOENV} go test ./osde2e -v -c --tags=integration -o harness.test

# TODO: Push to a known image tag and commit id
# push harness image
.PHONY: e2e-image-build-push
e2e-image-build-push:
${OSDE2E_CONVENTION_DIR}/e2e-image-build-push.sh "./osde2e/Dockerfile $(IMAGE_REGISTRY)/$(IMAGE_REPOSITORY)/$(HARNESS_IMAGE_NAME):latest"
21 changes: 21 additions & 0 deletions boilerplate/openshift/golang-osd-operator/Dockerfile.olm-registry
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM quay.io/openshift/origin-operator-registry:4.12 AS builder
ARG SAAS_OPERATOR_DIR
COPY ${SAAS_OPERATOR_DIR} manifests
RUN initializer --permissive

FROM registry.access.redhat.com/ubi8/ubi-micro:latest

COPY --from=builder /bin/registry-server /bin/registry-server
COPY --from=builder /bin/grpc_health_probe /bin/grpc_health_probe
COPY --from=builder /bin/initializer /bin/initializer

WORKDIR /registry
RUN chgrp -R 0 /registry && chmod -R g+rwx /registry

USER 1001

COPY --from=builder /registry /registry

EXPOSE 50051

CMD ["registry-server", "-t", "/tmp/terminate.log"]
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ check_mandatory_params operator_channel operator_name
# Parameters for the Dockerfile
SAAS_OPERATOR_DIR="saas-${operator_name}-bundle"
BUNDLE_DIR="${SAAS_OPERATOR_DIR}/${operator_name}"
DOCKERFILE_REGISTRY="Dockerfile.olm-registry"
DOCKERFILE_REGISTRY="build/Dockerfile.olm-registry"

# Checking SAAS_OPERATOR_DIR exist
if [ ! -d "${SAAS_OPERATOR_DIR}/.git" ] ; then
Expand All @@ -61,31 +61,7 @@ channels:
currentCSV: ${operator_name}.v${OPERATOR_NEW_VERSION}
EOF

# Build registry
cat <<EOF > $DOCKERFILE_REGISTRY
FROM quay.io/openshift/origin-operator-registry:4.10.0 AS builder
COPY $SAAS_OPERATOR_DIR manifests
RUN initializer --permissive

FROM registry.access.redhat.com/ubi8/ubi-micro:8.6-484

COPY --from=builder /bin/registry-server /bin/registry-server
COPY --from=builder /bin/grpc_health_probe /bin/grpc_health_probe
COPY --from=builder /bin/initializer /bin/initializer

WORKDIR /registry
RUN chgrp -R 0 /registry && chmod -R g+rwx /registry

USER 1001

COPY --from=builder /registry /registry

EXPOSE 50051

CMD ["registry-server", "-t", "/tmp/terminate.log"]
EOF

${CONTAINER_ENGINE} build --pull -f $DOCKERFILE_REGISTRY --tag "${registry_image}:${operator_channel}-latest" .
${CONTAINER_ENGINE} build --pull -f "${DOCKERFILE_REGISTRY}" --build-arg "SAAS_OPERATOR_DIR=${SAAS_OPERATOR_DIR}" --tag "${registry_image}:${operator_channel}-latest" .

if [ $? -ne 0 ] ; then
echo "docker build failed, exiting..."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ fi
if [[ -z "$CONTAINER_ENGINE" ]]; then
YQ_CMD="yq"
else
YQ_CMD="$CONTAINER_ENGINE run --rm -i quay.io/app-sre/yq:3.4.1 yq"
yq_image="quay.io/app-sre/yq:3.4.1"
$CONTAINER_ENGINE pull $yq_image
YQ_CMD="$CONTAINER_ENGINE run --rm -i $yq_image yq"
fi

# Get the image URI as repo URL + image digest
Expand Down Expand Up @@ -175,5 +177,5 @@ else
else
CE_OPTS="-v `pwd`:`pwd`"
fi
$CONTAINER_ENGINE run --rm ${CE_OPTS} -u `id -u`:0 -w `pwd` registry.access.redhat.com/ubi8/python-36:1-134 /bin/bash -c "python -m pip install oyaml; python ./boilerplate/openshift/golang-osd-operator/csv-generate/common-generate-operator-bundle.py -o ${operator_name} -d ${OUTPUT_DIR} ${PREV_VERSION_OPTS} -i ${REPO_DIGEST} -V ${operator_version}"
$CONTAINER_ENGINE run --pull=always --rm ${CE_OPTS} -u `id -u`:0 -w `pwd` registry.access.redhat.com/ubi8/python-36 /bin/bash -c "python -m pip install --disable-pip-version-check oyaml; python ./boilerplate/openshift/golang-osd-operator/csv-generate/common-generate-operator-bundle.py -o ${operator_name} -d ${OUTPUT_DIR} ${PREV_VERSION_OPTS} -i ${REPO_DIGEST} -V ${operator_version}"
fi
2 changes: 2 additions & 0 deletions boilerplate/openshift/golang-osd-operator/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ updates:
ignore:
- dependency-name: "app-sre/boilerplate"
# don't upgrade boilerplate via these means
- dependency-name: "openshift/origin-operator-registry"
# don't upgrade origin-operator-registry via these means
Loading