func (s *S) TestCloseReleasesWatches(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) _, err := conn.Create("/test", "one", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) _, _, watch, err := conn.GetW("/test") c.Assert(err, IsNil) c.Assert(zk.CountPendingWatches(), Equals, 2) conn.Close() c.Assert(zk.CountPendingWatches(), Equals, 0) select { case _, ok := <-watch: c.Assert(ok, Equals, false) case <-time.After(3e9): c.Fatal("Watch didn't fire") } }
func (s *S) TestExistsAndWatch(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) stat, watch, err := conn.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Check(zk.CountPendingWatches(), Equals, 2) select { case <-watch: c.Fatal("Watch fired") default: } _, err = conn.Create("/test", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, zk.EVENT_CREATED) c.Assert(event.Path, Equals, "/test") c.Check(zk.CountPendingWatches(), Equals, 1) stat, watch, err = conn.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, NotNil) c.Assert(stat.NumChildren(), Equals, 0) c.Check(zk.CountPendingWatches(), Equals, 2) }
func (s *S) TestWatchOnReconnection(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, session := s.init(c) event := <-session c.Assert(event.Type, Equals, zk.EVENT_SESSION) c.Assert(event.State, Equals, zk.STATE_CONNECTED) c.Check(zk.CountPendingWatches(), Equals, 1) stat, watch, err := conn.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Check(zk.CountPendingWatches(), Equals, 2) s.zkServer.Stop() time.Sleep(2e9) s.zkServer.Start() // The session channel should receive the reconnection notification. select { case event := <-session: c.Assert(event.State, Equals, zk.STATE_CONNECTING) case <-time.After(3e9): c.Fatal("Session watch didn't fire") } select { case event := <-session: c.Assert(event.State, Equals, zk.STATE_CONNECTED) case <-time.After(3e9): c.Fatal("Session watch didn't fire") } // The watch channel should receive just the connecting notification. select { case event := <-watch: c.Assert(event.State, Equals, zk.STATE_CONNECTING) case <-time.After(3e9): c.Fatal("Watch didn't fire") } select { case _, ok := <-watch: c.Assert(ok, Equals, false) case <-time.After(3e9): c.Fatal("Watch wasn't closed") } c.Check(zk.CountPendingWatches(), Equals, 1) }
func (s *S) TestSessionWatches(c *C) { c.Assert(zk.CountPendingWatches(), Equals, 0) zk1, watch1 := s.init(c) zk2, watch2 := s.init(c) zk3, watch3 := s.init(c) c.Assert(zk.CountPendingWatches(), Equals, 3) event1 := <-watch1 c.Assert(event1.Type, Equals, zk.EVENT_SESSION) c.Assert(event1.State, Equals, zk.STATE_CONNECTED) c.Assert(zk.CountPendingWatches(), Equals, 3) event2 := <-watch2 c.Assert(event2.Type, Equals, zk.EVENT_SESSION) c.Assert(event2.State, Equals, zk.STATE_CONNECTED) c.Assert(zk.CountPendingWatches(), Equals, 3) event3 := <-watch3 c.Assert(event3.Type, Equals, zk.EVENT_SESSION) c.Assert(event3.State, Equals, zk.STATE_CONNECTED) c.Assert(zk.CountPendingWatches(), Equals, 3) zk1.Close() c.Assert(zk.CountPendingWatches(), Equals, 2) zk2.Close() c.Assert(zk.CountPendingWatches(), Equals, 1) zk3.Close() c.Assert(zk.CountPendingWatches(), Equals, 0) }
func (s *S) TestWatchOnSessionExpiration(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, session := s.init(c) event := <-session c.Assert(event.Type, Equals, zk.EVENT_SESSION) c.Assert(event.State, Equals, zk.STATE_CONNECTED) c.Check(zk.CountPendingWatches(), Equals, 1) stat, watch, err := conn.ExistsW("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Check(zk.CountPendingWatches(), Equals, 2) // Use expiration trick described in the FAQ. clientId := conn.ClientId() zk2, session2, err := zk.Redial(s.zkAddr, 5e9, clientId) for event := range session2 { c.Log("Event from overlapping session: ", event) if event.State == zk.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 == zk.STATE_EXPIRED_SESSION { break } } select { case event := <-watch: c.Assert(event.State, Equals, zk.STATE_CONNECTING) case <-time.After(3e9): c.Fatal("Watch event didn't fire") } event = <-watch c.Assert(event.Type, Equals, zk.EVENT_CLOSED) c.Assert(event.State, Equals, zk.STATE_CLOSED) c.Check(zk.CountPendingWatches(), Equals, 1) }
func (s *S) TestGetAndWatchWithError(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) _, _, watch, err := conn.GetW("/test") c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZNONODE), Equals, true, Commentf("%v", err)) c.Assert(watch, IsNil) c.Check(zk.CountPendingWatches(), Equals, 1) }
func (s *S) TestExistsAndWatchWithError(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) stat, watch, err := conn.ExistsW("///") c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZBADARGUMENTS), Equals, true, Commentf("%v", err)) c.Assert(stat, IsNil) c.Assert(watch, IsNil) c.Check(zk.CountPendingWatches(), Equals, 1) }
func (s *S) TestChildrenAndWatch(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) children, stat, watch, err := conn.ChildrenW("/") c.Assert(err, IsNil) c.Assert(children, DeepEquals, []string{"zookeeper"}) c.Assert(stat.NumChildren(), Equals, 1) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(zk.CountPendingWatches(), Equals, 2) _, err = conn.Create("/test1", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, zk.EVENT_CHILD) c.Assert(event.Path, Equals, "/") c.Check(zk.CountPendingWatches(), Equals, 1) children, stat, watch, err = conn.ChildrenW("/") c.Assert(err, IsNil) c.Assert(stat.NumChildren(), Equals, 2) // The ordering is most likely unstable, so this test must be fixed. c.Assert(children, DeepEquals, []string{"test1", "zookeeper"}) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(zk.CountPendingWatches(), Equals, 2) _, err = conn.Create("/test2", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) event = <-watch c.Assert(event.Type, Equals, zk.EVENT_CHILD) c.Check(zk.CountPendingWatches(), Equals, 1) }
func (s *S) TestGetAndWatch(c *C) { c.Check(zk.CountPendingWatches(), Equals, 0) conn, _ := s.init(c) c.Check(zk.CountPendingWatches(), Equals, 1) _, err := conn.Create("/test", "one", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) data, stat, watch, err := conn.GetW("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "one") c.Assert(stat.Version(), Equals, 0) select { case <-watch: c.Fatal("Watch fired") default: } c.Check(zk.CountPendingWatches(), Equals, 2) _, err = conn.Set("/test", "two", -1) c.Assert(err, IsNil) event := <-watch c.Assert(event.Type, Equals, zk.EVENT_CHANGED) c.Check(zk.CountPendingWatches(), Equals, 1) data, _, watch, err = conn.GetW("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "two") select { case <-watch: c.Fatal("Watch fired") default: } c.Check(zk.CountPendingWatches(), Equals, 2) _, err = conn.Set("/test", "three", -1) c.Assert(err, IsNil) event = <-watch c.Assert(event.Type, Equals, zk.EVENT_CHANGED) c.Check(zk.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([]*zk.Conn, 0) c.Assert(zk.CountPendingWatches(), Equals, 0, Commentf("Test left live watches behind!")) }
func (s *S) SetUpTest(c *C) { c.Assert(zk.CountPendingWatches(), Equals, 0, Commentf("Test got a dirty watch state before running!")) zk.SetLogLevel(logLevel) }