// By default, the ZooKeeper C client will hang indefinitely if a // handler is closed twice. We get in the way and prevent it. func (s *S) TestClosingTwiceDoesntHang(c *C) { conn, _ := s.init(c) err := conn.Close() c.Assert(err, IsNil) err = conn.Close() c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZCLOSING), Equals, true, Commentf("%v", err)) }
func (s *S) TestDelete(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) err = conn.Delete("/test", 5) c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZBADVERSION), Equals, true, Commentf("%v", err)) err = conn.Delete("/test", -1) c.Assert(err, IsNil) err = conn.Delete("/test", -1) c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZNONODE), Equals, true, Commentf("%v", err)) }
func (s *S) TestGetAndError(c *C) { conn, _ := s.init(c) data, stat, err := conn.Get("/non-existent") c.Assert(data, Equals, "") c.Assert(stat, IsNil) c.Assert(err, ErrorMatches, `zookeeper: get "/non-existent": no node`) c.Check(zk.IsError(err, zk.ZNONODE), Equals, true, Commentf("%v", err)) }
func (s *S) TestChildren(c *C) { conn, _ := s.init(c) children, stat, err := conn.Children("/") c.Assert(err, IsNil) c.Assert(children, DeepEquals, []string{"zookeeper"}) c.Assert(stat.NumChildren(), Equals, 1) children, stat, err = conn.Children("/non-existent") c.Check(zk.IsError(err, zk.ZNONODE), Equals, true, Commentf("%v", err)) c.Assert(children, IsNil) c.Assert(stat, IsNil) }
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) TestCreateAndGet(c *C) { conn, _ := s.init(c) path, err := conn.Create("/test-", "bababum", zk.SEQUENCE|zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) c.Assert(path, Matches, "/test-[0-9]+") // Check the error condition from Create(). _, err = conn.Create(path, "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Check(zk.IsError(err, zk.ZNODEEXISTS), Equals, true, Commentf("%v", err)) data, _, err := conn.Get(path) c.Assert(err, IsNil) c.Assert(data, Equals, "bababum") }
func (s *S) TestSetACL(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) err = conn.SetACL("/test", zk.WorldACL(zk.PERM_ALL), 5) c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZBADVERSION), Equals, true, Commentf("%v", err)) err = conn.SetACL("/test", zk.WorldACL(zk.PERM_READ), -1) c.Assert(err, IsNil) acl, _, err := conn.ACL("/test") c.Assert(err, IsNil) c.Assert(acl, DeepEquals, zk.WorldACL(zk.PERM_READ)) }
func (s *S) TestAddAuth(c *C) { conn, _ := s.init(c) acl := []zk.ACL{{zk.PERM_READ, "digest", "joe:enQcM3mIEHQx7IrPNStYBc0qfs8="}} _, err := conn.Create("/test", "", zk.EPHEMERAL, acl) c.Assert(err, IsNil) _, _, err = conn.Get("/test") c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZNOAUTH), Equals, true, Commentf("%v", err)) err = conn.AddAuth("digest", "joe:passwd") c.Assert(err, IsNil) _, _, err = conn.Get("/test") c.Assert(err, IsNil) }
func (s *S) TestACL(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) acl, stat, err := conn.ACL("/test") c.Assert(err, IsNil) c.Assert(acl, DeepEquals, zk.WorldACL(zk.PERM_ALL)) c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) acl, stat, err = conn.ACL("/non-existent") c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZNONODE), Equals, true, Commentf("%v", err)) c.Assert(acl, IsNil) c.Assert(stat, IsNil) }
func (s *S) TestRecvTimeoutInitParameter(c *C) { conn, watch, err := zk.Dial(s.zkAddr, 0) c.Assert(err, IsNil) defer conn.Close() select { case <-watch: c.Fatal("Watch fired") default: } for i := 0; i != 1000; i++ { _, _, err := conn.Get("/zookeeper") if err != nil { c.Check(zk.IsError(err, zk.ZOPERATIONTIMEOUT), Equals, true, Commentf("%v", err)) c.SucceedNow() } } c.Fatal("Operation didn't timeout") }
func (s *S) TestRetryChangeFailsCreating(c *C) { conn, _ := s.init(c) // Read only! _, err := conn.Create("/test", "old", zk.EPHEMERAL, zk.WorldACL(zk.PERM_READ)) c.Assert(err, IsNil) var called bool err = conn.RetryChange("/test/sub", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL), func(data string, stat *zk.Stat) (string, error) { called = true return "", nil }) c.Assert(err, NotNil) c.Check(zk.IsError(err, zk.ZNOAUTH), Equals, true, Commentf("%v", err)) stat, err := conn.Exists("/test/sub") c.Assert(err, IsNil) c.Assert(stat, IsNil) c.Assert(called, Equals, true) }
func (s *S) TestConcurrentClose(c *C) { // make sure the server is ready to receive connections. s.init(c) // Close should wait until all outstanding requests have // completed before returning. The idea of this test is that // any request that requests or changes a zookeeper node must // make at least one round trip to the server, so we interpose a // proxy between the client and the server which can stop all // incoming traffic on demand, thus blocking the request until // we want it to unblock. // // We assume that all requests take less than 0.1s to complete, // thus when we wait below, neither of the above goroutines // should complete within the allotted time (the request because // it's waiting for a reply from the server and the close // because it's waiting for the request to complete). If the // locking doesn't work, the Close will return early. If the // proxy blocking doesn't work, the request will return early. // // When we reenable incoming messages from the server, both // goroutines should complete. We can't tell which completes // first, but the fact that the close blocked is sufficient to // tell that the locking is working correctly. for i, f := range requestFuncs { c.Logf("iter %d", i) p := newProxy(c, s.zkAddr) conn, watch, err := zk.Dial(p.addr(), 5e9) c.Assert(err, IsNil) c.Assert((<-watch).Ok(), Equals, true) // sanity check that the connection is actually // up and running. _, err = conn.Exists("/nothing") c.Assert(err, IsNil) p.stopIncoming() reqDone := make(chan bool) closeDone := make(chan bool) go func() { f(conn, "/closetest") reqDone <- true }() go func() { // sleep for long enough for the request to be initiated and the read lock taken. time.Sleep(0.05e9) conn.Close() closeDone <- true }() select { case <-reqDone: c.Fatalf("request %d finished early", i) case <-closeDone: c.Fatalf("request %d close finished early", i) case <-time.After(0.1e9): } p.startIncoming() for reqDone != nil || closeDone != nil { select { case <-reqDone: reqDone = nil case <-closeDone: closeDone = nil case <-time.After(0.4e9): c.Fatalf("request %d timed out waiting for req (%p) and close(%p)", i, reqDone, closeDone) } } p.close() err = f(conn, "/closetest") c.Check(zk.IsError(err, zk.ZCLOSING), Equals, true, Commentf("%v", err)) } }