integration: harden ACL test ergonomics
tsic.Curl returned ("", nil) when curl exited 0 with a zero-byte body —
the usual signature of a mid-stream reset — so EventuallyWithT could
not retry. Return an error on empty body instead.
Replace the 56 inline curl + assert.Len(13) blocks with
assertCurlDockerHostname so the empty-body fix benefits every callsite
without further touch-ups.
Gate ACL waits on actual filter visibility: snapshotClientFilters +
waitForClientFilterChange ensure the new PacketFilter has reached the
client before assertions fire; SyncOption + WithPreBarrier feeds a
server-side policy-loaded check into WaitForTailscaleSyncPerUser.
Move advertise-routes mutation out of EventuallyWithT in route_test
(cmd/hi/README forbids retrying state-mutating calls). Pace the
TestNodeOnlineStatus outer loop with a Ticker, not a Sleep.
This commit is contained in:
parent
78fd6efb38
commit
dfcc96d808
6 changed files with 321 additions and 300 deletions
|
|
@ -784,10 +784,42 @@ func (s *Scenario) WaitForTailscaleSync() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// WaitForTailscaleSyncPerUser blocks execution until each TailscaleClient has the expected
|
||||
// number of peers for its user. This is useful for policies like autogroup:self where nodes
|
||||
// only see same-user peers, not all nodes in the network.
|
||||
func (s *Scenario) WaitForTailscaleSyncPerUser(timeout, retryInterval time.Duration) error {
|
||||
// SyncOption configures WaitForTailscaleSyncPerUser.
|
||||
type SyncOption func(*syncOptions)
|
||||
|
||||
type syncOptions struct {
|
||||
preBarrier func(context.Context) error
|
||||
}
|
||||
|
||||
// WithPreBarrier runs a precondition check before per-user peer-count
|
||||
// waits begin, sharing the outer timeout via context. Use to gate on
|
||||
// a server-side signal (e.g. policy compile) that the peer-count
|
||||
// alone cannot observe.
|
||||
func WithPreBarrier(barrier func(context.Context) error) SyncOption {
|
||||
return func(o *syncOptions) { o.preBarrier = barrier }
|
||||
}
|
||||
|
||||
// WaitForTailscaleSyncPerUser blocks until each TailscaleClient has
|
||||
// the expected per-user peer count (necessary for policies like
|
||||
// autogroup:self where cross-user peers are invisible).
|
||||
func (s *Scenario) WaitForTailscaleSyncPerUser(timeout, retryInterval time.Duration, opts ...SyncOption) error {
|
||||
options := syncOptions{}
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
if options.preBarrier != nil {
|
||||
barrierCtx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
|
||||
err := options.preBarrier(barrierCtx)
|
||||
|
||||
cancel()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("pre-barrier: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var allErrors []error
|
||||
|
||||
for _, user := range s.users {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue