client_test.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. package tracing
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/assert"
  7. "go.opentelemetry.io/otel/exporters/otlp/otlptrace"
  8. semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
  9. "go.opentelemetry.io/otel/trace"
  10. commonpb "go.opentelemetry.io/proto/otlp/common/v1"
  11. resourcepb "go.opentelemetry.io/proto/otlp/resource/v1"
  12. tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
  13. )
  14. const (
  15. resourceSchemaUrl = "http://example.com/custom-resource-schema"
  16. instrumentSchemaUrl = semconv.SchemaURL
  17. )
  18. var (
  19. traceId = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}
  20. spanId = []byte{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8}
  21. parentSpanId = []byte{0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08}
  22. startTime = time.Date(2022, 4, 4, 0, 0, 0, 0, time.UTC)
  23. endTime = startTime.Add(5 * time.Second)
  24. traceState, _ = trace.ParseTraceState("key1=val1,key2=val2")
  25. instrScope = &commonpb.InstrumentationScope{Name: "go.opentelemetry.io/test/otel", Version: "v1.6.0"}
  26. otlpKeyValues = []*commonpb.KeyValue{
  27. {
  28. Key: "string_key",
  29. Value: &commonpb.AnyValue{
  30. Value: &commonpb.AnyValue_StringValue{
  31. StringValue: "string value",
  32. },
  33. },
  34. },
  35. {
  36. Key: "bool_key",
  37. Value: &commonpb.AnyValue{
  38. Value: &commonpb.AnyValue_BoolValue{
  39. BoolValue: true,
  40. },
  41. },
  42. },
  43. }
  44. otlpResource = &resourcepb.Resource{
  45. Attributes: []*commonpb.KeyValue{
  46. {
  47. Key: "service.name",
  48. Value: &commonpb.AnyValue{
  49. Value: &commonpb.AnyValue_StringValue{
  50. StringValue: "service-name",
  51. },
  52. },
  53. },
  54. },
  55. }
  56. )
  57. var _ otlptrace.Client = (*InMemoryOtlpClient)(nil)
  58. var _ InMemoryClient = (*InMemoryOtlpClient)(nil)
  59. var _ otlptrace.Client = (*NoopOtlpClient)(nil)
  60. var _ InMemoryClient = (*NoopOtlpClient)(nil)
  61. func TestUploadTraces(t *testing.T) {
  62. client := &InMemoryOtlpClient{}
  63. spans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})
  64. spans2 := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})
  65. err := client.UploadTraces(context.Background(), spans)
  66. assert.NoError(t, err)
  67. err = client.UploadTraces(context.Background(), spans2)
  68. assert.NoError(t, err)
  69. assert.Len(t, client.spans, 2)
  70. }
  71. func TestSpans(t *testing.T) {
  72. client := &InMemoryOtlpClient{}
  73. spans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})
  74. err := client.UploadTraces(context.Background(), spans)
  75. assert.NoError(t, err)
  76. assert.Len(t, client.spans, 1)
  77. enc, err := client.Spans()
  78. assert.NoError(t, err)
  79. expected := "CsECCiAKHgoMc2VydmljZS5uYW1lEg4KDHNlcnZpY2UtbmFtZRLxAQonCh1nby5vcGVudGVsZW1ldHJ5LmlvL3Rlc3Qvb3RlbBIGdjEuNi4wEp0BChAAAQIDBAUGBwgJCgsMDQ4PEgj//v38+/r5+BoTa2V5MT12YWwxLGtleTI9dmFsMiIIDw4NDAsKCQgqCnRyYWNlX25hbWUwATkAANJvaYjiFkEA8teZaojiFkocCgpzdHJpbmdfa2V5Eg4KDHN0cmluZyB2YWx1ZUoOCghib29sX2tleRICEAF6EhIOc3RhdHVzIG1lc3NhZ2UYARomaHR0cHM6Ly9vcGVudGVsZW1ldHJ5LmlvL3NjaGVtYXMvMS43LjAaKWh0dHA6Ly9leGFtcGxlLmNvbS9jdXN0b20tcmVzb3VyY2Utc2NoZW1h"
  80. assert.Equal(t, expected, enc)
  81. }
  82. func TestSpansEmpty(t *testing.T) {
  83. client := &InMemoryOtlpClient{}
  84. err := client.UploadTraces(context.Background(), []*tracepb.ResourceSpans{})
  85. assert.NoError(t, err)
  86. assert.Len(t, client.spans, 0)
  87. _, err = client.Spans()
  88. assert.ErrorIs(t, err, errNoTraces)
  89. }
  90. func TestSpansNil(t *testing.T) {
  91. client := &InMemoryOtlpClient{}
  92. err := client.UploadTraces(context.Background(), nil)
  93. assert.NoError(t, err)
  94. assert.Len(t, client.spans, 0)
  95. _, err = client.Spans()
  96. assert.ErrorIs(t, err, errNoTraces)
  97. }
  98. func TestSpansTooManySpans(t *testing.T) {
  99. client := &InMemoryOtlpClient{}
  100. for i := 0; i < MaxTraceAmount+1; i++ {
  101. spans := createResourceSpans([]*tracepb.Span{createOtlpSpan(traceId)})
  102. err := client.UploadTraces(context.Background(), spans)
  103. assert.NoError(t, err)
  104. }
  105. assert.Len(t, client.spans, MaxTraceAmount)
  106. _, err := client.Spans()
  107. assert.NoError(t, err)
  108. }
  109. func createResourceSpans(spans []*tracepb.Span) []*tracepb.ResourceSpans {
  110. return []*tracepb.ResourceSpans{createResourceSpan(spans)}
  111. }
  112. func createResourceSpan(spans []*tracepb.Span) *tracepb.ResourceSpans {
  113. return &tracepb.ResourceSpans{
  114. Resource: otlpResource,
  115. ScopeSpans: []*tracepb.ScopeSpans{
  116. {
  117. Scope: instrScope,
  118. Spans: spans,
  119. SchemaUrl: instrumentSchemaUrl,
  120. },
  121. },
  122. SchemaUrl: resourceSchemaUrl,
  123. }
  124. }
  125. func createOtlpSpan(tid []byte) *tracepb.Span {
  126. return &tracepb.Span{
  127. TraceId: tid,
  128. SpanId: spanId,
  129. TraceState: traceState.String(),
  130. ParentSpanId: parentSpanId,
  131. Name: "trace_name",
  132. Kind: tracepb.Span_SPAN_KIND_INTERNAL,
  133. StartTimeUnixNano: uint64(startTime.UnixNano()),
  134. EndTimeUnixNano: uint64(endTime.UnixNano()),
  135. Attributes: otlpKeyValues,
  136. DroppedAttributesCount: 0,
  137. Events: nil,
  138. DroppedEventsCount: 0,
  139. Links: nil,
  140. DroppedLinksCount: 0,
  141. Status: &tracepb.Status{
  142. Message: "status message",
  143. Code: tracepb.Status_STATUS_CODE_OK,
  144. },
  145. }
  146. }