func doTestWatchNetworks(t *testing.T, sm subnet.Manager, serverRegistry *subnet.MockSubnetRegistry) { ctx, cancel := context.WithCancel(context.Background()) wg := sync.WaitGroup{} wg.Add(1) defer func() { cancel() wg.Wait() }() events := make(chan []subnet.Event) go func() { subnet.WatchNetworks(ctx, sm, events) wg.Done() }() // skip over the initial snapshot <-events expectedNetname := "foobar" config := fmt.Sprintf(`{"Network": %q}`, expectedNetwork) err := serverRegistry.CreateNetwork(ctx, expectedNetname, config) if err != nil { t.Errorf("create network failed: %v", err) } evtBatch := <-events if len(evtBatch) != 1 { t.Fatalf("WatchNetworks create produced wrong sized event batch") } evt := evtBatch[0] if evt.Type != subnet.EventAdded { t.Fatalf("WatchNetworks create produced wrong event type") } if evt.Network != expectedNetname { t.Errorf("WatchNetwork create produced wrong network: expected %s, got %s", expectedNetname, evt.Network) } err = serverRegistry.DeleteNetwork(ctx, expectedNetname) if err != nil { t.Errorf("delete network failed: %v", err) } evtBatch = <-events if len(evtBatch) != 1 { t.Fatalf("WatchNetworks delete produced wrong sized event batch") } evt = evtBatch[0] if evt.Type != subnet.EventRemoved { t.Fatalf("WatchNetworks delete produced wrong event type") } if evt.Network != expectedNetname { t.Errorf("WatchNetwork delete produced wrong network: expected %s, got %s", expectedNetname, evt.Network) } }
func (m *Manager) watchNetworks() { wg := sync.WaitGroup{} defer wg.Wait() events := make(chan []subnet.Event) wg.Add(1) go func() { subnet.WatchNetworks(m.ctx, m.sm, events) wg.Done() }() // skip over the initial snapshot <-events for { select { case <-m.ctx.Done(): return case evtBatch := <-events: for _, e := range evtBatch { netname := e.Network if !m.isNetAllowed(netname) { log.Infof("Network %q is not allowed", netname) continue } switch e.Type { case subnet.EventAdded: n := NewNetwork(m.ctx, m.sm, m.bm, netname, m.ipMasq) if err := m.addNetwork(n); err != nil { log.Infof("Network %q: %v", netname, err) continue } log.Infof("Network added: %v", netname) wg.Add(1) go func() { m.runNetwork(n) wg.Done() }() case subnet.EventRemoved: log.Infof("Network removed: %v", netname) n, ok := m.getNetwork(netname) if !ok { log.Warningf("Network %v unknown; ignoring EventRemoved", netname) continue } n.Cancel() } } } } }
func TestWatchNetworks(t *testing.T) { f := newFixture(t) defer f.Close() events := make(chan []subnet.Event) f.wg.Add(1) go func() { subnet.WatchNetworks(f.ctx, f.sm, events) f.wg.Done() }() // skip over the initial snapshot <-events expectedNetname := "foobar" config := fmt.Sprintf(`{"Network": %q}`, expectedNetwork) err := f.registry.CreateNetwork(f.ctx, expectedNetname, config) if err != nil { t.Errorf("create network failed: %v", err) } evtBatch := <-events if len(evtBatch) != 1 { t.Fatalf("WatchNetworks create produced wrong sized event batch") } evt := evtBatch[0] if evt.Type != subnet.EventAdded { t.Fatalf("WatchNetworks create produced wrong event type") } if evt.Network != expectedNetname { t.Errorf("WatchNetwork create produced wrong network: expected %s, got %s", expectedNetname, evt.Network) } err = f.registry.DeleteNetwork(f.ctx, expectedNetname) if err != nil { t.Errorf("delete network failed: %v", err) } evtBatch = <-events if len(evtBatch) != 1 { t.Fatalf("WatchNetworks delete produced wrong sized event batch") } evt = evtBatch[0] if evt.Type != subnet.EventRemoved { t.Fatalf("WatchNetworks delete produced wrong event type") } if evt.Network != expectedNetname { t.Errorf("WatchNetwork delete produced wrong network: expected %s, got %s", expectedNetname, evt.Network) } }
func (m *Manager) watchNetworks() { wg := sync.WaitGroup{} events := make(chan []subnet.Event) wg.Add(1) go func() { subnet.WatchNetworks(m.ctx, m.sm, events) wg.Done() }() // skip over the initial snapshot <-events for { select { case <-m.ctx.Done(): break case evtBatch := <-events: for _, e := range evtBatch { netname := e.Network if !m.isNetAllowed(netname) { continue } switch e.Type { case subnet.EventAdded: if _, ok := m.networks[netname]; ok { continue } net := NewNetwork(m.ctx, m.sm, netname, m.ipMasq) m.networks[netname] = net wg.Add(1) go func() { m.RunNetwork(net) wg.Done() }() case subnet.EventRemoved: net, ok := m.networks[netname] if !ok { log.Warningf("Network %v unknown; ignoring EventRemoved", netname) continue } net.Cancel() delete(m.networks, netname) } } } } wg.Wait() }