func (s *S) TestExistsAndWatch(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, _ := s.init(c) c.Check(gozk.CountPendingWatches(), Equals, 1) stat, watch, err := zk.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Check(gozk.CountPendingWatches(), Equals, 2) select { case <-watch: c.Fatal("Watch fired") default: } _, err = zk.Create("/test", "", gozk.EPHEMERAL, gozk.WorldACL(gozk.PERM_ALL)) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, gozk.EVENT_CREATED) c.Assert(event.Path, Equals, "/test") c.Check(gozk.CountPendingWatches(), Equals, 1) stat, watch, err = zk.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, NotNil) c.Assert(stat.NumChildren(), Equals, int32(0)) c.Check(gozk.CountPendingWatches(), Equals, 2) }
func (s *S) TestWatchOnReconnection(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, session := s.init(c) event := <-session c.Assert(event.Type, Equals, gozk.EVENT_SESSION) c.Assert(event.State, Equals, gozk.STATE_CONNECTED) c.Check(gozk.CountPendingWatches(), Equals, 1) stat, watch, err := zk.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Check(gozk.CountPendingWatches(), Equals, 2) s.StopZK() time.Sleep(2e9) s.StartZK() // The session channel should receive the reconnection notification, select { case event := <-session: c.Assert(event.State, Equals, gozk.STATE_CONNECTING) case <-time.After(3e9): c.Fatal("Session watch didn't fire") } select { case event := <-session: c.Assert(event.State, Equals, gozk.STATE_CONNECTED) case <-time.After(3e9): c.Fatal("Session watch didn't fire") } // The watch channel should not, since it's not affected. select { case event := <-watch: c.Fatalf("Exists watch fired: %s", event) default: } // And it should still work. _, err = zk.Create("/test", "", gozk.EPHEMERAL, gozk.WorldACL(gozk.PERM_ALL)) c.Assert(err, IsNil) event = <-watch c.Assert(event.Type, Equals, gozk.EVENT_CREATED) c.Assert(event.Path, Equals, "/test") c.Check(gozk.CountPendingWatches(), Equals, 1) }
func (s *S) TestWatchOnSessionExpiration(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, session := s.init(c) event := <-session c.Assert(event.Type, Equals, gozk.EVENT_SESSION) c.Assert(event.State, Equals, gozk.STATE_CONNECTED) c.Check(gozk.CountPendingWatches(), Equals, 1) stat, watch, err := zk.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Check(gozk.CountPendingWatches(), Equals, 2) // Use expiration trick described in the FAQ. clientId := zk.ClientId() zk2, session2, err := gozk.ReInit(s.zkAddr, 5e9, clientId) for event := range session2 { c.Log("Event from overlapping session: ", event) if event.State == gozk.STATE_CONNECTED { // Wait for zk to process the connection. // Not reliable without this. :-( time.Sleep(1e9) zk2.Close() } } for event := range session { c.Log("Event from primary session: ", event) if event.State == gozk.STATE_EXPIRED_SESSION { break } } select { case event := <-watch: c.Assert(event.State, Equals, gozk.STATE_EXPIRED_SESSION) case <-time.After(3e9): c.Fatal("Watch event didn't fire") } event = <-watch c.Assert(event.Type, Equals, gozk.EVENT_CLOSED) c.Assert(event.State, Equals, gozk.STATE_CLOSED) c.Check(gozk.CountPendingWatches(), Equals, 1) }
func (s *S) TestSessionWatches(c *C) { c.Assert(gozk.CountPendingWatches(), Equals, 0) zk1, watch1 := s.init(c) zk2, watch2 := s.init(c) zk3, watch3 := s.init(c) c.Assert(gozk.CountPendingWatches(), Equals, 3) event1 := <-watch1 c.Assert(event1.Type, Equals, gozk.EVENT_SESSION) c.Assert(event1.State, Equals, gozk.STATE_CONNECTED) c.Assert(gozk.CountPendingWatches(), Equals, 3) event2 := <-watch2 c.Assert(event2.Type, Equals, gozk.EVENT_SESSION) c.Assert(event2.State, Equals, gozk.STATE_CONNECTED) c.Assert(gozk.CountPendingWatches(), Equals, 3) event3 := <-watch3 c.Assert(event3.Type, Equals, gozk.EVENT_SESSION) c.Assert(event3.State, Equals, gozk.STATE_CONNECTED) c.Assert(gozk.CountPendingWatches(), Equals, 3) zk1.Close() c.Assert(gozk.CountPendingWatches(), Equals, 2) zk2.Close() c.Assert(gozk.CountPendingWatches(), Equals, 1) zk3.Close() c.Assert(gozk.CountPendingWatches(), Equals, 0) }
func (s *S) TestGetAndWatchWithError(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, _ := s.init(c) c.Check(gozk.CountPendingWatches(), Equals, 1) _, _, watch, err := zk.GetW("/test") c.Assert(err, NotNil) c.Assert(err.Code(), Equals, gozk.ZNONODE) c.Assert(watch, IsNil) c.Check(gozk.CountPendingWatches(), Equals, 1) }
func (s *S) TestExistsAndWatchWithError(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, _ := s.init(c) c.Check(gozk.CountPendingWatches(), Equals, 1) stat, watch, err := zk.ExistsW("///") c.Assert(err, NotNil) c.Assert(err.Code(), Equals, gozk.ZBADARGUMENTS) c.Assert(stat, IsNil) c.Assert(watch, IsNil) c.Check(gozk.CountPendingWatches(), Equals, 1) }
func (s *S) TestCloseReleasesWatches(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, _ := s.init(c) c.Check(gozk.CountPendingWatches(), Equals, 1) _, err := zk.Create("/test", "one", gozk.EPHEMERAL, gozk.WorldACL(gozk.PERM_ALL)) c.Assert(err, IsNil) _, _, _, err = zk.GetW("/test") c.Assert(err, IsNil) c.Assert(gozk.CountPendingWatches(), Equals, 2) zk.Close() c.Assert(gozk.CountPendingWatches(), Equals, 0) }
func (s *S) TestChildrenAndWatch(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, _ := s.init(c) c.Check(gozk.CountPendingWatches(), Equals, 1) children, stat, watch, err := zk.ChildrenW("/") c.Assert(err, IsNil) c.Assert(children, Equals, []string{"zookeeper"}) c.Assert(stat.NumChildren(), Equals, int32(1)) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(gozk.CountPendingWatches(), Equals, 2) _, err = zk.Create("/test1", "", gozk.EPHEMERAL, gozk.WorldACL(gozk.PERM_ALL)) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, gozk.EVENT_CHILD) c.Assert(event.Path, Equals, "/") c.Check(gozk.CountPendingWatches(), Equals, 1) children, stat, watch, err = zk.ChildrenW("/") c.Assert(err, IsNil) c.Assert(stat.NumChildren(), Equals, int32(2)) // The ordering is most likely unstable, so this test must be fixed. c.Assert(children, Equals, []string{"test1", "zookeeper"}) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(gozk.CountPendingWatches(), Equals, 2) _, err = zk.Create("/test2", "", gozk.EPHEMERAL, gozk.WorldACL(gozk.PERM_ALL)) c.Assert(err, IsNil) event = <-watch c.Assert(event.Type, Equals, gozk.EVENT_CHILD) c.Check(gozk.CountPendingWatches(), Equals, 1) }
func (s *S) TestGetAndWatch(c *C) { c.Check(gozk.CountPendingWatches(), Equals, 0) zk, _ := s.init(c) c.Check(gozk.CountPendingWatches(), Equals, 1) _, err := zk.Create("/test", "one", gozk.EPHEMERAL, gozk.WorldACL(gozk.PERM_ALL)) c.Assert(err, IsNil) data, stat, watch, err := zk.GetW("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "one") c.Assert(stat.Version(), Equals, int32(0)) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(gozk.CountPendingWatches(), Equals, 2) _, err = zk.Set("/test", "two", -1) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, gozk.EVENT_CHANGED) c.Check(gozk.CountPendingWatches(), Equals, 1) data, _, watch, err = zk.GetW("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "two") select { case <-watch: c.Fatal("Watch fired") default: } c.Check(gozk.CountPendingWatches(), Equals, 2) _, err = zk.Set("/test", "three", -1) c.Assert(err, IsNil) event = <-watch c.Assert(event.Type, Equals, gozk.EVENT_CHANGED) c.Check(gozk.CountPendingWatches(), Equals, 1) }
func (s *S) TearDownTest(c *C) { // Close all handles opened in s.init(). for _, handle := range s.handles { handle.Close() } // Wait for all the goroutines created in s.init() to terminate. for s.liveWatches > 0 { select { case <-s.deadWatches: s.liveWatches -= 1 case <-time.After(5e9): panic("There's a locked watch goroutine :-(") } } // Reset the list of handles. s.handles = make([]*gozk.ZooKeeper, 0) c.Assert(gozk.CountPendingWatches(), Equals, 0, Bug("Test left live watches behind!")) }
func (s *S) SetUpTest(c *C) { c.Assert(gozk.CountPendingWatches(), Equals, 0, Bug("Test got a dirty watch state before running!")) gozk.SetLogLevel(logLevel) }