-
Notifications
You must be signed in to change notification settings - Fork 419
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from palazzem/api-msgpack
[core] add support for Msgpack encoder
- Loading branch information
Showing
9 changed files
with
347 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,159 @@ | ||
package tracer | ||
|
||
import ( | ||
"encoding/json" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/ugorji/go/codec" | ||
) | ||
|
||
func TestJSONEncoder(t *testing.T) { | ||
func TestEncoderContentType(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// create a traces list with a single span | ||
var traces [][]*Span | ||
var spans []*Span | ||
span := NewSpan("pylons.request", "pylons", "/", 0, 0, 0, nil) | ||
span.Start = 0 | ||
spans = append(spans, span) | ||
traces = append(traces, spans) | ||
|
||
// the encoder must return a valid JSON byte array that ends with a \n | ||
want := `[[{"name":"pylons.request","service":"pylons","resource":"/","type":"","start":0,"duration":0,"span_id":0,"trace_id":0,"parent_id":0,"error":0}]]` | ||
want += "\n" | ||
|
||
encoder := newJSONEncoder() | ||
err := encoder.Encode(traces) | ||
assert.Nil(err) | ||
assert.Equal(want, encoder.b.String()) | ||
testCases := []struct { | ||
encoder Encoder | ||
contentType string | ||
}{ | ||
{newJSONEncoder(), "application/json"}, | ||
{newMsgpackEncoder(), "application/msgpack"}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
assert.Equal(tc.contentType, tc.encoder.ContentType()) | ||
} | ||
} | ||
|
||
func TestJSONRead(t *testing.T) { | ||
func TestJSONEncoding(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// create a traces list with a single span | ||
var traces [][]*Span | ||
var spans []*Span | ||
span := NewSpan("pylons.request", "pylons", "/", 0, 0, 0, nil) | ||
span.Start = 0 | ||
spans = append(spans, span) | ||
traces = append(traces, spans) | ||
|
||
// fill the encoder internal buffer | ||
encoder := newJSONEncoder() | ||
_ = encoder.Encode(traces) | ||
expectedSize := encoder.b.Len() | ||
|
||
// the Read function must be used to get the value of the internal buffer | ||
buff := make([]byte, expectedSize) | ||
_, err := encoder.Read(buff) | ||
|
||
// it should match the encoding payload | ||
want := `[[{"name":"pylons.request","service":"pylons","resource":"/","type":"","start":0,"duration":0,"span_id":0,"trace_id":0,"parent_id":0,"error":0}]]` | ||
want += "\n" | ||
assert.Nil(err) | ||
assert.Equal(want, string(buff)) | ||
testCases := []struct { | ||
traces int | ||
size int | ||
}{ | ||
{1, 1}, | ||
{3, 1}, | ||
{1, 3}, | ||
{3, 3}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
payload := getTestTrace(tc.traces, tc.size) | ||
encoder := newJSONEncoder() | ||
err := encoder.Encode(payload) | ||
assert.Nil(err) | ||
|
||
// decode to check the right encoding | ||
var traces [][]*Span | ||
dec := json.NewDecoder(encoder.buffer) | ||
err = dec.Decode(&traces) | ||
assert.Nil(err) | ||
assert.Len(traces, tc.traces) | ||
|
||
for _, trace := range traces { | ||
assert.Len(trace, tc.size) | ||
span := trace[0] | ||
assert.Equal(uint64(42), span.TraceID) | ||
assert.Equal(uint64(52), span.SpanID) | ||
assert.Equal(uint64(42), span.ParentID) | ||
assert.Equal("web", span.Type) | ||
assert.Equal("high.throughput", span.Service) | ||
assert.Equal("sending.events", span.Name) | ||
assert.Equal("SEND /data", span.Resource) | ||
assert.Equal(int64(1481215590883401105), span.Start) | ||
assert.Equal(int64(1000000000), span.Duration) | ||
assert.Equal("192.168.0.1", span.Meta["http.host"]) | ||
assert.Equal(float64(41.99), span.Metrics["http.monitor"]) | ||
} | ||
} | ||
} | ||
|
||
func TestPoolBorrowCreate(t *testing.T) { | ||
func TestMsgpackEncoding(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// borrow an encoder from the pool | ||
pool := newEncoderPool(1) | ||
encoder := pool.Borrow() | ||
assert.NotNil(encoder) | ||
testCases := []struct { | ||
traces int | ||
size int | ||
}{ | ||
{1, 1}, | ||
{3, 1}, | ||
{1, 3}, | ||
{3, 3}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
payload := getTestTrace(tc.traces, tc.size) | ||
encoder := newMsgpackEncoder() | ||
err := encoder.Encode(payload) | ||
assert.Nil(err) | ||
|
||
// decode to check the right encoding | ||
var traces [][]*Span | ||
var mh codec.MsgpackHandle | ||
dec := codec.NewDecoder(encoder.buffer, &mh) | ||
err = dec.Decode(&traces) | ||
assert.Nil(err) | ||
assert.Len(traces, tc.traces) | ||
|
||
for _, trace := range traces { | ||
assert.Len(trace, tc.size) | ||
span := trace[0] | ||
assert.Equal(uint64(42), span.TraceID) | ||
assert.Equal(uint64(52), span.SpanID) | ||
assert.Equal(uint64(42), span.ParentID) | ||
assert.Equal("web", span.Type) | ||
assert.Equal("high.throughput", span.Service) | ||
assert.Equal("sending.events", span.Name) | ||
assert.Equal("SEND /data", span.Resource) | ||
assert.Equal(int64(1481215590883401105), span.Start) | ||
assert.Equal(int64(1000000000), span.Duration) | ||
assert.Equal("192.168.0.1", span.Meta["http.host"]) | ||
assert.Equal(float64(41.99), span.Metrics["http.monitor"]) | ||
} | ||
} | ||
} | ||
|
||
func TestPoolReturn(t *testing.T) { | ||
func TestPoolBorrowCreate(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// an encoder can return in the pool | ||
pool := newEncoderPool(1) | ||
encoder := newJSONEncoder() | ||
pool.pool <- encoder | ||
pool.Return(encoder) | ||
|
||
// the encoder is the one we get before | ||
returnedEncoder := <-pool.pool | ||
assert.Equal(returnedEncoder, encoder) | ||
// borrow an encoder from the pool | ||
pool, _ := newEncoderPool(MSGPACK_ENCODER, 1) | ||
encoder := pool.Borrow() | ||
assert.NotNil(encoder) | ||
} | ||
|
||
func TestPoolReuseEncoder(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// borrow, return and borrow again an encoder from the pool | ||
pool := newEncoderPool(1) | ||
pool, _ := newEncoderPool(MSGPACK_ENCODER, 1) | ||
encoder := pool.Borrow() | ||
pool.Return(encoder) | ||
anotherEncoder := pool.Borrow() | ||
assert.Equal(anotherEncoder, encoder) | ||
} | ||
|
||
func TestPoolSize(t *testing.T) { | ||
pool := newEncoderPool(1) | ||
encoder := newJSONEncoder() | ||
anotherEncoder := newJSONEncoder() | ||
pool, _ := newEncoderPool(MSGPACK_ENCODER, 1) | ||
encoder := newMsgpackEncoder() | ||
anotherEncoder := newMsgpackEncoder() | ||
|
||
// put two encoders in the pool with a maximum size of 1 | ||
// doesn't hang the caller | ||
pool.Return(encoder) | ||
pool.Return(anotherEncoder) | ||
} | ||
|
||
func TestPoolReturn(t *testing.T) { | ||
assert := assert.New(t) | ||
|
||
// an encoder can return in the pool | ||
pool, _ := newEncoderPool(MSGPACK_ENCODER, 5) | ||
encoder := newMsgpackEncoder() | ||
pool.pool <- encoder | ||
pool.Return(encoder) | ||
|
||
// the encoder is the one we get before | ||
returnedEncoder := <-pool.pool | ||
assert.Equal(returnedEncoder, encoder) | ||
} |
Oops, something went wrong.