Chainsaw E2E Tests
This guide documents every Chainsaw E2E test in this repository, what each one validates, why it exists, and how to run suites via label selectors.
How test selection works
This repo uses label selectors for just run-e2e and GitHub Actions workflows:
just run-e2eexecutes:chainsaw test e2e --selector <selector> ...- Selector input is controlled by
CHAINSAW_SELECTOR(default:all) - Additional Chainsaw options can be passed through
CHAINSAW_FLAGS
Key references:
run-e2ecommand:justfile- default selector and flags:
justfile - reusable workflow:
.github/workflows/e2e.yaml - PR trigger workflow selector (
pr):.github/workflows/e2e-pr-trigger.yaml - nightly trigger workflow selector (
all):.github/workflows/e2e-nightly-trigger.yaml - manual trigger workflow selector (input):
.github/workflows/e2e-manual-trigger.yaml
Selector matrix
| Selector | Command | Runs | Typical use |
|---|---|---|---|
all | CHAINSAW_SELECTOR=all just run-e2e | All Chainsaw suites | Full local run / nightly parity |
pr | CHAINSAW_SELECTOR=pr just run-e2e | PR smoke tests (currently only minimal-lke-standard) | Matches PR workflow selector |
category.baseline | CHAINSAW_SELECTOR=category.baseline just run-e2e | Baseline lifecycle behavior | Verify core provider health quickly |
category.scheduling | CHAINSAW_SELECTOR=category.scheduling just run-e2e | Scheduling behavior suites | Debug pod placement / constraints |
category.consolidation | CHAINSAW_SELECTOR=category.consolidation just run-e2e | Consolidation behavior suites | Debug scale-down/replacement behavior |
category.drift | CHAINSAW_SELECTOR=category.drift just run-e2e | Drift behavior suites | Debug node replacement from config drift |
Test inventory and justification
| Test | Path | Selector groups | What it validates | Why we need it |
|---|---|---|---|---|
| minimal-lke-standard | e2e/minimal-lke-standard/chainsaw-test.yaml | all, pr, category.baseline | Baseline scale-up/scale-down behavior with NodeClaim lifecycle and instance-type transitions under workload changes | Catches broad regressions in core provisioning/reconciliation path and verifies cluster can recover back to zero |
| scheduling-nodepool-label-selector | e2e/scheduling-nodepool-label-selector/chainsaw-test.yaml | all, category.scheduling | NodePool label targeting via pod nodeSelector, and confirms pods land on expected node/nodepool | Ensures constraint-based scheduling works and avoids silent misplacement of workloads |
| scheduling-taints-tolerations | e2e/scheduling-taints-tolerations/chainsaw-test.yaml | all, category.scheduling | Taint/toleration behavior with one tolerated and one non-tolerated workload | Prevents regressions where taints are ignored or non-tolerated pods are scheduled incorrectly |
| consolidation-empty-node-scale-down | e2e/consolidation-empty-node-scale-down/chainsaw-test.yaml | all, category.consolidation | NodeClaim count reduction on a dedicated consolidation NodePool after scale-down | Validates empty/underutilized consolidation behavior with deterministic pool constraints |
| consolidation-non-empty-step-scale | e2e/consolidation-non-empty-step-scale/chainsaw-test.yaml | all, category.consolidation | Non-empty replacement signal on a dedicated consolidation NodePool after stepped scale changes | Covers disruptive consolidation edge cases while avoiding default-pool sizing bias |
| drift-nodepool-labels-taints | e2e/drift-nodepool-labels-taints/chainsaw-test.yaml | all, category.drift | Drift-triggered replacement when a drift-specific NodePool template labels/taints change | Ensures NodePool template mutations propagate through replacement in an isolated test-owned pool |
Running tests
Run selector-based suites (recommended)
# Full suite
CHAINSAW_SELECTOR=all just run-e2e
# PR subset
CHAINSAW_SELECTOR=pr just run-e2e
# Category-focused debug
CHAINSAW_SELECTOR=category.drift just run-e2e
Run one specific test directory directly (debug convenience)
Use direct Chainsaw invocation when you want exactly one test file without introducing single-test labels:
chainsaw test e2e/minimal-lke-standard --config .chainsaw.yaml
Authoring and maintenance rules
When adding/updating an E2E test:
- Add labels for execution scope and category in
metadata.labels:- include
all - include
pronly when the test should run in the PR workflow (currently reserved forminimal-lke-standard) - include exactly one
category.*
- include
- Keep manifests close to ownership:
- put scenario-specific manifests next to that scenario’s
chainsaw-test.yaml - reserve
e2e/common/for manifests reused by multiple scenarios
- put scenario-specific manifests next to that scenario’s
- Treat the bootstrap cluster as having only the shared default
LinodeNodeClass; each Chainsaw scenario must create its own KarpenterNodePool. - Add the shared e2e isolation taint
e2e.linode.dev/test=true:NoScheduleto each test-ownedNodePool, and add the matching toleration to every workload that should run on that pool. - Keep test cleanup explicit to avoid cross-test leftovers.
- Update this document:
- add/update row in Selector matrix if a new selector is introduced
- add/update row in Test inventory and justification
- Ensure workflow selectors (
pr/all) still match intended scope.