blob: 7a906eb306cf36b5230de168dcfa02b790a7e650 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vtrace
import (
"encoding/binary"
"reflect"
"sort"
"testing"
"v.io/v23/uniqueid"
"v.io/v23/vtrace"
"v.io/x/ref/lib/flags"
)
var nextid = uint64(1)
func id() uniqueid.Id {
var out uniqueid.Id
binary.BigEndian.PutUint64(out[8:], nextid)
nextid++
return out
}
func makeTraces(n int, st *Store) []uniqueid.Id {
traces := make([]uniqueid.Id, n)
for i := range traces {
curid := id()
traces[i] = curid
st.ForceCollect(curid, 0)
}
return traces
}
func recordids(records ...vtrace.TraceRecord) map[uniqueid.Id]bool {
out := make(map[uniqueid.Id]bool)
for _, trace := range records {
out[trace.Id] = true
}
return out
}
func traceids(traces ...uniqueid.Id) map[uniqueid.Id]bool {
out := make(map[uniqueid.Id]bool)
for _, trace := range traces {
out[trace] = true
}
return out
}
func pretty(in map[uniqueid.Id]bool) []int {
out := make([]int, 0, len(in))
for k, _ := range in {
out = append(out, int(k[15]))
}
sort.Ints(out)
return out
}
func compare(t *testing.T, want map[uniqueid.Id]bool, records []vtrace.TraceRecord) {
got := recordids(records...)
if !reflect.DeepEqual(want, got) {
t.Errorf("Got wrong traces. Got %v, want %v.", pretty(got), pretty(want))
}
}
func TestTrimming(t *testing.T) {
st, err := NewStore(flags.VtraceFlags{CacheSize: 5})
if err != nil {
t.Fatalf("Could not create store: %v", err)
}
traces := makeTraces(10, st)
compare(t, traceids(traces[5:]...), st.TraceRecords())
traces = append(traces, id(), id(), id())
// Starting a span on an existing trace brings it to the front of the queue
// and prevent it from being removed when a new trace begins.
st.start(&span{trace: traces[5], id: id()})
st.ForceCollect(traces[10], 0)
compare(t, traceids(traces[10], traces[5], traces[7], traces[8], traces[9]), st.TraceRecords())
// Finishing a span on one of the traces should bring it back into the stored set.
st.finish(&span{trace: traces[7], id: id()})
st.ForceCollect(traces[11], 0)
compare(t, traceids(traces[10], traces[11], traces[5], traces[7], traces[9]), st.TraceRecords())
// Annotating a span on one of the traces should bring it back into the stored set.
st.annotate(&span{trace: traces[9], id: id()}, "hello")
st.ForceCollect(traces[12], 0)
compare(t, traceids(traces[10], traces[11], traces[12], traces[7], traces[9]), st.TraceRecords())
}
func TestRegexp(t *testing.T) {
traces := []uniqueid.Id{id(), id(), id()}
type testcase struct {
pattern string
results []uniqueid.Id
}
tests := []testcase{
{".*", traces},
{"foo.*", traces},
{".*bar", traces[1:2]},
{".*bang", traces[2:3]},
}
for _, test := range tests {
st, err := NewStore(flags.VtraceFlags{
CacheSize: 10,
CollectRegexp: test.pattern,
})
if err != nil {
t.Fatalf("Could not create store: %v", err)
}
newSpan(traces[0], "foo", traces[0], st)
newSpan(traces[1], "foobar", traces[1], st)
sp, err := newSpan(traces[2], "baz", traces[2], st)
if err != nil {
t.Fatal(err)
}
sp.Annotate("foobang")
compare(t, traceids(test.results...), st.TraceRecords())
}
}