package peer import ( "net/netip" "testing" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "vppn/m" ) func testPoller(t *testing.T) (*HubPoller, chan m.Peer, chan wgtypes.Key) { t.Helper() addCh := make(chan m.Peer, 8) removeCh := make(chan wgtypes.Key, 8) hp := &HubPoller{ selfVPNIP: netip.MustParseAddr("10.0.0.1"), vpnNet: netip.MustParsePrefix("10.0.0.0/24"), addCh: addCh, removeCh: removeCh, known: make(map[wgtypes.Key]struct{}), } return hp, addCh, removeCh } func stateWith(key wgtypes.Key, peerIP byte) m.NetworkState { return m.NetworkState{Peers: []m.Peer{{ PeerIP: peerIP, WGPubKey: key, }}} } func TestApply_EmitsAddsAndReportsChange(t *testing.T) { hp, addCh, _ := testPoller(t) key := mustKey(t) if changed := hp.apply(stateWith(key, 2)); !changed { t.Fatal("expected changed=true on first apply") } if len(addCh) != 1 { t.Fatalf("expected 1 add, got %d", len(addCh)) } if got := <-addCh; got.WGPubKey != key { t.Errorf("add pubkey mismatch") } } func TestApply_NoChangeWhenKnown(t *testing.T) { hp, addCh, _ := testPoller(t) key := mustKey(t) hp.apply(stateWith(key, 2)) <-addCh // drain initial add if changed := hp.apply(stateWith(key, 2)); changed { t.Fatal("expected changed=false when peer already known") } if len(addCh) != 0 { t.Fatalf("expected no re-emit, got %d adds", len(addCh)) } } func TestApply_RemovesVanishedPeer(t *testing.T) { hp, addCh, removeCh := testPoller(t) key := mustKey(t) hp.apply(stateWith(key, 2)) <-addCh // Empty state: the peer is gone. if changed := hp.apply(m.NetworkState{}); !changed { t.Fatal("expected changed=true when peer vanishes") } if len(removeCh) != 1 { t.Fatalf("expected 1 remove, got %d", len(removeCh)) } if got := <-removeCh; got != key { t.Errorf("remove key mismatch") } }