Run E2E Test
kubernetes-sigs/cloud-provider-azure
Parse a Go e2e test from tests/e2e/, translate each step to kubectl and az CLI commands, and interactively replay the test against a live cluster.
How Kopiur does strongly-typed, actionable error handling and end-to-end testing.
$ npx skills add home-operations/kopiur --skill error-handling-and-e2e -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install home-operations/kopiur error-handling-and-e2e --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/home-operations/kopiur.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/error-handling-and-e2e .claude/skills/error-handling-and-e2e && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "error-handling-and-e2e" agent skill from https://github.com/home-operations/kopiur/tree/main/.claude/skills/error-handling-and-e2e into .claude/skills/error-handling-and-e2e/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling-and-e2e", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/home-operations/kopiur/tree/main/.claude/skills/error-handling-and-e2eType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add home-operations/kopiur --skill error-handling-and-e2e -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install home-operations/kopiur error-handling-and-e2e --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/home-operations/kopiur.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/error-handling-and-e2e .agents/skills/error-handling-and-e2e && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "error-handling-and-e2e" agent skill from https://github.com/home-operations/kopiur/tree/main/.claude/skills/error-handling-and-e2e into .agents/skills/error-handling-and-e2e/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling-and-e2e", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add home-operations/kopiur --skill error-handling-and-e2e -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install home-operations/kopiur error-handling-and-e2e --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/home-operations/kopiur.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/error-handling-and-e2e .cursor/skills/error-handling-and-e2e && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "error-handling-and-e2e" agent skill from https://github.com/home-operations/kopiur/tree/main/.claude/skills/error-handling-and-e2e into .cursor/skills/error-handling-and-e2e/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling-and-e2e", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/home-operations/kopiur.git --path .claude/skills/error-handling-and-e2e--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add home-operations/kopiur --skill error-handling-and-e2e -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install home-operations/kopiur error-handling-and-e2e --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/home-operations/kopiur.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/error-handling-and-e2e .gemini/skills/error-handling-and-e2e && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "error-handling-and-e2e" agent skill from https://github.com/home-operations/kopiur/tree/main/.claude/skills/error-handling-and-e2e into .gemini/skills/error-handling-and-e2e/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling-and-e2e", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install home-operations/kopiur error-handling-and-e2eInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add home-operations/kopiur --skill error-handling-and-e2e -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/home-operations/kopiur.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/error-handling-and-e2e .github/skills/error-handling-and-e2e && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "error-handling-and-e2e" agent skill from https://github.com/home-operations/kopiur/tree/main/.claude/skills/error-handling-and-e2e into .github/skills/error-handling-and-e2e/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling-and-e2e", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add home-operations/kopiur --skill error-handling-and-e2e -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install home-operations/kopiur error-handling-and-e2e --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/home-operations/kopiur.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/error-handling-and-e2e .opencode/skills/error-handling-and-e2e && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "error-handling-and-e2e" agent skill from https://github.com/home-operations/kopiur/tree/main/.claude/skills/error-handling-and-e2e into .opencode/skills/error-handling-and-e2e/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "error-handling-and-e2e", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
error-handling-and-e2eHow Kopiur does strongly-typed, actionable error handling and end-to-end testing.
Error Handling And E2E is an agent skill from home-operations/kopiur. How Kopiur does strongly-typed, actionable error handling and end-to-end testing. Use when adding or changing any error type, error path, or fallible operation (kopia calls, kube IO, OTLP/telemetry init, validators, the mover), or when writing/extending tests — especially e2e scenarios in crates/e2e. Encodes the thiserror exhaustive-enum + classification pattern, the what/why/fix message rule, degrade-not-crash for non-critical subsystems, and the crates/e2e harness conventions (feature = "e2e", mise…
Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Testing & QA, covering End-to-end testing. It works with OpenTelemetry and Kubernetes. The repository describes itself as: A Kopia-native Kubernetes backup operator written in Rust. The licence is AGPL-3.0.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 379efb7. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
kubectlmisehelmcargoFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use kubectl and helm, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Error Handling And E2E loads about 2.7k tokens when it runs. Until then it costs about 164 tokens; SKILL.md has 1,305 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from home-operations/kopiur at commit 379efb7, republished under its AGPL-3.0 licence (© home-operations). 1,305 words, ~2,725 tokens.
.claude/skills/error-handling-and-e2e/SKILL.md (or your agent's skills folder).Two linked disciplines. Strong typed errors make invalid states unrepresentable and tell the operator exactly how to recover; e2e tests prove the whole pipeline reaches the user-visible success condition. Both exist because this is data-protection software — a silently-swallowed error or an untested path can lose backups.
Read alongside [[kopiur-design]] (the type-safety thesis) and CLAUDE.md.
crates/controller/src/error.rs)thiserror enum per crate/domain, #[derive(Debug, thiserror::Error)].
One variant per distinct failure mode. Use #[from] to wrap upstream errors
(kube::Error, KopiaError, serde_json::Error) so ? just works.match and no _ => arm — a new variant must fail to compile
until it is classified. See Error::class() -> ErrorClass
(Transient/Structural → backoff). A _ arm here is a latent data-loss bug.pub type Result<T, E = Error> alias per crate; reconcile/fallible fns
return it.error.rs tests) and — for any message a human
acts on — assert on to_string() so the actionable text can't silently rot.Every #[error("…")] an operator might read states what failed, the likely
why, and the concrete fix (expected value, env var, command). This is the
type-safety thesis extended to UX: homelabbers run this; a cryptic error wastes
time and can mask a data-protection gap.
#[error(
"OTEL_EXPORTER_OTLP_ENDPOINT='{value}' is not a valid URL. Use scheme+host+port, \
e.g. http://otel-collector:4317 (OTLP/gRPC) or :4318 (OTLP/HTTP); unset it to disable OTLP"
)]
InvalidOtlpEndpoint { value: String, #[source] source: url::ParseError },Prefer {named} fields over positional {0} when the message interpolates user
input — it reads better and survives reordering. Keep the underlying cause via
#[source]/#[from] so the chain is inspectable; don't bury it inside a string.
Reconciliation and data movement are critical; observability, OTLP export, and similar side-channels are not. A misconfigured non-critical subsystem must log the actionable error and continue, never abort the operator:
init_telemetry() returns Result; on error the binary logs it at error
and falls back (fmt-only logs + the always-on Prometheus pull). An optional
KOPIUR_OTEL_STRICT=true makes it fail-fast for those who want it.Structural (long requeue,
surfaced on .status + an Event), a kopia/API outage is Transient (short
requeue). Both go through error_policy_for, which records
controller_reconcile_errors_total{kind,class} and requeues by class.Reconcile errors should reach the user, not just the log: set a Condition /
phase on .status and emit a kube Event via the Recorder (Context already
carries one). The metric + log + status + Event together make a failure visible
in kubectl get, dashboards, and alerts.
crates/e2e)Both bug fixes and new features ship with e2e coverage ([[kopiur-design]] —
"Every change ships with tests"). Per [[regression-test-every-bugfix]], a fix
ships with a test at the cheapest tier that exercises the broken path; a new
feature additionally gets a full-pipeline e2e scenario whenever it has any
runtime-observable behavior. Reach for e2e (not just a unit test) when the
behavior only appears against a live operator: a reconcile that must reach its
terminal phase, a runtime dependency, an RBAC/SA gap, an option that survives
serialization but acts at runtime, a new backend/volume source the mover must
actually mount, or metrics that must be emitted and scrapable.
No e2e is too large to include — this tool is data-protection software and must
be thoroughly tested. If a feature needs new cluster infrastructure to exercise
(an NFS server, an SFTP server, a fresh namespace, a second backend), provision
it in the World rather than skipping the test:
Need variant + an ensure_* method (idempotent Fixture apply), plus a
builders::* Deployment/Service for any in-cluster server. Mirror the existing
servers (ensure_sftp/ensure_webdav/ensure_nfs).:latest) and verify it actually serves the
mover on a real kind cluster before trusting a green run — a server the client
can't talk to fails slowly and confusingly, not fast (see
[[sftp-openssh10-go-ssh-hang]]). Note in the test/PR if it's pinned-but-not-
yet-cluster-verified.The only features that legitimately skip e2e are those with no runtime-observable behavior (a pure type change/refactor) — and then say so explicitly.
crates/e2e/tests/lifecycle.rs)#![cfg(all(unix, feature = "e2e"))] at the top of the test file,
and #[ignore = "requires the e2e harness (mise run //crates/e2e:test)"] on
each #[tokio::test]. So the suite compiles everywhere and is skipped without a
cluster; it only runs under the harness.mise run //crates/e2e:test. The host-level steps are mise tasks
in crates/e2e/mise.toml (a monorepo subproject): build + load the images into
kind, seed the node's hostPath dirs, and helm upgrade --install with
deploy/e2e/values.yaml (webhook disabled — covered by unit/integration tiers).let Some(world) = World::connect().await else { return; }; then
world.ensure(&[Need::Filesystem /* | Need::Minio | Need::WorkloadNs */]).await?.
World (crates/e2e/src/world.rs) provisions namespaces/Secrets/PV-PVCs/MinIO/
buckets idempotently via the type-safe Fixture apply dispatch — never via
kubectl in a shell. Add a new fixture kind by extending the Need/Fixture
enums (exhaustive match).scripts/with-kind.sh (integration tier) and
the //crates/e2e:* tasks pin an isolated kubeconfig under target/e2e/ and
tear the cluster down; they never touch the homelab kubecontext. Do not add a
test that reads the ambient KUBECONFIG.kopiur_e2e (crates/e2e/src/lib.rs): E2E_NAMESPACE,
try_client() (returns None when no cluster → skip gracefully),
wait_until(...), default_timeout(), poll_interval(). Reuse them; don't
re-roll polling.Assert the user-visible success condition, not an intermediate detail:
Repository reaching Ready; a Snapshot reaching Succeeded with a real
kopiaSnapshotID; a Restore Completed; a schedule actually creating a
Snapshot; a finalizer deleting the snapshot; a Maintenance lease claimed.wait_phase(&api, name, "Succeeded") pattern (poll status to a target
phase with a timeout). A regression test must be written so it times out /
fails on the buggy code and passes on the fix — see
cluster_repository_backup_lifecycle (added for the "ClusterRepository refs
ignored" bug: it would hang at wait_phase(... "Succeeded") before the fix).When the assertion is "a metric is emitted," drive the real lifecycle, then
scrape /metrics and parse the exposition rather than trusting a code path:
:8081/metrics (and webhook /metrics); assert the
expected families/labels are present with sane values
(kopiur_controller_reconciliations_total{kind=…} > 0,
kopiur_resource_phase{kind=Snapshot,phase=Succeeded} == 1, backup
size/files/duration > 0, error/consecutive-failure counters reflect an
induced failure). kopiur_resource_phase and the per-CR/per-policy Snapshot
gauges are store-backed observable gauges: only the CR's active phase is
ever emitted (never a phase=…}=0 line for the inactive phases), and a
series disappears from the next scrape once its CR is deleted — so a
regression test for a lifecycle fix should also assert absence after
deletion, not just presence while the CR is live._total suffixes, otel_scope_*,
target_info)./healthz + /readyz return 200 (real endpoints, not the old
any-path listener).match (no _ =>).#[source] preserved.World infra needed). No e2e skipped for being "too large"; only skipped
when the feature has no runtime-observable behavior — stated explicitly.feature = "e2e" + #[ignore], uses kopiur_e2e helpers,
asserts the user-visible success condition, never a real cluster.cargo test --workspace + clippy -D warnings + fmt --check green;
record the bug + guard in the operator-bugs-fixed-by-e2e memory.© home-operations, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/error-handling-and-e2e of home-operations/kopiur.
Open the folder on GitHubat commit 379efb7
Error Handling And E2E next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Error Handling And E2E this skillhome-operations/kopiur | 113 | — | ~2.7k | Automated safety check: Pass | AGPL-3.0 | |
| Run E2E Testkubernetes-sigs/cloud-provider-azure | 294 | — | ~3.8k | Automated safety check: Pass | Apache-2.0 | |
| Must Gather Investigationscylladb/scylla-operator | 401 | — | ~2.4k | Automated safety check: Pass | Apache-2.0 | |
| Test Pyramidkubernetes-sigs/agent-sandbox | 4.2k | — | ~1.6k | Automated safety check: Pass | Apache-2.0 | |
| E2E Testgrafana/agento11y | 127 | — | ~1.7k | Automated safety check: Notes | Apache-2.0 | |
| Kaniop Developmentpando85/kaniop | 130 | — | ~3.1k | Automated safety check: Pass | AGPL-3.0 |
kubernetes-sigs/cloud-provider-azure
Parse a Go e2e test from tests/e2e/, translate each step to kubectl and az CLI commands, and interactively replay the test against a live cluster.
scylladb/scylla-operator
Investigate failed e2e tests from Ginkgo JSON reports and must-gather artifacts, systematically analyzing logs, events, and resource states to identify root causes.
kubernetes-sigs/agent-sandbox
Analyze the repo's unit and E2E tests and propose rebalancing toward a test pyramid — which E2E tests (or assertions inside them) can be covered by unit tests, which unit-level gaps genuinely need…
grafana/agento11y
Optional credential-free Hermes integration checks using an explicit loopback model provider and local telemetry receivers.
pando85/kaniop
Kaniop architecture, Rust controller conventions, commands, testing, and repository workflows.
kubernetes-sigs/cloud-provider-azure
Fetch and analyze Prow e2e pipeline failures for cloud-provider-azure.
home-operations/kopiur
How Kopiur writes and maintains user-facing docs — the MkDocs Material site under docs/ and the example manifests under deploy/examples/.
home-operations/kopiur
Design norms and locked decisions for the Kopiur Kopia-native Kubernetes backup operator (Rust/kube-rs).
Works with
Categories
How Kopiur does strongly-typed, actionable error handling and end-to-end testing. Error Handling And E2E is an agent skill from home-operations/kopiur. How Kopiur does strongly-typed, actionable error handling and end-to-end testing.
Error Handling And E2E fits situations like: changing any error type; fallible operation (kopia calls; OTLP/telemetry init; writing/extending tests — especially e2e scenarios in crates/e2e.
Run `npx skills add home-operations/kopiur --skill error-handling-and-e2e -a claude-code`. Or copy the skill folder (.claude/skills/error-handling-and-e2e in home-operations/kopiur) into .claude/skills/error-handling-and-e2e in your project. Claude Code loads it when a task matches its description.
Run `npx skills add home-operations/kopiur --skill error-handling-and-e2e -a codex`. Or copy the skill folder (.claude/skills/error-handling-and-e2e in home-operations/kopiur) into .agents/skills/error-handling-and-e2e in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add home-operations/kopiur --skill error-handling-and-e2e -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/error-handling-and-e2e, .gemini/skills/error-handling-and-e2e, .github/skills/error-handling-and-e2e and .opencode/skills/error-handling-and-e2e in your project.
Going by SKILL.md and its folder, Error Handling And E2E needs the command-line tools its instructions call (kubectl, mise, helm and cargo).
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Error Handling And E2E is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Error Handling And E2E: Run E2E Test (kubernetes-sigs/cloud-provider-azure, 294 stars), Must Gather Investigation (scylladb/scylla-operator, 401 stars), Test Pyramid (kubernetes-sigs/agent-sandbox, 4.2k stars) and E2E Test (grafana/agento11y, 127 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
home-operations (a GitHub organization) maintains it in home-operations/kopiur, which has 113 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 8, 2026.
Source: home-operations/kopiur on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.