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-e2e executes: 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-e2e command: 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 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, pr, 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-blockstorage-topology e2e/scheduling-blockstorage-topology/chainsaw-test.yaml all, pr, category.scheduling WaitForFirstConsumer claims with and without allowed topologies, scale-from-zero and replacement for matching bound PVCs, and rejection of incompatible PVC regions Verifies predicted CSI region labels match CSI registration and prevent provisioning into an incompatible volume region
scheduling-taints-tolerations e2e/scheduling-taints-tolerations/chainsaw-test.yaml all, pr, 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
scheduling-ephemeral-storage e2e/scheduling-ephemeral-storage/chainsaw-test.yaml all, pr, category.scheduling Confirms Pod and DaemonSet ephemeral-storage requests schedule, worker and NodeClaim report storage, and a request above usable storage remains unschedulable without another NodeClaim Guards predicted ephemeral-storage capacity, scheduling fit, and over-capacity rejection on Standard and Enterprise LKE
consolidation-empty-node-scale-down e2e/consolidation-empty-node-scale-down/chainsaw-test.yaml all, pr, 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, pr, 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, pr, 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

# 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

Cluster cleanup access

just destroy-lke-cluster <cluster_id> refreshes the cluster API ACL using CLUSTER_ACL_FLAGS (by default, the current runner’s public IPv4 address), then waits for Kubernetes API access before deleting test resources and the cluster. Cleanup jobs run on a separate runner from setup, so they cannot reuse setup’s IP allowlist.

Cleanup runner egress policies must allow ipv4.icanhazip.com:443 for IP discovery and the cluster API endpoint: *.linodelke.net:443 for standard LKE or *.enterprise.linodelke.net:6443 for LKE Enterprise.

Authoring and maintenance rules

When adding/updating an E2E test:

  1. Add labels for execution scope and category in metadata.labels:
    • include all
    • include pr only when the test should run in the PR workflow (currently reserved for minimal-lke-standard)
    • include exactly one category.*
  2. 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
  3. Treat the bootstrap cluster as having only the shared default LinodeNodeClass; each Chainsaw scenario must create its own Karpenter NodePool.
  4. Add the shared e2e isolation taint e2e.linode.dev/test=true:NoSchedule to each test-owned NodePool, and add the matching toleration to every workload that should run on that pool.
  5. Keep test cleanup explicit to avoid cross-test leftovers.
  6. Update this document:
    • add/update row in Selector matrix if a new selector is introduced
    • add/update row in Test inventory and justification
  7. Ensure workflow selectors (pr/all) still match intended scope.

This site uses Just the Docs, a documentation theme for Jekyll.