Beispiel #1
0
// 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()
}
Beispiel #2
0
func (suite *TestSuiteSource) TestSourceUsage(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()

	root := namespace.NewPathf("/unit-test/zk/%d/source", time.Now().Unix())
	value := []byte("test-value-12345")
	_, err = zk.Put(root, value, false)
	c.Assert(err, IsNil)
	read, _, err := zk.Get(root)
	c.Assert(read, DeepEquals, value)

	sourced, err := resource.Fetch(ctx, url+root.String())
	c.Assert(err, IsNil)
	c.Assert(sourced, DeepEquals, value)

	// Test default to what's in the environment variable -- no hosts specified.
	sourced, err = resource.Fetch(ctx, "zk://"+root.String())
	c.Assert(err, IsNil)
	c.Assert(sourced, DeepEquals, value)

	// Test default to what's in the environment variable -- no hosts specified.
	sourced, err = resource.Fetch(ctx, "zk://bogus/node")
	c.Assert(err, Not(IsNil))
}
Beispiel #3
0
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)
}
Beispiel #4
0
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!")
}
Beispiel #5
0
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)
}
Beispiel #6
0
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",
	})
}
Beispiel #7
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)
}
Beispiel #8
0
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)
}
Beispiel #9
0
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)
}
Beispiel #10
0
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
}
Beispiel #11
0
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.")
	}
}
Beispiel #12
0
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))
}