소스 정보
- 저장소
- openshift/assisted-service
- 최근 소스 활동
- 2026년 6월 25일 13:50
- 감지된 SKILL.md 언어
- 영어
- 스타
- 137
- 포크
- 276
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/openshift/assisted-service --skill assisted-service-writing-unit-tests명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | assisted-service-writing-unit-tests |
| description | Use when writing non-subsystem tests in assisted-service. |
Unit tests in assisted-service use Ginkgo/Gomega BDD framework with gomock for mocking. Core principle: Every gomock controller MUST call ctrl.Finish() in AfterEach to verify mock expectations.
Without ctrl.Finish(), tests pass even when mocks aren't called correctly - silent failures that hide bugs. Tests run against real PostgreSQL (suite or per-test) with automatic cleanup.
| Scenario | Pattern |
|---|---|
| Testing with mocks | Create controller in BeforeEach, call ctrl.Finish() in AfterEach |
| Testing without mocks | Use It() blocks directly or table-driven tests |
| Database per test | PrepareTestDB() in BeforeEach, DeleteTestDB() in AfterEach |
| Database for suite | InitializeDBTest() in BeforeSuite, TerminateDBTest() in AfterSuite |
| Event verification | eventstest.NewEventMatcher with matchers |
| OCP version in tests | Use hardcoded strings or common.TestDefaultConfig — do not use TestVersion() |
digraph mock_decision {
"Testing interface deps?" [shape=diamond];
"Need verify calls or control returns?" [shape=diamond];
"Use gomock mocks" [shape=box];
"Use real implementation" [shape=box];
"Testing interface deps?" -> "Need verify calls or control returns?" [label="yes"];
"Testing interface deps?" -> "Use real implementation" [label="no"];
"Need verify calls or control returns?" -> "Use gomock mocks" [label="yes"];
"Need verify calls or control returns?" -> "Use real implementation" [label="no"];
}
digraph db_decision {
"Tests share data?" [shape=diamond];
"Tests modify DB state?" [shape=diamond];
"Suite-level DB" [shape=box];
"Per-test DB" [shape=box];
"Tests share data?" -> "Suite-level DB" [label="yes"];
"Tests share data?" -> "Tests modify DB state?" [label="no"];
"Tests modify DB state?" -> "Per-test DB" [label="yes"];
"Tests modify DB state?" -> "Suite-level DB" [label="no"];
}
Covers: Non-subsystem tests in internal/ and pkg/ with gomock, Ginkgo/Gomega, database, events.
Does NOT cover: Subsystem tests (subsystem/), E2E, external service integration, performance tests. Subsystem tests use different patterns, including common.TestVersion() for OCP versions.
Test files: *_test.go (same package). Suites: *_suite_test.go.
Every Describe/Context creating a gomock controller needs ctrl.Finish() in AfterEach. No exceptions.
Without ctrl.Finish():
.Times(N) - Expected call count NOT checked.MaxTimes(0) - Unexpected calls NOT caught.Do() / .DoAndReturn() - Mock behavior runs without verificationBeforeEach(func() {
ctrl = gomock.NewController(GinkgoT())
mockHandler = eventsapi.NewMockHandler(ctrl)
})
AfterEach(func() {
ctrl.Finish() // REQUIRED - verifies all EXPECT() constraints
})
Why this matters: Missing ctrl.Finish() causes silent test failures - tests pass even when mocks aren't called correctly. Real bugs found in commit 338133e05 MGMT-23548.
Letter = Spirit: Following the pattern exactly IS following the spirit. This isn't ritual - it's how gomock verification works.
Suite-level (shared DB, read-only tests):
BeforeSuite(func() { common.InitializeDBTest() })
AfterSuite(func() { common.TerminateDBTest() })
Per-test (isolated DB, tests modify state):
BeforeEach(func() { db, dbName = common.PrepareTestDB() })
AfterEach(func() { common.DeleteTestDB(db, dbName) })
Use eventstest.NewEventMatcher with specific matchers:
mockEvents.EXPECT().SendHostEvent(gomock.Any(), eventstest.NewEventMatcher(
eventstest.WithNameMatcher(eventgen.HostStatusUpdatedEventName),
eventstest.WithHostIdMatcher(host.ID.String())))
Matchers: WithNameMatcher, WithHostIdMatcher, WithClusterIdMatcher, WithInfraEnvIdMatcher, WithSeverityMatcher
DescribeTable (simple cases):
DescribeTable("FunctionName",
func(input string, valid bool) { /* test logic */ },
Entry("descriptive case 1", "value1", true),
Entry("descriptive case 2", "value2", false))
Struct array (complex scenarios):
tests := []struct{name, input string; valid bool}{
{name: "case 1", input: "val1", valid: true}}
for _, t := range tests { It(t.name, func() { /* ... */ }) }
Ginkgo hierarchy: Describe("Component") → Context("when X") → It("should Y")
Isolation: No shared state between It blocks. Use BeforeEach for setup.
Gomock matchers: .Times(N), .MaxTimes(0), .AnyTimes(), gomock.Any()
Do not use common.TestVersion() in non-subsystem tests. TestVersion() resolves versions dynamically from data files and is designed for subsystem tests (subsystem/), which run against the real service. Non-subsystem tests mock version data and should use hardcoded version strings directly.
Correct patterns:
OpenshiftVersion: swag.String("4.14"),
Or use the package-level defaults from internal/common/test_configuration.go:
OpenshiftVersion: swag.String(common.OpenShiftVersion),
ReleaseVersion: common.ReleaseVersion,
ReleaseImageUrl: common.ReleaseImageURL,
See docs/dev/test-versions.md for the TestVersion() API used in subsystem tests.
These thoughts mean STOP - fix the issue:
ctrl.Finish() in AfterEachgomock.NewController but no ctrl.Finish() → Silent failurescommon.TestVersion() outside subsystem/ → Wrong pattern; use hardcoded strings or common.TestDefaultConfigIf you're rationalizing shortcuts due to time pressure, the test will be broken. No exceptions.
| Mistake | Symptom | Fix |
|---|---|---|
Missing ctrl.Finish() | Tests pass when mocks not called | Add ctrl.Finish() in AfterEach |
| Shared variables between tests | Flaky tests, race conditions | Move initialization to BeforeEach |
Missing GinkgoT() | Controller doesn't report failures | Use gomock.NewController(GinkgoT()) |
| Generic Entry names | "test 1", "test 2" in output | Descriptive: "valid IPv4 CIDR" |
| Wrong DB pattern | Pollution between tests | Suite-level for reads, per-test for writes |
| No event matchers | Generic gomock.Any() for events | Use eventstest.NewEventMatcher with specific matchers |
Using TestVersion() | Wrong abstraction for non-subsystem tests | Use hardcoded strings or common.TestDefaultConfig |
Check every test file:
gomock.NewController has ctrl.Finish() in AfterEachBeforeEach)PrepareTestDB()TestVersion() usage — use hardcoded strings or common.TestDefaultConfiggo test -v ./path/to/packageRed flags: Missing ctrl.Finish() → silent failures. Shared variables → flaky tests.