1515package http_test
1616
1717import (
18+ "bytes"
19+ "encoding/json"
1820 "io/ioutil"
1921 "net/http"
2022 "net/http/httptest"
23+ "sync/atomic"
2124 "testing"
22-
23- "fmt"
2425 "time"
2526
26- "strings"
27-
2827 "github.com/openzipkin/zipkin-go/idgenerator"
2928 "github.com/openzipkin/zipkin-go/model"
29+ "github.com/openzipkin/zipkin-go/reporter"
3030 zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http"
3131)
3232
33- func TestSpanIsBeingReported (t * testing.T ) {
33+ func generateSpans (n int ) []* model.SpanModel {
34+ spans := make ([]* model.SpanModel , n )
3435 idGen := idgenerator .NewRandom64 ()
3536 traceID := idGen .TraceID ()
3637
37- nSpans := 2
38- var aSpans []model.SpanModel
39- var eSpans []string
40-
41- for i := 0 ; i < nSpans ; i ++ {
42- span := model.SpanModel {
38+ for i := 0 ; i < n ; i ++ {
39+ spans [i ] = & model.SpanModel {
4340 SpanContext : model.SpanContext {
4441 TraceID : traceID ,
4542 ID : idGen .SpanID (traceID ),
@@ -48,44 +45,125 @@ func TestSpanIsBeingReported(t *testing.T) {
4845 Kind : model .Client ,
4946 Timestamp : time .Now (),
5047 }
51-
52- aSpans = append (aSpans , span )
53- eSpans = append (
54- eSpans ,
55- fmt .Sprintf (
56- `{"timestamp":%d,"traceId":"%s","id":"%s","name":"%s","kind":"%s"}` ,
57- span .Timestamp .Round (time .Microsecond ).UnixNano ()/ 1e3 ,
58- span .SpanContext .TraceID ,
59- span .SpanContext .ID ,
60- span .Name ,
61- span .Kind ,
62- ),
63- )
6448 }
6549
66- eSpansPayload := fmt .Sprintf ("[%s]" , strings .Join (eSpans , "," ))
50+ return spans
51+ }
6752
68- ts := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
53+ func newTestServer (t * testing.T , spans []* model.SpanModel , serializer reporter.SpanSerializer , onReceive func (int )) * httptest.Server {
54+ sofar := 0
55+ return httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
6956 if r .Method != "POST" {
7057 t .Errorf ("expected 'POST' request, got '%s'" , r .Method )
7158 }
7259
73- aSpanPayload , err := ioutil .ReadAll (r .Body )
60+ aPayload , err := ioutil .ReadAll (r .Body )
7461 if err != nil {
75- t .Errorf ("unexpected error: %s " , err . Error () )
62+ t .Errorf ("unexpected error: %v " , err )
7663 }
7764
78- if eSpansPayload != string (aSpanPayload ) {
79- t .Errorf ("unexpected span payload \n want %s, \n have %s\n " , eSpansPayload , string (aSpanPayload ))
65+ var aSpans []* model.SpanModel
66+ err = json .Unmarshal (aPayload , & aSpans )
67+ if err != nil {
68+ t .Errorf ("failed to parse json payload: %v" , err )
69+ }
70+ eSpans := spans [sofar : sofar + len (aSpans )]
71+ sofar += len (aSpans )
72+ onReceive (len (aSpans ))
73+
74+ ePayload , err := serializer .Serialize (eSpans )
75+ if err != nil {
76+ t .Errorf ("unexpected error: %v" , err )
77+ }
78+
79+ if ! bytes .Equal (aPayload , ePayload ) {
80+ t .Errorf ("unexpected span payload\n have %s\n want %s" , string (aPayload ), string (ePayload ))
8081 }
8182 }))
83+ }
84+
85+ func TestSpanIsBeingReported (t * testing.T ) {
86+ serializer := reporter.JSONSerializer {}
87+
88+ var numSpans int64
89+ eNumSpans := 2
90+ spans := generateSpans (eNumSpans )
91+ ts := newTestServer (t , spans , serializer , func (num int ) { atomic .AddInt64 (& numSpans , int64 (num )) })
92+ defer ts .Close ()
93+
94+ rep := zipkinhttp .NewReporter (ts .URL , zipkinhttp .Serializer (serializer ))
95+ for _ , span := range spans {
96+ rep .Send (* span )
97+ }
98+ rep .Close ()
99+
100+ aNumSpans := int (atomic .LoadInt64 (& numSpans ))
101+ if aNumSpans != eNumSpans {
102+ t .Errorf ("unexpected number of spans received\n have: %d, want: %d" , aNumSpans , eNumSpans )
103+ }
104+ }
105+
106+ func TestSpanIsReportedOnTime (t * testing.T ) {
107+ serializer := reporter.JSONSerializer {}
108+ batchInterval := 200 * time .Millisecond
82109
110+ var numSpans int64
111+ eNumSpans := 2
112+ spans := generateSpans (eNumSpans )
113+ ts := newTestServer (t , spans , serializer , func (num int ) { atomic .AddInt64 (& numSpans , int64 (num )) })
83114 defer ts .Close ()
84115
85- rep := zipkinhttp .NewReporter (ts .URL )
86- defer rep .Close ()
116+ rep := zipkinhttp .NewReporter (ts .URL ,
117+ zipkinhttp .Serializer (serializer ),
118+ zipkinhttp .BatchInterval (batchInterval ))
119+
120+ for _ , span := range spans {
121+ rep .Send (* span )
122+ }
123+
124+ time .Sleep (3 * batchInterval / 2 )
125+
126+ aNumSpans := int (atomic .LoadInt64 (& numSpans ))
127+ if aNumSpans != eNumSpans {
128+ t .Errorf ("unexpected number of spans received\n have: %d, want: %d" , aNumSpans , eNumSpans )
129+ }
130+
131+ rep .Close ()
132+ }
133+
134+ func TestSpanIsReportedAfterBatchSize (t * testing.T ) {
135+ serializer := reporter.JSONSerializer {}
136+ batchSize := 2
137+
138+ var numSpans int64
139+ eNumSpans := 6
140+ spans := generateSpans (eNumSpans )
141+ ts := newTestServer (t , spans , serializer , func (num int ) { atomic .AddInt64 (& numSpans , int64 (num )) })
142+ defer ts .Close ()
143+
144+ rep := zipkinhttp .NewReporter (ts .URL ,
145+ zipkinhttp .Serializer (serializer ),
146+ zipkinhttp .BatchSize (batchSize ))
147+
148+ for _ , span := range spans [:batchSize ] {
149+ rep .Send (* span )
150+ }
151+
152+ time .Sleep (100 * time .Millisecond )
153+
154+ aNumSpans := int (atomic .LoadInt64 (& numSpans ))
155+ if aNumSpans != batchSize {
156+ t .Errorf ("unexpected number of spans received\n have: %d, want: %d" , aNumSpans , batchSize )
157+ }
158+
159+ for _ , span := range spans [batchSize :] {
160+ rep .Send (* span )
161+ }
162+
163+ rep .Close ()
87164
88- for _ , span := range aSpans {
89- rep .Send (span )
165+ aNumSpans = int (atomic .LoadInt64 (& numSpans ))
166+ if aNumSpans != eNumSpans {
167+ t .Errorf ("unexpected number of spans received\n have: %d, want: %d" , aNumSpans , eNumSpans )
90168 }
91169}
0 commit comments