blob: 6afbb4bf5cd9810756432688a6f7e88006f59f33 [file] [log] [blame]
package blackbox
import (
"testing"
_ "veyron/lib/testutil"
"veyron/services/store/memstore"
"veyron2/storage"
)
// A Node has a Label and some Children.
type Node struct {
Label string
Children map[string]storage.ID
}
// Create a linear graph and truncate it.
func TestLinear(t *testing.T) {
const linearNodeCount = 10
st, err := memstore.New(rootPublicID, "")
if err != nil {
t.Fatalf("memstore.New() failed: %v", err)
}
if v, err := st.Bind("/").Get(rootPublicID, nil); v != nil || err == nil {
t.Errorf("Unexpected root")
}
if _, err := st.Bind("/").Put(rootPublicID, nil, &Node{}); err != nil {
t.Errorf("Unexpected error: %s", err)
}
// Create a linked list.
path := ""
var nodes [linearNodeCount]*Node
var ids [linearNodeCount]storage.ID
tr := memstore.NewTransaction()
for i := 0; i != linearNodeCount; i++ {
path = path + "/Children/a"
node := &Node{Label: path}
nodes[i] = node
stat, err := st.Bind(path).Put(rootPublicID, tr, node)
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
ids[i] = stat.ID
if _, err := st.Bind(path).Get(rootPublicID, tr); err != nil {
t.Errorf("Unexpected error: %s", err)
}
}
tr.Commit()
// Verify that all the nodes still exist.
st.GC()
for i, node := range nodes {
path := node.Label
id := ids[i]
ExpectExists(t, st, path, id)
}
// Truncate the graph to length 3.
{
node := nodes[2]
node.Children = nil
if _, err := st.Bind("/Children/a/Children/a/Children/a").Put(rootPublicID, nil, node); err != nil {
t.Errorf("Unexpected error: %s", err)
}
}
st.GC()
for i, node := range nodes {
path := node.Label
id := ids[i]
if i < 3 {
ExpectExists(t, st, path, id)
} else {
ExpectNotExists(t, st, path, id)
}
}
}
// Create a lollipop graph and remove part of the cycle.
func TestLollipop(t *testing.T) {
const linearNodeCount = 10
const loopNodeIndex = 5
const cutNodeIndex = 7
st, err := memstore.New(rootPublicID, "")
if err != nil {
t.Fatalf("memstore.New() failed: %v", err)
}
if v, err := st.Bind("/").Get(rootPublicID, nil); v != nil || err == nil {
t.Errorf("Unexpected root")
}
stat, err := st.Bind("/").Put(rootPublicID, nil, &Node{})
if err != nil || stat == nil {
t.Fatalf("Unexpected error: %s", err)
}
id := stat.ID
// Create a linked list.
path := ""
var nodes [linearNodeCount]*Node
var ids [linearNodeCount]storage.ID
tr := memstore.NewTransaction()
for i := 0; i != linearNodeCount; i++ {
path = path + "/Children/a"
node := &Node{Label: path}
nodes[i] = node
stat, err := st.Bind(path).Put(rootPublicID, tr, node)
if err != nil || stat == nil {
t.Errorf("Unexpected error: %s: %s", path, err)
}
id = stat.ID
ids[i] = id
}
// Add a back-loop.
{
node := nodes[linearNodeCount-1]
node.Children = map[string]storage.ID{"a": ids[loopNodeIndex]}
if _, err := st.Bind(node.Label).Put(rootPublicID, tr, node); err != nil {
t.Errorf("Unexpected error: %s", err)
}
}
tr.Commit()
// Verify that all the nodes still exist.
st.GC()
for i, node := range nodes {
path := node.Label
id := ids[i]
ExpectExists(t, st, path, id)
}
// Truncate part of the loop.
{
node := nodes[cutNodeIndex]
node.Children = nil
if _, err := st.Bind(node.Label).Put(rootPublicID, nil, node); err != nil {
t.Errorf("Unexpected error: %s", err)
}
}
st.GC()
for i, node := range nodes {
path := node.Label
id := ids[i]
if i <= cutNodeIndex {
ExpectExists(t, st, path, id)
} else {
ExpectNotExists(t, st, path, id)
}
}
}