Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ae42980
test(e2e): restore Kind+Karmada harness scaffolding
scotwells Jul 9, 2026
da45c94
test(e2e): deploy compute operators in-cluster via real overlays
scotwells Jul 9, 2026
76cffb5
test(e2e): scale a zeroed Karmada control plane back up on re-run
scotwells Jul 9, 2026
af7a86e
test(e2e): restore federation and referenced-data chainsaw suites
scotwells Jul 9, 2026
e6ed781
test(e2e): adapt restored suites to the in-cluster deploy path
scotwells Jul 9, 2026
f026d95
test(e2e): add second-cell federation coverage for pop-ord
scotwells Jul 9, 2026
1566fe3
test(e2e): skip client-side validation on cluster applies
scotwells Jul 10, 2026
a0d6cee
test(e2e): tune clusters for busy hosts at creation time
scotwells Jul 10, 2026
03f0b23
fix(rbac): grant the manager list/watch on networks
scotwells Jul 10, 2026
2612db1
test(e2e): fix management deploy layer (webhook cert volume + metrics…
scotwells Jul 10, 2026
fe906df
test(e2e): keep Karmada API server alive + widen chainsaw timeouts un…
scotwells Jul 10, 2026
cea88f3
ci(e2e): run in-cluster federation e2e on GitHub Actions
scotwells Jul 9, 2026
f336f38
test(e2e): run chainsaw suites serially
scotwells Jul 10, 2026
4d072ff
test(e2e): assert all three city PropagationPolicy selectors
scotwells Jul 10, 2026
034c25d
test(e2e): seed hand-crafted projection/write-back fixtures with requ…
scotwells Jul 10, 2026
5c32bde
test(e2e): assert referenced-data companions by their un-prefixed name
scotwells Jul 10, 2026
b2b3ebf
test(e2e): retry Karmada NodePort applies while the apiserver settles
scotwells Jul 10, 2026
8f7cf8a
test(e2e): drop the delete-cascade stranded-companion scenario pendin…
scotwells Jul 10, 2026
fdba7eb
test(e2e): raise two per-step timeouts for the full CI chain
scotwells Jul 10, 2026
413cf8a
test(e2e): widen three downstream-assert timeouts for CI latency
scotwells Jul 10, 2026
b6b7ac7
fix(rbac): grant the manager watch on namespaces
scotwells Jul 10, 2026
925302b
test(e2e): assert Ready=False for the blocked cell Instance
scotwells Jul 10, 2026
3268114
test(e2e): give cell operators a Karmada hub credential
scotwells Jul 10, 2026
6b07728
test(e2e): stand up e2e on the shared test-infra federation foundation
scotwells Jul 10, 2026
3c56bfa
test(e2e): repoint suite kubeconfig paths at the federation foundation
scotwells Jul 10, 2026
7ac5588
test(e2e): point the chainsaw config and docs at the federation kubec…
scotwells Jul 10, 2026
e694a75
ci(e2e): run e2e against the test-infra federation foundation
scotwells Jul 10, 2026
ebd3e30
fix(e2e): rename the tool-bin var to avoid a foundation var collision
scotwells Jul 10, 2026
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
136 changes: 124 additions & 12 deletions .github/workflows/test-e2e.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
name: E2E Tests

# In-cluster federation e2e (issue #149).
#
# Stands up the full topology on the shared test-infra federation foundation —
# three Kind clusters (one management/control-plane hosting Karmada, two POP
# cells) with the real production kustomize overlays and hub RBAC — then runs the
# Chainsaw suites against it. This exercises the operators as deployed pods
# authenticating to Karmada as a non-admin identity, not as an in-process test
# binary.

on:
push:
branches: [main]
pull_request:

# The e2e Taskfile pulls the test-infra foundation in as a remote Taskfile
# include; opt into Task's remote-taskfile support for every step that runs a
# task (paired with `task --yes` for the non-interactive trust prompt).
env:
TASK_X_REMOTE_TASKFILES: "1"

# Cancel a superseded run on the same ref. The e2e job is expensive (three Kind
# clusters + a Karmada control plane), so we don't want stale pushes burning a
# runner. Unlike the cheaper test/lint workflows this only triggers on PRs and
# main pushes rather than every branch push, for the same cost reason.
concurrency:
group: e2e-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
test-e2e:
name: Run on Ubuntu
# ubuntu-latest is 4 vCPU / 16 GB. The harness is deliberately engineered for
# a constrained/busy host — single-replica Karmada, leader election disabled,
# generous 10m component waits, join retries — so this fits without a larger
# (paid) runner. If real runs show OOM or repeated timeouts, switch to a
# larger hosted runner label (e.g. ubuntu-latest-8-cores); that carries a
# billing implication, hence starting on the free tier.
runs-on: ubuntu-latest
# Env standup can spend up to ~20m if both Karmada waits approach their 10m
# ceilings on a slow runner; deploy ~5m; the Chainsaw suites ~15m (the
# referenced-data GC-sweep suite alone floors around 6m). 50m leaves headroom
# over the ~35m expected without letting a genuinely hung run idle too long.
timeout-minutes: 50
steps:
- name: Clone the code
uses: actions/checkout@v4
Expand All @@ -17,19 +55,93 @@ jobs:
with:
go-version: '~1.25.0'

- name: Install the latest version of kind
run: |
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# go-task drives the entire harness (task e2e:env:up / e2e:deploy /
# e2e:test). The action publishes major refs as branches (v1/v2/v3); the
# version input pins the go-task binary itself. repo-token avoids GitHub
# API rate limiting when the action resolves the release.
- name: Install go-task
uses: arduino/setup-task@v3
with:
version: 3.52.0
repo-token: ${{ secrets.GITHUB_TOKEN }}

# kind, kubectl, helm, and karmadactl are installed by the test-infra
# federation foundation's own ensure-tools; chainsaw is fetched into ./bin
# by the compute task tooling. No harness-side python/PyYAML is used any
# more (the foundation rewrites kubeconfigs with kubectl; the remaining
# python3 calls parse `go list` JSON with the stdlib only).

- name: Verify kind installation
run: kind version
# Split into env / deploy / test so a failure lands on the phase that broke
# rather than a single opaque "task e2e:up" step. e2e:env:up == e2e:up minus
# the deploy; the two together are exactly what e2e:up runs. `--yes` accepts
# Task's one-time trust prompt for the remote test-infra include.
- name: Provision Kind + Karmada environment
run: task --yes e2e:env:up

- name: Create kind cluster
run: kind create cluster
- name: Build image and deploy operators
run: task --yes e2e:deploy

- name: Running Test e2e
- name: Run Chainsaw e2e suites
run: task --yes e2e:test

# Always capture what the clusters looked like when a step failed. The
# runner is ephemeral so teardown is unnecessary; diagnostics are the only
# thing worth keeping.
- name: Collect diagnostics
if: failure()
run: |
go mod tidy
make test-e2e
set +e
DIAG=tmp/e2e/diagnostics
KDIR=.test-infra/kubeconfigs/federation
mkdir -p "$DIAG"

# Host / kind level: container state plus a full per-cluster export
# (kubelet, containerd, and every pod log).
kind get clusters > "$DIAG/kind-clusters.txt" 2>&1
docker ps -a > "$DIAG/docker-ps.txt" 2>&1
for c in compute-control-plane compute-pop-dfw compute-pop-ord; do
kind export logs "$DIAG/kind-$c" --name "$c" 2>&1 | tail -n 2
done

# Per-cluster Kubernetes state + the compute-manager operator logs
# (current and previous, all containers) from every plane.
for kc in compute-control-plane compute-pop-dfw compute-pop-ord karmada; do
cfg="$KDIR/$kc.yaml"
[ -f "$cfg" ] || continue
out="$DIAG/$kc"; mkdir -p "$out"
kubectl --kubeconfig="$cfg" get pods -A -o wide > "$out/pods.txt" 2>&1
kubectl --kubeconfig="$cfg" get events -A --sort-by=.lastTimestamp > "$out/events.txt" 2>&1
kubectl --kubeconfig="$cfg" -n compute-system describe deploy compute-manager \
> "$out/compute-manager-describe.txt" 2>&1
kubectl --kubeconfig="$cfg" -n compute-system logs deploy/compute-manager \
--all-containers --tail=-1 > "$out/compute-manager.log" 2>&1
kubectl --kubeconfig="$cfg" -n compute-system logs deploy/compute-manager \
--all-containers --previous --tail=-1 > "$out/compute-manager-previous.log" 2>&1
done

# Karmada control-plane pods + component logs (they live in the
# management cluster) and the federation view from the Karmada API.
if [ -f "$KDIR/compute-control-plane.yaml" ]; then
kubectl --kubeconfig="$KDIR/compute-control-plane.yaml" -n karmada-system get pods -o wide \
> "$DIAG/karmada-pods.txt" 2>&1
for d in karmada-apiserver karmada-controller-manager karmada-scheduler; do
kubectl --kubeconfig="$KDIR/compute-control-plane.yaml" -n karmada-system logs deploy/$d \
--tail=-1 > "$DIAG/karmada-$d.log" 2>&1
done
fi
if [ -f "$KDIR/karmada.yaml" ]; then
kubectl --kubeconfig="$KDIR/karmada.yaml" get clusters -o wide \
> "$DIAG/karmada-clusters.txt" 2>&1
kubectl --kubeconfig="$KDIR/karmada.yaml" get workloaddeployments -A -o wide \
> "$DIAG/karmada-workloaddeployments.txt" 2>&1
fi
echo "Diagnostics collected under $DIAG"

- name: Upload diagnostics
if: failure()
uses: actions/upload-artifact@v4
with:
name: e2e-diagnostics
path: tmp/e2e/diagnostics
retention-days: 7
if-no-files-found: warn
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@ bin/

# Local e2e environment artefacts (Kind kubeconfigs, etc.)
tmp/

# test-infra federation foundation: its self-clone and the kubeconfigs it writes
.test-infra/

# Task's remote-taskfile cache (populated with TASK_X_REMOTE_TASKFILES=1)
.task/
Loading
Loading