func (suite *TestSuiteRegistry) TestFollow(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() p := namespace.NewPath(fmt.Sprintf("/unit-test/registry/%d/follow", time.Now().Unix())) _, err = zk.Put(p.Sub("1"), []byte(url+p.Sub("2").String()), false) c.Assert(err, IsNil) _, err = zk.Put(p.Sub("2"), []byte(url+p.Sub("3").String()), false) c.Assert(err, IsNil) _, err = zk.Put(p.Sub("3"), []byte(url+p.Sub("4").String()), false) c.Assert(err, IsNil) _, err = zk.Put(p.Sub("4"), []byte("end"), false) c.Assert(err, IsNil) u, err := net.Parse(url + p.Sub("1").String()) c.Assert(err, IsNil) path, value, version, err := namespace.FollowUrl(ctx, *u) c.Log("path=", path, ",value=", value, ",version=", version, ",err=", err) c.Assert(err, IsNil) c.Assert(value, DeepEquals, []byte("end")) c.Assert(path.String(), Equals, url+p.Sub("4").String()) c.Assert(version, Not(Equals), namespace.InvalidVersion) }
// TODO - Some problems here where the first connection close isn't allowed because other clients // are using the the registry and ref count is > 0... func (suite *TestSuiteRegistry) DISABLED_TestEphemeral(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) p := namespace.NewPath(fmt.Sprintf("/unit-test/registry/%d/ephemeral", time.Now().Unix())) v := []byte("test") _, err = zk.Put(p, v, true) c.Assert(err, IsNil) read, _, err := zk.Get(p) c.Assert(read, DeepEquals, v) exists, _ := zk.Exists(p) c.Assert(exists, Equals, true) // disconnect err = zk.Close() c.Assert(err, IsNil) // reconnect zk, err = namespace.Dial(ctx, url) c.Assert(err, IsNil) _, _, err = zk.Get(p) c.Assert(err, Equals, ErrNotExist) exists, _ = zk.Exists(p) c.Assert(exists, Equals, false) zk.Close() }
func (suite *TestSuiteTemplate) TestGet(c *C) { // Write something url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(context.Background(), url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() k := fmt.Sprintf("/unit-test/registry/template/%d/test", time.Now().Unix()) p := namespace.NewPath(k) v := []byte("test") _, err = zk.Put(p, v, false) c.Assert(err, IsNil) suite.template = "The value is {{get \"zk://" + k + "\"}}!" // Generate the auth token required by the server. token := auth.NewToken(1*time.Hour).Add("secure", 1) header := http.Header{} token.SetHeader(header, testutil.PrivateKeyFunc) ctx := resource.ContextPutHttpHeader(context.Background(), header) applied, err := template.Execute(ctx, fmt.Sprintf("http://localhost:%d/secure", suite.port)) c.Assert(err, IsNil) c.Log(string(applied)) c.Assert(string(applied), Equals, "The value is test!") }
func (suite *TestSuiteRegistry) TestTriggerMembers(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() p := namespace.NewPath(fmt.Sprintf("/unit-test/registry/%d/trigger/members", time.Now().Unix())) _, err = zk.Put(p, []byte{1}, false) c.Assert(err, IsNil) time.Sleep(delay) members, stop, err := zk.Trigger(namespace.Members{Path: p}) c.Assert(err, IsNil) count := new(int) go func() { for { e := <-members *count++ c.Log("**** Got event:", e, " count=", *count) } }() _, err = zk.Put(p.Sub("1"), []byte{1}, false) c.Assert(err, IsNil) time.Sleep(delay) _, err = zk.Put(p.Sub("2"), []byte{1}, false) c.Assert(err, IsNil) time.Sleep(delay) _, err = zk.Put(p.Sub("3"), []byte{1}, false) c.Assert(err, IsNil) time.Sleep(delay) err = zk.Delete(p.Sub("3")) c.Assert(err, IsNil) time.Sleep(delay * 2) stop <- 1 c.Assert(*count, Equals, 4) }
func (suite *TestSuiteTemplate) TestList(c *C) { // Write something url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(context.Background(), url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() k := "/unit-test/registry/template/test" p := namespace.NewPath(k) err = zk.Delete(p) // Write new data v := []byte("test") _, err = zk.Put(p, v, false) c.Assert(err, IsNil) // write children for i := 0; i < 5; i++ { cp := p.Sub(fmt.Sprintf("child-%d", i)) cv := []byte(fmt.Sprintf("value-%d", i)) _, err = zk.Put(cp, cv, false) c.Assert(err, IsNil) } suite.template = "{{range list \"zk://" + k + "\"}}\n{{.}}{{end}}" // Generate the auth token required by the server. token := auth.NewToken(1*time.Hour).Add("secure", 1) header := http.Header{} token.SetHeader(header, testutil.PrivateKeyFunc) ctx := resource.ContextPutHttpHeader(context.Background(), header) applied, err := template.Execute(ctx, fmt.Sprintf("http://localhost:%d/secure", suite.port)) c.Assert(err, IsNil) c.Log(string(applied)) l := strings.Split(string(applied), "\n")[1:] c.Assert(l, DeepEquals, []string{ url + "/unit-test/registry/template/test/child-4", url + "/unit-test/registry/template/test/child-3", url + "/unit-test/registry/template/test/child-2", url + "/unit-test/registry/template/test/child-1", url + "/unit-test/registry/template/test/child-0", }) }
func (suite *TestSuiteRegistry) TestUsage(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() p := namespace.NewPath(fmt.Sprintf("/unit-test/namespace.%d/test", time.Now().Unix())) v := []byte("test") _, err = zk.Put(p, v, false) c.Assert(err, IsNil) read, _, err := zk.Get(p) c.Assert(read, DeepEquals, v) check := map[namespace.Path]int{} for i := 0; i < 10; i++ { cp := p.Sub(fmt.Sprintf("child-%d", i)) _, err = zk.Put(cp, []byte{0}, false) c.Assert(err, IsNil) check[cp] = i } list, err := zk.List(p) c.Assert(err, IsNil) c.Log(list) c.Assert(len(list), Equals, len(check)) for _, p := range list { _, has := check[p] c.Assert(has, Equals, true) } // delete all children for i := 0; i < 10; i++ { cp := p.Sub(fmt.Sprintf("child-%d", i)) err = zk.Delete(cp) c.Assert(err, IsNil) } list, err = zk.List(p) c.Assert(err, IsNil) c.Assert(len(list), Equals, 0) exists, err := zk.Exists(p.Sub("child-0")) c.Assert(err, IsNil) c.Assert(exists, Equals, false) }
func (suite *TestSuiteRegistry) TestVersions(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() p := namespace.NewPath(fmt.Sprintf("/unit-test/registry/%d/version", time.Now().Unix())) v := []byte("test") version, err := zk.Put(p, v, true) c.Assert(err, IsNil) c.Assert(version, Not(Equals), namespace.InvalidVersion) read, version2, err := zk.Get(p) c.Assert(read, DeepEquals, v) c.Assert(version, Equals, version2) // try to update with version version3, err := zk.PutVersion(p, []byte{1}, version2) c.Assert(err, IsNil) c.Assert(version3 > version2, Equals, true) // now try to delete with outdated version number err = zk.DeleteVersion(p, version) c.Assert(err, Equals, ErrBadVersion) // read again cv, version4, err := zk.Get(p) c.Assert(err, IsNil) c.Assert(version4, Equals, version3) c.Assert(cv, DeepEquals, []byte{1}) // delete again err = zk.DeleteVersion(p, version4) c.Assert(err, IsNil) _, _, err = zk.Get(p) c.Assert(err, Equals, ErrNotExist) }
func (suite *TestSuiteRegistry) TestTriggerDelete(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() p := namespace.NewPath(fmt.Sprintf("/unit-test/registry/%d/trigger/delete", time.Now().Unix())) deleted, stop, err := zk.Trigger(namespace.Delete{Path: p}) c.Assert(err, IsNil) count := new(int) go func() { e, open := <-deleted if !open { return } *count++ c.Log("**** Got event:", e, " count=", *count) }() _, err = zk.Put(p, []byte{1}, false) c.Assert(err, IsNil) time.Sleep(delay) err = zk.Delete(p) c.Assert(err, IsNil) time.Sleep(delay) stop <- 1 time.Sleep(delay) c.Assert(*count, Equals, 1) }
func (suite *TestSuiteRegistry) TestTriggerCreate(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() p := namespace.NewPath(fmt.Sprintf("/unit-test/namespace.%d/trigger/create", time.Now().Unix())) created, stop, err := zk.Trigger(namespace.Create{Path: p}) c.Assert(err, IsNil) count := new(int) done := make(chan int) go func() { for { select { case e := <-created: *count++ c.Log("**** Got event:", e, " count=", *count) case <-done: break } } }() _, err = zk.Put(p, []byte{1}, false) c.Assert(err, IsNil) time.Sleep(delay) done <- 1 time.Sleep(delay) c.Assert(*count, Equals, 1) stop <- 1 }
func (suite *TestSuiteRegistry) TestTriggerChange(c *C) { ctx := ContextPutTimeout(context.Background(), 1*time.Minute) url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(ctx, url) c.Assert(err, IsNil) c.Log(zk) defer zk.Close() p := namespace.NewPath(fmt.Sprintf("/unit-test/registry/%d/trigger/change", time.Now().Unix())) changed, stop, err := zk.Trigger(namespace.Change{Path: p}) c.Assert(err, IsNil) count := new(int) done := make(chan int) go func() { for { select { case e := <-changed: *count++ c.Log("**** Got event:", e, " count=", *count) case <-done: break } } }() _, err = zk.Put(p, []byte{1}, false) c.Assert(err, IsNil) c.Log("*** create") time.Sleep(delay) _, err = zk.Put(p, []byte{2}, false) c.Assert(err, IsNil) c.Log("*** change") time.Sleep(delay) _, err = zk.Put(p, []byte{3}, false) c.Assert(err, IsNil) c.Log("*** change") time.Sleep(delay) _, err = zk.Put(p, []byte{4}, false) c.Assert(err, IsNil) c.Log("*** change") time.Sleep(delay * 2) stop <- 1 time.Sleep(delay * 2) done <- 1 if *count < 3 { panic("Should be at least 3 events... sometimes zk will send 4 changes.") } }
func (suite *TestSuiteTemplate) TestTemplateExecuteWithVarBlock(c *C) { // Write something url := "zk://" + strings.Join(Hosts(), ",") zk, err := namespace.Dial(context.Background(), url) c.Assert(err, IsNil) c.Log(zk) k := "/unit-test/registry/template/test-template-execute-vars/PG_PASS" p := namespace.NewPath(k) err = zk.Delete(p) // Write new data v := []byte("password") _, err = zk.Put(p, v, false) c.Assert(err, IsNil) zk.Close() // Now use the value in zk in the template // Generate the auth token required by the server. token := auth.NewToken(1*time.Hour).Add("secure", 1) header := http.Header{} token.SetHeader(header, testutil.PrivateKeyFunc) // This is the content to be served by the test server. // Using the Execute will add additional functions that can be included in the var blocks. suite.template = ` {{define "comments"}} # The variable define blocks allow the definition of variables that are reused throughout the # main body of the template. The variables are referenced as '<blockname>.<fieldname>'. {{end}} {{define "app"}} # blockname is 'app' version: 1.2 image: repo build: 1234 user: "******"USER"}}" # Getting the environment variable and use that as value. password: "******"zk:///unit-test/registry/template/test-template-execute-vars/PG_PASS" }}" {{end}} {{define "host"}} label: appserver name: myhost port: {{.port}} # Here we allow the application to pass in a context that's refereceable. {{end}} { "image" : "repo/myapp:` + "{{my `app.version`}}-{{my `app.build`}}" + `", "host" : "` + "{{my `host.name`}}" + `",{{/* use this for comment in JSON :) */}} "user" : "` + "{{my `app.user`}}" + `", "password" : "` + "{{my `app.password`}}" + `", "port" : "` + "{{my `host.port`}}" + `" }` // The url is a template too. url = "http://localhost:{{.port}}/secure" data := map[string]interface{}{ "Name": "test", "Age": 20, "port": suite.port, } ctx := template.ContextPutTemplateData(resource.ContextPutHttpHeader(context.Background(), header), data) text, err := template.Execute(ctx, url) c.Assert(err, IsNil) c.Log(string(text)) obj := make(map[string]string) err = json.Unmarshal(text, &obj) c.Assert(err, IsNil) c.Assert(obj["image"], Equals, "repo/myapp:1.2-1234") c.Assert(obj["user"], Equals, os.Getenv("USER")) c.Assert(obj["host"], Equals, "myhost") c.Assert(obj["port"], Equals, fmt.Sprintf("%d", suite.port)) c.Assert(obj["password"], Equals, string(v)) }