func MakeWriter(t testing.TB, qs graph.QuadStore, opts graph.Options, data ...quad.Quad) graph.QuadWriter { w, err := writer.NewSingleReplication(qs, opts) require.Nil(t, err) if len(data) > 0 { err = w.AddQuadSet(data) require.Nil(t, err) } return w }
func removeQuad(qs graph.QuadStore, q []quad.Quad) error { w, err := writer.NewSingleReplication(qs, nil) if err != nil { return err } for _, q := range q { err = w.RemoveQuad(q) if err != nil { return fmt.Errorf("removing quad: %v (%v)", err, q) } } return nil }
// WriteFixtureQuadStore writes id QuadSet into qs. func WriteFixtureQuadStore(qs graph.QuadStore, id string) (int, error) { quads := Fixtures.QuadSet(id) if quads == nil { return 0, fmt.Errorf("unknown fixture: %q", id) } w, err := writer.NewSingleReplication(qs, nil) if err != nil { return 0, err } err = w.AddQuadSet(quads.Quads) if err != nil { return 0, err } return len(quads.Quads), nil }
func TestOptimize(t *testing.T) { tmpFile, _ := ioutil.TempFile(os.TempDir(), "cayley_test") t.Log(tmpFile.Name()) defer os.RemoveAll(tmpFile.Name()) err := createNewBolt(tmpFile.Name(), nil) if err != nil { t.Fatalf("Failed to create working directory") } qs, err := newQuadStore(tmpFile.Name(), nil) if qs == nil || err != nil { t.Error("Failed to create leveldb QuadStore.") } w, _ := writer.NewSingleReplication(qs, nil) w.AddQuadSet(makeQuadSet()) // With an linksto-fixed pair fixed := qs.FixedIterator() fixed.Add(qs.ValueOf("F")) fixed.Tagger().Add("internal") lto := iterator.NewLinksTo(qs, fixed, quad.Object) oldIt := lto.Clone() newIt, ok := lto.Optimize() if !ok { t.Errorf("Failed to optimize iterator") } if newIt.Type() != Type() { t.Errorf("Optimized iterator type does not match original, got:%v expect:%v", newIt.Type(), Type()) } newQuads := iteratedQuads(qs, newIt) oldQuads := iteratedQuads(qs, oldIt) if !reflect.DeepEqual(newQuads, oldQuads) { t.Errorf("Optimized iteration does not match original") } graph.Next(oldIt) oldResults := make(map[string]graph.Value) oldIt.TagResults(oldResults) graph.Next(newIt) newResults := make(map[string]graph.Value) newIt.TagResults(newResults) if !reflect.DeepEqual(newResults, oldResults) { t.Errorf("Discordant tag results, new:%v old:%v", newResults, oldResults) } }
func makeTestStore(data []quad.Quad) (*QuadStore, graph.QuadWriter, []pair) { seen := make(map[string]struct{}) qs := newQuadStore() var ( val int64 ind []pair ) writer, _ := writer.NewSingleReplication(qs, nil) for _, t := range data { for _, qp := range []string{t.Subject, t.Predicate, t.Object, t.Label} { if _, ok := seen[qp]; !ok && qp != "" { val++ ind = append(ind, pair{qp, val}) seen[qp] = struct{}{} } } writer.AddQuad(t) } return qs, writer, ind }
func TestDeletedFromIterator(t *testing.T) { tmpFile, _ := ioutil.TempFile(os.TempDir(), "cayley_test") t.Log(tmpFile.Name()) defer os.RemoveAll(tmpFile.Name()) err := createNewBolt(tmpFile.Name(), nil) if err != nil { t.Fatalf("Failed to create working directory") } qs, err := newQuadStore(tmpFile.Name(), nil) if qs == nil || err != nil { t.Error("Failed to create leveldb QuadStore.") } defer qs.Close() w, _ := writer.NewSingleReplication(qs, nil) w.AddQuadSet(makeQuadSet()) expect := []quad.Quad{ {"E", "follows", "F", ""}, } sort.Sort(ordered(expect)) // Subject iterator. it := qs.QuadIterator(quad.Subject, qs.ValueOf("E")) if got := iteratedQuads(qs, it); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get expected results, got:%v expect:%v", got, expect) } it.Reset() w.RemoveQuad(quad.Quad{"E", "follows", "F", ""}) expect = nil if got := iteratedQuads(qs, it); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get expected results, got:%v expect:%v", got, expect) } }
func makeTestStore(data []quad.Quad) (*QuadStore, graph.QuadWriter, []pair) { seen := make(map[string]struct{}) qs := newQuadStore() var ( val int64 ind []pair ) writer, _ := writer.NewSingleReplication(qs, nil) for _, t := range data { for _, dir := range quad.Directions { qp := t.GetString(dir) if _, ok := seen[qp]; !ok && qp != "" { val++ ind = append(ind, pair{qp, val}) seen[qp] = struct{}{} } } writer.WriteQuad(t) } return qs, writer, ind }
func makeTestStore(data []quad.Quad, opts graph.Options) (graph.QuadStore, graph.QuadWriter, []pair) { seen := make(map[quad.Value]struct{}) qs, _ := newQuadStore("", opts) qs, _ = newQuadStoreForRequest(qs, opts) var ( val int64 ind []pair ) writer, _ := writer.NewSingleReplication(qs, nil) for _, t := range data { for _, qp := range []quad.Value{t.Subject, t.Predicate, t.Object, t.Label} { if _, ok := seen[qp]; !ok && qp != nil { val++ ind = append(ind, pair{qp.String(), val}) seen[qp] = struct{}{} } } } writer.WriteQuads(data) return qs, writer, ind }
func TestSetIterator(t *testing.T) { tmpFile, _ := ioutil.TempFile(os.TempDir(), "cayley_test") t.Log(tmpFile.Name()) defer os.RemoveAll(tmpFile.Name()) err := createNewBolt(tmpFile.Name(), nil) if err != nil { t.Fatalf("Failed to create working directory") } qs, err := newQuadStore(tmpFile.Name(), nil) if qs == nil || err != nil { t.Error("Failed to create leveldb QuadStore.") } defer qs.Close() w, _ := writer.NewSingleReplication(qs, nil) w.AddQuadSet(makeQuadSet()) expect := []quad.Quad{ {"C", "follows", "B", ""}, {"C", "follows", "D", ""}, } sort.Sort(ordered(expect)) // Subject iterator. it := qs.QuadIterator(quad.Subject, qs.ValueOf("C")) if got := iteratedQuads(qs, it); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get expected results, got:%v expect:%v", got, expect) } it.Reset() and := iterator.NewAnd(qs) and.AddSubIterator(qs.QuadsAllIterator()) and.AddSubIterator(it) if got := iteratedQuads(qs, and); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get confirm expected results, got:%v expect:%v", got, expect) } // Object iterator. it = qs.QuadIterator(quad.Object, qs.ValueOf("F")) expect = []quad.Quad{ {"B", "follows", "F", ""}, {"E", "follows", "F", ""}, } sort.Sort(ordered(expect)) if got := iteratedQuads(qs, it); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get expected results, got:%v expect:%v", got, expect) } and = iterator.NewAnd(qs) and.AddSubIterator(qs.QuadIterator(quad.Subject, qs.ValueOf("B"))) and.AddSubIterator(it) expect = []quad.Quad{ {"B", "follows", "F", ""}, } if got := iteratedQuads(qs, and); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get confirm expected results, got:%v expect:%v", got, expect) } // Predicate iterator. it = qs.QuadIterator(quad.Predicate, qs.ValueOf("status")) expect = []quad.Quad{ {"B", "status", "cool", "status_graph"}, {"D", "status", "cool", "status_graph"}, {"G", "status", "cool", "status_graph"}, } sort.Sort(ordered(expect)) if got := iteratedQuads(qs, it); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get expected results from predicate iterator, got:%v expect:%v", got, expect) } // Label iterator. it = qs.QuadIterator(quad.Label, qs.ValueOf("status_graph")) expect = []quad.Quad{ {"B", "status", "cool", "status_graph"}, {"D", "status", "cool", "status_graph"}, {"G", "status", "cool", "status_graph"}, } sort.Sort(ordered(expect)) if got := iteratedQuads(qs, it); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get expected results from predicate iterator, got:%v expect:%v", got, expect) } it.Reset() // Order is important and = iterator.NewAnd(qs) and.AddSubIterator(qs.QuadIterator(quad.Subject, qs.ValueOf("B"))) and.AddSubIterator(it) expect = []quad.Quad{ {"B", "status", "cool", "status_graph"}, } if got := iteratedQuads(qs, and); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get confirm expected results, got:%v expect:%v", got, expect) } it.Reset() // Order is important and = iterator.NewAnd(qs) and.AddSubIterator(it) and.AddSubIterator(qs.QuadIterator(quad.Subject, qs.ValueOf("B"))) expect = []quad.Quad{ {"B", "status", "cool", "status_graph"}, } if got := iteratedQuads(qs, and); !reflect.DeepEqual(got, expect) { t.Errorf("Failed to get confirm expected results, got:%v expect:%v", got, expect) } }
func TestIterator(t *testing.T) { tmpFile, err := ioutil.TempFile(os.TempDir(), "cayley_test") if err != nil { t.Fatalf("Could not create working directory: %v", err) } defer os.RemoveAll(tmpFile.Name()) t.Log(tmpFile.Name()) err = createNewBolt(tmpFile.Name(), nil) if err != nil { t.Fatal("Failed to create LevelDB database.") } qs, err := newQuadStore(tmpFile.Name(), nil) if qs == nil || err != nil { t.Error("Failed to create leveldb QuadStore.") } w, _ := writer.NewSingleReplication(qs, nil) w.AddQuadSet(makeQuadSet()) var it graph.Iterator it = qs.NodesAllIterator() if it == nil { t.Fatal("Got nil iterator.") } size, _ := it.Size() if size <= 0 || size >= 20 { t.Errorf("Unexpected size, got:%d expect:(0, 20)", size) } if typ := it.Type(); typ != graph.All { t.Errorf("Unexpected iterator type, got:%v expect:%v", typ, graph.All) } optIt, changed := it.Optimize() if changed || optIt != it { t.Errorf("Optimize unexpectedly changed iterator.") } expect := []string{ "A", "B", "C", "D", "E", "F", "G", "follows", "status", "cool", "status_graph", } sort.Strings(expect) for i := 0; i < 2; i++ { got := iteratedNames(qs, it) sort.Strings(got) if !reflect.DeepEqual(got, expect) { t.Errorf("Unexpected iterated result on repeat %d, got:%v expect:%v", i, got, expect) } it.Reset() } for _, pq := range expect { if !it.Contains(qs.ValueOf(pq)) { t.Errorf("Failed to find and check %q correctly", pq) } } // FIXME(kortschak) Why does this fail? /* for _, pq := range []string{"baller"} { if it.Contains(qs.ValueOf(pq)) { t.Errorf("Failed to check %q correctly", pq) } } */ it.Reset() it = qs.QuadsAllIterator() graph.Next(it) fmt.Printf("%#v\n", it.Result()) q := qs.Quad(it.Result()) fmt.Println(q) set := makeQuadSet() var ok bool for _, e := range set { if e.String() == q.String() { ok = true break } } if !ok { t.Errorf("Failed to find %q during iteration, got:%q", q, set) } qs.Close() }
func TestLoadDatabase(t *testing.T) { tmpFile, err := ioutil.TempFile(os.TempDir(), "cayley_test") if err != nil { t.Fatalf("Could not create working directory: %v", err) } defer os.RemoveAll(tmpFile.Name()) t.Log(tmpFile.Name()) err = createNewBolt(tmpFile.Name(), nil) if err != nil { t.Fatal("Failed to create Bolt database.", err) } qs, err := newQuadStore(tmpFile.Name(), nil) if qs == nil || err != nil { t.Error("Failed to create Bolt QuadStore.") } w, _ := writer.NewSingleReplication(qs, nil) w.AddQuad(quad.Quad{ Subject: "Something", Predicate: "points_to", Object: "Something Else", Label: "context", }) for _, pq := range []string{"Something", "points_to", "Something Else", "context"} { if got := qs.NameOf(qs.ValueOf(pq)); got != pq { t.Errorf("Failed to roundtrip %q, got:%q expect:%q", pq, got, pq) } } if s := qs.Size(); s != 1 { t.Errorf("Unexpected quadstore size, got:%d expect:1", s) } qs.Close() os.RemoveAll(tmpFile.Name()) err = createNewBolt(tmpFile.Name(), nil) if err != nil { t.Fatal("Failed to create Bolt database.", err) } qs, err = newQuadStore(tmpFile.Name(), nil) if qs == nil || err != nil { t.Error("Failed to create Bolt QuadStore.") } w, _ = writer.NewSingleReplication(qs, nil) ts2, didConvert := qs.(*QuadStore) if !didConvert { t.Errorf("Could not convert from generic to LevelDB QuadStore") } //Test horizon horizon := qs.Horizon() if horizon.Int() != 0 { t.Errorf("Unexpected horizon value, got:%d expect:0", horizon.Int()) } w.AddQuadSet(makeQuadSet()) if s := qs.Size(); s != 11 { t.Errorf("Unexpected quadstore size, got:%d expect:11", s) } if s := ts2.SizeOf(qs.ValueOf("B")); s != 5 { t.Errorf("Unexpected quadstore size, got:%d expect:5", s) } horizon = qs.Horizon() if horizon.Int() != 11 { t.Errorf("Unexpected horizon value, got:%d expect:11", horizon.Int()) } w.RemoveQuad(quad.Quad{ Subject: "A", Predicate: "follows", Object: "B", Label: "", }) if s := qs.Size(); s != 10 { t.Errorf("Unexpected quadstore size after RemoveQuad, got:%d expect:10", s) } if s := ts2.SizeOf(qs.ValueOf("B")); s != 4 { t.Errorf("Unexpected quadstore size, got:%d expect:4", s) } qs.Close() }
func TestLoadDatabase(t *testing.T) { tmpDir, err := ioutil.TempDir(os.TempDir(), "cayley_test") if err != nil { t.Fatalf("Could not create working directory: %v", err) } defer os.RemoveAll(tmpDir) t.Log(tmpDir) err = createNewLevelDB(tmpDir, nil) if err != nil { t.Fatal("Failed to create LevelDB database.") } qs, err := newTripleStore(tmpDir, nil) if qs == nil || err != nil { t.Error("Failed to create leveldb TripleStore.") } w, _ := writer.NewSingleReplication(qs, nil) w.AddQuad(quad.Quad{"Something", "points_to", "Something Else", "context"}) for _, pq := range []string{"Something", "points_to", "Something Else", "context"} { if got := qs.NameOf(qs.ValueOf(pq)); got != pq { t.Errorf("Failed to roundtrip %q, got:%q expect:%q", pq, got, pq) } } if s := qs.Size(); s != 1 { t.Errorf("Unexpected triplestore size, got:%d expect:1", s) } qs.Close() err = createNewLevelDB(tmpDir, nil) if err != nil { t.Fatal("Failed to create LevelDB database.") } qs, err = newTripleStore(tmpDir, nil) if qs == nil || err != nil { t.Error("Failed to create leveldb TripleStore.") } w, _ = writer.NewSingleReplication(qs, nil) ts2, didConvert := qs.(*TripleStore) if !didConvert { t.Errorf("Could not convert from generic to LevelDB TripleStore") } w.AddQuadSet(makeTripleSet()) if s := qs.Size(); s != 11 { t.Errorf("Unexpected triplestore size, got:%d expect:11", s) } if s := ts2.SizeOf(qs.ValueOf("B")); s != 5 { t.Errorf("Unexpected triplestore size, got:%d expect:5", s) } w.RemoveQuad(quad.Quad{"A", "follows", "B", ""}) if s := qs.Size(); s != 10 { t.Errorf("Unexpected triplestore size after RemoveTriple, got:%d expect:10", s) } if s := ts2.SizeOf(qs.ValueOf("B")); s != 4 { t.Errorf("Unexpected triplestore size, got:%d expect:4", s) } qs.Close() }
func TestLoadDatabase(t *testing.T) { tmpDir, err := ioutil.TempDir(os.TempDir(), "cayley_test") if err != nil { t.Fatalf("Could not create working directory: %v", err) } defer os.RemoveAll(tmpDir) t.Log(tmpDir) err = createNewLevelDB(tmpDir, nil) if err != nil { t.Fatal("Failed to create LevelDB database.") } qs, err := newQuadStore(tmpDir, nil) if qs == nil || err != nil { t.Error("Failed to create leveldb QuadStore.") } w, _ := writer.NewSingleReplication(qs, nil) err = w.WriteQuad(quad.Make( "Something", "points_to", "Something Else", "context", )) if err != nil { t.Fatal("Failed to add quad:", err) } for _, pq := range []string{"Something", "points_to", "Something Else", "context"} { if got := quad.StringOf(qs.NameOf(qs.ValueOf(quad.Raw(pq)))); got != pq { t.Errorf("Failed to roundtrip %q, got:%q expect:%q", pq, got, pq) } } if s := qs.Size(); s != 1 { t.Errorf("Unexpected quadstore size, got:%d expect:1", s) } qs.Close() err = createNewLevelDB(tmpDir, nil) if err != graph.ErrDatabaseExists { t.Fatal("Failed to create LevelDB database.") } qs, err = newQuadStore(tmpDir, nil) if qs == nil || err != nil { t.Error("Failed to create leveldb QuadStore.") } w, _ = writer.NewSingleReplication(qs, nil) ts2, didConvert := qs.(*QuadStore) if !didConvert { t.Errorf("Could not convert from generic to LevelDB QuadStore") } //Test horizon horizon := qs.Horizon() if horizon.Int() != 1 { t.Errorf("Unexpected horizon value, got:%d expect:1", horizon.Int()) } w.WriteQuads(graphtest.MakeQuadSet()) if s := qs.Size(); s != 12 { t.Errorf("Unexpected quadstore size, got:%d expect:12", s) } if s := ts2.SizeOf(qs.ValueOf(quad.Raw("B"))); s != 5 { t.Errorf("Unexpected quadstore size, got:%d expect:5", s) } horizon = qs.Horizon() if horizon.Int() != 12 { t.Errorf("Unexpected horizon value, got:%d expect:12", horizon.Int()) } w.RemoveQuad(quad.Make( "A", "follows", "B", "", )) if s := qs.Size(); s != 11 { t.Errorf("Unexpected quadstore size after RemoveQuad, got:%d expect:11", s) } if s := ts2.SizeOf(qs.ValueOf(quad.Raw("B"))); s != 4 { t.Errorf("Unexpected quadstore size, got:%d expect:4", s) } qs.Close() }