hscontrol/servertest: add policy, route, ephemeral, and content tests
Extend the servertest harness with: - TestClient.Direct() accessor for advanced operations - TestClient.WaitForPeerCount and WaitForCondition helpers - TestHarness.ChangePolicy for ACL policy testing - AssertDERPMapPresent and AssertSelfHasAddresses New test suites: - content_test.go: self node, DERP map, peer properties, user profiles, update history monotonicity, and endpoint update propagation - policy_test.go: default allow-all, explicit policy, policy triggers updates on all nodes, multiple policy changes, multi-user mesh - ephemeral_test.go: ephemeral connect, cleanup after disconnect, mixed ephemeral/regular, reconnect prevents cleanup - routes_test.go: addresses in AllowedIPs, route advertise and approve, advertised routes via hostinfo, CGNAT range validation Also fix node_departs test to use WaitForCondition instead of assert.Eventually, and convert concurrent_join_and_leave to interleaved_join_and_leave with grace-period-tolerant assertions.
This commit is contained in:
parent
ca7362e9aa
commit
f87b08676d
9 changed files with 932 additions and 30 deletions
|
|
@ -419,6 +419,61 @@ func (c *TestClient) SelfName() string {
|
|||
return nm.SelfNode.Hostinfo().Hostname()
|
||||
}
|
||||
|
||||
// WaitForPeerCount blocks until the client sees exactly n peers.
|
||||
func (c *TestClient) WaitForPeerCount(tb testing.TB, n int, timeout time.Duration) {
|
||||
tb.Helper()
|
||||
|
||||
deadline := time.After(timeout)
|
||||
|
||||
for {
|
||||
if nm := c.Netmap(); nm != nil && len(nm.Peers) == n {
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-c.updates:
|
||||
// Check again.
|
||||
case <-deadline:
|
||||
nm := c.Netmap()
|
||||
|
||||
got := 0
|
||||
if nm != nil {
|
||||
got = len(nm.Peers)
|
||||
}
|
||||
|
||||
tb.Fatalf("servertest: WaitForPeerCount(%s, %d): timeout after %v (got %d peers)", c.Name, n, timeout, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WaitForCondition blocks until condFn returns true on the latest
|
||||
// netmap, or until timeout expires. This is useful for waiting for
|
||||
// specific state changes (e.g., peer going offline).
|
||||
func (c *TestClient) WaitForCondition(tb testing.TB, desc string, timeout time.Duration, condFn func(*netmap.NetworkMap) bool) {
|
||||
tb.Helper()
|
||||
|
||||
deadline := time.After(timeout)
|
||||
|
||||
for {
|
||||
if nm := c.Netmap(); nm != nil && condFn(nm) {
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-c.updates:
|
||||
// Check again.
|
||||
case <-deadline:
|
||||
tb.Fatalf("servertest: WaitForCondition(%s, %q): timeout after %v", c.Name, desc, timeout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Direct returns the underlying controlclient.Direct for
|
||||
// advanced operations like SetHostinfo or SendUpdate.
|
||||
func (c *TestClient) Direct() *controlclient.Direct {
|
||||
return c.direct
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer for debug output.
|
||||
func (c *TestClient) String() string {
|
||||
nm := c.Netmap()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue