Skip to content
Open
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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ registry-scanner/hack
registry-scanner/test
scripts/
test/e2e
test/ginkgo
test/testdata
test/utils
*.iml
Expand Down
133 changes: 133 additions & 0 deletions .github/workflows/ci-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,136 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: coverage.out
test-e2e:
name: Run end-to-end tests
runs-on: ubuntu-latest
strategy:
matrix:
k3s-version: [ v1.27.1 ]
# k3s-version: [v1.20.2, v1.19.2, v1.18.9, v1.17.11, v1.16.15]
steps:
- name: Install K3D
run: |
set -x
curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
sudo mkdir -p $HOME/.kube && sudo chown -R runner $HOME/.kube
k3d cluster create --servers 3 --image rancher/k3s:${{ matrix.k3s-version }}-k3s1
kubectl version
k3d version
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Golang
uses: actions/setup-go@v6
with:
go-version-file: 'test/ginkgo/go.mod'
- name: GH actions workaround - Kill XSP4 process
run: |
sudo pkill mono || true
- name: Restore go build cache
uses: actions/cache@v4
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
- name: Add /usr/local/bin to PATH
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
- name: Download Go dependencies
run: |
cd test/ginkgo && go mod download
- name: Build local image updater, deploy operator
env:
ARGOCD_CLUSTER_CONFIG_NAMESPACES: argocd-e2e-cluster-config
K3D_CLUSTER_NAME: k3s-default
run: |
set -o pipefail
make -C test/ginkgo test-e2e-ci

- name: Run ginkgo tests
run: |
set -o pipefail
make e2e-tests-parallel-ginkgo 2>&1 | tee /tmp/e2e-test-ginkgo.log

- name: Save application controller and server logs
if: ${{ failure() }}
run: |
# Collect logs from test namespaces. The ginkgo tests use dynamically generated
# namespace names with the prefix 'gitops-e2e-test-'.
set -x

# Find all gitops-e2e-test-* namespaces
E2E_NAMESPACES=$(kubectl get namespaces -o=name | grep 'gitops-e2e-test-' | sed 's|namespace/||' || true)

if [ -n "$E2E_NAMESPACES" ]; then
for NS in $E2E_NAMESPACES; do
echo "--- Collecting resources from namespace $NS ---"
kubectl get all -n "$NS" >> /tmp/pods.log 2>&1 || true

# Collect application controller logs
APP_CONTROLLER=$(kubectl get po -n "$NS" -o=name 2>/dev/null | grep argocd-application-controller || true)
if [ -n "$APP_CONTROLLER" ]; then
kubectl logs -n "$NS" "$APP_CONTROLLER" >> /tmp/e2e-application-controller.log 2>&1 || true
fi

# Collect server logs
SERVER_POD=$(kubectl get po -n "$NS" -o=name 2>/dev/null | grep argocd-server || true)
if [ -n "$SERVER_POD" ]; then
kubectl logs -n "$NS" "$SERVER_POD" >> /tmp/e2e-server.log 2>&1 || true
kubectl describe -n "$NS" "$SERVER_POD" >> /tmp/e2e-server.log 2>&1 || true
fi

# Collect image updater logs
IMAGE_UPDATER_POD=$(kubectl get po -n "$NS" -o=name 2>/dev/null | grep 'image-updater' || true)
if [ -n "$IMAGE_UPDATER_POD" ]; then
kubectl logs -n "$NS" "$IMAGE_UPDATER_POD" >> /tmp/e2e-image-updater.log 2>&1 || true
fi
done
fi

# Also collect operator logs from argocd-operator-system namespace
OPERATOR_POD=$(kubectl get po -n argocd-operator-system -o=name 2>/dev/null | grep controller-manager || true)
if [ -n "$OPERATOR_POD" ]; then
echo "--- Collecting operator logs ---"
kubectl logs -n argocd-operator-system "$OPERATOR_POD" -c manager > /tmp/e2e-operator-run.log 2>&1 || true
fi

- name: Upload operator logs
uses: actions/upload-artifact@v5
with:
name: e2e-operator-run-${{ matrix.k3s-version }}.log
path: /tmp/e2e-operator-run.log
if: ${{ failure() }}

- name: Upload ginkgo test logs
uses: actions/upload-artifact@v5
with:
name: e2e-test-${{ matrix.k3s-version }}.log
path: /tmp/e2e-test-ginkgo.log
if: ${{ failure() }}

- name: Upload application controller logs
uses: actions/upload-artifact@v5
with:
name: e2e-application-controller-${{ matrix.k3s-version }}.log
path: /tmp/e2e-application-controller.log
if: ${{ failure() }}

- name: Upload server logs
uses: actions/upload-artifact@v5
with:
name: e2e-server-${{ matrix.k3s-version }}.log
path: /tmp/e2e-server.log
if: ${{ failure() }}

- name: Upload image updater logs
uses: actions/upload-artifact@v5
with:
name: e2e-image-updater-${{ matrix.k3s-version }}.log
path: /tmp/e2e-image-updater.log
if: ${{ failure() }}

- name: Upload pod descriptions
uses: actions/upload-artifact@v5
with:
name: e2e-pods-${{ matrix.k3s-version }}.log
path: /tmp/pods.log
if: ${{ failure() }}
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,22 @@ golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary.
$(GOLANGCI_LINT): $(LOCALBIN)
$(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION))

## E2E
.PHONY: e2e-tests-sequential-ginkgo
e2e-tests-sequential-ginkgo: ginkgo
@echo "Running operator sequential Ginkgo E2E tests..."
$(GINKGO_CLI) -v --trace --timeout 90m -r ./test/ginkgo/sequential

.PHONY: e2e-tests-parallel-ginkgo
e2e-tests-parallel-ginkgo: ginkgo
@echo "Running operator parallel Ginkgo E2E tests..."
$(GINKGO_CLI) -p -v -procs=5 --trace --timeout 90m -r ./test/ginkgo/parallel

GINKGO_CLI = $(shell pwd)/bin/ginkgo
.PHONY: ginkgo
ginkgo: ## Download ginkgo locally if necessary.
$(call go-install-tool,$(GINKGO_CLI),github.com/onsi/ginkgo/v2/ginkgo,v2.27.2)

# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist
# $1 - target path with name of binary
# $2 - package url which can be installed
Expand Down
108 changes: 108 additions & 0 deletions test/ginkgo/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Default image for argocd-operator. Can be overridden.
ARGOCD_OPERATOR_IMAGE ?= quay.io/argoprojlabs/argocd-operator:latest

# Get version from root VERSION file
IMAGE_NAMESPACE?=quay.io/argoprojlabs
IMAGE_NAME=argocd-image-updater
ifdef IMAGE_NAMESPACE
IMAGE_PREFIX=${IMAGE_NAMESPACE}/
else
IMAGE_PREFIX=
endif

VERSION := $(shell cat ../../VERSION)
IMAGE_TAG?=v${VERSION}
# Image URL to use all building/pushing image targets
ARGOCD_IMAGE_UPDATER_IMAGE ?= ${IMAGE_PREFIX}${IMAGE_NAME}:${IMAGE_TAG}

# Define the patch template
define PATCH_TEMPLATE
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
env:
- name: ARGOCD_IMAGE_UPDATER_IMAGE
value: $(ARGOCD_IMAGE_UPDATER_IMAGE)
endef
export PATCH_TEMPLATE

# Tools - assuming they are in the path or in the project's bin directory
KUSTOMIZE ?= $(CURDIR)/../../bin/kustomize
KUBECTL ?= kubectl
K3D ?= k3d

K3D_CLUSTER_NAME ?= test-e2e-local

ifndef ignore-not-found
ignore-not-found = false
endif

.PHONY: deploy-argocd-operator kustomize test-e2e-local k3d-cluster-create k3d-cluster-delete k3d-image-import
kustomize:
$(MAKE) -C ../../ kustomize

deploy-argocd-operator: kustomize ## Deploy argocd-operator from a stable git reference.
@echo "Deploying Argo CD Operator..."
@set -e; \
TMP_DIR=$$(mktemp -d); \
cp prereqs/kustomization.yaml $$TMP_DIR/kustomization.yaml; \
echo "Applying argocd-operator manifests with image $(ARGOCD_OPERATOR_IMAGE)..."; \
echo "Setting argocd-image-updater image to $(ARGOCD_IMAGE_UPDATER_IMAGE)..."; \
echo "$$PATCH_TEMPLATE" > $$TMP_DIR/patch.yaml; \
cd $$TMP_DIR && \
$(KUSTOMIZE) edit set image quay.io/argoprojlabs/argocd-operator=$(ARGOCD_OPERATOR_IMAGE) && \
$(KUSTOMIZE) edit add patch --path patch.yaml; \
$(KUSTOMIZE) build $$TMP_DIR | $(KUBECTL) apply --server-side=true -f -; \
rm -rf $$TMP_DIR; \
echo "Argo CD Operator deployment initiated.";

undeploy-argocd-operator: kustomize ## Deploy argocd-operator from a stable git reference.
@echo "Undeploying Argo CD Operator..."
@set -e; \
TMP_DIR=$$(mktemp -d); \
cp prereqs/kustomization.yaml $$TMP_DIR/kustomization.yaml; \
$(KUSTOMIZE) build $$TMP_DIR | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -; \
rm -rf $$TMP_DIR; \
echo "Argo CD Operator undeployment initiated.";

k3d-cluster-create: ## Create k3d cluster for e2e tests
@echo "--- Creating k3d cluster $(K3D_CLUSTER_NAME) ---"
$(K3D) cluster create $(K3D_CLUSTER_NAME)

k3d-cluster-delete: ## Delete k3d cluster for e2e tests
@echo "--- Deleting k3d cluster $(K3D_CLUSTER_NAME) ---"
$(K3D) cluster delete $(K3D_CLUSTER_NAME)

k3d-image-import: ## Import local image to k3d cluster
@echo "--- Importing image $(ARGOCD_IMAGE_UPDATER_IMAGE) to k3d cluster $(K3D_CLUSTER_NAME) ---"
$(K3D) image import $(ARGOCD_IMAGE_UPDATER_IMAGE) -c $(K3D_CLUSTER_NAME)

# Currently run only parallel tests because we don't have sequential tests yet.
test-e2e-local: ## Build local image updater, deploy operator, and run parallel e2e tests.
@echo "--- Creating k3d cluster---"
$(MAKE) k3d-cluster-create
@echo "--- Building local argocd-image-updater image ---"
$(MAKE) -C ../../ docker-build
@echo "--- Importing image to k3d cluster ---"
$(MAKE) k3d-image-import
@echo "--- Deploying argocd-operator with local image-updater ---"
$(MAKE) deploy-argocd-operator
@echo "--- Running Parallel E2E tests ---"
$(MAKE) -C ../../ e2e-tests-parallel-ginkgo
@echo "--- Deleting k3d cluster ---"
$(MAKE) k3d-cluster-delete

test-e2e-ci: ## Build local image updater, deploy operator.
@echo "--- Building local argocd-image-updater image ---"
$(MAKE) -C ../../ docker-build
@echo "--- Importing image to k3d cluster ---"
$(MAKE) k3d-image-import
@echo "--- Deploying argocd-operator with local image-updater ---"
$(MAKE) deploy-argocd-operator
Loading