sentinel_test.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package redis_test
  2. import (
  3. "github.com/go-redis/redis"
  4. . "github.com/onsi/ginkgo"
  5. . "github.com/onsi/gomega"
  6. )
  7. var _ = Describe("Sentinel", func() {
  8. var client *redis.Client
  9. BeforeEach(func() {
  10. client = redis.NewFailoverClient(&redis.FailoverOptions{
  11. MasterName: sentinelName,
  12. SentinelAddrs: []string{":" + sentinelPort},
  13. })
  14. Expect(client.FlushDB().Err()).NotTo(HaveOccurred())
  15. })
  16. AfterEach(func() {
  17. Expect(client.Close()).NotTo(HaveOccurred())
  18. })
  19. It("should facilitate failover", func() {
  20. // Set value on master.
  21. err := client.Set("foo", "master", 0).Err()
  22. Expect(err).NotTo(HaveOccurred())
  23. // Verify.
  24. val, err := sentinelMaster.Get("foo").Result()
  25. Expect(err).NotTo(HaveOccurred())
  26. Expect(val).To(Equal("master"))
  27. // Create subscription.
  28. ch := client.Subscribe("foo").Channel()
  29. // Wait until replicated.
  30. Eventually(func() string {
  31. return sentinelSlave1.Get("foo").Val()
  32. }, "1s", "100ms").Should(Equal("master"))
  33. Eventually(func() string {
  34. return sentinelSlave2.Get("foo").Val()
  35. }, "1s", "100ms").Should(Equal("master"))
  36. // Wait until slaves are picked up by sentinel.
  37. Eventually(func() string {
  38. return sentinel.Info().Val()
  39. }, "10s", "100ms").Should(ContainSubstring("slaves=2"))
  40. // Kill master.
  41. sentinelMaster.Shutdown()
  42. Eventually(func() error {
  43. return sentinelMaster.Ping().Err()
  44. }, "5s", "100ms").Should(HaveOccurred())
  45. // Wait for Redis sentinel to elect new master.
  46. Eventually(func() string {
  47. return sentinelSlave1.Info().Val() + sentinelSlave2.Info().Val()
  48. }, "30s", "1s").Should(ContainSubstring("role:master"))
  49. // Check that client picked up new master.
  50. Eventually(func() error {
  51. return client.Get("foo").Err()
  52. }, "5s", "100ms").ShouldNot(HaveOccurred())
  53. // Publish message to check if subscription is renewed.
  54. err = client.Publish("foo", "hello").Err()
  55. Expect(err).NotTo(HaveOccurred())
  56. var msg *redis.Message
  57. Eventually(ch, "5s").Should(Receive(&msg))
  58. Expect(msg.Channel).To(Equal("foo"))
  59. Expect(msg.Payload).To(Equal("hello"))
  60. })
  61. It("supports DB selection", func() {
  62. Expect(client.Close()).NotTo(HaveOccurred())
  63. client = redis.NewFailoverClient(&redis.FailoverOptions{
  64. MasterName: sentinelName,
  65. SentinelAddrs: []string{":" + sentinelPort},
  66. DB: 1,
  67. })
  68. err := client.Ping().Err()
  69. Expect(err).NotTo(HaveOccurred())
  70. })
  71. })