Skip to content

Commit

Permalink
Sdcicd 917 boilerplate update for osde2e (#126)
Browse files Browse the repository at this point in the history
* removing old osde2e dir

* onboarding to boilerplate osde2e convention

* onboarding to boilerplate osde2e convention

* updated boilerplate

* updated boilerplate
  • Loading branch information
ritmun authored Feb 13, 2023
1 parent 6a4d252 commit dce54a5
Show file tree
Hide file tree
Showing 13 changed files with 284 additions and 72 deletions.
2 changes: 1 addition & 1 deletion boilerplate/_data/last-boilerplate-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
76942d7dbb2425eb028459cfc5f88e92b6d4d504
b882991ad169f49cb8e09c2e5fbe8740fb1f9a08
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/ubi7/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 $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"
1 change: 1 addition & 0 deletions boilerplate/update.cfg
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
openshift/golang-osd-operator
openshift/golang-osd-operator-osde2e
8 changes: 4 additions & 4 deletions osde2e/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

# 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/aws-vpce-operator/
WORKDIR ${PKG}

# compile test binary
COPY . .

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

COPY osde2e.test osde2e.test
COPY ./harness.test harness.test

ENTRYPOINT [ "/osde2e.test" ]
ENTRYPOINT [ "/harness.test" ]
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
// THIS FILE IS GENERATED BY BOILERPLATE. DO NOT EDIT.
//go:build integration
// +build integration

package exampleaddontestharness
package osde2etests

import (
"path/filepath"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
_ "github.com/openshift/aws-vpce-operator/osde2e/tests"
"path/filepath"
"testing"
)

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

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

suiteConfig, reporterConfig := GinkgoConfiguration()
reporterConfig.JUnitReport = filepath.Join(testResultsDirectory, jUnitOutputFilename)
RunSpecs(t, "AVO Test Harness", suiteConfig, reporterConfig)
RunSpecs(t, "Aws Vpce Operator", suiteConfig, reporterConfig)

}
7 changes: 7 additions & 0 deletions osde2e/aws_vpce_operator_tests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package osde2etests

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

var _ = ginkgo.Describe("aws-vpce-operator", func() {
// Add your tests
})
17 changes: 0 additions & 17 deletions osde2e/harness-build-push.sh

This file was deleted.

Loading

0 comments on commit dce54a5

Please sign in to comment.