Beispiel #1
0
func (tbl *testTable) Construct(t *testing.T) xrefs.Service {
	p := make(testProtoTable)
	tickets := stringset.New()
	for _, n := range tbl.Nodes {
		tickets.Add(n.Ticket)
	}
	for _, es := range tbl.EdgeSets {
		tickets.Remove(es.EdgeSet.Source.Ticket)
		testutil.FatalOnErrT(t, "Error writing edge set: %v", p.Put(ctx, EdgeSetKey(mustFix(t, es.EdgeSet.Source.Ticket)), es))
	}
	// Fill in EdgeSets for zero-degree nodes
	for ticket := range tickets {
		es := &srvpb.PagedEdgeSet{
			EdgeSet: &srvpb.EdgeSet{
				Source: getNode(ticket),
			},
		}
		testutil.FatalOnErrT(t, "Error writing edge set: %v", p.Put(ctx, EdgeSetKey(mustFix(t, es.EdgeSet.Source.Ticket)), es))
	}
	for _, ep := range tbl.EdgePages {
		testutil.FatalOnErrT(t, "Error writing edge page: %v", p.Put(ctx, []byte(edgePagesTablePrefix+ep.PageKey), ep))
	}
	for _, d := range tbl.Decorations {
		testutil.FatalOnErrT(t, "Error writing file decorations: %v", p.Put(ctx, DecorationsKey(mustFix(t, d.FileTicket)), d))
	}
	return NewCombinedTable(table.ProtoBatchParallel{p})
}
Beispiel #2
0
func TestAsyncNilCallbacks(t *testing.T) {
	done := make(chan struct{}, 1)

	err := StartAsync(exec.Command(find(t, "true")), &Callbacks{
		OnExit: func(state *os.ProcessState, err error) {
			done <- struct{}{}
		},
	})
	testutil.FatalOnErrT(t, "Error starting async: %v", err)

	err = StartAsync(exec.Command(find(t, "false")), &Callbacks{
		OnExit: func(state *os.ProcessState, err error) {
			done <- struct{}{}
		},
	})
	testutil.FatalOnErrT(t, "Error starting async: %v", err)

	err = StartAsync(exec.Command(find(t, "true")), &Callbacks{
		OnSuccess: func(state *os.ProcessState) {
			done <- struct{}{}
		},
	})
	testutil.FatalOnErrT(t, "Error starting async: %v", err)

	timeout := time.After(5 * time.Second)
	for i := 0; i < 3; i++ {
		select {
		case <-done:
		case <-timeout:
			t.Fatal("Process did not finish before timeout")
		}
	}
}
Beispiel #3
0
func TestNodes(t *testing.T) {
	st := tbl.Construct(t)

	for _, node := range tbl.Nodes {
		reply, err := st.Nodes(ctx, &xpb.NodesRequest{
			Ticket: []string{node.Ticket},
		})
		testutil.FatalOnErrT(t, "NodesRequest error: %v", err)

		if len(reply.Node) != 1 {
			t.Fatalf("Expected 1 node for %q; found %d: {%v}", node.Ticket, len(reply.Node), reply)
		} else if expected := nodeInfo(node); !reflect.DeepEqual(reply.Node[0], expected) {
			t.Fatalf("Expected {%v}; received {%v}", expected, reply.Node[0])
		}
	}

	var tickets []string
	var expected []*xpb.NodeInfo
	for _, n := range tbl.Nodes {
		tickets = append(tickets, n.Ticket)
		expected = append(expected, nodeInfo(n))
	}
	reply, err := st.Nodes(ctx, &xpb.NodesRequest{Ticket: tickets})
	testutil.FatalOnErrT(t, "NodesRequest error: %v", err)

	sort.Sort(byNodeTicket(expected))
	sort.Sort(byNodeTicket(reply.Node))

	if !reflect.DeepEqual(expected, reply.Node) {
		t.Fatalf("Expected {%v}; received {%v}", expected, reply.Node)
	}
}
Beispiel #4
0
func TestNodes(t *testing.T) {
	st := tbl.Construct(t)

	for _, node := range tbl.Nodes {
		reply, err := st.Nodes(ctx, &xpb.NodesRequest{
			Ticket: []string{node.Ticket},
		})
		testutil.FatalOnErrT(t, "NodesRequest error: %v", err)

		if len(reply.Nodes) != 1 {
			t.Fatalf("Expected 1 node for %q; found %d: {%v}", node.Ticket, len(reply.Nodes), reply)
		} else if err := testutil.DeepEqual(nodeInfo(node), reply.Nodes[node.Ticket]); err != nil {
			t.Fatal(err)
		}
	}

	var tickets []string
	expected := make(map[string]*xpb.NodeInfo)
	for _, n := range tbl.Nodes {
		tickets = append(tickets, n.Ticket)
		expected[n.Ticket] = nodeInfo(n)
	}
	reply, err := st.Nodes(ctx, &xpb.NodesRequest{Ticket: tickets})
	testutil.FatalOnErrT(t, "NodesRequest error: %v", err)

	if err := testutil.DeepEqual(expected, reply.Nodes); err != nil {
		t.Fatal(err)
	}
}
Beispiel #5
0
// OrderTest tests the ordering of the streamed entries while reading from the
// CreateFunc created graphstore.Service.
func OrderTest(t *testing.T, create CreateFunc, batchSize int) {
	gs, destroy, err := create()
	testutil.FatalOnErrT(t, "CreateFunc error: %v", err)
	defer func() {
		testutil.FatalOnErrT(t, "gs close error: %v", gs.Close(ctx))
		testutil.FatalOnErrT(t, "DestroyFunc error: %v", destroy())
	}()

	updates := make([]spb.WriteRequest_Update, batchSize)
	req := &spb.WriteRequest{
		Source: &spb.VName{},
		Update: make([]*spb.WriteRequest_Update, batchSize),
	}
	for i := 0; i < 1024; i++ {
		randVName(req.Source, keySize)

		for j := 0; j < batchSize; j++ {
			randUpdate(&updates[j], keySize)
			req.Update[j] = &updates[j]
		}

		testutil.FatalOnErrT(t, "write error: %v", gs.Write(ctx, req))
	}

	var lastEntry *spb.Entry
	testutil.FatalOnErrT(t, "entryLess error: %v",
		gs.Scan(ctx, new(spb.ScanRequest), func(entry *spb.Entry) error {
			if compare.Entries(lastEntry, entry) != compare.LT {
				return fmt.Errorf("expected {%v} < {%v}", lastEntry, entry)
			}
			return nil
		}))
}
Beispiel #6
0
func TestParse(t *testing.T) {
	tests := []struct {
		str string
		sz  Size
	}{
		{"0", 0},
		{"1024", 1024 * Byte},
		{"100", 100 * Byte},
		{"0tb", 0},
		{"1b", Byte},
		{"1kb", Kilobyte},
		{"1mb", Megabyte},
		{"1Gb", Gigabyte},
		{"1tb", Terabyte},
		{"1Pb", Petabyte},
		{"1KiB", Kibibyte},
		{"1mib", Mebibyte},
		{"1gib", Gibibyte},
		{"1tib", Tebibyte},
		{"1PiB", Pebibyte},
		{"4TB", 4 * Terabyte},
		{"43.5MB", Size(43.5 * float64(Megabyte))},
	}

	for _, test := range tests {
		found, err := Parse(test.str)
		testutil.FatalOnErrT(t, "Unexpected error: %v", err)
		if found != test.sz {
			t.Errorf("Parse(%q): expected: %s; found: %s", test.str, test.sz, found)
		}
	}
}
Beispiel #7
0
func (tbl *testTable) Construct(t *testing.T) xrefs.Service {
	p := make(testProtoTable)
	for _, n := range tbl.Nodes {
		testutil.FatalOnErrT(t, "Error writing node: %v", p.Put(ctx, NodeKey(mustFix(t, n.Ticket)), n))
	}
	for _, es := range tbl.EdgeSets {
		testutil.FatalOnErrT(t, "Error writing edge set: %v", p.Put(ctx, EdgeSetKey(mustFix(t, es.EdgeSet.SourceTicket)), es))
	}
	for _, ep := range tbl.EdgePages {
		testutil.FatalOnErrT(t, "Error writing edge page: %v", p.Put(ctx, []byte(edgePagesTablePrefix+ep.PageKey), ep))
	}
	for _, d := range tbl.Decorations {
		testutil.FatalOnErrT(t, "Error writing file decorations: %v", p.Put(ctx, DecorationsKey(mustFix(t, d.FileTicket)), d))
	}
	return NewCombinedTable(table.ProtoBatchParallel{p})
}
Beispiel #8
0
func TestDriverErrorHandler(t *testing.T) {
	m := &mock{
		t:            t,
		Outputs:      outs("a", "b", "c"),
		Compilations: comps("target1", "target2"),
		AnalyzeError: errFromAnalysis,
	}
	var analysisErr error
	d := &Driver{
		Analyzer:     m,
		Compilations: m,
		Output:       m.out(),
		AnalysisError: func(_ context.Context, cu *apb.CompilationUnit, err error) error {
			analysisErr = err
			return nil // don't return err
		},
	}
	testutil.FatalOnErrT(t, "Driver error: %v", d.Run(context.Background()))
	if len(m.Requests) != len(m.Compilations) {
		t.Errorf("Expected %d AnalysisRequests; found %v", len(m.Compilations), m.Requests)
	}
	if analysisErr != errFromAnalysis {
		t.Errorf("Expected AnalysisError: %v; found: %v", errFromAnalysis, analysisErr)
	}
}
Beispiel #9
0
func TestDriver(t *testing.T) {
	m := &mock{
		t:            t,
		Outputs:      outs("a", "b", "c"),
		Compilations: comps("target1", "target2"),
	}
	var setupIdx, teardownIdx int
	d := &Driver{
		Analyzer:     m,
		Compilations: m,
		Output:       m.out(),
		Setup: func(_ context.Context, cu *apb.CompilationUnit) error {
			setupIdx++
			return nil
		},
		Teardown: func(_ context.Context, cu *apb.CompilationUnit) error {
			if setupIdx != teardownIdx+1 {
				t.Error("Teardown was not called directly after Setup/Analyze")
			}
			teardownIdx++
			return nil
		},
	}
	testutil.FatalOnErrT(t, "Driver error: %v", d.Run(context.Background()))
	if len(m.Requests) != len(m.Compilations) {
		t.Errorf("Expected %d AnalysisRequests; found %v", len(m.Compilations), m.Requests)
	}
	if setupIdx != len(m.Compilations) {
		t.Errorf("Expected %d calls to Setup; found %d", len(m.Compilations), setupIdx)
	}
	if teardownIdx != len(m.Compilations) {
		t.Errorf("Expected %d calls to Teardown; found %d", len(m.Compilations), teardownIdx)
	}
}
Beispiel #10
0
func TestDecorationsRefs(t *testing.T) {
	d := tbl.Decorations[1]

	st := tbl.Construct(t)
	reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
		Location:   &xpb.Location{Ticket: d.FileTicket},
		References: true,
		Filter:     []string{"**"},
	})
	testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)

	if len(reply.SourceText) != 0 {
		t.Errorf("Unexpected source text: %q", string(d.SourceText))
	}
	if reply.Encoding != "" {
		t.Errorf("Unexpected encoding: %q", d.Encoding)
	}

	expected := refs(xrefs.NewNormalizer(d.SourceText), d.Decoration)
	if !reflect.DeepEqual(expected, reply.Reference) {
		t.Fatalf("Expected references %v; found %v", expected, reply.Reference)
	}

	expectedNodes := nodeInfos(tbl.Nodes[7:13])

	sort.Sort(byNodeTicket(expectedNodes))
	sort.Sort(byNodeTicket(reply.Node))

	if err := testutil.DeepEqual(expectedNodes, reply.Node); err != nil {
		t.Fatal(err)
	}
}
Beispiel #11
0
func TestDecorationsDirtyBuffer(t *testing.T) {
	d := tbl.Decorations[1]

	st := tbl.Construct(t)
	dirty := []byte(`(defn map [f coll]
  (if (seq coll)
    []
    (cons (f (first coll)) (map f (rest coll)))))
`)
	reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
		Location:    &xpb.Location{Ticket: d.FileTicket},
		DirtyBuffer: dirty,
		References:  true,
		Filter:      []string{"**"},
	})
	testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)

	if len(reply.SourceText) != 0 {
		t.Errorf("Unexpected source text: %q", string(d.SourceText))
	}
	if reply.Encoding != "" {
		t.Errorf("Unexpected encoding: %q", d.Encoding)
	}

	p := xrefs.NewPatcher(d.SourceText, dirty)
	norm := xrefs.NewNormalizer(dirty)
	var expected []*xpb.DecorationsReply_Reference
	for _, d := range d.Decoration {
		if _, _, exists := p.Patch(d.Anchor.StartOffset, d.Anchor.EndOffset); exists {
			expected = append(expected, decorationToReference(norm, d))
		}
	}
	if !reflect.DeepEqual(expected, reply.Reference) {
		t.Fatalf("Expected references %v; found %v", expected, reply.Reference)
	}

	// These are a subset of the anchor nodes in tbl.Decorations[1].  tbl.Nodes[8]
	// and tbl.Nodes[10] are missing because [8] was an anchor in the edited
	// region and [10] was its target.
	expectedNodes := nodeInfos([]*srvpb.Node{
		tbl.Nodes[7], tbl.Nodes[9], tbl.Nodes[11], tbl.Nodes[12],
	})

	// Ensure patching affects the anchor node facts
	mapFacts(expectedNodes[2], map[string]string{
		"/kythe/loc/start": "48",
		"/kythe/loc/end":   "52",
	})

	sort.Sort(byNodeTicket(expectedNodes))
	sort.Sort(byNodeTicket(reply.Node))

	if !reflect.DeepEqual(expectedNodes, reply.Node) {
		t.Fatalf("Expected nodes %v; found %v", expected, reply.Node)
	}
}
Beispiel #12
0
func TestEdgesMissing(t *testing.T) {
	st := tbl.Construct(t)
	reply, err := st.Edges(ctx, &xpb.EdgesRequest{
		Ticket: []string{"kythe:#someMissingTicket"},
	})
	testutil.FatalOnErrT(t, "EdgesRequest error: %v", err)

	if len(reply.EdgeSet) > 0 || len(reply.Node) > 0 || reply.NextPageToken != "" {
		t.Fatalf("Received unexpected reply for missing edges: {%v}", reply)
	}
}
Beispiel #13
0
func TestNodesMissing(t *testing.T) {
	st := tbl.Construct(t)
	reply, err := st.Nodes(ctx, &xpb.NodesRequest{
		Ticket: []string{"kythe:#someMissingTicket"},
	})
	testutil.FatalOnErrT(t, "NodesRequest error: %v", err)

	if len(reply.Node) > 0 {
		t.Fatalf("Received unexpected reply for missing node: {%v}", reply)
	}
}
Beispiel #14
0
func TestDriverEmpty(t *testing.T) {
	m := &mock{t: t}
	d := &Driver{
		Analyzer:     m,
		Compilations: m,
		Output:       m.out(),
	}
	testutil.FatalOnErrT(t, "Driver error: %v", d.Run(context.Background()))
	if len(m.Requests) != 0 {
		t.Fatalf("Unexpected AnalysisRequests: %v", m.Requests)
	}
}
Beispiel #15
0
func (tbl *testTable) Construct(t *testing.T) *Table {
	p := make(testProtoTable)
	var tickets stringset.Set
	for _, n := range tbl.Nodes {
		tickets.Add(n.Ticket)
	}
	for _, es := range tbl.EdgeSets {
		tickets.Discard(es.Source.Ticket)
		testutil.FatalOnErrT(t, "Error writing edge set: %v", p.Put(ctx, EdgeSetKey(mustFix(t, es.Source.Ticket)), es))
	}
	// Fill in EdgeSets for zero-degree nodes
	for ticket := range tickets {
		es := &srvpb.PagedEdgeSet{
			Source: getNode(ticket),
		}
		testutil.FatalOnErrT(t, "Error writing edge set: %v", p.Put(ctx, EdgeSetKey(mustFix(t, es.Source.Ticket)), es))
	}
	for _, ep := range tbl.EdgePages {
		testutil.FatalOnErrT(t, "Error writing edge page: %v", p.Put(ctx, EdgePageKey(ep.PageKey), ep))
	}
	for _, d := range tbl.Decorations {
		testutil.FatalOnErrT(t, "Error writing file decorations: %v", p.Put(ctx, DecorationsKey(mustFix(t, d.File.Ticket)), d))
	}
	for _, cr := range tbl.RefSets {
		testutil.FatalOnErrT(t, "Error writing cross-references: %v", p.Put(ctx, CrossReferencesKey(mustFix(t, cr.SourceTicket)), cr))
	}
	for _, crp := range tbl.RefPages {
		testutil.FatalOnErrT(t, "Error writing cross-references: %v", p.Put(ctx, CrossReferencesPageKey(crp.PageKey), crp))
	}
	return NewCombinedTable(table.ProtoBatchParallel{p})
}
Beispiel #16
0
func TestDecorationsEmpty(t *testing.T) {
	st := tbl.Construct(t)
	reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
		Location: &xpb.Location{
			Ticket: tbl.Decorations[0].FileTicket,
		},
		References: true,
	})
	testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)

	if len(reply.Reference) > 0 {
		t.Fatalf("Unexpected DecorationsReply: {%v}", reply)
	}
}
Beispiel #17
0
func TestCrossReferencesNone(t *testing.T) {
	st := tbl.Construct(t)
	reply, err := st.CrossReferences(ctx, &xpb.CrossReferencesRequest{
		Ticket:            []string{"kythe://someCorpus?lang=otpl#sig2"},
		DocumentationKind: xpb.CrossReferencesRequest_ALL_DOCUMENTATION,
		DefinitionKind:    xpb.CrossReferencesRequest_ALL_DEFINITIONS,
		ReferenceKind:     xpb.CrossReferencesRequest_ALL_REFERENCES,
	})
	testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)

	if len(reply.CrossReferences) > 0 || len(reply.Nodes) > 0 {
		t.Fatalf("Expected empty CrossReferencesReply; found %v", reply)
	}
}
Beispiel #18
0
func TestEdgesMultiPage(t *testing.T) {
	tests := []struct {
		Ticket string
		Kinds  []string

		EdgeSet *srvpb.PagedEdgeSet
		Pages   []*srvpb.EdgePage
	}{{
		Ticket:  tbl.EdgeSets[1].Source.Ticket,
		EdgeSet: tbl.EdgeSets[1],
		Pages:   []*srvpb.EdgePage{tbl.EdgePages[1], tbl.EdgePages[2]},
	}}

	st := tbl.Construct(t)

	for _, test := range tests {
		reply, err := st.Edges(ctx, &xpb.EdgesRequest{
			Ticket: []string{test.Ticket},
			Kind:   test.Kinds,
		})
		testutil.FatalOnErrT(t, "EdgesRequest error: %v", err)

		if len(reply.Nodes) > 0 {
			t.Errorf("Received unexpected nodes in EdgesReply: {%v}", reply)
		}
		if reply.NextPageToken != "" {
			t.Errorf("Received unexpected next_page_token in EdgesReply: {%v}", reply)
		}
		if len(reply.EdgeSets) != 1 {
			t.Errorf("Expected 1 EdgeSet in EdgesReply; found %d: {%v}", len(reply.EdgeSets), reply)
		}

		expected := edgeSet(test.Kinds, test.EdgeSet, test.Pages)
		if err := testutil.DeepEqual(expected, reply.EdgeSets[test.Ticket]); err != nil {
			t.Error(err)
		}
		if err := testutil.DeepEqual(map[string]int64{
			"%/kythe/edge/defines/binding": 1,
			"%/kythe/edge/ref":             2,
			"someEdgeKind":                 2,
			"anotherEdge":                  1,
		}, reply.TotalEdgesByKind); err != nil {
			t.Error(err)
		}
	}
}
Beispiel #19
0
func TestIsUnique(t *testing.T) {
	d, err := New(HashSize * 2)
	testutil.FatalOnErrT(t, "Error creating Deduper: %v", err)

	tests := []struct {
		val  string
		uniq bool
	}{
		{"a", true},
		{"a", false},
		{"a", false},
		{"b", true},
		{"a", false},
		{"b", false},
		{"c", true},
		// cache size exceeded (impl-specific behavior below)
		{"c", false},
		{"b", false},
		{"a", true},
		// cache size exceeded
		{"c", false},
		{"b", true},
	}

	var unique, duplicates uint64
	for _, test := range tests {
		uniq := d.IsUnique([]byte(test.val))
		if uniq != test.uniq {
			t.Fatalf("Expected IsUnique(%v) to be %s; found it wasn't", test.uniq, test.val)
		}
		if uniq {
			unique++
		} else {
			duplicates++
		}
		if found := d.Unique(); unique != found {
			t.Fatalf("Expected Unique() == %d; found %d", unique, found)
		}
		if found := d.Duplicates(); duplicates != found {
			t.Fatalf("Expected Duplicates() == %d; found %d", unique, found)
		}
	}
}
Beispiel #20
0
func TestDecorationsSourceText(t *testing.T) {
	expected := tbl.Decorations[0]

	st := tbl.Construct(t)
	reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
		Location:   &xpb.Location{Ticket: expected.FileTicket},
		SourceText: true,
	})
	testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)

	if !bytes.Equal(reply.SourceText, expected.SourceText) {
		t.Errorf("Expected source text %q; found %q", string(expected.SourceText), string(reply.SourceText))
	}
	if reply.Encoding != expected.Encoding {
		t.Errorf("Expected source text %q; found %q", expected.Encoding, reply.Encoding)
	}
	if len(reply.Reference) > 0 {
		t.Errorf("Unexpected references in DecorationsReply %v", reply.Reference)
	}
}
Beispiel #21
0
func TestEdgesSinglePage(t *testing.T) {
	tests := []struct {
		Tickets []string
		Kinds   []string

		EdgeSet *srvpb.PagedEdgeSet
	}{{
		Tickets: []string{tbl.EdgeSets[0].EdgeSet.SourceTicket},
		EdgeSet: tbl.EdgeSets[0],
	}, {
		Tickets: []string{tbl.EdgeSets[0].EdgeSet.SourceTicket},
		Kinds:   []string{"someEdgeKind", "anotherEdge"},
		EdgeSet: tbl.EdgeSets[0],
	}}

	st := tbl.Construct(t)

	for _, test := range tests {
		reply, err := st.Edges(ctx, &xpb.EdgesRequest{
			Ticket: test.Tickets,
			Kind:   test.Kinds,
		})
		testutil.FatalOnErrT(t, "EdgesRequest error: %v", err)

		if len(reply.Node) > 0 {
			t.Errorf("Received unexpected nodes in EdgesReply: {%v}", reply)
		}
		if reply.NextPageToken != "" {
			t.Errorf("Received unexpected next_page_token in EdgesReply: {%v}", reply)
		}
		if len(reply.EdgeSet) != 1 {
			t.Errorf("Expected 1 EdgeSet in EdgesReply; found %d: {%v}", len(reply.EdgeSet), reply)
		}

		expected := edgeSet(test.Kinds, test.EdgeSet, nil)
		if !reflect.DeepEqual(reply.EdgeSet[0], expected) {
			t.Errorf("Expected {%v}; found {%v}", expected, reply.EdgeSet)
		}
	}
}
Beispiel #22
0
func TestAsyncError(t *testing.T) {
	done := make(chan struct{}, 1)
	err := StartAsync(exec.Command(find(t, "false")), &Callbacks{
		OnStart: func(p *os.Process) {
			if p == nil {
				t.Error("Process was nil")
			}
			done <- struct{}{}
		},
		OnExit: func(state *os.ProcessState, err error) {
			if err == nil {
				t.Errorf("Process exited with no error: %v", state)
			}
			done <- struct{}{}
		},
		OnSuccess: func(state *os.ProcessState) {
			t.Errorf("Process was unexpectedly successful: %v", state)
		},
		OnError: func(state *os.ProcessState, err error) {
			if state.Success() {
				t.Errorf("Process was unexpectedly successful: %v", state)
			}
			if !state.Exited() {
				t.Errorf("Process did not exit: %v", state)
			}
			done <- struct{}{}
		},
	})
	testutil.FatalOnErrT(t, "Error starting async: %v", err)

	timeout := time.After(5 * time.Second)
	for i := 0; i < 3; i++ {
		select {
		case <-done:
		case <-timeout:
			t.Fatal("Process did not finish before timeout")
		}
	}
}
Beispiel #23
0
func TestEdgesLastPage(t *testing.T) {
	tests := [][]string{
		nil, // all kinds
		{"%/kythe/edge/ref"},
		{"%/kythe/edge/defines/binding"},
	}

	tickets := []string{tbl.EdgeSets[1].Source.Ticket}
	es := tbl.EdgeSets[1]
	pages := []*srvpb.EdgePage{tbl.EdgePages[1], tbl.EdgePages[2]}

	st := tbl.Construct(t)

	for _, kinds := range tests {
		reply, err := st.Edges(ctx, &xpb.EdgesRequest{
			Ticket: tickets,
			Kind:   kinds,
		})
		testutil.FatalOnErrT(t, "EdgesRequest error: %v", err)

		if len(reply.Node) > 0 {
			t.Errorf("Received unexpected nodes in EdgesReply: {%v}", reply)
		}
		if reply.NextPageToken != "" {
			t.Errorf("Received unexpected next_page_token in EdgesReply: {%v}", reply)
		}
		if len(reply.EdgeSet) != 1 {
			t.Fatalf("Expected 1 EdgeSet in EdgesReply; found %d: {%v}", len(reply.EdgeSet), reply)
		}

		expected := edgeSet(kinds, es, pages)
		if !reflect.DeepEqual(reply.EdgeSet[0], expected) {
			t.Errorf("Expected {%v}; found {%v}", expected, reply.EdgeSet)
		}
	}
}
Beispiel #24
0
func TestCrossReferences(t *testing.T) {
	ticket := "kythe://someCorpus?lang=otpl#signature"

	st := tbl.Construct(t)
	reply, err := st.CrossReferences(ctx, &xpb.CrossReferencesRequest{
		Ticket:         []string{ticket},
		DefinitionKind: xpb.CrossReferencesRequest_BINDING_DEFINITIONS,
		ReferenceKind:  xpb.CrossReferencesRequest_ALL_REFERENCES,
	})
	testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)

	expected := &xpb.CrossReferencesReply_CrossReferenceSet{
		Ticket: ticket,

		Reference: []*xpb.Anchor{{
			Ticket: "kythe://c?lang=otpl?path=/a/path#51-55",
			Kind:   "/kythe/edge/ref",
			Parent: "kythe://someCorpus?path=some/path#aFileNode",

			Start: &xpb.Location_Point{
				ByteOffset:   51,
				LineNumber:   4,
				ColumnOffset: 15,
			},
			End: &xpb.Location_Point{
				ByteOffset:   55,
				LineNumber:   5,
				ColumnOffset: 2,
			},

			Snippet: "some random text",
		}},

		Definition: []*xpb.Anchor{{
			Ticket: "kythe://c?lang=otpl?path=/a/path#27-33",
			Kind:   "/kythe/edge/defines/binding",
			Parent: "kythe://someCorpus?path=some/path#aFileNode",

			Start: &xpb.Location_Point{
				ByteOffset:   27,
				LineNumber:   2,
				ColumnOffset: 10,
			},
			End: &xpb.Location_Point{
				ByteOffset:   33,
				LineNumber:   3,
				ColumnOffset: 5,
			},

			Snippet: "here and  ",
		}},
	}

	xr := reply.CrossReferences[ticket]
	if xr == nil {
		log.Fatal("Missing expected CrossReferences")
	}

	if err := testutil.DeepEqual(expected, xr); err != nil {
		t.Fatal(err)
	}
}
Beispiel #25
0
func TestEdgeSetBuilder(t *testing.T) {
	tests := []struct {
		src       *srvpb.Node
		grp       *srvpb.EdgeGroup
		edgeSet   *srvpb.PagedEdgeSet
		edgePages []*srvpb.EdgePage
	}{{
		src: getNode("someSource"),
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "someEdgeKind",
			Edge: getEdgeTargets("kythe:#aTarget"),
		},
	}, {
		// flush
		edgeSet: &srvpb.PagedEdgeSet{
			Source: getNode("someSource"),
			Group: []*srvpb.EdgeGroup{{
				Kind: "someEdgeKind",
				Edge: getEdgeTargets("kythe:#aTarget"),
			}},
			TotalEdges: 1,
		},
	}, {
		src: getNode("someOtherSource"),
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "someEdgeKind",
			Edge: getEdgeTargets(
				"kythe:#aTarget",
				"kythe:#anotherTarget",
			),
		},
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "someEdgeKind",
			Edge: getEdgeTargets(
				"kythe:#onceMoreWithFeeling",
			),
		},
	}, {
		src: getNode("aThirdSource"),

		// forced flush due to new source
		edgeSet: &srvpb.PagedEdgeSet{
			Source: getNode("someOtherSource"),
			Group: []*srvpb.EdgeGroup{{
				Kind: "someEdgeKind",
				Edge: getEdgeTargets(
					"kythe:#aTarget",
					"kythe:#anotherTarget",
					"kythe:#onceMoreWithFeeling",
				),
			}},

			TotalEdges: 3, // fits exactly MaxEdgePageSize
		},
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "edgeKind123",
			Edge: getEdgeTargets("kythe:#aTarget"),
		},
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "edgeKind123",
			Edge: getEdgeTargets(
				"kythe:#bTarget",
				"kythe:#anotherTarget",
				"kythe:#threeTarget",
				"kythe:#fourTarget",
			),
		},

		edgePages: []*srvpb.EdgePage{{
			SourceTicket: "aThirdSource",
			PageKey:      "aThirdSource.0000000000",
			EdgesGroup: &srvpb.EdgeGroup{
				Kind: "edgeKind123",
				Edge: getEdgeTargets(
					"kythe:#aTarget",
					"kythe:#bTarget",
					"kythe:#anotherTarget",
				),
			},
		}},
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "edgeKind123",
			Edge: getEdgeTargets(
				"kythe:#five", "kythe:#six", "kythe:#seven", "kythe:#eight", "kythe:#nine",
			),
		},

		edgePages: []*srvpb.EdgePage{{
			SourceTicket: "aThirdSource",
			PageKey:      "aThirdSource.0000000001",
			EdgesGroup: &srvpb.EdgeGroup{
				Kind: "edgeKind123",
				Edge: getEdgeTargets(
					"kythe:#threeTarget", "kythe:#fourTarget", "kythe:#five",
				),
			},
		}, {
			SourceTicket: "aThirdSource",
			PageKey:      "aThirdSource.0000000002",
			EdgesGroup: &srvpb.EdgeGroup{
				Kind: "edgeKind123",
				Edge: getEdgeTargets(
					"kythe:#six", "kythe:#seven", "kythe:#eight",
				),
			},
		}},
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "edgeKind123",
			Edge: getEdgeTargets(
				"kythe:#ten", "kythe:#eleven",
			),
		},
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "edgeKindFinal",
			Edge: getEdgeTargets(
				"kythe:#ten",
			),
		},

		edgePages: []*srvpb.EdgePage{{
			SourceTicket: "aThirdSource",
			PageKey:      "aThirdSource.0000000003",
			EdgesGroup: &srvpb.EdgeGroup{
				Kind: "edgeKind123",
				Edge: getEdgeTargets(
					"kythe:#nine", "kythe:#ten", "kythe:#eleven",
				),
			},
		}},
	}, {
		grp: &srvpb.EdgeGroup{
			Kind: "edgeKindFinal",
			Edge: getEdgeTargets(
				"kythe:#two", "kythe:#three",
			),
		},
	}, {
		// flush

		edgeSet: &srvpb.PagedEdgeSet{
			TotalEdges: 15,

			Source: getNode("aThirdSource"),
			Group: []*srvpb.EdgeGroup{{
				Kind: "edgeKindFinal",
				Edge: getEdgeTargets(
					"kythe:#ten", "kythe:#two", "kythe:#three",
				),
			}},

			PageIndex: []*srvpb.PageIndex{{
				PageKey:   "aThirdSource.0000000000",
				EdgeKind:  "edgeKind123",
				EdgeCount: 3,
			}, {
				PageKey:   "aThirdSource.0000000001",
				EdgeKind:  "edgeKind123",
				EdgeCount: 3,
			}, {
				PageKey:   "aThirdSource.0000000002",
				EdgeKind:  "edgeKind123",
				EdgeCount: 3,
			}, {
				PageKey:   "aThirdSource.0000000003",
				EdgeKind:  "edgeKind123",
				EdgeCount: 3,
			}},
		},
	}}

	tESB := newTestESB(&EdgeSetBuilder{
		MaxEdgePageSize: 3,
	})
	var edgeSets, edgePages int
	for _, test := range tests {
		if test.src != nil {
			testutil.FatalOnErrT(t, "Failure to StartEdgeSet: %v",
				tESB.StartEdgeSet(ctx, test.src))
		} else if test.grp != nil {
			testutil.FatalOnErrT(t, "Failure to AddGroup: %v",
				tESB.AddGroup(ctx, test.grp))
		} else {
			testutil.FatalOnErrT(t, "Failure to Flush: %v",
				tESB.Flush(ctx))
		}

		if test.edgeSet != nil {
			// Expected a new PagedEdgeSet
			if edgeSets+1 != len(tESB.PagedEdgeSets) {
				t.Fatalf("Missing expected PagedEdgeSet: %v", test.edgeSet)
			} else if found := tESB.PagedEdgeSets[len(tESB.PagedEdgeSets)-1]; !reflect.DeepEqual(test.edgeSet, found) {
				t.Errorf("Expected PagedEdgeSet: %v; found: %v", test.edgeSet, found)
			}
			edgeSets++
		} else if edgeSets != len(tESB.PagedEdgeSets) {
			t.Fatalf("Unexpected PagedEdgeSet: %v", tESB.PagedEdgeSets[len(tESB.PagedEdgeSets)-1])
		}

		// Expected new EdgePage(s)
		for i := 0; i < len(test.edgePages); i++ {
			if edgePages >= len(tESB.EdgePages) {
				t.Fatalf("Missing expected EdgePages: %v", test.edgePages[i])
			} else if err := testutil.DeepEqual(test.edgePages[i], tESB.EdgePages[edgePages]); err != nil {
				t.Error(err)
			}
			edgePages++
		}
		if edgePages != len(tESB.EdgePages) {
			t.Fatalf("Unexpected EdgePage(s): %v", tESB.EdgePages[edgePages:])
		}
	}
}
Beispiel #26
0
func TestPager(t *testing.T) {
	var outputSets, expectedSets []*testSet
	var outputPages, expectedPages []*testPage

	p := &SetPager{
		MaxPageSize: 4,

		OutputSet: func(_ context.Context, total int, s Set, grps []Group) error {
			ts := s.(*testSet)
			ts.Total = total
			for _, g := range grps {
				ts.Groups = append(ts.Groups, g.(*testGroup))
			}
			outputSets = append(outputSets, ts)
			return nil
		},
		OutputPage: func(_ context.Context, s Set, g Group) error {
			ts := s.(*testSet)
			outputPages = append(outputPages, &testPage{
				Index: ts.Pages,
				Group: g.(*testGroup),
			})
			ts.Pages++
			return nil
		},

		NewSet: func(h Head) Set {
			return &testSet{Head: h.(string)}
		},
		Combine: func(l, r Group) Group {
			lg, rg := l.(*testGroup), r.(*testGroup)
			if lg.Key != rg.Key {
				return nil
			}
			lg.Vals = append(lg.Vals, rg.Vals...)
			return lg
		},
		Split: func(total int, g Group) (Group, Group) {
			tg := g.(*testGroup)
			ng := &testGroup{
				Key:  tg.Key,
				Vals: tg.Vals[:total],
			}
			tg.Vals = tg.Vals[total:]
			return ng, tg
		},
		Size: func(g Group) int { return len(g.(*testGroup).Vals) },
	}

	ctx := context.Background()
	testutil.FatalOnErrT(t, "StartSet error: %v", p.StartSet(ctx, "head key"))
	testutil.FatalOnErrT(t, "AddGroup error: %v", p.AddGroup(ctx, &testGroup{
		Key:  "key1",
		Vals: []int{11, 12, 13},
	}))
	testutil.FatalOnErrT(t, "AddGroup error: %v", p.AddGroup(ctx, &testGroup{
		Key:  "key1",
		Vals: []int{14, 15, 16},
	}))
	expectedPages = append(expectedPages, &testPage{
		Index: 0,
		Group: &testGroup{
			Key:  "key1",
			Vals: []int{11, 12, 13, 14},
		},
	})

	if err := testutil.DeepEqual(expectedSets, outputSets); err != nil {
		t.Fatalf("error checking Sets: %v", err)
	}
	if err := testutil.DeepEqual(expectedPages, outputPages); err != nil {
		t.Fatalf("error checking Pages: %v", err)
	}

	testutil.FatalOnErrT(t, "AddGroup error: %v", p.AddGroup(ctx, &testGroup{
		Key:  "key2",
		Vals: []int{21},
	}))
	testutil.FatalOnErrT(t, "AddGroup error: %v", p.AddGroup(ctx, &testGroup{
		Key:  "key2",
		Vals: []int{22, 23},
	}))
	expectedPages = append(expectedPages, &testPage{
		Index: 1,
		Group: &testGroup{
			Key:  "key2",
			Vals: []int{21, 22, 23},
		},
	})

	if err := testutil.DeepEqual(expectedSets, outputSets); err != nil {
		t.Fatalf("error checking Sets: %v", err)
	}
	if err := testutil.DeepEqual(expectedPages, outputPages); err != nil {
		t.Fatalf("error checking Pages: %v", err)
	}

	testutil.FatalOnErrT(t, "StartSet error: %v", p.StartSet(ctx, "next set"))
	expectedSets = append(expectedSets, &testSet{
		Head:  "head key",
		Total: 9,
		Groups: []*testGroup{{
			Key:  "key1",
			Vals: []int{15, 16},
		}},
		Pages: len(expectedPages),
	})

	if err := testutil.DeepEqual(expectedSets, outputSets); err != nil {
		t.Fatalf("error checking Sets: %v", err)
	}
	if err := testutil.DeepEqual(expectedPages, outputPages); err != nil {
		t.Fatalf("error checking Pages: %v", err)
	}

	testutil.FatalOnErrT(t, "StartSet error: %v", p.StartSet(ctx, "final set"))
	expectedSets = append(expectedSets, &testSet{
		Head: "next set",
	})

	if err := testutil.DeepEqual(expectedSets, outputSets); err != nil {
		t.Fatalf("error checking Sets: %v", err)
	}
	if err := testutil.DeepEqual(expectedPages, outputPages); err != nil {
		t.Fatalf("error checking Pages: %v", err)
	}

	testutil.FatalOnErrT(t, "AddGroup error: %v", p.AddGroup(ctx, &testGroup{
		Key:  "key0",
		Vals: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
	}))
	expectedPages = append(expectedPages, &testPage{
		Index: 0,
		Group: &testGroup{
			Key:  "key0",
			Vals: []int{1, 2, 3, 4},
		},
	})
	expectedPages = append(expectedPages, &testPage{
		Index: 1,
		Group: &testGroup{
			Key:  "key0",
			Vals: []int{5, 6, 7, 8},
		},
	})

	if err := testutil.DeepEqual(expectedSets, outputSets); err != nil {
		t.Fatalf("error checking Sets: %v", err)
	}
	if err := testutil.DeepEqual(expectedPages, outputPages); err != nil {
		t.Fatalf("error checking Pages: %v", err)
	}

	testutil.FatalOnErrT(t, "Flush error: %v", p.Flush(ctx))
	expectedSets = append(expectedSets, &testSet{
		Head:  "final set",
		Total: 12,
		Groups: []*testGroup{{
			Key:  "key0",
			Vals: []int{9, 10, 11, 12},
		}},
		Pages: 2,
	})

	if err := testutil.DeepEqual(expectedSets, outputSets); err != nil {
		t.Fatalf("error checking Sets: %v", err)
	}
	if err := testutil.DeepEqual(expectedPages, outputPages); err != nil {
		t.Fatalf("error checking Pages: %v", err)
	}
}
Beispiel #27
0
func TestCrossReferences(t *testing.T) {
	ticket := "kythe://someCorpus?lang=otpl#signature"

	st := tbl.Construct(t)
	reply, err := st.CrossReferences(ctx, &xpb.CrossReferencesRequest{
		Ticket:         []string{ticket},
		DefinitionKind: xpb.CrossReferencesRequest_BINDING_DEFINITIONS,
		ReferenceKind:  xpb.CrossReferencesRequest_ALL_REFERENCES,

		ExperimentalSignatures: true,
	})
	testutil.FatalOnErrT(t, "CrossReferencesRequest error: %v", err)

	expected := &xpb.CrossReferencesReply_CrossReferenceSet{
		Ticket:      ticket,
		DisplayName: &xpb.Printable{RawText: ""},

		Reference: []*xpb.CrossReferencesReply_RelatedAnchor{{Anchor: &xpb.Anchor{
			Ticket: "kythe:?path=some/utf16/file#0-4",
			Kind:   "/kythe/edge/ref",
			Parent: "kythe://someCorpus?path=some/utf16/file#utf16FTW",

			Start: &xpb.Location_Point{LineNumber: 1},
			End:   &xpb.Location_Point{ByteOffset: 4, LineNumber: 1, ColumnOffset: 4},

			SnippetStart: &xpb.Location_Point{
				LineNumber: 1,
			},
			SnippetEnd: &xpb.Location_Point{
				ByteOffset:   28,
				LineNumber:   1,
				ColumnOffset: 28,
			},
			Snippet: "これはいくつかのテキストです",
		}}, {Anchor: &xpb.Anchor{
			Ticket: "kythe://c?lang=otpl?path=/a/path#51-55",
			Kind:   "/kythe/edge/ref",
			Parent: "kythe://someCorpus?path=some/path#aFileNode",

			Start: &xpb.Location_Point{
				ByteOffset:   51,
				LineNumber:   4,
				ColumnOffset: 15,
			},
			End: &xpb.Location_Point{
				ByteOffset:   55,
				LineNumber:   5,
				ColumnOffset: 2,
			},

			SnippetStart: &xpb.Location_Point{
				ByteOffset: 36,
				LineNumber: 4,
			},
			SnippetEnd: &xpb.Location_Point{
				ByteOffset:   52,
				LineNumber:   4,
				ColumnOffset: 16,
			},
			Snippet: "some random text",
		}}},

		Definition: []*xpb.CrossReferencesReply_RelatedAnchor{{Anchor: &xpb.Anchor{
			Ticket: "kythe://c?lang=otpl?path=/a/path#27-33",
			Kind:   "/kythe/edge/defines/binding",
			Parent: "kythe://someCorpus?path=some/path#aFileNode",

			Start: &xpb.Location_Point{
				ByteOffset:   27,
				LineNumber:   2,
				ColumnOffset: 10,
			},
			End: &xpb.Location_Point{
				ByteOffset:   33,
				LineNumber:   3,
				ColumnOffset: 5,
			},

			SnippetStart: &xpb.Location_Point{
				ByteOffset: 17,
				LineNumber: 2,
			},
			SnippetEnd: &xpb.Location_Point{
				ByteOffset:   27,
				LineNumber:   2,
				ColumnOffset: 10,
			},
			Snippet: "here and  ",
		}}},
	}

	if err := testutil.DeepEqual(&xpb.CrossReferencesReply_Total{
		Definitions: 1,
		References:  2,
	}, reply.Total); err != nil {
		t.Error(err)
	}

	xr := reply.CrossReferences[ticket]
	if xr == nil {
		t.Fatalf("Missing expected CrossReferences; found: %#v", reply)
	}
	sort.Sort(byOffset(xr.Reference))

	if err := testutil.DeepEqual(expected, xr); err != nil {
		t.Fatal(err)
	}
}
Beispiel #28
0
func TestDecorationsDirtyBuffer(t *testing.T) {
	d := tbl.Decorations[1]

	st := tbl.Construct(t)
	// s/empty?/seq/
	dirty := []byte(`(defn map [f coll]
  (if (seq coll)
    []
    (cons (f (first coll)) (map f (rest coll)))))
`)
	reply, err := st.Decorations(ctx, &xpb.DecorationsRequest{
		Location:    &xpb.Location{Ticket: d.File.Ticket},
		DirtyBuffer: dirty,
		References:  true,
		Filter:      []string{"**"},
	})
	testutil.FatalOnErrT(t, "DecorationsRequest error: %v", err)

	if len(reply.SourceText) != 0 {
		t.Errorf("Unexpected source text: %q", string(reply.SourceText))
	}
	if reply.Encoding != "" {
		t.Errorf("Unexpected encoding: %q", reply.Encoding)
	}

	expected := []*xpb.DecorationsReply_Reference{
		{
			// Unpatched anchor for "map"
			SourceTicket: "kythe://c?lang=otpl?path=/a/path#6-9",
			TargetTicket: "kythe://c?lang=otpl?path=/a/path#map",
			Kind:         "/kythe/defines/binding",

			AnchorStart: &xpb.Location_Point{
				ByteOffset:   6,
				LineNumber:   1,
				ColumnOffset: 6,
			},
			AnchorEnd: &xpb.Location_Point{
				ByteOffset:   9,
				LineNumber:   1,
				ColumnOffset: 9,
			},
		},
		// Skipped anchor for "empty?" (inside edit region)
		{
			// Patched anchor for "cons" (moved backwards by 3 bytes)
			SourceTicket: "kythe://c?lang=otpl?path=/a/path#51-55",
			TargetTicket: "kythe://core?lang=otpl#cons",
			Kind:         "/kythe/refs",
			AnchorStart: &xpb.Location_Point{
				ByteOffset:   48,
				LineNumber:   4,
				ColumnOffset: 5,
			},
			AnchorEnd: &xpb.Location_Point{
				ByteOffset:   52,
				LineNumber:   4,
				ColumnOffset: 9,
			},
		},
	}
	if err := testutil.DeepEqual(expected, reply.Reference); err != nil {
		t.Fatal(err)
	}

	// These are a subset of the anchor nodes in tbl.Decorations[1].  tbl.Nodes[10] is missing because
	// it is the target of an anchor in the edited region.
	expectedNodes := nodeInfos([]*srvpb.Node{tbl.Nodes[9], tbl.Nodes[12]})

	sort.Sort(byNodeTicket(expectedNodes))
	sort.Sort(byNodeTicket(reply.Node))

	if err := testutil.DeepEqual(expectedNodes, reply.Node); err != nil {
		t.Fatal(err)
	}
}