Skip to content

Commit

Permalink
rewrite Create tests for better coverage.
Browse files Browse the repository at this point in the history
note this commit shows the fact we don't need CreateContainer as a method, its an argument to Create. TTL is still needed from having a different payload, but later could be logic in Create based on the CreateMode we are given.
  • Loading branch information
jeffbean committed Jul 4, 2024
1 parent 58019c3 commit 426dd88
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 33 deletions.
4 changes: 4 additions & 0 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,10 @@ func (c *Conn) Create(path string, data []byte, flags int32, acl []ACL) (string,
return "", err
}

if createMode.isTTL {
return "", ErrInvalidFlags
}

res := &createResponse{}
_, err = c.request(opCreate, &CreateRequest{path, data, acl, createMode.toFlag()}, res, nil)
if err == ErrConnectionClosed {
Expand Down
130 changes: 97 additions & 33 deletions zk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,52 +68,90 @@ func TestIntegration_StateChanges(t *testing.T) {

func TestIntegration_Create(t *testing.T) {
ts, err := StartTestCluster(t, 1, nil, logWriter{t: t, p: "[ZKERR] "})
if err != nil {
t.Fatal(err)
}
requireNoErrorf(t, err)
defer ts.Stop()

zk, _, err := ts.ConnectAll()
if err != nil {
t.Fatalf("Connect returned error: %+v", err)
}
requireNoErrorf(t, err, "ConnectAll()")
defer zk.Close()

path := "/gozk-test"
tests := []struct {
name string
createFlags int32
specifiedPath string
wantErr string
}{
{
name: "valid create persistant",
createFlags: FlagPersistent,
},
{
name: "valid container from Create",
createFlags: FlagContainer,
// NOTE for v2: we dont need CreateContainer method.
},
{
name: "invalid path",
specifiedPath: "not/valid",
wantErr: "zk: invalid path",
},
{
name: "invalid create ttl",
createFlags: FlagTTL,
wantErr: "zk: invalid flags specified",
},

if err := zk.Delete(path, -1); err != nil && err != ErrNoNode {
t.Fatalf("Delete returned error: %+v", err)
}
if p, err := zk.Create(path, []byte{1, 2, 3, 4}, 0, WorldACL(PermAll)); err != nil {
t.Fatalf("Create returned error: %+v", err)
} else if p != path {
t.Fatalf("Create returned different path '%s' != '%s'", p, path)
{
name: "invalid flag for create mode",
createFlags: 999,
wantErr: "invalid flag value: [999]",
},
}
if data, stat, err := zk.Get(path); err != nil {
t.Fatalf("Get returned error: %+v", err)
} else if stat == nil {
t.Fatal("Get returned nil stat")
} else if len(data) < 4 {
t.Fatal("Get returned wrong size data")

const testPath = "/ttl_znode_tests"
// create sub node to create per test in avoiding using the root path.
_, err = zk.Create(testPath, nil /* data */, FlagPersistent, WorldACL(PermAll))
requireNoErrorf(t, err)

for idx, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path := filepath.Join(testPath, fmt.Sprint(idx))
if tt.specifiedPath != "" {
path = tt.specifiedPath
}

_, err := zk.Create(path, []byte{12}, tt.createFlags, WorldACL(PermAll))
if tt.wantErr == "" {
requireNoErrorf(t, err, fmt.Sprintf("error not expected: path; %q; flags %v", path, tt.createFlags))
return
}

// want an error
if err == nil {
t.Fatalf("did not get expected error: %q", tt.wantErr)
}
if !strings.Contains(err.Error(), tt.wantErr) {
t.Fatalf("wanted error not found: %v; got: %v", tt.wantErr, err.Error())
}
})
}
}

func TestIntegration_CreateTTL(t *testing.T) {
ts, err := StartTestCluster(t, 1, nil, logWriter{t: t, p: "[ZKERR] "})
if err != nil {
t.Fatal(err)
}
requireNoErrorf(t, err)
defer ts.Stop()

zk, _, err := ts.ConnectAll()
if err != nil {
t.Fatalf("Connect returned error: %+v", err)
}
requireNoErrorf(t, err, "ConnectAll()")
defer zk.Close()

tests := []struct {
name string
createFlags int32
giveDuration time.Duration
wantErr string
name string
createFlags int32
specifiedPath string
giveDuration time.Duration
wantErr string
}{
{
name: "valid create ttl",
Expand All @@ -125,6 +163,17 @@ func TestIntegration_CreateTTL(t *testing.T) {
createFlags: 5,
giveDuration: time.Minute,
},
{
name: "invalid path",
createFlags: FlagTTL,
specifiedPath: "not/valid",
wantErr: "zk: invalid path",
},
{
name: "invalid container with ttl",
createFlags: FlagContainer,
wantErr: "zk: invalid flags specified",
},
{
name: "invalid flag for create mode",
createFlags: 999,
Expand All @@ -141,6 +190,10 @@ func TestIntegration_CreateTTL(t *testing.T) {
for idx, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path := filepath.Join(testPath, fmt.Sprint(idx))
if tt.specifiedPath != "" {
path = tt.specifiedPath
}

_, err := zk.CreateTTL(path, []byte{12}, tt.createFlags, WorldACL(PermAll), tt.giveDuration)
if tt.wantErr == "" {
requireNoErrorf(t, err, fmt.Sprintf("error not expected: path; %q; flags %v", path, tt.createFlags))
Expand Down Expand Up @@ -175,9 +228,10 @@ func TestIntegration_CreateContainer(t *testing.T) {
defer zk.Close()

tests := []struct {
name string
createFlags int32
wantErr string
name string
createFlags int32
specifiedPath string
wantErr string
}{
{
name: "valid create container",
Expand All @@ -188,6 +242,12 @@ func TestIntegration_CreateContainer(t *testing.T) {
createFlags: 4,
// container flag, ensure matches ZK Create Mode (change detector test)
},
{
name: "invalid path",
createFlags: FlagContainer,
specifiedPath: "not/valid",
wantErr: "zk: invalid path",
},
{
name: "invalid create mode",
createFlags: 999,
Expand Down Expand Up @@ -228,6 +288,10 @@ func TestIntegration_CreateContainer(t *testing.T) {
for idx, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path := filepath.Join(testPath, fmt.Sprint(idx))
if tt.specifiedPath != "" {
path = tt.specifiedPath
}

_, err := zk.CreateContainer(path, []byte{12}, tt.createFlags, WorldACL(PermAll))
if tt.wantErr == "" {
requireNoErrorf(t, err, fmt.Sprintf("error not expected: path; %q; flags %v", path, tt.createFlags))
Expand Down

0 comments on commit 426dd88

Please sign in to comment.