Skip to content

[test] Add tests for guard.WasmGuard dispatch methods - #8148

Merged
lpcox merged 2 commits into
mainfrom
add-guard-wasm-dispatch-tests-107a180551f4a669
Jun 26, 2026
Merged

lpcox merged 2 commits into
mainfrom
add-guard-wasm-dispatch-tests-107a180551f4a669

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Test Coverage Improvement: WasmGuard dispatch methods

Function Analyzed

  • Package: internal/guard
  • File: internal/guard/wasm.go
  • Previous Coverage: 79.2%
  • New Coverage: 92.1%
  • Improvement: +12.9%
  • Complexity: High (WASM execution, host functions, memory protocol)

Why This Function?

The internal/guard package had the lowest coverage (79.2%) among testable packages, with several core dispatch functions at 0% coverage. These functions are the primary interface between the Go gateway and WASM security guard modules:

Function Before After
unmarshalWasmResponse 0.0% 100.0%
NewWasmGuard 0.0% 100.0%
hostLog 0.0% 100.0%
LabelResource 0.0% 83.3%
LabelAgent 0.0% 76.0%
hostCallBackend 27.3% 87.3%
LabelResponse 0.0% 59.1%

Tests Added

TestUnmarshalWasmResponse — 6 cases:

  • ✅ Empty bytes → JSON error
  • ✅ Invalid JSON → error with func name in message
  • ✅ JSON array → error (cannot unmarshal into map)
  • ✅ Valid JSON object → success
  • ✅ Empty JSON object → success
  • ✅ funcName appears in error message

TestNewWasmGuard — 3 cases:

  • ✅ File not found → "failed to read WASM file" error
  • ✅ File with invalid WASM bytes → error from instantiation
  • ✅ Valid minimal WASM missing required guard exports → error

TestHostLog — 6 cases:

  • ✅ Memory read failure (huge msgLen) → silent return, no panic
  • ✅ logLevelDebug (0)
  • ✅ logLevelInfo (1)
  • ✅ logLevelWarn (2)
  • ✅ logLevelError (3)
  • ✅ Unknown log level → fallback format

TestLabelAgent — 5 cases:

  • ✅ Nil policy → normalizePolicyPayload error
  • ✅ Empty string policy → error
  • ✅ Policy without allow-only → buildStrictLabelAgentPayload error
  • ✅ Failed (trapped) guard → immediate error
  • ✅ WASM returning empty → "label_agent returned empty response"

TestLabelResource — 3 cases:

  • ✅ Failed guard → immediate error
  • ✅ Function not exported from WASM module → error
  • ✅ WASM returns empty bytes → unmarshalWasmResponse JSON error

TestLabelResponse — 4 cases:

  • ✅ Failed guard → immediate error
  • ✅ Function not exported → error
  • ✅ WASM returns empty result → (nil, nil) (no labeling)
  • ✅ WASM returns invalid JSON bytes → unmarshalWasmResponse error

TestHostCallBackend — 8 cases:

  • ✅ Tool name memory read failure (oversized len)
  • ✅ Args memory read failure (oversized argsLen)
  • ✅ Invalid JSON args → JSON unmarshal error
  • ✅ Backend call failure → -1 error sentinel
  • ✅ Result too large with 4-byte hint buffer → -2 with hint
  • ✅ Result too large with <4-byte buffer → -2 without hint
  • ✅ Success with no args → positive result length
  • ✅ Success with valid JSON args → positive result length

New WASM Fixtures

Three inline WASM byte-slice fixtures added (hand-computed from WAT, no compiler required):

  • labelResourceReturnsZeroWasm — exports label_resource, returns 0 (empty result)
  • labelResponseReturnsZeroWasm — exports label_response, returns 0 (empty result)
  • labelResponseReturnsTwoWasm — exports label_response, returns 2 (claims 2 bytes in zeroed buffer = invalid JSON)

Coverage Report

Before: 79.2% coverage
After:  92.1% coverage
Improvement: +12.9%

Test Execution

All 30 new tests pass:

--- PASS: TestUnmarshalWasmResponse (0.00s)
--- PASS: TestNewWasmGuard (0.00s)
--- PASS: TestHostLog (0.00s)
--- PASS: TestLabelAgent_PolicyValidationErrors (0.00s)
--- PASS: TestLabelAgent_FailedGuard (0.00s)
--- PASS: TestLabelAgent_EmptyWasmResponse (0.00s)
--- PASS: TestLabelResource_FailedGuard (0.00s)
--- PASS: TestLabelResource_FunctionNotExported (0.00s)
--- PASS: TestLabelResource_EmptyWasmResponseTriggersMarshalError (0.00s)
--- PASS: TestLabelResponse_FailedGuard (0.00s)
--- PASS: TestLabelResponse_FunctionNotExported (0.00s)
--- PASS: TestLabelResponse_EmptyResultReturnsNil (0.00s)
--- PASS: TestLabelResponse_InvalidJsonResponseReturnsError (0.00s)
--- PASS: TestHostCallBackend_ToolNameReadFailure (0.00s)
--- PASS: TestHostCallBackend_ArgsReadFailure (0.00s)
--- PASS: TestHostCallBackend_InvalidArgsJSON (0.00s)
--- PASS: TestHostCallBackend_BackendCallFailure (0.00s)
--- PASS: TestHostCallBackend_ResultTooLarge (0.00s)
--- PASS: TestHostCallBackend_ResultTooLarge_BufferLessThan4 (0.00s)
--- PASS: TestHostCallBackend_SuccessWithNoArgs (0.00s)
--- PASS: TestHostCallBackend_SuccessWithValidArgs (0.00s)
ok  	github.com/github/gh-aw-mcpg/internal/guard	coverage: 92.1% of statements

Generated by Test Coverage Improver

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • go.opentelemetry.io
  • go.yaml.in
  • golang.org
  • google.golang.org
  • gopkg.in
  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "go.opentelemetry.io"
    - "go.yaml.in"
    - "golang.org"
    - "google.golang.org"
    - "gopkg.in"
    - "proxy.golang.org"

See Network Configuration for more information.

Generated by Test Coverage Improver · 576.1 AIC · ⊞ 7.1K · ◷

Cover previously-untested dispatch functions in internal/guard/wasm.go:

- unmarshalWasmResponse (0% → 100%)
- NewWasmGuard (0% → 100%)
- hostLog (0% → 100%)
- LabelAgent (0% → 76%)
- LabelResource (0% → 83%)
- LabelResponse (0% → 59%)
- hostCallBackend (27% → 87%)

Overall guard package coverage: 79.2% → 92.1% (+12.9%)

New WASM fixtures added (inline byte slices, no compiler needed):
- labelResourceReturnsZeroWasm: exports label_resource, returns 0
- labelResponseReturnsZeroWasm: exports label_response, returns 0
- labelResponseReturnsTwoWasm: exports label_response, returns 2
  (claims 2 bytes written to zeroed buffer — exercises invalid-JSON path)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lpcox
lpcox marked this pull request as ready for review June 26, 2026 22:32
Copilot AI review requested due to automatic review settings June 26, 2026 22:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dedicated test suite for internal/guard’s WasmGuard dispatch and host-call paths, increasing confidence in the WASM↔Go boundary behavior and improving package-level coverage.

Changes:

  • Introduces wasm_dispatch_test.go with table/branch coverage for unmarshalWasmResponse, NewWasmGuard, hostLog, LabelAgent, LabelResource, LabelResponse, and hostCallBackend.
  • Adds small inline WASM byte fixtures to hit specific dispatch edge cases (empty results / invalid JSON) without requiring a WASM toolchain.
  • Exercises error/sentinel protocols for hostCallBackend (e.g., -1 error, -2 buffer-too-small) via direct host-function invocation.
Show a summary per file
File Description
internal/guard/wasm_dispatch_test.go Adds focused unit tests and WASM fixtures to cover WasmGuard dispatch methods and host-call behavior.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 1/1 changed files
  • Comments generated: 3
  • Review effort level: Low

Comment thread internal/guard/wasm_dispatch_test.go Resolved
Comment on lines +484 to +489
g.hostCallBackend(context.Background(), g.module, stack)
// Result too large: the gateway signals buffer-too-small by returning -2,
// which is encoded as uint64(0xFFFFFFFE) via setResult(int32(-2)).
const bufTooSmall = uint64(0xFFFFFFFE)
assert.Equal(t, bufTooSmall, stack[0], "result too large should return -2 buffer-too-small sentinel")
}
Comment on lines +508 to +513
stack[5] = 2 // resultSize < 4 — cannot write required-size hint

g.hostCallBackend(context.Background(), g.module, stack)
const bufTooSmall = uint64(0xFFFFFFFE)
assert.Equal(t, bufTooSmall, stack[0], "result too large with small buffer should still return -2")
}
@lpcox

lpcox commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Copilot AI commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@copilot address review feedback and fix linting error https://github.com/github/gh-aw-mcpg/actions/runs/28254607796/job/83762156749?pr=8148

Addressed in commit d212d08.

  • Renamed the LabelResource test to use UnmarshalError wording.
  • Strengthened TestHostCallBackend_ResultTooLarge to assert the required-size hint written to resultPtr when resultSize >= 4.
  • Strengthened TestHostCallBackend_ResultTooLarge_BufferLessThan4 to prefill and verify the buffer is unchanged when resultSize < 4.
  • Fixed the lint failure by formatting internal/guard/wasm_dispatch_test.go.

Validation run: targeted go test for updated cases, make lint, and full make agent-finished.

Copilot finished work on behalf of lpcox June 26, 2026 22:41
Copilot AI requested a review from lpcox June 26, 2026 22:41
@lpcox
lpcox merged commit 0fb0af6 into main Jun 26, 2026
26 checks passed
@lpcox
lpcox deleted the add-guard-wasm-dispatch-tests-107a180551f4a669 branch June 26, 2026 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants