func watchWithIndex(kv kvdb.Kvdb, t *testing.T) { fmt.Println("\nwatchWithIndex") tree := "indexTree" subtree := tree + "/subtree" key := subtree + "/watchWithIndex" key1 := subtree + "/watchWithIndex21" kv.DeleteTree(tree) kvp, err := kv.Create(key, []byte("bar"), 0) assert.NoError(t, err, "Unexpected error in create: %v", err) time.Sleep(time.Millisecond * 100) waitIndex := kvp.ModifiedIndex + 2 watchData := watchData{ t: t, key: key, localIndex: waitIndex, } err = kv.WatchTree(tree, waitIndex, &watchData, watchWithIndexCb) if err != nil { fmt.Printf("Cannot test watchTree for watchWithIndex: %v", err) return } // Should not get updates for these kv.Put(key, []byte("bar1"), 0) kv.Put(key, []byte("bar1"), 0) // Should get updates for these kv.Put(key, []byte("bar2"), 0) kv.Create(key1, []byte("bar"), 0) kv.Delete(key) }
func deleteTree(kv kvdb.Kvdb, t *testing.T) { fmt.Println("deleteTree") prefix := "tree" keys := map[string]string{ prefix + "/1cbc9a98-072a-4793-8608-01ab43db96c8": "bar", prefix + "/foo": "baz", } for key, val := range keys { _, err := kv.Put(key, []byte(val), 0) assert.NoError(t, err, "Unexpected error on Put") } for key := range keys { _, err := kv.Get(key) assert.NoError(t, err, "Unexpected error on Get") } err := kv.DeleteTree(prefix) assert.NoError(t, err, "Unexpected error on DeleteTree") for key := range keys { _, err := kv.Get(key) assert.Error(t, err, "Get should fail on all keys after DeleteTree") } }
func grantRevokeUser(kvRootUser kvdb.Kvdb, datastoreInit kvdb.DatastoreInit, t *testing.T) { fmt.Println("grantRevokeUser") kvRootUser.Create("allow1/foo", []byte("bar"), 0) kvRootUser.Create("allow2/foo", []byte("bar"), 0) kvRootUser.Create("disallow/foo", []byte("bar"), 0) err := kvRootUser.GrantUserAccess("test", kvdb.ReadWritePermission, "allow1/*") assert.NoError(t, err, "Error in Grant User") err = kvRootUser.GrantUserAccess("test", kvdb.ReadWritePermission, "allow2/*") assert.NoError(t, err, "Error in Grant User") err = kvRootUser.GrantUserAccess("test", kvdb.ReadWritePermission, "disallow/*") assert.NoError(t, err, "Error in Grant User") err = kvRootUser.RevokeUsersAccess("test", kvdb.ReadWritePermission, "disallow/*") assert.NoError(t, err, "Error in Revoke User") options := make(map[string]string) options[kvdb.UsernameKey] = "test" options[kvdb.PasswordKey] = "test123" options[kvdb.CAFileKey] = "/etc/pwx/pwx-ca.crt" options[kvdb.CertFileKey] = "/etc/pwx/pwx-user-cert.crt" options[kvdb.CertKeyFileKey] = "/etc/pwx/pwx-user-key.key" machines := []string{"https://192.168.56.101:2379"} kvTestUser, _ := datastoreInit("pwx/test", machines, options, fatalErrorCb()) actual := "actual" _, err = kvTestUser.Put("allow1/foo", []byte(actual), 0) assert.NoError(t, err, "Error in writing to allowed tree") kvPair, err := kvTestUser.Get("allow1/foo") assert.NoError(t, err, "Error in accessing allowed values") if err == nil { assert.Equal(t, string(kvPair.Value), "actual") } _, err = kvTestUser.Put("allow2/foo", []byte(actual), 0) assert.NoError(t, err, "Error in writing to allowed tree") kvPair, err = kvTestUser.Get("allow2/foo") assert.NoError(t, err, "Error in accessing allowed values") if err == nil { assert.Equal(t, string(kvPair.Value), "actual") } actual2 := "actual2" _, err = kvTestUser.Put("disallow/foo", []byte(actual2), 0) assert.Error(t, err, "Expected error in writing to disallowed tree") kvPair, err = kvTestUser.Get("disallow/foo") assert.Error(t, err, "Expected error in accessing disallowed values") kvRootUser.DeleteTree("allow1") kvRootUser.DeleteTree("allow2") kvRootUser.DeleteTree("disallow") }
func enumerate(kv kvdb.Kvdb, t *testing.T) { fmt.Println("enumerate") prefix := "enumerate" keys := map[string]string{ prefix + "/1cbc9a98-072a-4793-8608-01ab43db96c8": "bar", prefix + "/foo": "baz", } kv.DeleteTree(prefix) defer func() { kv.DeleteTree(prefix) }() errPairs, err := kv.Enumerate(prefix) assert.Equal(t, 0, len(errPairs), "Expected 0 pairs") folderKey := prefix + "/folder/" _, err = kv.Put(folderKey, []byte(""), 0) assert.NoError(t, err, "Unexpected error on Put") kvPairs, err := kv.Enumerate(folderKey) assert.Equal(t, nil, err, "Unexpected error on Enumerate") kv.DeleteTree(prefix) for key, val := range keys { _, err := kv.Put(key, []byte(val), 0) assert.NoError(t, err, "Unexpected error on Put") } kvPairs, err = kv.Enumerate(prefix) assert.NoError(t, err, "Unexpected error on Enumerate") assert.Equal(t, len(kvPairs), len(keys), "Expecting %d keys under %s got: %d", len(keys), prefix, len(kvPairs)) for i := range kvPairs { v, ok := keys[kvPairs[i].Key] assert.True(t, ok, "unexpected kvpair (%s)->(%s)", kvPairs[i].Key, kvPairs[i].Value) assert.Equal(t, v, string(kvPairs[i].Value), "Invalid kvpair (%s)->(%s) expect value %s", kvPairs[i].Key, kvPairs[i].Value, v) } }
func collect(kv kvdb.Kvdb, t *testing.T) { fmt.Println("collect") root := "pwx/test/collect" firstLevel := root + "/first" secondLevel := root + "/second" kv.DeleteTree(root) kvp, _ := kv.Create(firstLevel, []byte("bar"), 0) fmt.Printf("KVP is %v", kvp) collector, _ := kvdb.NewUpdatesCollector(kv, secondLevel, kvp.CreatedIndex) time.Sleep(time.Second) var updates []*kvdb.KVPair updateFn := func(start, end int) uint64 { maxVersion := uint64(0) for i := start; i < end; i++ { newLeaf := strconv.Itoa(i) kvp1, _ := kv.Create(secondLevel+"/"+newLeaf, []byte(newLeaf), 0) kvp2, _ := kv.Update(firstLevel, []byte(newLeaf), 0) updates = append(updates, kvp1) maxVersion = kvp2.ModifiedIndex } return maxVersion } updateFn(0, 10) // Allow watch updates to come back. time.Sleep(time.Millisecond * 500) collector.Stop() updateFn(10, 20) lastKVIndex := kvp.CreatedIndex lastLeafIndex := -1 cb := func(prefix string, opaque interface{}, kvp *kvdb.KVPair, err error) error { assert.True(t, err == nil, "Error is nil %v", err) assert.True(t, kvp.ModifiedIndex > lastKVIndex, "Modified index %v lower than last index %v", kvp.ModifiedIndex, lastKVIndex) lastKVIndex = kvp.ModifiedIndex strValue := string(kvp.Value) value := secondLevel + "/" + strValue assert.True(t, strings.Compare(kvp.Key, value) == 0, "Key: %v, Value: %v", kvp.Key, value) leafIndex, _ := strconv.Atoi(strValue) assert.True(t, leafIndex == lastLeafIndex+1, "Last leaf: %v, leaf: %v", kvp.Key, value) lastLeafIndex = leafIndex return nil } replayCb := make([]kvdb.ReplayCb, 1) replayCb[0].Prefix = secondLevel replayCb[0].WatchCB = cb _, err := collector.ReplayUpdates(replayCb) assert.True(t, err == nil, "Replay encountered error %v", err) assert.True(t, lastLeafIndex == 9, "Last leaf index %v, expected : 9", lastLeafIndex) // Test with no updates. thirdLevel := root + "/third" kvp, _ = kv.Create(thirdLevel, []byte("bar_update"), 0) collector, _ = kvdb.NewUpdatesCollector(kv, thirdLevel, kvp.ModifiedIndex) time.Sleep(2 * time.Second) _, err = collector.ReplayUpdates(replayCb) assert.True(t, err == nil, "Replay encountered error %v", err) assert.True(t, lastLeafIndex == 9, "Last leaf index %v, expected : 9", lastLeafIndex) // Test with kvdb returning error because update index was too old. fourthLevel := root + "/fourth" kv.Create(fourthLevel, []byte(strconv.Itoa(0)), 0) for i := 1; i < 2000; i++ { kv.Update(fourthLevel, []byte(strconv.Itoa(i)), 0) } collector, _ = kvdb.NewUpdatesCollector(kv, fourthLevel, kvp.ModifiedIndex) kv.Update(fourthLevel, []byte(strconv.Itoa(2000)), 0) time.Sleep(500 * time.Millisecond) cb = func(prefix string, opaque interface{}, kvp *kvdb.KVPair, err error) error { fmt.Printf("Error is %v", err) assert.True(t, err != nil, "Error is nil %v", err) return nil } replayCb[0].WatchCB = cb collector.ReplayUpdates(replayCb) }
func snapshot(kv kvdb.Kvdb, t *testing.T) { fmt.Println("snapshot") prefix := "snapshot/" kv.DeleteTree(prefix) defer func() { kv.DeleteTree(prefix) }() inputData := make(map[string]string) inputDataVersion := make(map[string]uint64) key := "key" value := "bar" count := 100 doneUpdate := make(chan bool, 2) updateFn := func(count int, v string) { for i := 0; i < count; i++ { suffix := strconv.Itoa(i) inputKey := prefix + key + suffix inputValue := v kv, err := kv.Put(inputKey, []byte(inputValue), 0) assert.NoError(t, err, "Unexpected error on Put") inputData[inputKey] = inputValue inputDataVersion[inputKey] = kv.ModifiedIndex } doneUpdate <- true } updateFn(count, value) <-doneUpdate newValue := "bar2" go updateFn(50, newValue) snap, snapVersion, err := kv.Snapshot(prefix) assert.NoError(t, err, "Unexpected error on Snapshot") <-doneUpdate kvPairs, err := snap.Enumerate(prefix) assert.NoError(t, err, "Unexpected error on Enumerate") assert.Equal(t, len(kvPairs), count, "Expecting %d keys under %s got: %d, kv: %v", count, prefix, len(kvPairs), kvPairs) for i := range kvPairs { currValue, ok1 := inputData[kvPairs[i].Key] mapVersion, ok2 := inputDataVersion[kvPairs[i].Key] assert.True(t, ok1 && ok2, "unexpected kvpair (%s)->(%s)", kvPairs[i].Key, kvPairs[i].Value) expectedValue := value if mapVersion <= snapVersion { expectedValue = currValue } assert.Equal(t, expectedValue, string(kvPairs[i].Value), "Invalid kvpair %v (%s)->(%s) expect value %s"+ " snap version: %v kvVersion: %v", i, kvPairs[i].Key, kvPairs[i].Value, expectedValue, snapVersion, mapVersion) assert.True(t, mapVersion > snapVersion || mapVersion == kvPairs[i].ModifiedIndex, "Invalid kvpair %v (%s)->(%s) expect version %v"+ " snap version: %v kvVersion: %v", i, kvPairs[i].Key, kvPairs[i].Value, mapVersion, snapVersion, kvPairs[i].KVDBIndex) } }