545 lines
14 KiB
Go
545 lines
14 KiB
Go
|
package zipkin
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
"github.com/google/go-cmp/cmp"
|
||
|
"github.com/influxdata/telegraf"
|
||
|
"github.com/influxdata/telegraf/testutil"
|
||
|
"github.com/openzipkin/zipkin-go-opentracing/_thrift/gen-go/zipkincore"
|
||
|
)
|
||
|
|
||
|
func TestLineProtocolConverter_Record(t *testing.T) {
|
||
|
mockAcc := testutil.Accumulator{}
|
||
|
type fields struct {
|
||
|
acc telegraf.Accumulator
|
||
|
}
|
||
|
type args struct {
|
||
|
t Trace
|
||
|
}
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
fields fields
|
||
|
args args
|
||
|
wantErr bool
|
||
|
want []testutil.Metric
|
||
|
}{
|
||
|
{
|
||
|
name: "threespan",
|
||
|
fields: fields{
|
||
|
acc: &mockAcc,
|
||
|
},
|
||
|
args: args{
|
||
|
t: Trace{
|
||
|
Span{
|
||
|
ID: "8090652509916334619",
|
||
|
TraceID: "2505404965370368069",
|
||
|
Name: "Child",
|
||
|
ParentID: "22964302721410078",
|
||
|
Timestamp: time.Unix(0, 1498688360851331000).UTC(),
|
||
|
Duration: time.Duration(53106) * time.Microsecond,
|
||
|
ServiceName: "trivial",
|
||
|
Annotations: []Annotation{},
|
||
|
BinaryAnnotations: []BinaryAnnotation{
|
||
|
BinaryAnnotation{
|
||
|
Key: "lc",
|
||
|
Value: "dHJpdmlhbA==",
|
||
|
Host: "2130706433:0",
|
||
|
ServiceName: "trivial",
|
||
|
Type: "STRING",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Span{
|
||
|
ID: "103618986556047333",
|
||
|
TraceID: "2505404965370368069",
|
||
|
Name: "Child",
|
||
|
ParentID: "22964302721410078",
|
||
|
Timestamp: time.Unix(0, 1498688360904552000).UTC(),
|
||
|
Duration: time.Duration(50410) * time.Microsecond,
|
||
|
ServiceName: "trivial",
|
||
|
Annotations: []Annotation{},
|
||
|
BinaryAnnotations: []BinaryAnnotation{
|
||
|
BinaryAnnotation{
|
||
|
Key: "lc",
|
||
|
Value: "dHJpdmlhbA==",
|
||
|
Host: "2130706433:0",
|
||
|
ServiceName: "trivial",
|
||
|
Type: "STRING",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Span{
|
||
|
ID: "22964302721410078",
|
||
|
TraceID: "2505404965370368069",
|
||
|
Name: "Parent",
|
||
|
ParentID: "22964302721410078",
|
||
|
Timestamp: time.Unix(0, 1498688360851318000).UTC(),
|
||
|
Duration: time.Duration(103680) * time.Microsecond,
|
||
|
ServiceName: "trivial",
|
||
|
Annotations: []Annotation{
|
||
|
Annotation{
|
||
|
Timestamp: time.Unix(0, 1498688360851325000).UTC(),
|
||
|
Value: "Starting child #0",
|
||
|
Host: "2130706433:0",
|
||
|
ServiceName: "trivial",
|
||
|
},
|
||
|
Annotation{
|
||
|
Timestamp: time.Unix(0, 1498688360904545000).UTC(),
|
||
|
Value: "Starting child #1",
|
||
|
Host: "2130706433:0",
|
||
|
ServiceName: "trivial",
|
||
|
},
|
||
|
Annotation{
|
||
|
Timestamp: time.Unix(0, 1498688360954992000).UTC(),
|
||
|
Value: "A Log",
|
||
|
Host: "2130706433:0",
|
||
|
ServiceName: "trivial",
|
||
|
},
|
||
|
},
|
||
|
BinaryAnnotations: []BinaryAnnotation{
|
||
|
BinaryAnnotation{
|
||
|
Key: "lc",
|
||
|
Value: "dHJpdmlhbA==",
|
||
|
Host: "2130706433:0",
|
||
|
ServiceName: "trivial",
|
||
|
Type: "STRING",
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
want: []testutil.Metric{
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"id": "8090652509916334619",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"service_name": "trivial",
|
||
|
"name": "Child",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(53106) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360851331000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"id": "8090652509916334619",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"name": "Child",
|
||
|
"service_name": "trivial",
|
||
|
"annotation": "dHJpdmlhbA==",
|
||
|
"endpoint_host": "2130706433:0",
|
||
|
"annotation_key": "lc",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(53106) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360851331000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"id": "103618986556047333",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"service_name": "trivial",
|
||
|
"name": "Child",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(50410) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360904552000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"id": "103618986556047333",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"name": "Child",
|
||
|
"service_name": "trivial",
|
||
|
"annotation": "dHJpdmlhbA==",
|
||
|
"endpoint_host": "2130706433:0",
|
||
|
"annotation_key": "lc",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(50410) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360904552000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"id": "22964302721410078",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"service_name": "trivial",
|
||
|
"name": "Parent",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(103680) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360851318000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"service_name": "trivial",
|
||
|
"annotation": "Starting child #0",
|
||
|
"endpoint_host": "2130706433:0",
|
||
|
"id": "22964302721410078",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"name": "Parent",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(103680) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360851318000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"service_name": "trivial",
|
||
|
"annotation": "Starting child #1",
|
||
|
"endpoint_host": "2130706433:0",
|
||
|
"id": "22964302721410078",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"name": "Parent",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(103680) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360851318000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"parent_id": "22964302721410078",
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"name": "Parent",
|
||
|
"service_name": "trivial",
|
||
|
"annotation": "A Log",
|
||
|
"endpoint_host": "2130706433:0",
|
||
|
"id": "22964302721410078",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(103680) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360851318000).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"trace_id": "2505404965370368069",
|
||
|
"service_name": "trivial",
|
||
|
"annotation": "dHJpdmlhbA==",
|
||
|
"annotation_key": "lc",
|
||
|
"id": "22964302721410078",
|
||
|
"parent_id": "22964302721410078",
|
||
|
"name": "Parent",
|
||
|
"endpoint_host": "2130706433:0",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(103680) * time.Microsecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(0, 1498688360851318000).UTC(),
|
||
|
},
|
||
|
},
|
||
|
wantErr: false,
|
||
|
},
|
||
|
|
||
|
//// Test data from distributed trace repo sample json
|
||
|
// https://github.com/mattkanwisher/distributedtrace/blob/master/testclient/sample.json
|
||
|
{
|
||
|
name: "distributed_trace_sample",
|
||
|
fields: fields{
|
||
|
acc: &mockAcc,
|
||
|
},
|
||
|
args: args{
|
||
|
t: Trace{
|
||
|
Span{
|
||
|
ID: "6802735349851856000",
|
||
|
TraceID: "0:6802735349851856000",
|
||
|
Name: "main.dud",
|
||
|
ParentID: "6802735349851856000",
|
||
|
Timestamp: time.Unix(1, 0).UTC(),
|
||
|
Duration: 1,
|
||
|
ServiceName: "trivial",
|
||
|
Annotations: []Annotation{
|
||
|
Annotation{
|
||
|
Timestamp: time.Unix(0, 1433330263415871000).UTC(),
|
||
|
Value: "cs",
|
||
|
Host: "0:9410",
|
||
|
ServiceName: "go-zipkin-testclient",
|
||
|
},
|
||
|
},
|
||
|
BinaryAnnotations: []BinaryAnnotation{},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
want: []testutil.Metric{
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"id": "6802735349851856000",
|
||
|
"parent_id": "6802735349851856000",
|
||
|
"trace_id": "0:6802735349851856000",
|
||
|
"name": "main.dud",
|
||
|
"service_name": "trivial",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(1) * time.Nanosecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(1, 0).UTC(),
|
||
|
},
|
||
|
testutil.Metric{
|
||
|
Measurement: "zipkin",
|
||
|
Tags: map[string]string{
|
||
|
"annotation": "cs",
|
||
|
"endpoint_host": "0:9410",
|
||
|
"id": "6802735349851856000",
|
||
|
"parent_id": "6802735349851856000",
|
||
|
"trace_id": "0:6802735349851856000",
|
||
|
"name": "main.dud",
|
||
|
"service_name": "go-zipkin-testclient",
|
||
|
},
|
||
|
Fields: map[string]interface{}{
|
||
|
"duration_ns": (time.Duration(1) * time.Nanosecond).Nanoseconds(),
|
||
|
},
|
||
|
Time: time.Unix(1, 0).UTC(),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
for i, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
mockAcc.ClearMetrics()
|
||
|
l := &LineProtocolConverter{
|
||
|
acc: tt.fields.acc,
|
||
|
}
|
||
|
if err := l.Record(tt.args.t); (err != nil) != tt.wantErr {
|
||
|
t.Errorf("LineProtocolConverter.Record() error = %v, wantErr %v", err, tt.wantErr)
|
||
|
}
|
||
|
got := []testutil.Metric{}
|
||
|
for _, metric := range mockAcc.Metrics {
|
||
|
got = append(got, *metric)
|
||
|
}
|
||
|
if !cmp.Equal(got, tt.want) {
|
||
|
t.Errorf("LineProtocolConverter.Record()/%s/%d error = %s ", tt.name, i, cmp.Diff(got, tt.want))
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Test_microToTime(t *testing.T) {
|
||
|
type args struct {
|
||
|
micro int64
|
||
|
}
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
args args
|
||
|
want time.Time
|
||
|
}{
|
||
|
{
|
||
|
name: "given zero micro seconds expected unix time zero",
|
||
|
args: args{
|
||
|
micro: 0,
|
||
|
},
|
||
|
want: time.Unix(0, 0).UTC(),
|
||
|
},
|
||
|
{
|
||
|
name: "given a million micro seconds expected unix time one",
|
||
|
args: args{
|
||
|
micro: 1000000,
|
||
|
},
|
||
|
want: time.Unix(1, 0).UTC(),
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
if got := microToTime(tt.args.micro); !reflect.DeepEqual(got, tt.want) {
|
||
|
t.Errorf("microToTime() = %v, want %v", got, tt.want)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func newAnnotation(micro int64) *zipkincore.Annotation {
|
||
|
return &zipkincore.Annotation{
|
||
|
Timestamp: micro,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Test_minMax(t *testing.T) {
|
||
|
type args struct {
|
||
|
span *zipkincore.Span
|
||
|
}
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
args args
|
||
|
now func() time.Time
|
||
|
wantMin time.Time
|
||
|
wantMax time.Time
|
||
|
}{
|
||
|
{
|
||
|
name: "Single annotation",
|
||
|
args: args{
|
||
|
span: &zipkincore.Span{
|
||
|
Annotations: []*zipkincore.Annotation{
|
||
|
newAnnotation(1000000),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
wantMin: time.Unix(1, 0).UTC(),
|
||
|
wantMax: time.Unix(1, 0).UTC(),
|
||
|
},
|
||
|
{
|
||
|
name: "Three annotations",
|
||
|
args: args{
|
||
|
span: &zipkincore.Span{
|
||
|
Annotations: []*zipkincore.Annotation{
|
||
|
newAnnotation(1000000),
|
||
|
newAnnotation(2000000),
|
||
|
newAnnotation(3000000),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
wantMin: time.Unix(1, 0).UTC(),
|
||
|
wantMax: time.Unix(3, 0).UTC(),
|
||
|
},
|
||
|
{
|
||
|
name: "Annotations are in the future",
|
||
|
args: args{
|
||
|
span: &zipkincore.Span{
|
||
|
Annotations: []*zipkincore.Annotation{
|
||
|
newAnnotation(3000000),
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
wantMin: time.Unix(2, 0).UTC(),
|
||
|
wantMax: time.Unix(3, 0).UTC(),
|
||
|
now: func() time.Time {
|
||
|
return time.Unix(2, 0).UTC()
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
name: "No Annotations",
|
||
|
args: args{
|
||
|
span: &zipkincore.Span{
|
||
|
Annotations: []*zipkincore.Annotation{},
|
||
|
},
|
||
|
},
|
||
|
wantMin: time.Unix(2, 0).UTC(),
|
||
|
wantMax: time.Unix(2, 0).UTC(),
|
||
|
now: func() time.Time {
|
||
|
return time.Unix(2, 0).UTC()
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
if tt.now != nil {
|
||
|
now = tt.now
|
||
|
}
|
||
|
got, got1 := minMax(tt.args.span)
|
||
|
if !reflect.DeepEqual(got, tt.wantMin) {
|
||
|
t.Errorf("minMax() got = %v, want %v", got, tt.wantMin)
|
||
|
}
|
||
|
if !reflect.DeepEqual(got1, tt.wantMax) {
|
||
|
t.Errorf("minMax() got1 = %v, want %v", got1, tt.wantMax)
|
||
|
}
|
||
|
now = time.Now
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Test_host(t *testing.T) {
|
||
|
type args struct {
|
||
|
h *zipkincore.Endpoint
|
||
|
}
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
args args
|
||
|
want string
|
||
|
}{
|
||
|
{
|
||
|
name: "Host Found",
|
||
|
args: args{
|
||
|
h: &zipkincore.Endpoint{
|
||
|
Ipv4: 1234,
|
||
|
Port: 8888,
|
||
|
},
|
||
|
},
|
||
|
want: "0.0.4.210:8888",
|
||
|
},
|
||
|
{
|
||
|
name: "No Host",
|
||
|
args: args{
|
||
|
h: nil,
|
||
|
},
|
||
|
want: "0.0.0.0",
|
||
|
},
|
||
|
{
|
||
|
name: "int overflow zipkin uses an int16 type as an unsigned int 16.",
|
||
|
args: args{
|
||
|
h: &zipkincore.Endpoint{
|
||
|
Ipv4: 1234,
|
||
|
Port: -1,
|
||
|
},
|
||
|
},
|
||
|
want: "0.0.4.210:65535",
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
if got := host(tt.args.h); got != tt.want {
|
||
|
t.Errorf("host() = %v, want %v", got, tt.want)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func Test_serviceName(t *testing.T) {
|
||
|
type args struct {
|
||
|
h *zipkincore.Endpoint
|
||
|
}
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
args args
|
||
|
want string
|
||
|
}{
|
||
|
{
|
||
|
name: "Found ServiceName",
|
||
|
args: args{
|
||
|
h: &zipkincore.Endpoint{
|
||
|
ServiceName: "zipkin",
|
||
|
},
|
||
|
},
|
||
|
want: "zipkin",
|
||
|
},
|
||
|
{
|
||
|
name: "No ServiceName",
|
||
|
args: args{
|
||
|
h: nil,
|
||
|
},
|
||
|
want: "unknown",
|
||
|
},
|
||
|
}
|
||
|
for _, tt := range tests {
|
||
|
t.Run(tt.name, func(t *testing.T) {
|
||
|
if got := serviceName(tt.args.h); got != tt.want {
|
||
|
t.Errorf("serviceName() = %v, want %v", got, tt.want)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
}
|