KCC Direct MockGCP Implementer
This skill guides you through implementing Phase 3 (MockGCP and Alignment) for a direct KCC resource to verify behavioral correctness against simulated GCP services.
Inputs
ResourceKind: The kind of the resource (e.g., VertexAIDataset).
service_name: The short name of the GCP service (e.g., aiplatform).
api_version: The KCC API version (e.g., v1alpha1, v1beta1).
group: The API group (e.g., vertexai).
kind_lowercase: The lowercase kind name (e.g., vertexaidataset).
testname: The specific test folder name under pkg/test/resourcefixture/testdata/basic/<group>/<api_version>/<kind_lowercase>/.
Workflow
1. Locate E2E Fixtures
- The test fixtures are located under
pkg/test/resourcefixture/testdata/basic/<group>/<api_version>/<kind_lowercase>/.
2. Add or Enhance Mock Service
- If a mock service for
<service_name> does not exist under mockgcp/mock<service_name>/, create one:
- Follow the guide in
mockgcp/GEMINI.md and mockgcp/README.md.
- Add the relevant proto to the Makefile and run
make gen-proto if needed.
- Implement the mock service entrypoint in
mockgcp/mock<service_name>/service.go and register it in mockgcp/register.go.
- If the mock service already exists, implement the necessary CRUD (Create, Read, Update, Delete) methods for
<ResourceKind> in mockgcp/mock<service_name>/<kind_lowercase>.go.
2b. Remove from Ratcheting Exclusions (MANDATORY)
Before running the test cases against real or mock GCP, you MUST ensure the target resource is removed from the ratcheting exclusion list in tests/e2e/ratcheting.go. This enables the re-reconciliation test step, which is a fundamental use case KCC resources must support.
- Open
tests/e2e/ratcheting.go.
- Locate the function
ShouldTestRereconiliation.
- Locate the
switch statement that checks primaryResource.GroupVersionKind().
- If there is a
case block for your target resource's GroupKind, remove that case line from the switch statement.
3. Incremental Mock Alignment
Run hack/compare-mock "fixtures/^<testname>$" to execute the tests against the mock implementation.
[!WARNING]
WHENEVER A TEST CASE IS UPDATED, WE MUST RECORD REAL GCP LOGS AGAIN.
If you make any modifications to a test case configuration, manifest files (such as create.yaml, update.yaml, or dependencies.yaml), or the controller's runtime mapping configuration, you MUST run the test case against real GCP (hack/record-gcp or with E2E_GCP_TARGET=real) to regenerate the authentic _http.log baseline before comparing or committing any mock log changes. Do not attempt to manually edit the logs or bypass recording live traffic.
Use the fix-diffs-mockgcp skill (mockgcp/.gemini/skills/fix-diffs-mockgcp/SKILL.md) to align the mock logs with the real GCP output:
- Output-Only Fields/IDs: If real GCP produces dynamic values that mockgcp lacks, implement a
populate<ResourceKind>Defaults function in mockgcp/mock<service_name>/<kind_lowercase>.go called on Insert and Get to match the required format.
- Volatile/Random Values: For values like timestamps or etags that are functionally identical but structurally unpredictable, update
normalize.go for the service.
- Critical Rule: Always scope the
Previsit normalization in normalize.go to ensure it only applies to your service URL (e.g. strings.Contains(event.URL(), "<service_name>.googleapis.com")) to prevent log corruption in unrelated services.
Iterate on running hack/compare-mock "fixtures/^<testname>$" and making incremental code updates until the HTTP logs match real GCP perfectly with clean, minimal diffs.
Once the logs align, run the comparison with WRITE_GOLDEN_OUTPUT=1 against mock GCP to generate the _http_mock.log file:
WRITE_GOLDEN_OUTPUT=1 RUN_E2E=1 E2E_GCP_TARGET=mock E2E_KUBE_TARGET=envtest go test -v ./tests/e2e -run "TestAllInSeries/fixtures/<testname>"
Make sure both _http.log and _http_mock.log are present in the fixture directory.
4. Verify and Run Presubmits
- Run local validation:
scripts/validate-prereqs.sh.
- Run the e2e fixtures presubmit:
./dev/ci/presubmits/tests-e2e-fixtures-<kind_lowercase>.
- Make sure to stage and commit both
_http.log and _http_mock.log files in your Pull Request.
1---2name: kcc-direct-mockgcp-implementer3description: Guides the implementation of Phase 3 (MockGCP and Alignment) for a direct KCC resource, verifying behavioral correctness against simulated GCP services. Use this when you need to implement or align mockgcp for a KCC resource.4---56# KCC Direct MockGCP Implementer78This skill guides you through implementing Phase 3 (MockGCP and Alignment) for a direct KCC resource to verify behavioral correctness against simulated GCP services.910## Inputs11- `ResourceKind`: The kind of the resource (e.g., `VertexAIDataset`).12- `service_name`: The short name of the GCP service (e.g., `aiplatform`).13- `api_version`: The KCC API version (e.g., `v1alpha1`, `v1beta1`).14- `group`: The API group (e.g., `vertexai`).15- `kind_lowercase`: The lowercase kind name (e.g., `vertexaidataset`).16- `testname`: The specific test folder name under `pkg/test/resourcefixture/testdata/basic/<group>/<api_version>/<kind_lowercase>/`.1718## Workflow1920### 1. Locate E2E Fixtures21- The test fixtures are located under `pkg/test/resourcefixture/testdata/basic/<group>/<api_version>/<kind_lowercase>/`.2223### 2. Add or Enhance Mock Service24- If a mock service for `<service_name>` does not exist under `mockgcp/mock<service_name>/`, create one:25 - Follow the guide in `mockgcp/GEMINI.md` and `mockgcp/README.md`.26 - Add the relevant proto to the Makefile and run `make gen-proto` if needed.27 - Implement the mock service entrypoint in `mockgcp/mock<service_name>/service.go` and register it in `mockgcp/register.go`.28- If the mock service already exists, implement the necessary CRUD (Create, Read, Update, Delete) methods for `<ResourceKind>` in `mockgcp/mock<service_name>/<kind_lowercase>.go`.2930### 2b. Remove from Ratcheting Exclusions (MANDATORY)31Before running the test cases against real or mock GCP, you **MUST** ensure the target resource is removed from the ratcheting exclusion list in `tests/e2e/ratcheting.go`. This enables the re-reconciliation test step, which is a fundamental use case KCC resources must support.321. Open `tests/e2e/ratcheting.go`.332. Locate the function `ShouldTestRereconiliation`.343. Locate the `switch` statement that checks `primaryResource.GroupVersionKind()`.354. If there is a `case` block for your target resource's `GroupKind`, remove that `case` line from the switch statement.3637### 3. Incremental Mock Alignment38- Run `hack/compare-mock "fixtures/^<testname>$"` to execute the tests against the mock implementation.3940 > [!WARNING]41 > **WHENEVER A TEST CASE IS UPDATED, WE MUST RECORD REAL GCP LOGS AGAIN.**42 > If you make any modifications to a test case configuration, manifest files (such as `create.yaml`, `update.yaml`, or `dependencies.yaml`), or the controller's runtime mapping configuration, you **MUST** run the test case against real GCP (`hack/record-gcp` or with `E2E_GCP_TARGET=real`) to regenerate the authentic `_http.log` baseline before comparing or committing any mock log changes. Do not attempt to manually edit the logs or bypass recording live traffic.4344- Use the `fix-diffs-mockgcp` skill (`mockgcp/.gemini/skills/fix-diffs-mockgcp/SKILL.md`) to align the mock logs with the real GCP output:45 - **Output-Only Fields/IDs**: If real GCP produces dynamic values that mockgcp lacks, implement a `populate<ResourceKind>Defaults` function in `mockgcp/mock<service_name>/<kind_lowercase>.go` called on `Insert` and `Get` to match the required format.46 - **Volatile/Random Values**: For values like timestamps or etags that are functionally identical but structurally unpredictable, update `normalize.go` for the service.47 - **Critical Rule**: Always scope the `Previsit` normalization in `normalize.go` to ensure it only applies to your service URL (e.g. `strings.Contains(event.URL(), "<service_name>.googleapis.com")`) to prevent log corruption in unrelated services.48- Iterate on running `hack/compare-mock "fixtures/^<testname>$"` and making incremental code updates until the HTTP logs match real GCP perfectly with clean, minimal diffs.49- Once the logs align, run the comparison with `WRITE_GOLDEN_OUTPUT=1` against mock GCP to generate the `_http_mock.log` file:50 ```bash51 WRITE_GOLDEN_OUTPUT=1 RUN_E2E=1 E2E_GCP_TARGET=mock E2E_KUBE_TARGET=envtest go test -v ./tests/e2e -run "TestAllInSeries/fixtures/<testname>"52 ```53 Make sure both `_http.log` and `_http_mock.log` are present in the fixture directory.5455### 4. Verify and Run Presubmits56- Run local validation: `scripts/validate-prereqs.sh`.57- Run the e2e fixtures presubmit: `./dev/ci/presubmits/tests-e2e-fixtures-<kind_lowercase>`.58- Make sure to stage and commit both `_http.log` and `_http_mock.log` files in your Pull Request.