a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
118 lines
3.6 KiB
Go
118 lines
3.6 KiB
Go
package query
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/zzet/gortex/internal/graph"
|
|
)
|
|
|
|
// The test graph's call chain is main -> Start -> Connect -> Ping.
|
|
// These tests pin a community over a subset of those nodes and assert
|
|
// the walk's community gate keeps in-community neighbours, drops
|
|
// cross-community ones, and lets membership-less nodes through.
|
|
|
|
func TestWalkBudgeted_CommunityFilter_DropsCrossCommunity(t *testing.T) {
|
|
e := NewEngine(buildTestGraph())
|
|
|
|
// main + Start are in community "a"; Connect is in community "b".
|
|
nodeToComm := map[string]string{
|
|
"main.go::main": "a",
|
|
"pkg/server.go::Start": "a",
|
|
"pkg/db.go::Connect": "b",
|
|
"pkg/db.go::Ping": "b",
|
|
}
|
|
|
|
sg := e.WalkBudgeted("main.go::main", WalkOptions{
|
|
EdgeKinds: []graph.EdgeKind{graph.EdgeCalls},
|
|
Direction: "out",
|
|
CommunityID: "a",
|
|
NodeToComm: nodeToComm,
|
|
})
|
|
ids := nodeIDs(sg.Nodes)
|
|
assert.Contains(t, ids, "main.go::main")
|
|
assert.Contains(t, ids, "pkg/server.go::Start")
|
|
// Connect is in community "b" — dropped, and Ping behind it never
|
|
// gets reached.
|
|
assert.NotContains(t, ids, "pkg/db.go::Connect")
|
|
assert.NotContains(t, ids, "pkg/db.go::Ping")
|
|
}
|
|
|
|
func TestWalkBudgeted_CommunityFilter_KeepsInCommunity(t *testing.T) {
|
|
e := NewEngine(buildTestGraph())
|
|
|
|
// Whole chain in community "a".
|
|
nodeToComm := map[string]string{
|
|
"main.go::main": "a",
|
|
"pkg/server.go::Start": "a",
|
|
"pkg/db.go::Connect": "a",
|
|
"pkg/db.go::Ping": "a",
|
|
}
|
|
|
|
sg := e.WalkBudgeted("main.go::main", WalkOptions{
|
|
EdgeKinds: []graph.EdgeKind{graph.EdgeCalls},
|
|
Direction: "out",
|
|
CommunityID: "a",
|
|
NodeToComm: nodeToComm,
|
|
})
|
|
ids := nodeIDs(sg.Nodes)
|
|
assert.Contains(t, ids, "pkg/server.go::Start")
|
|
assert.Contains(t, ids, "pkg/db.go::Connect")
|
|
assert.Contains(t, ids, "pkg/db.go::Ping")
|
|
}
|
|
|
|
func TestWalkBudgeted_CommunityFilter_StructuralNodePassthrough(t *testing.T) {
|
|
e := NewEngine(buildTestGraph())
|
|
|
|
// Only main + Start carry a membership. Connect / Ping have NO
|
|
// entry — they are treated as membership-less structural nodes and
|
|
// must pass the gate (an absent entry is not exclusion).
|
|
nodeToComm := map[string]string{
|
|
"main.go::main": "a",
|
|
"pkg/server.go::Start": "a",
|
|
}
|
|
|
|
sg := e.WalkBudgeted("main.go::main", WalkOptions{
|
|
EdgeKinds: []graph.EdgeKind{graph.EdgeCalls},
|
|
Direction: "out",
|
|
CommunityID: "a",
|
|
NodeToComm: nodeToComm,
|
|
})
|
|
ids := nodeIDs(sg.Nodes)
|
|
assert.Contains(t, ids, "pkg/server.go::Start")
|
|
// Connect + Ping have no membership -> not excluded.
|
|
assert.Contains(t, ids, "pkg/db.go::Connect")
|
|
assert.Contains(t, ids, "pkg/db.go::Ping")
|
|
}
|
|
|
|
func TestWalkBudgeted_CommunityFilter_NilMapNoOp(t *testing.T) {
|
|
e := NewEngine(buildTestGraph())
|
|
|
|
// CommunityID set but NodeToComm nil — the filter must no-op (the
|
|
// production wiring passes nil when analysis hasn't run).
|
|
sg := e.WalkBudgeted("main.go::main", WalkOptions{
|
|
EdgeKinds: []graph.EdgeKind{graph.EdgeCalls},
|
|
Direction: "out",
|
|
CommunityID: "a",
|
|
NodeToComm: nil,
|
|
})
|
|
ids := nodeIDs(sg.Nodes)
|
|
assert.Contains(t, ids, "pkg/server.go::Start")
|
|
assert.Contains(t, ids, "pkg/db.go::Connect")
|
|
assert.Contains(t, ids, "pkg/db.go::Ping")
|
|
}
|
|
|
|
func TestWalkBudgeted_CommunityFilter_EmptyIDNoOp(t *testing.T) {
|
|
e := NewEngine(buildTestGraph())
|
|
|
|
// Empty CommunityID disables the gate even when NodeToComm is set.
|
|
sg := e.WalkBudgeted("main.go::main", WalkOptions{
|
|
EdgeKinds: []graph.EdgeKind{graph.EdgeCalls},
|
|
Direction: "out",
|
|
CommunityID: "",
|
|
NodeToComm: map[string]string{"pkg/db.go::Connect": "b"},
|
|
})
|
|
assert.Contains(t, nodeIDs(sg.Nodes), "pkg/db.go::Connect")
|
|
}
|