mirror of
https://github.com/therootcompany/golib.git
synced 2026-11-04 06:55:00 +00:00
83 lines
2.4 KiB
Go
83 lines
2.4 KiB
Go
package ippolicy
|
|
|
|
import (
|
|
"net/netip"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/therootcompany/golib/net/iplist"
|
|
)
|
|
|
|
// TestPolicyStartPushesSourceUpdatesIntoDerivedSets confirms that when a
|
|
// source IP list changes and the Policy's background loop runs, the derived
|
|
// DomainSet is updated without an explicit Policy.Load call. This is the gap
|
|
// flagged in the handoff: sources refresh on their own tickers but derived
|
|
// sets never saw the new entries.
|
|
func TestPolicyStartPushesSourceUpdatesIntoDerivedSets(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "allowed.tsv")
|
|
if err := os.WriteFile(path, []byte("192.0.2.1\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Short refresh interval so the source re-reads the file promptly.
|
|
whitelist, err := iplist.NewIPList(t.Context(), iplist.IPListConfig{
|
|
Source: path,
|
|
CacheDir: t.TempDir(),
|
|
RefreshInterval: 20 * time.Millisecond,
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
p := New(t.Context(), Config{Whitelist: whitelist})
|
|
defer p.Stop()
|
|
|
|
if p.Evaluate(netip.MustParseAddr("192.0.2.1")) != Whitelisted {
|
|
t.Fatal("initial whitelist did not match 192.0.2.1")
|
|
}
|
|
|
|
// Start the source ticker (re-reads file) and the Policy loop (pushes
|
|
// entries into the derived set).
|
|
whitelist.Start(t.Context(), 20*time.Millisecond)
|
|
p.Start(t.Context(), 20*time.Millisecond)
|
|
|
|
// Change the source: drop 192.0.2.1, add 192.0.2.2.
|
|
if err := os.WriteFile(path, []byte("192.0.2.2\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Within a few intervals the derived set must reflect the new entry.
|
|
deadline := time.Now().Add(2 * time.Second)
|
|
for time.Now().Before(deadline) {
|
|
if p.Evaluate(netip.MustParseAddr("192.0.2.2")) == Whitelisted {
|
|
break
|
|
}
|
|
time.Sleep(20 * time.Millisecond)
|
|
}
|
|
if p.Evaluate(netip.MustParseAddr("192.0.2.2")) != Whitelisted {
|
|
t.Fatal("derived set was not updated by Policy.Start loop (192.0.2.2 missing)")
|
|
}
|
|
}
|
|
|
|
// TestPolicyStartIsIdempotent confirms Start can be called multiple times
|
|
// safely (only one loop starts).
|
|
func TestPolicyStartIsIdempotent(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "allowed.tsv")
|
|
if err := os.WriteFile(path, []byte("192.0.2.1\n"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
whitelist, err := iplist.NewIPList(t.Context(), iplist.IPListConfig{
|
|
Source: path,
|
|
CacheDir: t.TempDir(),
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
p := New(t.Context(), Config{Whitelist: whitelist})
|
|
defer p.Stop()
|
|
for range 3 {
|
|
p.Start(t.Context(), time.Hour)
|
|
}
|
|
}
|