diff --git a/exporter/stackdriverexporter/spandata_test.go b/exporter/stackdriverexporter/spandata_test.go index 115fb0cfa38f..fe6538da2b26 100644 --- a/exporter/stackdriverexporter/spandata_test.go +++ b/exporter/stackdriverexporter/spandata_test.go @@ -18,147 +18,185 @@ import ( "testing" "time" - resourcepb "github.com/census-instrumentation/opencensus-proto/gen-go/resource/v1" - tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1" - "github.com/golang/protobuf/ptypes" - "github.com/golang/protobuf/ptypes/wrappers" "github.com/stretchr/testify/assert" - "go.opencensus.io/trace" - "go.opencensus.io/trace/tracestate" + "google.golang.org/grpc/codes" + "go.opentelemetry.io/otel/api/kv" + "go.opentelemetry.io/otel/api/kv/value" + "go.opentelemetry.io/collector/consumer/pdata" + apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/sdk/export/trace" + "go.opentelemetry.io/otel/sdk/instrumentation" ) -func TestProtoSpanToOCSpanData_endToEnd(t *testing.T) { - // The goal of this test is to ensure that each - // tracepb.Span is transformed to its *trace.SpanData correctly! - - endTime := time.Now().Round(time.Second).UTC() - endTimeProto, _ := ptypes.TimestampProto(endTime) - startTime := endTime.Add(-90 * time.Second).UTC() - startTimeProto, _ := ptypes.TimestampProto(startTime) - - protoSpan := &tracepb.Span{ - TraceId: []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanId: []byte{0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8}, - ParentSpanId: []byte{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8}, - Name: &tracepb.TruncatableString{Value: "End-To-End Here"}, - Kind: tracepb.Span_SERVER, - StartTime: startTimeProto, - EndTime: endTimeProto, - Status: &tracepb.Status{ - Code: 13, - Message: "This is not a drill!", - }, - SameProcessAsParentSpan: &wrappers.BoolValue{Value: false}, - TimeEvents: &tracepb.Span_TimeEvents{ - TimeEvent: []*tracepb.Span_TimeEvent{ - { - Time: startTimeProto, - Value: &tracepb.Span_TimeEvent_MessageEvent_{ - MessageEvent: &tracepb.Span_TimeEvent_MessageEvent{ - Type: tracepb.Span_TimeEvent_MessageEvent_SENT, UncompressedSize: 1024, CompressedSize: 512, - }, - }, - }, - { - Time: endTimeProto, - Value: &tracepb.Span_TimeEvent_MessageEvent_{ - MessageEvent: &tracepb.Span_TimeEvent_MessageEvent{ - Type: tracepb.Span_TimeEvent_MessageEvent_RECEIVED, UncompressedSize: 1024, CompressedSize: 1000, - }, - }, - }, - }, - }, - Links: &tracepb.Span_Links{ - Link: []*tracepb.Span_Link{ - { - TraceId: []byte{0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, - SpanId: []byte{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, - Type: tracepb.Span_Link_PARENT_LINKED_SPAN, - }, - { - TraceId: []byte{0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF}, - SpanId: []byte{0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7}, - Type: tracepb.Span_Link_CHILD_LINKED_SPAN, - }, - }, - }, - Tracestate: &tracepb.Span_Tracestate{ - Entries: []*tracepb.Span_Tracestate_Entry{ - {Key: "foo", Value: "bar"}, - {Key: "a", Value: "b"}, - }, - }, - Attributes: &tracepb.Span_Attributes{ - AttributeMap: map[string]*tracepb.AttributeValue{ - "cache_hit": {Value: &tracepb.AttributeValue_BoolValue{BoolValue: true}}, - "timeout_ns": {Value: &tracepb.AttributeValue_IntValue{IntValue: 12e9}}, - "ping_count": {Value: &tracepb.AttributeValue_IntValue{IntValue: 25}}, - "agent": {Value: &tracepb.AttributeValue_StringValue{ - StringValue: &tracepb.TruncatableString{Value: "ocagent"}, - }}, - }, - }, - } +func TestPDataResourceSpansToOTSpanData_endToEnd(t *testing.T) { + // The goal of this test is to ensure that each span in + // pdata.ResourceSpans is transformed to its *trace.SpanData correctly! - resource := &resourcepb.Resource{ - Type: "k8s", - Labels: map[string]string{ - "namespace": "kube-system", - }, - } + endTime := time.Now().Round(time.Second) + pdataEndTime := pdata.TimestampUnixNano(endTime.UnixNano()) + startTime := endTime.Add(-90 * time.Second) + pdataStartTime := pdata.TimestampUnixNano(startTime.UnixNano()) - gotOCSpanData, err := protoSpanToOCSpanData(protoSpan, resource) - if err != nil { - t.Fatalf("Failed to convert from ProtoSpan to OCSpanData: %v", err) - } + rs := pdata.NewResourceSpans() + rs.InitEmpty() + + span := pdata.NewSpan() + span.InitEmpty() + traceID := pdata.NewTraceID([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}) + spanID := pdata.NewSpanID([]byte{0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8}) + parentSpanID := pdata.NewSpanID([]byte{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8}) + span.SetTraceID(traceID) + span.SetSpanID(spanID) + span.SetParentSpanID(parentSpanID) + span.SetName("End-To-End Here") + span.SetKind(pdata.SpanKindSERVER) + span.SetStartTime(pdataStartTime) + span.SetEndTime(pdataEndTime) + + status := pdata.NewSpanStatus() + status.InitEmpty() + status.SetCode(13) + status.SetMessage("This is not a drill!") + status.CopyTo(span.Status()) + + events := pdata.NewSpanEventSlice() + events.Resize(2) + + events.At(0).SetTimestamp(pdataStartTime) + events.At(0).SetName("start") + + events.At(1).SetTimestamp(pdataEndTime) + events.At(1).SetName("end") + pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{ + "flag": pdata.NewAttributeValueBool(false), + }).CopyTo(events.At(1).Attributes()) + events.MoveAndAppendTo(span.Events()) - ocTracestate, err := tracestate.New(new(tracestate.Tracestate), tracestate.Entry{Key: "foo", Value: "bar"}, - tracestate.Entry{Key: "a", Value: "b"}) - if err != nil || ocTracestate == nil { - t.Fatalf("Failed to create ocTracestate: %v", err) + links := pdata.NewSpanLinkSlice() + links.Resize(2) + links.At(0).SetTraceID(pdata.NewTraceID([]byte{0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF})) + links.At(0).SetSpanID(pdata.NewSpanID([]byte{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7})) + links.At(1).SetTraceID(pdata.NewTraceID([]byte{0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF})) + links.At(1).SetSpanID([]byte{0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7}) + links.MoveAndAppendTo(span.Links()) + + pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{ + "cache_hit": pdata.NewAttributeValueBool(true), + "timeout_ns": pdata.NewAttributeValueInt(12e9), + "ping_count": pdata.NewAttributeValueInt(25), + "agent": pdata.NewAttributeValueString("ocagent"), + }).CopyTo(span.Attributes()) + + resource := pdata.NewResource() + resource.InitEmpty() + pdata.NewAttributeMap().InitFromMap(map[string]pdata.AttributeValue{ + "namespace": pdata.NewAttributeValueString("kube-system"), + }).CopyTo(resource.Attributes()) + resource.CopyTo(rs.Resource()) + + il := pdata.NewInstrumentationLibrary() + il.InitEmpty() + il.SetName("test_il_name") + il.SetVersion("test_il_version") + + spans := pdata.NewSpanSlice() + spans.Append(&span) + + ilss := pdata.NewInstrumentationLibrarySpansSlice() + ilss.Resize(1) + il.CopyTo(ilss.At(0).InstrumentationLibrary()) + spans.MoveAndAppendTo(ilss.At(0).Spans()) + ilss.CopyTo(rs.InstrumentationLibrarySpans()) + + gotOTSpanData, err := pdataResourceSpansToOTSpanData(rs) + if err != nil { + t.Fatalf("Failed to convert from pdata ResourceSpans to OTSpanData: %v", err) } - wantOCSpanData := &trace.SpanData{ - SpanContext: trace.SpanContext{ - TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, - SpanID: trace.SpanID{0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8}, - Tracestate: ocTracestate, + wantOTSpanData := &trace.SpanData{ + SpanContext: apitrace.SpanContext{ + TraceID: apitrace.ID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, + SpanID: apitrace.SpanID{0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8}, }, - SpanKind: trace.SpanKindServer, - ParentSpanID: trace.SpanID{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8}, + SpanKind: apitrace.SpanKindServer, + ParentSpanID: apitrace.SpanID{0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8}, Name: "End-To-End Here", StartTime: startTime, EndTime: endTime, - MessageEvents: []trace.MessageEvent{ - {Time: startTime, EventType: trace.MessageEventTypeSent, UncompressedByteSize: 1024, CompressedByteSize: 512}, - {Time: endTime, EventType: trace.MessageEventTypeRecv, UncompressedByteSize: 1024, CompressedByteSize: 1000}, + MessageEvents: []trace.Event{ + { + Time: startTime, + Name: "start", + Attributes: []kv.KeyValue{}, + }, + { + Time: endTime, + Name: "end", + Attributes: []kv.KeyValue{ + { + Key: kv.Key("flag"), + Value: value.Bool(false), + }, + }, + }, }, - Links: []trace.Link{ + Links: []apitrace.Link{ { - TraceID: trace.TraceID{0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, - SpanID: trace.SpanID{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, - Type: trace.LinkTypeParent, + SpanContext: apitrace.SpanContext{ + TraceID: apitrace.ID{0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF}, + SpanID: apitrace.SpanID{0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, + }, + Attributes: []kv.KeyValue{}, }, { - TraceID: trace.TraceID{0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF}, - SpanID: trace.SpanID{0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7}, - Type: trace.LinkTypeChild, + SpanContext: apitrace.SpanContext{ + TraceID: apitrace.ID{0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF}, + SpanID: apitrace.SpanID{0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7}, + }, + Attributes: []kv.KeyValue{}, }, }, - Status: trace.Status{ - Code: trace.StatusCodeInternal, - Message: "This is not a drill!", + StatusCode: codes.Internal, + StatusMessage: "This is not a drill!", + Attributes: []kv.KeyValue{ + { + Key: kv.Key("namespace"), + Value: value.String("kube-system"), + }, + { + Key: kv.Key("ping_count"), + Value: value.Int64(25), + }, + { + Key: kv.Key("agent"), + Value: value.String("ocagent"), + }, + { + Key: kv.Key("cache_hit"), + Value: value.Bool(true), + }, + { + Key: kv.Key("timeout_ns"), + Value: value.Int64(12e9), + }, }, - HasRemoteParent: true, - Attributes: map[string]interface{}{ - "namespace": "kube-system", - "timeout_ns": int64(12e9), - "agent": "ocagent", - "cache_hit": true, - "ping_count": int64(25), // Should be transformed into int64 + InstrumentationLibrary: instrumentation.Library{ + Name: "test_il_name", + Version: "test_il_version", }, } - assert.EqualValues(t, wantOCSpanData, gotOCSpanData) + assert.EqualValues(t, 1, len(gotOTSpanData)) + assert.EqualValues(t, wantOTSpanData.SpanContext, gotOTSpanData[0].SpanContext) + assert.EqualValues(t, wantOTSpanData.SpanKind, gotOTSpanData[0].SpanKind) + assert.EqualValues(t, wantOTSpanData.ParentSpanID, gotOTSpanData[0].ParentSpanID) + assert.EqualValues(t, wantOTSpanData.Name, gotOTSpanData[0].Name) + assert.EqualValues(t, wantOTSpanData.StartTime, gotOTSpanData[0].StartTime) + assert.EqualValues(t, wantOTSpanData.EndTime, gotOTSpanData[0].EndTime) + assert.EqualValues(t, wantOTSpanData.MessageEvents, gotOTSpanData[0].MessageEvents) + assert.EqualValues(t, wantOTSpanData.Links, gotOTSpanData[0].Links) + assert.EqualValues(t, wantOTSpanData.StatusCode, gotOTSpanData[0].StatusCode) + assert.EqualValues(t, wantOTSpanData.StatusMessage, gotOTSpanData[0].StatusMessage) + assert.ElementsMatch(t, wantOTSpanData.Attributes, gotOTSpanData[0].Attributes) + assert.EqualValues(t, wantOTSpanData.InstrumentationLibrary, gotOTSpanData[0].InstrumentationLibrary) }