notify_test.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package storage
  2. import (
  3. "testing"
  4. "time"
  5. )
  6. func TestHubSubscribePublishUnsubscribe(t *testing.T) {
  7. h := NewHub()
  8. a := NewSubscriber(1, 4)
  9. b := NewSubscriber(2, 4)
  10. h.Subscribe(a, "orders")
  11. h.Subscribe(a, "orders") // idempotent
  12. h.Subscribe(b, "other")
  13. h.Publish(Notification{PID: 9, Channel: "orders", Payload: "one"})
  14. select {
  15. case n := <-a.Notifications():
  16. if n.Payload != "one" || n.LSN == 0 {
  17. t.Fatalf("unexpected notification: %+v", n)
  18. }
  19. case <-time.After(time.Second):
  20. t.Fatal("notification not delivered")
  21. }
  22. select {
  23. case n := <-b.Notifications():
  24. t.Fatalf("received notification for another channel: %+v", n)
  25. default:
  26. }
  27. h.Unsubscribe(a, "orders")
  28. h.Publish(Notification{Channel: "orders", Payload: "two"})
  29. select {
  30. case n := <-a.Notifications():
  31. t.Fatalf("received notification after unsubscribe: %+v", n)
  32. case <-time.After(50 * time.Millisecond):
  33. }
  34. }
  35. func TestHubSlowConsumerIsDropped(t *testing.T) {
  36. h := NewHub()
  37. s := NewSubscriber(1, 2)
  38. h.Subscribe(s, "ch")
  39. for i := 0; i < 5; i++ {
  40. h.Publish(Notification{Channel: "ch", Payload: "x"})
  41. }
  42. select {
  43. case <-s.Overflow():
  44. case <-time.After(time.Second):
  45. t.Fatal("overflow signal not closed")
  46. }
  47. if channels := h.Channels(); len(channels) != 0 {
  48. t.Fatalf("slow consumer still subscribed: %v", channels)
  49. }
  50. published, dropped := h.Stats()
  51. if published != 2 || dropped == 0 {
  52. t.Fatalf("published=%d dropped=%d", published, dropped)
  53. }
  54. }
  55. func TestHubsAreIsolated(t *testing.T) {
  56. one := NewHub()
  57. two := NewHub()
  58. s := NewSubscriber(1, 2)
  59. one.Subscribe(s, "ch")
  60. two.Publish(Notification{Channel: "ch", Payload: "nope"})
  61. select {
  62. case n := <-s.Notifications():
  63. t.Fatalf("cross-hub notification: %+v", n)
  64. case <-time.After(50 * time.Millisecond):
  65. }
  66. }
  67. func TestNotificationLSNMonotonicAcrossNotifyOnlyPublishes(t *testing.T) {
  68. h := NewHub()
  69. s := NewSubscriber(1, 8)
  70. h.Subscribe(s, "ch")
  71. h.Publish(Notification{Channel: "ch", Payload: "a"})
  72. h.Publish(Notification{Channel: "ch", Payload: "b", LSN: 1000})
  73. h.Publish(Notification{Channel: "ch", Payload: "c"})
  74. var got []uint64
  75. for i := 0; i < 3; i++ {
  76. got = append(got, (<-s.Notifications()).LSN)
  77. }
  78. if got[0] == 0 || got[1] != 1000 || got[2] <= got[1] {
  79. t.Fatalf("lsns = %v", got)
  80. }
  81. }