How this skill is triggered — by the user, by Claude, or both
Slash command
/rhoai-security-reviewer:bug-test-planThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate a comprehensive, ecosystem-aware test plan for a Jira bug in the RHOAI/ODH ecosystem. The test plan must specify the correct test layer, target repository, framework, and patterns for each component involved.
Generate a comprehensive, ecosystem-aware test plan for a Jira bug in the RHOAI/ODH ecosystem. The test plan must specify the correct test layer, target repository, framework, and patterns for each component involved.
Walk through this decision tree for each aspect of the bug fix:
1. Is the fix pure business logic with no Kubernetes/cluster dependency?
-> Write a UNIT TEST in the same package as the code changed.
2. Does the fix involve webhook validation, CEL rules, CRD conversion,
or controller reconciliation logic that can be verified against a
simulated API server?
-> Write an INTEGRATION TEST using envtest, in the same repo.
3. Does the fix involve behavior that can only be verified against a
real running cluster (operator deployment lifecycle, cross-component
interactions, real network behavior)?
-> Write an E2E TEST in the same repo's tests/e2e/ directory.
4. Does the fix involve UI behavior visible in the RHOAI dashboard?
-> Write a CYPRESS TEST in the odh-dashboard repo.
5. Does the fix involve product-level behavior that should be validated
at the QE layer (model serving, model registry, workbenches,
explainability, cluster health)?
-> Write a PYTEST TEST in the opendatahub-tests repo.
This is the PRIMARY cross-repo test repository. ods-ci (Robot
Framework) is deprecated — all new QE tests go in opendatahub-tests.
Bias toward unit and integration tests. They run in seconds, have zero infrastructure flake, and are the most valuable per line of code. Only propose an e2e test if the behavior genuinely cannot be verified at a lower level.
Test coverage follows a layered priority:
Level 1: Unit tests — ALWAYS required. Every fix gets a unit test.
Level 2: E2E tests — WHEN the fix affects cluster-level behavior.
Level 3: opendatahub-tests — WHEN the fix affects product-level QE validation.
Unit tests (always required):
*_test.go fileNewWithT(t)make unit-testfunc TestMyFix(t *testing.T) {
g := NewWithT(t)
result := functionUnderTest(input)
g.Expect(result).Should(Equal(expected))
}
Integration tests using envtest (webhook, CEL, controller reconciliation) also run as part of make unit-test:
internal/controller/components/*/, internal/webhook/*/suite_test.go — DO NOT create a new suiteE2E tests (when fix affects cluster behavior):
tests/e2e/make e2e-testUnit tests:
__tests__/ directoriespackage.json scriptsCypress e2e tests (UI behavior):
*.cy.tsMakefile and .github/workflows/ for test targetsMakefile for test targets (make test, make unit-test, etc.).github/workflows/ for CI test definitions*_test.go or test_*.py files and match their patternsCONTRIBUTING.md or CLAUDE.md that describes test expectationsThis is the primary cross-repo test repository for RHOAI/ODH. If the bug fix involves product-level behavior that should be validated against a real cluster, propose a test here.
opendatahub-io/opendatahub-testsuvuv run pytest -m <marker> tests/Test organization:
tests/
├── conftest.py # component-shared fixtures
├── cluster_health/ # node health, operator status
├── model_serving/ # largest suite (vLLM, Triton, MLServer, OpenVINO)
├── model_registry/ # REST API, catalog, RBAC
├── model_explainability/ # TrustyAI, guardrails, LM Eval
├── llama_stack/ # inference, vector IO, safety
├── workbenches/ # notebook controller
└── fixtures/ # reusable pytest plugin fixtures
Available markers: smoke, sanity, tier1, tier2, tier3, model_serving, model_registry, llama_stack, model_explainability, gpu, multinode, pre_upgrade, post_upgrade, parallel, cluster_health, operator_health
Key rules for opendatahub-tests:
openshift-python-wrapper for K8s interactions — never raw subprocess callsindirect=True for parametrized fixturesutilities/ firstconftest.py if one exists in the directoryTest pattern example (parametrized model deployment):
@pytest.mark.parametrize(
"model_namespace, serving_runtime, vllm_inference_service",
[
pytest.param(
{"name": "granite-starter-raw"},
{"deployment_type": KServeDeploymentType.RAW_DEPLOYMENT},
{"gpu_count": 1, "name": "granite-starter-raw"},
id="granite-starter-raw-single-gpu",
),
],
indirect=True,
)
class TestGraniteStarterModel:
@pytest.mark.smoke
def test_granite_starter_inference(
self,
vllm_inference_service: Generator[InferenceService, Any, Any],
vllm_pod_resource: Pod,
response_snapshot: Any,
) -> None:
"""Test inference with OpenAI protocol.
Given: A running vLLM inference service with Granite model.
When: A chat completion request is sent via OpenAI protocol.
Then: The response matches the expected snapshot.
"""
validate_raw_openai_inference_request(
pod_name=vllm_pod_resource.name,
isvc=vllm_inference_service,
response_snapshot=response_snapshot,
chat_query=CHAT_QUERY,
)
| Repo | Unit Tests | Integration Tests | E2E/QE Tests | Lint |
|---|---|---|---|---|
| opendatahub-operator | make unit-test | make unit-test | make e2e-test | make lint |
| opendatahub-tests | N/A | N/A | uv run pytest -m smoke | ruff check, mypy |
| odh-dashboard | Check package.json | N/A | Cypress | Check package.json |
| kubeflow | make test | GitHub Actions | ./run-e2e-test.sh | Check Makefile |
| Other Go repos | make test or go test ./... | Check Makefile | Check Makefile | make lint |
| Other Python repos | pytest or tox -e test | Check tox.ini | N/A | ruff check |
Your primary output is a JSON file conforming to this schema:
{
"issue_key": "RHOAIENG-XXXXX",
"decision_rationale": "The fix is a nil-guard in the reconciler (pure Go logic), so a unit test is the primary layer. An integration test with envtest is also warranted since it involves controller reconciliation. No e2e test needed — envtest can simulate the API server behavior.",
"target_test_repos": [
{
"repo": "opendatahub-io/opendatahub-operator",
"test_directory": "internal/controller/components/kserve/",
"framework": "go-test-gomega",
"run_command": "make unit-test"
}
],
"unit_tests": [
{
"description": "Test nil ConfigMap data handling",
"file": "pkg/controller/reconciler_test.go",
"setup": "Create mock client returning ConfigMap with nil Data",
"input": "ConfigMap{Data: nil}",
"expected": "Reconciler returns without error, no nil pointer panic",
"edge_cases": ["Empty Data map vs nil Data", "Missing ConfigMap entirely"]
}
],
"integration_tests": [
{
"description": "Verify controller handles missing ConfigMap gracefully",
"components": ["odh-model-controller", "kserve"],
"setup": "Deploy controller without creating the expected ConfigMap",
"steps": ["Deploy InferenceService", "Check controller logs", "Verify no crash loop"],
"expected": "Controller logs warning but continues reconciliation",
"api_verification": "GET /apis/serving.kserve.io/v1beta1/inferenceservices returns 200"
}
],
"regression_tests": [
{
"description": "Reproduce original nil pointer crash",
"steps": ["Deploy RHOAI 3.4 with default config", "Delete the kserve-config ConfigMap", "Trigger reconciliation"],
"before_fix": "Controller crashes with nil pointer dereference",
"after_fix": "Controller logs warning and creates default ConfigMap"
}
],
"manual_verification_steps": [
"Deploy RHOAI on OCP 4.16",
"Check pod status: oc get pods -n redhat-ods-applications",
"Verify no CrashLoopBackOff in controller pods"
],
"environment_requirements": {
"ocp_version": "4.16+",
"rhoai_version": "3.4",
"platform": "any",
"special_config": "none"
},
"effort_estimate": "moderate",
"qe_coverage_note": "This fix should be covered by a test in opendatahub-tests. Suggested: verify that InferenceService reconciliation succeeds when kserve-config ConfigMap is absent. Component: model_serving. Marker: tier1."
}
Field descriptions:
decision_rationale: string explaining why these test layers were chosen, walking through the decision treetarget_test_repos: array of objects specifying where tests should be added:
repo: midstream org/repo (e.g., "opendatahub-io/opendatahub-operator")test_directory: directory within the repo for the testsframework: test framework (e.g., "go-test-gomega", "ginkgo-envtest", "pytest", "jest", "cypress")run_command: command to run the testsunit_tests: array of test case objects with description, file, setup, input, expected, edge_cases (string array)integration_tests: array of test case objects with description, components (string array), setup, steps (string array), expected, api_verification (optional string)regression_tests: array of test case objects with description, steps (string array), before_fix, after_fixmanual_verification_steps: array of strings with step-by-step instructionsenvironment_requirements: object with ocp_version, rhoai_version, platform, special_configeffort_estimate: one of "lightweight", "moderate", "heavy"qe_coverage_note: string or null — if the fix warrants product-level QE coverage in opendatahub-tests, describe what test to write, which component directory, and which marker. Set to null if not applicable.Analyze the bug and fix:
decision_rationaleIdentify target test repos:
opendatahub-io/opendatahub-testsDesign unit tests:
Design integration tests:
Design regression tests:
Specify manual verification:
oc commands, URLs, or UI steps to checkWrite QE coverage note (if applicable):
suite_test.go. In opendatahub-tests, add to existing conftest.py.t.Cleanup() or DeferCleanup(). In opendatahub-tests, use context manager fixtures.The test plan should be designed so that:
If a test would pass both with and without the fix, it's not testing the right thing.
Write two files in the output directory specified in the prompt header:
test-plan.json — the JSON object described abovetest-plan.md — a human-readable rendering:# Test Plan: {KEY}
## Decision Rationale
[Why these test layers were chosen — walk through the decision tree]
## Target Test Repositories
| Repo | Test Directory | Framework | Run Command |
|------|---------------|-----------|-------------|
| [repo] | [directory] | [framework] | [command] |
## Unit Tests
- **Test case:** [description]
- **File:** [test file path]
- **Setup:** [prerequisites/mocks]
- **Input:** [test input]
- **Expected:** [expected behavior]
- **Edge cases:** [variations to cover]
## Integration Tests
- **Test case:** [description]
- **Components involved:** [list]
- **Setup:** [cluster state, mock services]
- **Steps:** [numbered steps]
- **Expected:** [expected outcome]
- **API verification:** [if applicable]
## Regression Tests
- **Test case:** Reproduce original bug
- **Steps:** [steps that trigger the original failure]
- **Before fix:** [expected failure behavior]
- **After fix:** [expected success behavior]
## Manual Verification Steps
1. [Step-by-step instructions]
2. [What to check in logs, pod status, UI, etc.]
## Environment Requirements
- **OCP version:** [required version(s)]
- **RHOAI version:** [required version(s)]
- **Platform:** [AWS/GCP/bare metal/any]
- **Special config:** [disconnected, multi-tenant, GPU nodes, etc.]
## Effort Estimate: [lightweight / moderate / heavy]
[Brief justification for the effort level]
## QE Coverage Note
[If applicable: suggested opendatahub-tests test with component, marker, and description. Otherwise: "N/A"]
Be specific and practical. Reference actual file paths, function names, and test frameworks used by the component. Read the architecture context and fix attempt to tailor your test plan to the specific codebase.
npx claudepluginhub ikredhat/skills-registry --plugin rhoai-security-reviewerGuides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
Guides reception of code review feedback: verify before implementing, avoid performative agreement, push back with technical reasoning when needed.
Estimates input tokens and offers response depth choices (brief to exhaustive) before answering. Activates on explicit token/depth/length requests.