func (s *S) TestRetryChangeSetting(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "old", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) err = conn.RetryChange("/test", zk.EPHEMERAL, []zk.ACL{}, func(data string, stat *zk.Stat) (string, error) { c.Assert(data, Equals, "old") c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) return "brand new", nil }) c.Assert(err, IsNil) data, stat, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 1) c.Assert(data, Equals, "brand new") // ACL was unchanged by RetryChange(). acl, _, err := conn.ACL("/test") c.Assert(err, IsNil) c.Assert(acl, DeepEquals, zk.WorldACL(zk.PERM_ALL)) }
func (s *S) TestRetryChangeConflictOnCreate(c *C) { conn, _ := s.init(c) changeFunc := func(data string, stat *zk.Stat) (string, error) { switch data { case "": c.Assert(stat, IsNil) _, err := conn.Create("/test", "conflict", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) return "<none> => conflict", nil case "conflict": c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) return "conflict => new", nil default: c.Fatal("Unexpected node data: " + data) } return "can't happen", nil } err := conn.RetryChange("/test", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL), changeFunc) c.Assert(err, IsNil) data, stat, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "conflict => new") c.Assert(stat, NotNil) c.Assert(stat.Version(), 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) 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") }
// cases to test: // child server, stopped normally; reattach, start // non-direct child server, killed abnormally; reattach, start (->error), remove pid.txt; start // non-direct child server, still running; reattach, start (->error), stop, start // child server, still running; reattach, start (-> error) // child server, still running; reattach, stop, start. // non-direct child server, still running; reattach, stop, start. func (s *S) TestAttachServer(c *C) { // Create a cookie so that we know we are reattaching to the same instance. conn, _ := s.init(c) _, err := conn.Create("/testAttachCookie", "testAttachCookie", 0, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) s.checkCookie(c) s.zkServer.Stop() s.zkServer = nil s.testAttachServer(c, (*S).startServer) s.testAttachServer(c, (*S).startServerIndirect) s.testAttachServerAbnormalTerminate(c, (*S).startServer) s.testAttachServerAbnormalTerminate(c, (*S).startServerIndirect) srv, err := zk.AttachServer(s.zkTestRoot) c.Assert(err, IsNil) s.zkServer = srv err = s.zkServer.Start() c.Assert(err, IsNil) conn, _ = s.init(c) err = conn.Delete("/testAttachCookie", -1) c.Assert(err, IsNil) }
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) 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) 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) 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) TestRetryChangeCreating(c *C) { conn, _ := s.init(c) err := conn.RetryChange("/test", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL), func(data string, stat *zk.Stat) (string, error) { c.Assert(data, Equals, "") c.Assert(stat, IsNil) return "new", nil }) c.Assert(err, IsNil) data, stat, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) c.Assert(data, Equals, "new") acl, _, err := conn.ACL("/test") c.Assert(err, IsNil) c.Assert(acl, DeepEquals, zk.WorldACL(zk.PERM_ALL)) }
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) 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) TestRetryChangeErrorInCallback(c *C) { conn, _ := s.init(c) err := conn.RetryChange("/test", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL), func(data string, stat *zk.Stat) (string, error) { return "don't use this", errors.New("BOOM!") }) c.Assert(err, NotNil) c.Assert(err.Error(), Equals, "BOOM!") stat, err := conn.Exists("/test") c.Assert(err, IsNil) c.Assert(stat, IsNil) }
func (s *S) TestRetryChangeConflictOnSetDueToDelete(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "old", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) changeFunc := func(data string, stat *zk.Stat) (string, error) { switch data { case "old": c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) err := conn.Delete("/test", 0) c.Assert(err, IsNil) return "old => <deleted>", nil case "": c.Assert(stat, IsNil) return "<deleted> => new", nil default: c.Fatal("Unexpected node data: " + data) } return "can't happen", nil } err = conn.RetryChange("/test", zk.EPHEMERAL, zk.WorldACL(zk.PERM_READ), changeFunc) c.Assert(err, IsNil) data, stat, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "<deleted> => new") c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) // Should be the new ACL. acl, _, err := conn.ACL("/test") c.Assert(err, IsNil) c.Assert(acl, DeepEquals, zk.WorldACL(zk.PERM_READ)) }
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)) }
// Surprisingly for some (including myself, initially), the watch // returned by the exists method actually fires on data changes too. func (s *S) TestExistsWatchOnDataChange(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) _, watch, err := conn.ExistsW("/test") c.Assert(err, IsNil) _, err = conn.Set("/test", "new", -1) c.Assert(err, IsNil) event := <-watch c.Assert(event.Path, Equals, "/test") c.Assert(event.Type, Equals, zk.EVENT_CHANGED) }
func main() { zk, session, err := zookeeper.Dial("localhost:2181", 5e9) if err != nil { log.Fatalf("Can't connect: %v", err) } defer zk.Close() // Wait for connection. event := <-session if event.State != zookeeper.STATE_CONNECTED { log.Fatalf("Can't connect: %v", event) } _, err = zk.Create("/counter", "0", 0, zookeeper.WorldACL(zookeeper.PERM_ALL)) if err != nil { log.Fatalf("Can't create counter: %v", err) } else { fmt.Println("Counter created!") } }
func (s *S) TestCreateSetAndGet(c *C) { conn, _ := s.init(c) start := time.Now() _, err := conn.Create("/test", "", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) _, stat, err := conn.Get("/test") c.Assert(err, IsNil) checkTimeBetween(c, "ctime", stat.CTime(), start, time.Now()) start = time.Now() stat, err = conn.Set("/test", "bababum", -1) // Any version. c.Assert(err, IsNil) c.Assert(stat.Version(), Equals, 1) checkTimeBetween(c, "mtime", stat.MTime(), start, time.Now()) data, _, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(data, Equals, "bababum") }
func (s *S) TestRetryChangeUnchangedValueDoesNothing(c *C) { conn, _ := s.init(c) _, err := conn.Create("/test", "old", zk.EPHEMERAL, zk.WorldACL(zk.PERM_ALL)) c.Assert(err, IsNil) err = conn.RetryChange("/test", zk.EPHEMERAL, []zk.ACL{}, func(data string, stat *zk.Stat) (string, error) { c.Assert(data, Equals, "old") c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) return "old", nil }) c.Assert(err, IsNil) data, stat, err := conn.Get("/test") c.Assert(err, IsNil) c.Assert(stat, NotNil) c.Assert(stat.Version(), Equals, 0) // Unchanged! c.Assert(data, Equals, "old") }