package span import ( "database/sql" "fmt" "testing" ) func TestNewRootSpanID(t *testing.T) { id := NewRootSpanID() if id.Parent != 0 { t.Errorf("unexpected parent: %+v", id) } if id.Span == 0 { t.Errorf("zero Span: %+v", id) } if id.Trace == 0 { t.Errorf("zero root: %+v", id) } if id.Trace == id.Span { t.Errorf("duplicate IDs: %+v", id) } } func TestNewSpanID(t *testing.T) { root := NewRootSpanID() id := NewSpanID(root) if id.Parent != root.Span { t.Errorf("unexpected parent: %+v", id) } if id.Span == 0 { t.Errorf("zero Span: %+v", id) } if id.Trace != root.Trace { t.Errorf("mismatched root: %+v", id) } } func TestSpanIDString(t *testing.T) { id := SpanID{ Trace: 100, Span: 300, } got := id.String() want := "0000000000000064/000000000000012c" if got != want { t.Errorf("got %#v, want %#v", got, want) } } func TestSpanIDStringWithParent(t *testing.T) { id := SpanID{ Trace: 100, Parent: 200, Span: 300, } actual := id.String() expected := "0000000000000064/000000000000012c/00000000000000c8" if actual != expected { t.Errorf("Was %#v, but expected %#v", actual, expected) } } func TestSpanIDFormat(t *testing.T) { id := SpanID{ Trace: 100, Span: 300, } got := id.Format("/* %s */ %s", "SELECT 1") want := "/* 0000000000000064/000000000000012c */ SELECT 1" if got != want { t.Errorf("got %#v, want %#v", got, want) } } func ExampleSpanID_Format() { // Assume we're connected to a database. var ( event SpanID db *sql.DB userID int ) // This passes the root ID and the parent event ID to the database, which // allows us to correlate, for example, slow queries with the web requests // which caused them. query := event.Format(`/* %s/%s */ %s`, `SELECT email FROM users WHERE id = ?`) r := db.QueryRow(query, userID) if r == nil { panic("user not found") } var email string if err := r.Scan(&email); err != nil { panic("couldn't read email") } fmt.Printf("User's email: %s\n", email) } func TestParseSpanID(t *testing.T) { id, err := ParseSpanID("0000000000000064/000000000000012c") if err != nil { t.Fatal(err) } if id.Trace != 100 || id.Span != 300 { t.Errorf("unexpected ID: %+v", id) } } func TestParseSpanIDWithParent(t *testing.T) { id, err := ParseSpanID("0000000000000064/000000000000012c/0000000000000096") if err != nil { t.Fatalf("unexpected error: %v", err) } if id.Trace != 100 || id.Parent != 150 || id.Span != 300 { t.Errorf("unexpected event ID: %+v", id) } } func TestParseSpanIDMalformed(t *testing.T) { id, err := ParseSpanID(`0000000000000064000000000000012c`) if id != nil { t.Errorf("unexpected ID: %+v", id) } if err != ErrBadSpanID { t.Error(err) } } func TestParseSpanIDBadTrace(t *testing.T) { id, err := ParseSpanID("0000000000g000064/000000000000012c") if id != nil { t.Errorf("unexpected ID: %+v", id) } if err != ErrBadSpanID { t.Error(err) } } func TestParseSpanIDBadID(t *testing.T) { id, err := ParseSpanID("0000000000000064/0000000000g00012c") if id != nil { t.Errorf("unexpected ID: %+v", id) } if err != ErrBadSpanID { t.Error(err) } } func TestParseSpanIDBadParent(t *testing.T) { id, err := ParseSpanID("0000000000000064/000000000000012c/00000000000g0096") if id != nil { t.Errorf("unexpected event ID: %+v", id) } if err != ErrBadSpanID { t.Errorf("unexpected error: %v", err) } } func BenchmarkNewRootSpanID(b *testing.B) { for i := 0; i < b.N; i++ { NewRootSpanID() } } func BenchmarkNewSpanID(b *testing.B) { root := NewRootSpanID() for i := 0; i < b.N; i++ { NewSpanID(root) } } func BenchmarkSpanIDString(b *testing.B) { id := SpanID{ Trace: 100, Parent: 200, Span: 300, } for i := 0; i < b.N; i++ { _ = id.String() } } func BenchmarkParseSpanID(b *testing.B) { for i := 0; i < b.N; i++ { _, err := ParseSpanID("0000000000000064/000000000000012c") if err != nil { b.Fatal(err) } } }