func TestBufferedSub(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) defer l.Unsubscribe(s) bs := events.NewBufferedSubscription(s, 10*events.BufferSize) go func() { for i := 0; i < 10*events.BufferSize; i++ { l.Log(events.DeviceConnected, fmt.Sprintf("event-%d", i)) if i%30 == 0 { // Give the buffer routine time to pick up the events time.Sleep(20 * time.Millisecond) } } }() recv := 0 for recv < 10*events.BufferSize { evs := bs.Since(recv, nil) for _, ev := range evs { if ev.ID != recv+1 { t.Fatalf("Incorrect ID; %d != %d", ev.ID, recv+1) } recv = ev.ID } } }
func TestSubscriber(t *testing.T) { l := events.NewLogger() s := l.Subscribe(0) if s == nil { t.Fatal("Unexpected nil Subscription") } }
func TestIDs(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) defer l.Unsubscribe(s) l.Log(events.DeviceConnected, "foo") _ = l.Subscribe(events.AllEvents) l.Log(events.DeviceConnected, "bar") ev, err := s.Poll(timeout) if err != nil { t.Fatal("Unexpected error:", err) } if ev.Data.(string) != "foo" { t.Fatal("Incorrect event:", ev) } id := ev.ID ev, err = s.Poll(timeout) if err != nil { t.Fatal("Unexpected error:", err) } if ev.Data.(string) != "bar" { t.Fatal("Incorrect event:", ev) } if ev.ID != id+1 { t.Fatalf("ID not incremented (%d != %d)", ev.ID, id+1) } }
func TestSinceUsesSubscriptionId(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.DeviceConnected) defer l.Unsubscribe(s) bs := events.NewBufferedSubscription(s, 10*events.BufferSize) l.Log(events.DeviceConnected, "a") // SubscriptionID = 1 l.Log(events.DeviceDisconnected, "b") l.Log(events.DeviceDisconnected, "c") l.Log(events.DeviceConnected, "d") // SubscriptionID = 2 // We need to loop for the events, as they may not all have been // delivered to the buffered subscription when we get here. t0 := time.Now() for time.Since(t0) < time.Second { events := bs.Since(0, nil) if len(events) == 2 { break } if len(events) > 2 { t.Fatal("Incorrect number of events:", len(events)) } } events := bs.Since(1, nil) if len(events) != 1 { t.Fatal("Incorrect number of events:", len(events)) } }
func TestTimeout(t *testing.T) { l := events.NewLogger() s := l.Subscribe(0) _, err := s.Poll(timeout) if err != events.ErrTimeout { t.Fatal("Unexpected non-Timeout error:", err) } }
func TestEventAfterSubscribeIgnoreMask(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.DeviceDisconnected) l.Log(events.DeviceConnected, "foo") _, err := s.Poll(timeout) if err != events.ErrTimeout { t.Fatal("Unexpected non-Timeout error:", err) } }
func TestEventBeforeSubscribe(t *testing.T) { l := events.NewLogger() l.Log(events.DeviceConnected, "foo") s := l.Subscribe(0) _, err := s.Poll(timeout) if err != events.ErrTimeout { t.Fatal("Unexpected non-Timeout error:", err) } }
func TestBufferOverflow(t *testing.T) { l := events.NewLogger() _ = l.Subscribe(events.AllEvents) t0 := time.Now() for i := 0; i < events.BufferSize*2; i++ { l.Log(events.DeviceConnected, "foo") } if time.Since(t0) > timeout { t.Fatalf("Logging took too long") } }
func BenchmarkBufferedSub(b *testing.B) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) defer l.Unsubscribe(s) bufferSize := events.BufferSize bs := events.NewBufferedSubscription(s, bufferSize) // The coord channel paces the sender according to the receiver, // ensuring that no events are dropped. The benchmark measures sending + // receiving + synchronization overhead. coord := make(chan struct{}, bufferSize) for i := 0; i < bufferSize-1; i++ { coord <- struct{}{} } // Receive the events done := make(chan struct{}) go func() { defer close(done) recv := 0 var evs []events.Event for i := 0; i < b.N; { evs = bs.Since(recv, evs[:0]) for _, ev := range evs { if ev.GlobalID != recv+1 { b.Fatal("skipped event", ev.GlobalID, recv) } recv = ev.GlobalID coord <- struct{}{} } i += len(evs) } }() // Send the events eventData := map[string]string{ "foo": "bar", "other": "data", "and": "something else", } for i := 0; i < b.N; i++ { l.Log(events.DeviceConnected, eventData) <-coord } <-done b.ReportAllocs() }
func TestUnsubscribe(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) l.Log(events.DeviceConnected, "foo") _, err := s.Poll(timeout) if err != nil { t.Fatal("Unexpected error:", err) } l.Unsubscribe(s) l.Log(events.DeviceConnected, "foo") _, err = s.Poll(timeout) if err != events.ErrClosed { t.Fatal("Unexpected non-Closed error:", err) } }
func TestSubscriptionIDs(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.DeviceConnected) defer l.Unsubscribe(s) l.Log(events.DeviceDisconnected, "a") l.Log(events.DeviceConnected, "b") l.Log(events.DeviceConnected, "c") l.Log(events.DeviceDisconnected, "d") ev, err := s.Poll(timeout) if err != nil { t.Fatal("Unexpected error:", err) } if ev.GlobalID != 2 { t.Fatal("Incorrect GlobalID:", ev.GlobalID) } if ev.SubscriptionID != 1 { t.Fatal("Incorrect SubscriptionID:", ev.SubscriptionID) } ev, err = s.Poll(timeout) if err != nil { t.Fatal("Unexpected error:", err) } if ev.GlobalID != 3 { t.Fatal("Incorrect GlobalID:", ev.GlobalID) } if ev.SubscriptionID != 2 { t.Fatal("Incorrect SubscriptionID:", ev.SubscriptionID) } ev, err = s.Poll(timeout) if err != events.ErrTimeout { t.Fatal("Unexpected error:", err) } }
func TestEventAfterSubscribe(t *testing.T) { l := events.NewLogger() s := l.Subscribe(events.AllEvents) l.Log(events.DeviceConnected, "foo") ev, err := s.Poll(timeout) if err != nil { t.Fatal("Unexpected error:", err) } if ev.Type != events.DeviceConnected { t.Error("Incorrect event type", ev.Type) } switch v := ev.Data.(type) { case string: if v != "foo" { t.Error("Incorrect Data string", v) } default: t.Errorf("Incorrect Data type %#v", v) } }
func TestNewLogger(t *testing.T) { l := events.NewLogger() if l == nil { t.Fatal("Unexpected nil Logger") } }