Problem
internal/devlake is the core package — every CLI command depends on client.go (API calls), state.go (state file persistence), and discovery.go (instance auto-detection). Yet go test ./... reports [no test files] for this package.
The riskiest untested code is SaveState() (state.go:122-149), which reads existing JSON from disk, overlays new state fields, and writes back. A bug in the merge logic could silently corrupt state files, losing deployment metadata, connection IDs, or project references.
With 10 new plugins landing in v0.4.0, each adding scope types and connection entries, an undetected regression in the API client or state management would cascade across the entire CLI.
Scope of Changes
client_test.go
- Use
httptest.NewServer to mock DevLake API responses
- Test
doGet[T], doPost[T], doPut[T], doPatch[T] with success/error/malformed JSON
- Test
ListConnections, CreateConnection, DeleteConnection
- Test
PutScopes, ListScopes
- Test
CreateProject, PatchBlueprint, TriggerBlueprint
- Test
Ping, Health
state_test.go
- Roundtrip:
SaveState → LoadState preserves all fields
- Merge behavior:
SaveState overlays onto existing Azure metadata without clobbering
FindStateFile priority: matching endpoint → first existing → create new
UpdateConnections appends/replaces correctly
- Edge cases: empty file, invalid JSON, missing file
discovery_test.go
inferLocalCompanionURLs returns correct Grafana/ConfigUI for known ports
Discover with explicit URL, state file, localhost fallback
tryStateFile with unreachable backend
Acceptance Criteria
Problem
internal/devlakeis the core package — every CLI command depends onclient.go(API calls),state.go(state file persistence), anddiscovery.go(instance auto-detection). Yetgo test ./...reports[no test files]for this package.The riskiest untested code is
SaveState()(state.go:122-149), which reads existing JSON from disk, overlays new state fields, and writes back. A bug in the merge logic could silently corrupt state files, losing deployment metadata, connection IDs, or project references.With 10 new plugins landing in v0.4.0, each adding scope types and connection entries, an undetected regression in the API client or state management would cascade across the entire CLI.
Scope of Changes
client_test.gohttptest.NewServerto mock DevLake API responsesdoGet[T],doPost[T],doPut[T],doPatch[T]with success/error/malformed JSONListConnections,CreateConnection,DeleteConnectionPutScopes,ListScopesCreateProject,PatchBlueprint,TriggerBlueprintPing,Healthstate_test.goSaveState→LoadStatepreserves all fieldsSaveStateoverlays onto existing Azure metadata without clobberingFindStateFilepriority: matching endpoint → first existing → create newUpdateConnectionsappends/replaces correctlydiscovery_test.goinferLocalCompanionURLsreturns correct Grafana/ConfigUI for known portsDiscoverwith explicit URL, state file, localhost fallbacktryStateFilewith unreachable backendAcceptance Criteria
go test ./internal/devlake/...passesSaveStatemerge logic (the highest-risk code path)Discoverfallback chaingo build ./...andgo vet ./...pass