Skip to content
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

feat: Initial E2E framework and simple tests #211

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
123 changes: 122 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@ permissions:
contents: read

jobs:
changes:
runs-on: ubuntu-latest
outputs:
code: ${{ steps.filter.outputs.code_any_changed }}
docs: ${{ steps.filter.outputs.docs_any_changed }}
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: tj-actions/changed-files@c3a1bb2c992d77180ae65be6ae6c166cf40f857c # v45.0.3
id: filter
with:
files_yaml: |
code:
- '!**.md'
- '!**/*.md'
- '!docs/**'
- '!Dockerfile.*'
- '!hack/**'
docs:
- 'docs/**'

check-go:
name: Check go modules synchronicity
runs-on: ubuntu-22.04
Expand Down Expand Up @@ -58,7 +78,10 @@ jobs:
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
checks: write
name: Lint Go code
if: ${{ needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-22.04
needs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
Expand All @@ -75,7 +98,10 @@ jobs:

build-go:
name: Build & cache Go code
if: ${{ needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-22.04
needs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
Expand All @@ -91,7 +117,10 @@ jobs:

test:
name: Run unit tests
if: ${{ needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-22.04
needs:
- changes
steps:
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
Expand All @@ -110,4 +139,96 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
file: test/out/coverage.out


test-e2e:
name: Run end-to-end tests
if: ${{ needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-22.04
needs:
- changes
env:
GOPATH: /home/runner/go
steps:
- name: Install required packages
run: |
sudo apt-get install libpwquality-tools
- name: Checkout code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Setup Golang
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with:
go-version: ${{ env.GOLANG_VERSION }}
- name: GH actions workaround - Kill XSP4 process
run: |
sudo pkill mono || true
- name: Install microk8s
run: |
set -x
sudo snap install --classic microk8s
sudo microk8s enable metallb:192.168.56.100-192.168.56.254
sudo microk8s enable hostpath-storage
mkdir -p $HOME/.kube
sudo microk8s config > $HOME/.kube/config
sudo chown runner $HOME/.kube/config
sudo chmod go-r $HOME/.kube/config
kubectl version
- name: Restore go build cache
uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0
with:
path: ~/.cache/go-build
key: ${{ runner.os }}-go-build-v1-${{ github.run_id }}
- name: Add ~/go/bin to PATH
run: |
echo "/home/runner/go/bin" >> $GITHUB_PATH
- name: Add /usr/local/bin to PATH
run: |
echo "/usr/local/bin" >> $GITHUB_PATH
- name: Install vcluster
run: |
curl -L -o vcluster "https://github.com/loft-sh/vcluster/releases/latest/download/vcluster-linux-amd64" && sudo install -c -m 0755 vcluster /usr/local/bin && rm -f vcluster
vcluster --version
- name: Download Go dependencies
run: |
go mod download
go install github.com/mattn/goreman@latest
- name: Set up the test environment
run: |
make setup-e2e2
- name: Run the principal and agents
run: |
make start-e2e2 2>&1 | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g" > /tmp/e2e-argocd-agent.log &
sleep 10
- name: Run the e2e tests
run: |
set -o pipefail
make test-e2e2 2>&1 | tee /tmp/test-e2e.log
goreman run stop-all || echo "goreman trouble"
sleep 30
- name: Create Argo CD logs
run: |
kubectl --context vcluster-agent-autonomous logs -n argocd argocd-application-controller-0 > /tmp/vcluster-agent-autonomous-controller.log
kubectl --context vcluster-agent-managed logs -n argocd argocd-application-controller-0 > /tmp/vcluster-agent-managed-controller.log
if: ${{ failure() }}
- name: Upload e2e-argocd-agent logs
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: e2e-argocd-agent.log
path: /tmp/e2e-argocd-agent.log
if: ${{ failure() }}
- name: Upload test logs
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: test-e2e.log
path: /tmp/test-e2e.log
if: ${{ failure() }}
- name: Upload vcluster-agent-autonomous-controller logs
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: vcluster-agent-autonomous-controller.log
path: /tmp/vcluster-agent-autonomous-controller.log
if: ${{ failure() }}
- name: Upload vcluster-agent-managed-controller logs
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: vcluster-agent-managed-controller.log
path: /tmp/vcluster-agent-managed-controller.log
if: ${{ failure() }}
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ MOCKERY_V2_VERSION?=v2.43.0
.PHONY: build
build: agent principal

.PHONY: setup-e2e2
setup-e2e2:
test/e2e2/test-env/setup-vcluster-env.sh create

.PHONY: start-argocd-agent
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re: the Makefile target of start-argocd-agent. Rather than start-argocd-agent, which might imply this would start Argo agent for development purposes (similar to make start from Argo CD), WDYT about:

  • start-argocd-agent-for-e2e (maybe too long?)
  • start-e2e / start-e2e2 (shorter, this is what we use in argo cd, and in rollouts operator)
  • Other options?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Changed it to start-e2e2

start-e2e2:
test/e2e2/test-env/gen-creds.sh
goreman -f test/e2e2/test-env/Procfile start

.PHONY: test-e2e2
test-e2e2:
go test -count=1 -v -race -timeout 30m github.com/argoproj-labs/argocd-agent/test/e2e2

.PHONY: test
test:
mkdir -p test/out
Expand Down
69 changes: 69 additions & 0 deletions test/e2e2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Running the end-to-end tests locally

## Setup

The e2e test scripts require [vcluster](https://github.com/loft-sh/vcluster) to be installed on your system. They also require an administrative connection to a host cluster.

**Warning** Don't run these scripts against a cluster that you care about, there is no guarantee they won't break the cluster in some way.

The scripts use `vcluster` to create three virtual clusters on the host cluster:

* vcluster-control-plane - For hosting the control plane and principal
* vcluster-agent-managed - A cluster with agent in managed mode
* vcluster-agent-autonomous - A cluster with agent in autonomous mode

The scripts will install Argo CD to each of those vclusters, in varying degrees of completeness.

Both the vcluster and Argo CD installations require that LoadBalancer functionality is available on the host cluster.

## Running the tests

To setup the test environment on the cluster, execute the following command from the repository root:

```shell
make setup-e2e2
```

To run the principal and agents, execute the following command from the repository root:

```shell
make start-e2e2
```

To run the tests, execute the following command from the repository root in a separate terminal instance:

```shell
make test-e2e2
```

# Writing new end-to-end tests

There is some helper code in the `fixture` subdirectory. The tests use the [stretchr/testify](https://github.com/stretchr/testify) test framework. New tests should be created as part of a test suite, either an existing one or, preferably, as part of a new one.

A new test suite should embed the `fixture.BaseSuite` struct, which will provide some automatic setup and teardown functionality for the suite.

```go
type MyTestSuite struct {
fixture.BaseSuite
}
```

This will configure your suite with a `context.Context` as well as three `kubernetes clients`, one for the principal vcluster, one for the managed-agent vcluster, and one for the autonomous-agent vcluster. This is implemented in the `SetupSuite()` method which has been defined on the BaseSuite. If your suite does not need it's own `SetupSuite()` method, the one from BaseSuite will be used automatically. If you do need to specify a `SetupSuite()` method for your own suite, be sure to call the BaseSuite's method as the first thing.

```go
func (suite *MyTestSuite) SetupSuite() {
suite.BaseSuite.SetupSuite()
...
}
```

The BaseSuite also defines the `SetupTest()` and `TearDownTest()` methods to perform cleanup. If your suite does not need it's own version of these methods, the ones from BaseSuite will be used automatically. If you do need to specify one of these methods for your own suite, be sure to call the BaseSuite's method as the first thing.

```go
func (suite *MyTestSuite) TearDownTest() {
suite.BaseSuite.TearDownTest()
...
}
```

The kubernetes client is a wrapper around `client-go/dynamic`. It is able to access the ArgoCD types as well as the types from `k8s.io/api/core/v1`, `k8s.io/api/apps/v1`, and `k8s.io/api/rbac/v1`. If you need support for additional types, you can add then to the scheme used in the `NewKubeClient` function in `fixture/kubeclient.go`
Loading
Loading