Skip to content

e2e-tests (1/4): Repackage gnmi-test-server and e2e test infrastructure#407

Draft
nikatza wants to merge 7 commits into
mainfrom
refactor-tests-1
Draft

e2e-tests (1/4): Repackage gnmi-test-server and e2e test infrastructure#407
nikatza wants to merge 7 commits into
mainfrom
refactor-tests-1

Conversation

@nikatza

@nikatza nikatza commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

This PR refactors the gNMI test server into a reusable package and adds e2e test infrastructure.

Package gNMI test server into testserver package

Extract gNMI server implementation into a reusable testserver package. This enables running the server in-process with envtest, not just as a standalone container.

Add test server factory with functional opts and HTTP API

Add configurable options to NewTestServer(): WithGRPCPort(), WithHTTPPort(), WithBindAddress(). Add an HTTP API for inspecting and manipulating server state during tests — GET/POST/DELETE /v1/state for reading, merging, and clearing state.

Inject YANG list keys into stored state

When you Set a path like /interfaces/interface[name=eth0]/config with {"mtu":1500}, the name=eth0 key lives in the path, not in the payload. But when you later Get that path, the lookup searches for a JSON object with "name":"eth0" inside it. Without this fix, Set stores {"mtu":1500} and Get can't find it. Now Set injects the key into the stored JSON: {"name":"eth0","mtu":1500}.

Add NXOS behavior emulation

Adds WithNXOSBehavior() option which strips fields containing the DME unset marker when storing, and returns empty TypedValue for non-existent paths. Enable via -nxos CLI flag.

Add unit tests for State.Set

Cover JSON state manipulation: key injection for final/intermediate/nested keyed paths, in-place update vs append semantics, empty-path root merge, and NX-OS marker stripping.

Update build configuration

Update Dockerfile, Makefile targets (test-gnmi-unit), and deployment config for the new package structure.

Add shared e2e test utilities

Add common test infrastructure in test/e2e/testutil/: kubectl helpers, JSON comparison utilities, retry/polling functions, and centralized timeout constants.

@nikatza nikatza force-pushed the refactor-tests-1 branch from d6f35e8 to 4f9dd88 Compare June 16, 2026 21:32
@nikatza nikatza force-pushed the refactor-tests-1 branch from 4f9dd88 to 23777e1 Compare June 16, 2026 21:40
@nikatza nikatza changed the title Repackage gnmi-test-server and e2e test infrastructure e2e-tests (1/4): Repackage gnmi-test-server and e2e test infrastructure Jun 16, 2026
@nikatza nikatza force-pushed the refactor-tests-1 branch 7 times, most recently from 791563e to 090c7f3 Compare June 24, 2026 12:18
@nikatza nikatza force-pushed the refactor-tests-1 branch 12 times, most recently from 2c34099 to d481ab3 Compare July 7, 2026 13:30
nikatza added 6 commits July 7, 2026 16:24
Extract gNMI server implementation into a reusable `testserver` package.
This enables running later the server in-process, i.e., with envtest.

No behavioral changes - this is a pure refactor to enable reuse.

Signed-off-by: Pujol <enric.pujol@sap.com>
Add configurable options to NewTestServer:
- WithGRPCPort(port) - specify gRPC port (default: random)
- WithHTTPPort(port) - specify HTTP port (default: random)
- WithBindAddress(addr) - specify bind address (default: 127.0.0.1)

Add an HTTP API for inspecting and manipulating server state. This
becomes useful during tests for initialization and validation.
- GET /v1/state: return the current accumulated state as JSON
- POST /v1/state: merge a JSON body into the state at the root level,
  e.g. to preload configuration into the server. The merge is shallow:
top-level keys overwrite, nested objects are replaced
- DELETE /v1/state: clear all state
- POST /v1/clear: clear all state, for clients that cannot send DELETE
- The /v1/state endpoint honors the X-HTTP-Method-Override header so
  clients restricted to GET/POST can still invoke DELETE
- GetState()/ClearState() helper methods on Server

Update main.go to use these options with the CLI flags, binding to
0.0.0.0 for pod deployments.

Signed-off-by: Pujol <enric.pujol@sap.com>
gNMI/OpenConfig carries list keys in the path (e.g.
interface[name=eth0]) but stores them as child leaves inside the list
entry. A Set payload therefore often omits the key field, since it is
implied by the path.

State.Set now, for every keyed path element:
  - locates the array entry whose key leaves match the path keys,
    appending a new entry when none match, so repeated Sets to the
    same key update in place instead of duplicating;
  - materializes the key(s) as leaves inside the entry — for
    intermediate elements directly into the buffer, and for the final
    element into the value being written.

Without this, a subsequent keyed Get (which matches on the key leaves
via a gjson #(key=="val") query) would not find the entry.

Signed-off-by: Pujol <enric.pujol@sap.com>
Adds the WithNXOSBehavior() option, which enforces:
- Stripping fields containing the DME_UNSET_PROPERTY_MARKER value when
  storing (the marker means "unset this field", not "store this
  literal string").
- Returning an empty TypedValue for non-existent paths, which triggers
  the client's ErrNil handling.

Add a -nxos CLI flag to main.go to enable NXOS emulation mode.

Signed-off-by: Pujol <enric.pujol@sap.com>
Cover JSON state manipulation in the gNMI test server:
- list-key injection for final, intermediate, and deeply nested
  keyed path elements
- in-place update vs. append semantics for keyed list entries
- empty-path root merge and keyless nested writes
- NX-OS DME unset-marker stripping
- Set/Get round-trip via a keyed path query

Add testify as a test dependency.

Signed-off-by: Pujol <enric.pujol@sap.com>
- Update test/gnmi/Dockerfile for testserver package structure
- Update test-e2e target to load the image into the kind cluster
- Update Makefile / Makefile.maker.yaml build + license-scan config
- Add gnmi-test-server.yaml deployment config
- Update main Dockerfile

Signed-off-by: Pujol <enric.pujol@sap.com>
@nikatza nikatza force-pushed the refactor-tests-1 branch from d481ab3 to a1fd1b5 Compare July 7, 2026 14:24
Add common test infrastructure for e2e tests:

test/e2e/testutil/helpers.go:
- Run, Apply, ApplyWithPatch - kubectl command execution
- CompareJSON, normalizeJSON - JSON comparison utilities
- ExtractResourceIdentifier, WaitForCondition - resource helpers
- Cert-manager and Prometheus operator install/uninstall
- LoadImageToKindClusterWithName, GetProjectDir, UncommentCode

test/e2e/testutil/provider.go:
- Provider registry (NXOS, IOSXR) with factory functions
- CoreResources and ConfigResources GVK lists
- ResourcePluralName for CRD plural mappings
- CreateTestDevice helper

test/e2e/testutil/timeouts.go:
- DefaultTimeout, LongTimeout, VeryLongTimeout constants

test/e2e/e2e_test.go:
- Add idempotent namespace creation (dry-run + apply)
- Add --ignore-not-found to cleanup commands
- Pre-delete gnmi-test-server pod before deploying

Signed-off-by: Pujol <enric.pujol@sap.com>
@nikatza nikatza force-pushed the refactor-tests-1 branch from a1fd1b5 to 5611390 Compare July 7, 2026 15:00
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Merging this branch will not change overall coverage

Impacted Packages Coverage Δ 🤖
github.com/ironcore-dev/network-operator/test/e2e 0.00% (ø)
github.com/ironcore-dev/network-operator/test/e2e/testutil 0.00% (ø)
github.com/ironcore-dev/network-operator/test/gnmi 0.00% (ø)
github.com/ironcore-dev/network-operator/test/gnmi/testserver 0.00% (ø)

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/ironcore-dev/network-operator/test/e2e/testutil/helpers.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/test/e2e/testutil/provider.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/test/e2e/testutil/timeouts.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/test/gnmi/main.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/test/gnmi/testserver/server.go 0.00% (ø) 0 0 0

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/ironcore-dev/network-operator/test/e2e/e2e_test.go
  • github.com/ironcore-dev/network-operator/test/e2e/testutil/provider_test.go
  • github.com/ironcore-dev/network-operator/test/gnmi/testserver/server_test.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant