Skip to content

Developer guide

Day-to-day what to regenerate and what to test when you change APIs, reconcilers, or the MQ boundary. For install, Task targets, and local clusters see DEVELOPMENT.md; for system design see ARCHITECTURE.md.

Deep dive
🧩 GO_MODULE.md — module layout, import layers, go-arch-lint
⚙️ OPERATOR_RUNTIME.md — manager wiring, probes, concurrency

Doc index: README.md · Agent entry: ../AGENTS.md

On this page

Section
📐 I changed a CRD field
🔄 I changed reconcile logic
🔌 I extended the MQAdmin port
🎭 Mocks and the MQAdmin port
Before you commit

I changed a CRD field — what do I regenerate?

Edit types and kubebuilder markers in api/v1alpha1/, then run codegen in this order (or rely on task verify, which runs the same steps and fails on drift):

Step Command Produces / updates
1 task generate api/*/zz_generated.deepcopy.go; mockery mocks if .mockery.yaml lists interfaces
2 task manifests config/crd/bases/*.yaml, config/rbac/role.yaml, webhook manifests under config/
3 (automatic in task verify) hack/helm-sync-crds.shcharts/mkurator/crds/
4 If CR spec OpenAPI changed task test:schema:updatetest/schema/golden/*.spec.openapi.yaml
5 If config/samples/ CR YAML changed task samples:synccharts/mkurator/samples/resources/

One-liner after API edits:

task generate && task manifests && task test:schema:update

Then task verify before commit (also runs schema contract tests).

Also update by hand (not generated)

Change Where
Admission rules for new/renamed fields internal/validation/ + *_test.go (table-driven)
Webhook handler (thin) internal/webhook/v1alpha1/ — delegates to validation
Reconciler mapping CR spec → port types internal/controller/*_controller.go
Drift / DEFINE vs DISPLAY policy ATTRIBUTE_RECONCILIATION.md and reconciler helpers
User-facing samples config/samples/, config/samples/README.md
Helm-only sample files charts/mkurator/samples/resources/ (README, Secret template)

OpenAPI contract tests live in test/schema/: they diff committed CRD YAML against golden spec fragments — no cluster. Adding a new CR kind requires a row in test/schema/extract.go plus a golden file.


I changed reconcile logic — what tests?

Pick the lowest tier that exercises the behaviour (ADR-0011).

You changed Add or extend
Pure helpers (needsUpdate, status, events, shared wait/enqueue) internal/controller/*_test.go — stdlib testing, t.Parallel() where safe
A reconciler path (define, drift, delete, requeue, finalizer) internal/controller/*_unit_test.gofake client + mock Admin; or Ginkgo *_reconciler_test.go with envtest + mocks
Controller registration / wiring wiring_envtest_test.go, events_envtest_test.go
Validation only internal/validation/*_test.go — no cluster, no MQ
Admission webhook wiring internal/webhook/v1alpha1/ envtest suite

Default PR loop (no Queue Manager):

task test:run    # unit + envtest, -race, internal/ coverage floor

Envtest loads CRDs from config/crd/bases (internal/controller/suite_test.go). It uses a real Kubernetes API server from setup-envtest; MQ is always mocked.

File naming convention

Pattern Tier Typical use
*_unit_test.go Unit Single reconciler with client/fake + mqadmintest.NewMockAdmin
*_reconciler_test.go envtest Ginkgo specs creating CRs via k8sClient, MQFactory mocked
*_envtest_test.go envtest Cross-cutting (events, wiring)
reconcile_shared_test.go Unit Shared reconcile helpers

Do not call real mqweb from internal/controller tests.


I extended the MQAdmin port — what tests?

The port is internal/mqadmin.Admin and Factory (ARCHITECTURE.md). Reconcilers must use typed methods only — not raw RunMQSC (ADR-0014).

Step Action
1 Add method(s) and domain types on internal/mqadmin/admin.go
2 task generate (runs task test:generate → mockery → test/mocks/mqadmin/)
3 Implement in internal/adapter/mqrest/
4 Unit: internal/adapter/mqrest/*_test.go with httptest server where HTTP/MQSC parsing matters
5 Integration: test/integration/mq/*_integration_test.go//go:build integration, task test:integration
6 Reconciler unit/envtest: expect new mock calls in controller tests
7 e2e (optional, slow): kind + live MQ — only when end-to-end install path must be proven; see DEVELOPMENT.md

Integration is gated by KURATOR_INTEGRATION_MQ=1 (set by task test:integration). It does not run in task test:run or default go test ./....


Mocks and the MQAdmin port

Where mocks live

Path Contents
.mockery.yaml mockery v3 config (template: testify)
test/mocks/mqadmin/ Generated MockAdmin, MockFactorydo not edit by hand
internal/mqadmin/ Real Admin / Factory interfaces and domain errors

Regenerate mocks:

task test:generate    # or: task generate (includes mockery)

task verify diffs test/mocks/ after regeneration; drift fails CI.

How reconcilers use the port

Production code obtains an Admin per connection:

Reconciler.MQFactory.ForConnection(ctx, qmc) → (Admin, error)

Tests inject mocks at the factory boundary (same field name on reconcilers):

  1. mockFactory := mqadmintest.NewMockFactory(t) (or GinkgoT()).
  2. mockFactory.EXPECT().ForConnection(...).Return(mockAdmin, nil).
  3. mockAdmin := mqadmintest.NewMockAdmin(t).
  4. mockAdmin.EXPECT().DefineQueue(...).Return(nil) (etc.).

Example (envtest Ginkgo): internal/controller/queue_reconciler_test.go.

Example (stdlib unit): internal/controller/queue_controller_unit_test.go.

NewMockFactory / NewMockAdmin register t.Cleanup to assert expectations. Use github.com/stretchr/testify/mock matchers (mock.Anything, typed QueueSpec, …).

REST adapter tests without mockery

internal/adapter/mqrest unit tests often use an httptest.Server to fake mqweb responses — no Kubernetes, no mockery. Use integration tier when behaviour depends on a real IBM MQ container (hack/mq-docker/README.md).


Before you commit

task verify      # deepcopy, CRDs, RBAC, mocks, Helm CRDs, samples, schema goldens
task lint
task test:run

See DEVELOPMENT.md — Before you push and CONTRIBUTING.md for commit format.


Document Use when
DEVELOPMENT.md Local stack, Task reference, integration/e2e env vars
CICD.md What CI runs on PRs vs scheduled jobs
GO_MODULE.md Package boundaries and allowed imports
OPERATOR_RUNTIME.md Manager, leader election, health, metrics
test/schema/README.md CRD OpenAPI golden workflow