Beispiel #1
0
func checkEncodeDecode(t *testing.T, typ wire.Type, tests []encodeDecodeTest) {
	for _, tt := range tests {
		buffer := bytes.Buffer{}

		// encode and match bytes
		err := Binary.Encode(tt.value, &buffer)
		if assert.NoError(t, err, "Encode failed:\n%s", tt.value) {
			assert.Equal(t, tt.encoded, buffer.Bytes())
		}

		// decode and match value
		value, err := Binary.Decode(bytes.NewReader(tt.encoded), typ)
		if assert.NoError(t, err, "Decode failed:\n%s", tt.value) {
			assert.True(
				t, wire.ValuesAreEqual(tt.value, value),
				fmt.Sprintf("\n\t   %v (expected)\n\t!= %v (actual)", tt.value, value),
			)
		}

		// encode the decoded value again
		buffer = bytes.Buffer{}
		err = Binary.Encode(value, &buffer)
		if assert.NoError(t, err, "Encode of decoded value failed:\n%s", tt.value) {
			assert.Equal(t, tt.encoded, buffer.Bytes())
		}
	}
}
Beispiel #2
0
// assertRoundTrip checks if x.ToWire() results in the given Value and whether
// x.FromWire() with the given value results in the original x.
func assertRoundTrip(t *testing.T, x thriftType, v wire.Value, msg string, args ...interface{}) bool {
	message := fmt.Sprintf(msg, args...)
	if w, err := x.ToWire(); assert.NoError(t, err, "failed to serialize: %v", x) {
		if !assert.True(
			t, wire.ValuesAreEqual(v, w), "%v: %v.ToWire() != %v", message, x, v) {
			return false
		}

		var buff bytes.Buffer
		if !assert.NoError(t, protocol.Binary.Encode(w, &buff), "%v: failed to serialize", message) {
			return false
		}

		// Flip v to deserialize(serialize(x.ToWire())) to ensure full round
		// tripping

		newV, err := protocol.Binary.Decode(bytes.NewReader(buff.Bytes()), v.Type())
		if !assert.NoError(t, err, "%v: failed to deserialize", message) {
			return false
		}

		if !assert.True(
			t, wire.ValuesAreEqual(newV, v), "%v: deserialize(serialize(%v.ToWire())) != %v", message, x, v) {
			return false
		}

		v = newV
	}

	xType := reflect.TypeOf(x)
	if xType.Kind() == reflect.Ptr {
		xType = xType.Elem()
	}

	gotX := reflect.New(xType)
	err := gotX.MethodByName("FromWire").
		Call([]reflect.Value{reflect.ValueOf(v)})[0].
		Interface()

	if assert.Nil(t, err, "FromWire: %v", message) {
		return assert.Equal(t, x, gotX.Interface(), "FromWire: %v", message)
	}
	return false
}
Beispiel #3
0
func TestBinaryLargeLength(t *testing.T) {
	// 5 MB + 4 bytes for length
	data := make([]byte, 5242880+4)
	data[0], data[1], data[2], data[3] = 0x0, 0x50, 0x0, 0x0 // 5 MB

	value, err := Binary.Decode(bytes.NewReader(data), wire.TBinary)
	require.NoError(t, err, "failed to decode value")

	want := wire.NewValueBinary(data[4:])
	assert.True(t, wire.ValuesAreEqual(want, value), "values did not match")
}
Beispiel #4
0
func TestDisableEnveloperEncode(t *testing.T) {
	rand := rand.New(rand.NewSource(time.Now().Unix()))

	tests := []struct {
		value wire.Value
		want  []byte
	}{
		{
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{}}),
			[]byte{0x00},
		},
		{
			wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(42)},
			}}),
			[]byte{
				0x08, 0x00, 0x01,
				0x00, 0x00, 0x00, 0x2a,
				0x00,
			},
		},
	}

	for _, tt := range tests {
		e := wire.Envelope{Value: tt.value, Type: wire.Call}
		generate(&e.Name, rand)
		generate(&e.SeqID, rand)

		var buffer bytes.Buffer
		proto := disableEnvelopingProtocol{protocol.Binary, wire.Reply}
		if !assert.NoError(t, proto.EncodeEnveloped(e, &buffer)) {
			continue
		}

		assert.Equal(t, tt.want, buffer.Bytes())

		gotE, err := proto.DecodeEnveloped(bytes.NewReader(tt.want))
		if !assert.NoError(t, err) {
			continue
		}

		assert.Equal(t, wire.Reply, gotE.Type)
		assert.True(t, wire.ValuesAreEqual(tt.value, gotE.Value))
	}
}
Beispiel #5
0
func TestListOfBinaryReadNil(t *testing.T) {
	value := wire.NewValueStruct(wire.Struct{Fields: []wire.Field{{
		ID: 1,
		Value: wire.NewValueList(
			wire.ValueListFromSlice(wire.TBinary, []wire.Value{
				wire.NewValueBinary([]byte("foo")),
				wire.NewValueBinary(nil),
				wire.NewValueBinary([]byte("bar")),
				wire.NewValueBinary([]byte("baz")),
			}),
		),
	}}})

	var c tc.PrimitiveContainers
	require.NoError(t, c.FromWire(value))

	got, err := c.ToWire()
	require.NoError(t, err)
	require.NoError(t, wire.EvaluateValue(got))
	assert.True(t, wire.ValuesAreEqual(value, got))
}
Beispiel #6
0
func roundTrip(t *testing.T, x thriftType, msg string) thriftType {
	v, err := x.ToWire()
	if !assert.NoError(t, err, "failed to serialize: %v", x) {
		return nil
	}

	var buff bytes.Buffer
	if !assert.NoError(t, protocol.Binary.Encode(v, &buff), "%v: failed to serialize", msg) {
		return nil
	}

	newV, err := protocol.Binary.Decode(bytes.NewReader(buff.Bytes()), v.Type())
	if !assert.NoError(t, err, "%v: failed to deserialize", msg) {
		return nil
	}

	if !assert.True(
		t, wire.ValuesAreEqual(newV, v), "%v: deserialize(serialize(%v.ToWire())) != %v", msg, x, v) {
		return nil
	}

	xType := reflect.TypeOf(x)
	if xType.Kind() == reflect.Ptr {
		xType = xType.Elem()
	}

	gotX := reflect.New(xType)
	errval := gotX.MethodByName("FromWire").
		Call([]reflect.Value{reflect.ValueOf(newV)})[0].
		Interface()

	if !assert.Nil(t, errval, "FromWire: %v", msg) {
		return nil
	}

	assert.Equal(t, x, gotX.Interface(), "FromWire: %v", msg)
	return gotX.Interface().(thriftType)
}
Beispiel #7
0
func TestStructWithDefaults(t *testing.T) {
	enumDefaultFoo := te.EnumDefaultFoo
	enumDefaultBar := te.EnumDefaultBar
	enumDefaultBaz := te.EnumDefaultBaz

	tests := []struct {
		give     *ts.DefaultsStruct
		giveWire wire.Value

		wantToWire   wire.Value
		wantFromWire *ts.DefaultsStruct
	}{
		{
			give:     &ts.DefaultsStruct{},
			giveWire: wire.NewValueStruct(wire.Struct{}),

			wantToWire: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(100)},
				{ID: 2, Value: wire.NewValueI32(200)},
				{ID: 3, Value: wire.NewValueI32(1)},
				{ID: 4, Value: wire.NewValueI32(2)},
				{
					ID: 5,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{
							wire.NewValueString("hello"),
							wire.NewValueString("world"),
						}),
					),
				},
				{
					ID: 6,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TDouble, []wire.Value{
							wire.NewValueDouble(1.0),
							wire.NewValueDouble(2.0),
							wire.NewValueDouble(3.0),
						}),
					),
				},
				{
					ID: 7,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(100.0)},
								{ID: 2, Value: wire.NewValueDouble(200.0)},
							}}),
						},
					}}),
				},
				{
					ID: 8,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(3.0)},
								{ID: 2, Value: wire.NewValueDouble(4.0)},
							}}),
						},
					}}),
				},
			}}),
			wantFromWire: &ts.DefaultsStruct{
				RequiredPrimitive: int32p(100),
				OptionalPrimitive: int32p(200),
				RequiredEnum:      &enumDefaultBar,
				OptionalEnum:      &enumDefaultBaz,
				RequiredList:      []string{"hello", "world"},
				OptionalList:      []float64{1.0, 2.0, 3.0},
				RequiredStruct: &ts.Frame{
					TopLeft: &ts.Point{X: 1.0, Y: 2.0},
					Size:    &ts.Size{Width: 100.0, Height: 200.0},
				},
				OptionalStruct: &ts.Edge{
					StartPoint: &ts.Point{X: 1.0, Y: 2.0},
					EndPoint:   &ts.Point{X: 3.0, Y: 4.0},
				},
			},
		},
		{
			give: &ts.DefaultsStruct{
				RequiredPrimitive: int32p(0),
				OptionalEnum:      &enumDefaultFoo,
				RequiredList:      []string{},
			},
			giveWire: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(0)},
				{ID: 4, Value: wire.NewValueI32(0)},
				{
					ID: 5,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{}),
					),
				},
			}}),

			wantToWire: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
				{ID: 1, Value: wire.NewValueI32(0)},
				{ID: 2, Value: wire.NewValueI32(200)},
				{ID: 3, Value: wire.NewValueI32(1)},
				{ID: 4, Value: wire.NewValueI32(0)},
				{
					ID: 5,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TBinary, []wire.Value{}),
					),
				},
				{
					ID: 6,
					Value: wire.NewValueList(
						wire.ValueListFromSlice(wire.TDouble, []wire.Value{
							wire.NewValueDouble(1.0),
							wire.NewValueDouble(2.0),
							wire.NewValueDouble(3.0),
						}),
					),
				},
				{
					ID: 7,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(100.0)},
								{ID: 2, Value: wire.NewValueDouble(200.0)},
							}}),
						},
					}}),
				},
				{
					ID: 8,
					Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
						{
							ID: 1,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(1.0)},
								{ID: 2, Value: wire.NewValueDouble(2.0)},
							}}),
						},
						{
							ID: 2,
							Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
								{ID: 1, Value: wire.NewValueDouble(3.0)},
								{ID: 2, Value: wire.NewValueDouble(4.0)},
							}}),
						},
					}}),
				},
			}}),
			wantFromWire: &ts.DefaultsStruct{
				RequiredPrimitive: int32p(0),
				OptionalPrimitive: int32p(200),
				RequiredEnum:      &enumDefaultBar,
				OptionalEnum:      &enumDefaultFoo,
				RequiredList:      []string{},
				OptionalList:      []float64{1.0, 2.0, 3.0},
				RequiredStruct: &ts.Frame{
					TopLeft: &ts.Point{X: 1.0, Y: 2.0},
					Size:    &ts.Size{Width: 100.0, Height: 200.0},
				},
				OptionalStruct: &ts.Edge{
					StartPoint: &ts.Point{X: 1.0, Y: 2.0},
					EndPoint:   &ts.Point{X: 3.0, Y: 4.0},
				},
			},
		},
	}

	for _, tt := range tests {
		if gotWire, err := tt.give.ToWire(); assert.NoError(
			t, err, "%v.ToWire() failed", tt.give) {
			assert.True(
				t, wire.ValuesAreEqual(tt.wantToWire, gotWire),
				"%v.ToWire() != %v", tt.give, tt.wantToWire)
		}

		var gotFromWire ts.DefaultsStruct
		if err := gotFromWire.FromWire(tt.giveWire); assert.NoError(t, err) {
			assert.Equal(t, tt.wantFromWire, &gotFromWire)
		}
	}
}