Beispiel #1
0
func (h pluginHandler) Handshake(request *api.HandshakeRequest) (*api.HandshakeResponse, error) {
	return &api.HandshakeResponse{
		Name:           h.plugin.Name,
		APIVersion:     api.APIVersion,
		Features:       h.features,
		LibraryVersion: ptr.String(version.Version),
	}, nil
}
Beispiel #2
0
// Handshake with this server without any expectation of failure.
func (s *fakePluginServer) Handshake(t *testing.T, pluginName string, features []api.Feature) Handle {
	s.Plugin.EXPECT().Handshake(&api.HandshakeRequest{}).
		Return(&api.HandshakeResponse{
			Name:           pluginName,
			APIVersion:     api.APIVersion,
			LibraryVersion: ptr.String(version.Version),
			Features:       features,
		}, nil)

	handle, err := NewTransportHandle(pluginName, s.ClientTransport)
	require.NoError(t, err, "handshake with fakePluginServer failed")

	return handle
}
Beispiel #3
0
func TestStruct(t *testing.T) {
	tests := []struct {
		desc string
		x    thriftType
	}{
		{
			"StructCollision",
			&tc.StructCollision{
				CollisionField:  true,
				CollisionField2: "true",
			},
		},
		{
			"StructCollision2 (struct_collision)",
			&tc.StructCollision2{
				CollisionField:  true,
				CollisionField2: "such trueness",
			},
		},
		{
			"PrimitiveContainers",
			&tc.PrimitiveContainers{
				A: []string{"arbre", "fleur"},
				B: map[string]struct{}{
					"croissant": {},
					"baguette":  {},
				},
				C: map[string]string{
					"voiture": "bleue",
					"cammion": "rouge",
				},
			},
		},
		{
			"StructConstant (struct_constant)",
			tc.StructConstant,
		},
		{
			"UnionCollision .CollisionField",
			&tc.UnionCollision{
				CollisionField: ptr.Bool(true),
			},
		},
		{
			"UnionCollision .collision_field",
			&tc.UnionCollision{
				CollisionField2: ptr.String("so true"),
			},
		},
		{
			"UnionCollision2 (union_collision) .CollisionField",
			&tc.UnionCollision2{
				CollisionField: &[]bool{true}[0],
			},
		},
		{
			"UnionCollision (union_collision) .collision_field",
			&tc.UnionCollision2{
				CollisionField2: ptr.String("true indeed"),
			},
		},
	}
	for _, tt := range tests {
		roundTrip(t, tt.x, tt.desc)
	}
}
Beispiel #4
0
func runGauntlet(t crossdock.T, clientt thrift.TChanClient) {
	checks := crossdock.Checks(t)

	token := random.String(5)
	bytesToken := random.Bytes(1)

	tests := []gauntlet.TT{
		{
			Function: "TestBinary",
			Give:     []interface{}{bytesToken},
			Want:     bytesToken,
		},
		{
			Function: "TestByte",
			Give:     []interface{}{int8(42)},
			Want:     int8(42),
		},
		{
			Function: "TestDouble",
			Give:     []interface{}{float64(12.34)},
			Want:     float64(12.34),
		},
		{
			Function: "TestEnum",
			Details:  "MyNumberz",
			Give:     []interface{}{gauntlet_tchannel.Numberz(gauntlet_tchannel.MyNumberz)},
			Want:     gauntlet_tchannel.Numberz(gauntlet_tchannel.MyNumberz),
		},
		{
			Function: "TestEnum",
			Details:  "NumberzThree",
			Give:     []interface{}{gauntlet_tchannel.Numberz_THREE},
			Want:     gauntlet_tchannel.Numberz_THREE,
		},
		{
			Function: "TestEnum",
			Details:  "unrecognized Numberz",
			Give:     []interface{}{gauntlet_tchannel.Numberz(42)},
			Want:     gauntlet_tchannel.Numberz(42),
		},
		{
			Function: "TestException",
			Details:  "Xception",
			Give:     []interface{}{"Xception"},
			WantError: &gauntlet_tchannel.Xception{
				ErrorCode: ptr.Int32(1001),
				Message:   ptr.String("Xception"),
			},
		},
		{
			Function:      "TestException",
			Details:       "TException",
			Give:          []interface{}{"TException"},
			WantErrorLike: `UnexpectedError: error for procedure "ThriftTest::testException" of service "yarpc-test": great sadness`,
		},
		{
			Function: "TestException",
			Details:  "no error",
			Give:     []interface{}{"yolo"},
		},
		{
			Function: "TestI32",
			Give:     []interface{}{int32(123)},
			Want:     int32(123),
		},
		{
			Function: "TestI64",
			Give:     []interface{}{int64(18934714)},
			Want:     int64(18934714),
		},
		{
			Function: "TestInsanity",
			Give: []interface{}{
				&gauntlet_tchannel.Insanity{
					UserMap: map[gauntlet_tchannel.Numberz]gauntlet_tchannel.UserId{
						gauntlet_tchannel.Numberz_THREE: gauntlet_tchannel.UserId(100),
						gauntlet_tchannel.Numberz(100):  gauntlet_tchannel.UserId(200),
					},
					Xtructs: []*gauntlet_tchannel.Xtruct{
						{StringThing: ptr.String("0")},
						{ByteThing: ptr.Int8(1)},
						{I32Thing: ptr.Int32(2)},
						{I64Thing: ptr.Int64(3)},
					},
				},
			},
			Want: map[gauntlet_tchannel.UserId]map[gauntlet_tchannel.Numberz]*gauntlet_tchannel.Insanity{
				1: {
					gauntlet_tchannel.Numberz_TWO: &gauntlet_tchannel.Insanity{
						UserMap: map[gauntlet_tchannel.Numberz]gauntlet_tchannel.UserId{
							gauntlet_tchannel.Numberz_THREE: gauntlet_tchannel.UserId(100),
							gauntlet_tchannel.Numberz(100):  gauntlet_tchannel.UserId(200),
						},
						Xtructs: []*gauntlet_tchannel.Xtruct{
							{StringThing: ptr.String("0")},
							{ByteThing: ptr.Int8(1)},
							{I32Thing: ptr.Int32(2)},
							{I64Thing: ptr.Int64(3)},
						},
					},
					gauntlet_tchannel.Numberz_THREE: &gauntlet_tchannel.Insanity{
						UserMap: map[gauntlet_tchannel.Numberz]gauntlet_tchannel.UserId{
							gauntlet_tchannel.Numberz_THREE: gauntlet_tchannel.UserId(100),
							gauntlet_tchannel.Numberz(100):  gauntlet_tchannel.UserId(200),
						},
						Xtructs: []*gauntlet_tchannel.Xtruct{
							{StringThing: ptr.String("0")},
							{ByteThing: ptr.Int8(1)},
							{I32Thing: ptr.Int32(2)},
							{I64Thing: ptr.Int64(3)},
						},
					},
				},
				2: {
					gauntlet_tchannel.Numberz_SIX: &gauntlet_tchannel.Insanity{},
				},
			},
		},
		{
			Function: "TestList",
			Give:     []interface{}{[]int32{1, 2, 3}},
			Want:     []int32{1, 2, 3},
		},
		{
			Function: "TestMap",
			Give:     []interface{}{map[int32]int32{1: 2, 3: 4, 5: 6}},
			Want:     map[int32]int32{1: 2, 3: 4, 5: 6},
		},
		{
			Function: "TestMapMap",
			Give:     []interface{}{int32(42)},
			Want: map[int32]map[int32]int32{
				-4: {
					-4: -4,
					-3: -3,
					-2: -2,
					-1: -1,
				},
				4: {
					1: 1,
					2: 2,
					3: 3,
					4: 4,
				},
			},
		},
		{
			Function: "TestMulti",
			Give: []interface{}{
				int8(100),
				int32(200),
				int64(300),
				map[int16]string{1: "1", 2: "2", 3: "3"},
				gauntlet_tchannel.Numberz_EIGHT,
				gauntlet_tchannel.UserId(42),
			},
			Want: &gauntlet_tchannel.Xtruct{
				StringThing: ptr.String("Hello2"),
				ByteThing:   ptr.Int8(100),
				I32Thing:    ptr.Int32(200),
				I64Thing:    ptr.Int64(300),
			},
		},
		{
			Function: "TestMultiException",
			Details:  "Xception",
			Give:     []interface{}{"Xception", "foo"},
			WantError: &gauntlet_tchannel.Xception{
				ErrorCode: ptr.Int32(1001),
				Message:   ptr.String("This is an Xception"),
			},
		},
		{
			Function: "TestMultiException",
			Details:  "Xception2",
			Give:     []interface{}{"Xception2", "foo"},
			WantError: &gauntlet_tchannel.Xception2{
				ErrorCode:   ptr.Int32(2002),
				StructThing: &gauntlet_tchannel.Xtruct{StringThing: ptr.String("foo")},
			},
		},
		{
			Function: "TestMultiException",
			Details:  "no error",
			Give:     []interface{}{"hello", "foo"},
			Want:     &gauntlet_tchannel.Xtruct{StringThing: ptr.String("foo")},
		},
		{
			Function: "TestNest",
			Give: []interface{}{
				&gauntlet_tchannel.Xtruct2{
					ByteThing: ptr.Int8(-1),
					I32Thing:  ptr.Int32(-1234),
					StructThing: &gauntlet_tchannel.Xtruct{
						StringThing: ptr.String("0"),
						ByteThing:   ptr.Int8(1),
						I32Thing:    ptr.Int32(2),
						I64Thing:    ptr.Int64(3),
					},
				},
			},
			Want: &gauntlet_tchannel.Xtruct2{
				ByteThing: ptr.Int8(-1),
				I32Thing:  ptr.Int32(-1234),
				StructThing: &gauntlet_tchannel.Xtruct{
					StringThing: ptr.String("0"),
					ByteThing:   ptr.Int8(1),
					I32Thing:    ptr.Int32(2),
					I64Thing:    ptr.Int64(3),
				},
			},
		},
		{
			Function: "TestSet",
			Give: []interface{}{
				map[int32]bool{
					1:  true,
					2:  true,
					-1: true,
					-2: true,
				},
			},
			Want: map[int32]bool{
				1:  true,
				2:  true,
				-1: true,
				-2: true,
			},
		},
		{
			Function: "TestString",
			Give:     []interface{}{token},
			Want:     token,
		},
		{
			Function: "TestStringMap",
			Give: []interface{}{
				map[string]string{
					"foo":   "bar",
					"hello": "world",
				},
			},
			Want: map[string]string{
				"foo":   "bar",
				"hello": "world",
			},
		},
		{
			Function: "TestStruct",
			Give: []interface{}{
				&gauntlet_tchannel.Xtruct{
					StringThing: ptr.String("0"),
					ByteThing:   ptr.Int8(1),
					I32Thing:    ptr.Int32(2),
					I64Thing:    ptr.Int64(3),
				},
			},
			Want: &gauntlet_tchannel.Xtruct{
				StringThing: ptr.String("0"),
				ByteThing:   ptr.Int8(1),
				I32Thing:    ptr.Int32(2),
				I64Thing:    ptr.Int64(3),
			},
		},
		{
			Function: "TestTypedef",
			Give:     []interface{}{gauntlet_tchannel.UserId(42)},
			Want:     gauntlet_tchannel.UserId(42),
		},
		{
			Function: "TestVoid",
			Give:     []interface{}{},
		},
		{
			Service:  "SecondService",
			Function: "BlahBlah",
			Give:     []interface{}{},
		},
		{
			Service:  "SecondService",
			Function: "SecondtestString",
			Give:     []interface{}{"hello"},
			Want:     "hello",
		},
	}

	for _, tt := range tests {
		desc := gauntlet.BuildDesc(tt)

		client := buildClient(t, desc, tt.Service, clientt)
		f := client.MethodByName(tt.Function)
		if !checks.True(f.IsValid(), "%v: invalid function", desc) {
			continue
		}

		ctx, cancel := thrift.NewContext(time.Second)
		defer cancel()

		args := []reflect.Value{reflect.ValueOf(ctx)}
		if give, ok := gauntlet.BuildArgs(t, desc, f.Type(), tt.Give, 1); ok {
			args = append(args, give...)
		} else {
			continue
		}

		got, err := extractCallResponse(t, desc, f.Call(args))
		if isUnrecognizedProcedure(err) {
			t.Skipf("%v: procedure not defined", desc)
			continue
		}
		gauntlet.Assert(t, tt, desc, got, err)
	}
}
Beispiel #5
0
func TestClient(t *testing.T) {
	mockCtrl := gomock.NewController(t)
	defer mockCtrl.Finish()

	internalError := exception.ExceptionTypeInternalError
	unknownMethod := exception.ExceptionTypeUnknownMethod

	tests := []struct {
		desc string

		// Either transportError or decode* can be set.
		transportError error
		decodeEnvelope wire.Envelope
		decodeError    error

		wantError error // expected error if any
	}{
		{
			desc: "nothing went wrong",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.Reply,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
		},
		{
			desc:        "decode error",
			decodeError: errors.New("great sadness"),
			wantError:   errors.New("great sadness"),
		},
		{
			desc: "internal error",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.Exception,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString("great sadness")},
					{ID: 2, Value: wire.NewValueI32(6)}, // Internal error
				}}),
			},
			wantError: &exception.TApplicationException{
				Message: ptr.String("great sadness"),
				Type:    &internalError,
			},
		},
		{
			desc: "unknown method",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.Exception,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString(`unknown method "hello"`)},
					{ID: 2, Value: wire.NewValueI32(1)}, // Internal error
				}}),
			},
			wantError: &exception.TApplicationException{
				Message: ptr.String(`unknown method "hello"`),
				Type:    &unknownMethod,
			},
		},
		{
			desc: "unknown envelope type",
			decodeEnvelope: wire.Envelope{
				Name:  "hello",
				Type:  wire.EnvelopeType(12),
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{}),
			},
			wantError: errUnknownEnvelopeType(12),
		},
		{
			desc:           "transport error",
			transportError: errors.New("great sadness"),
			wantError:      errors.New("great sadness"),
		},
	}

	for _, tt := range tests {
		proto := NewMockProtocol(mockCtrl)
		proto.EXPECT().EncodeEnveloped(
			wire.Envelope{
				Name:  "hello",
				Type:  wire.Call,
				SeqID: 1,
				Value: wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
					{ID: 1, Value: wire.NewValueString("world")},
				}}),
			},
			gomock.Any(),
		).Do(func(_ wire.Envelope, w io.Writer) {
			_, err := w.Write([]byte{1, 2, 3})
			assert.NoError(t, err, tt.desc)
		}).Return(nil)

		transport := envelopetest.NewMockTransport(mockCtrl)
		if tt.transportError != nil {
			transport.EXPECT().Send([]byte{1, 2, 3}).Return(nil, tt.transportError)
		} else {
			transport.EXPECT().Send([]byte{1, 2, 3}).Return([]byte{4, 5, 6}, nil)
			proto.EXPECT().DecodeEnveloped(gomock.Any()).
				Return(tt.decodeEnvelope, tt.decodeError)
		}

		client := NewClient(proto, transport)
		_, err := client.Send("hello", wire.NewValueStruct(wire.Struct{Fields: []wire.Field{
			{ID: 1, Value: wire.NewValueString("world")},
		}}))
		assert.Equal(t, tt.wantError, err)
	}
}
Beispiel #6
0
// RunGauntlet takes an rpc object and runs the gauntlet
func RunGauntlet(t crossdock.T, c Config) {
	checks := crossdock.Checks(t)
	if c.Services == 0 {
		c.Services = AllServices
	}

	bytesToken := random.Bytes(10)
	tests := []TT{
		{
			Function: "TestBinary",
			Give:     []interface{}{bytesToken},
			Want:     bytesToken,
		},
		{
			Function: "TestByte",
			Give:     []interface{}{ptr.Int8(42)},
			Want:     int8(42),
		},
		{
			Function: "TestDouble",
			Give:     []interface{}{ptr.Float64(12.34)},
			Want:     float64(12.34),
		},
		{
			Function: "TestEnum",
			Details:  "MyNumberz",
			Give:     []interface{}{numberzp(gauntlet.MyNumberz)},
			Want:     gauntlet.MyNumberz,
		},
		{
			Function: "TestEnum",
			Details:  "NumberzThree",
			Give:     []interface{}{numberzp(gauntlet.NumberzThree)},
			Want:     gauntlet.NumberzThree,
		},
		{
			Function: "TestEnum",
			Details:  "unrecognized Numberz",
			Give:     []interface{}{numberzp(gauntlet.Numberz(42))},
			Want:     gauntlet.Numberz(42),
		},
		{
			Function: "TestException",
			Details:  "Xception",
			Give:     []interface{}{ptr.String("Xception")},
			WantError: &gauntlet.Xception{
				ErrorCode: ptr.Int32(1001),
				Message:   ptr.String("Xception"),
			},
		},
		{
			Function:      "TestException",
			Details:       "TException",
			Give:          []interface{}{ptr.String("TException")},
			WantErrorLike: "great sadness",
		},
		{
			Function: "TestException",
			Details:  "no error",
			Give:     []interface{}{ptr.String("yolo")},
		},
		{
			Function: "TestI32",
			Give:     []interface{}{ptr.Int32(123)},
			Want:     int32(123),
		},
		{
			Function: "TestI64",
			Give:     []interface{}{ptr.Int64(18934714)},
			Want:     int64(18934714),
		},
		{
			Function: "TestInsanity",
			Give: []interface{}{
				&gauntlet.Insanity{
					UserMap: map[gauntlet.Numberz]gauntlet.UserId{
						gauntlet.NumberzThree: gauntlet.UserId(100),
						gauntlet.Numberz(100): gauntlet.UserId(200),
					},
					Xtructs: []*gauntlet.Xtruct{
						{StringThing: ptr.String("0")},
						{ByteThing: ptr.Int8(1)},
						{I32Thing: ptr.Int32(2)},
						{I64Thing: ptr.Int64(3)},
					},
				},
			},
			Want: map[gauntlet.UserId]map[gauntlet.Numberz]*gauntlet.Insanity{
				1: {
					gauntlet.NumberzTwo: &gauntlet.Insanity{
						UserMap: map[gauntlet.Numberz]gauntlet.UserId{
							gauntlet.NumberzThree: gauntlet.UserId(100),
							gauntlet.Numberz(100): gauntlet.UserId(200),
						},
						Xtructs: []*gauntlet.Xtruct{
							{StringThing: ptr.String("0")},
							{ByteThing: ptr.Int8(1)},
							{I32Thing: ptr.Int32(2)},
							{I64Thing: ptr.Int64(3)},
						},
					},
					gauntlet.NumberzThree: &gauntlet.Insanity{
						UserMap: map[gauntlet.Numberz]gauntlet.UserId{
							gauntlet.NumberzThree: gauntlet.UserId(100),
							gauntlet.Numberz(100): gauntlet.UserId(200),
						},
						Xtructs: []*gauntlet.Xtruct{
							{StringThing: ptr.String("0")},
							{ByteThing: ptr.Int8(1)},
							{I32Thing: ptr.Int32(2)},
							{I64Thing: ptr.Int64(3)},
						},
					},
				},
				2: {
					gauntlet.NumberzSix: &gauntlet.Insanity{},
				},
			},
		},
		{
			Function: "TestList",
			Give:     []interface{}{[]int32{1, 2, 3}},
			Want:     []int32{1, 2, 3},
		},
		{
			Function: "TestMap",
			Give:     []interface{}{map[int32]int32{1: 2, 3: 4, 5: 6}},
			Want:     map[int32]int32{1: 2, 3: 4, 5: 6},
		},
		{
			Function: "TestMapMap",
			Give:     []interface{}{ptr.Int32(42)},
			Want: map[int32]map[int32]int32{
				-4: {
					-4: -4,
					-3: -3,
					-2: -2,
					-1: -1,
				},
				4: {
					1: 1,
					2: 2,
					3: 3,
					4: 4,
				},
			},
		},
		{
			Function: "TestMulti",
			Give: []interface{}{
				ptr.Int8(100),
				ptr.Int32(200),
				ptr.Int64(300),
				map[int16]string{1: "1", 2: "2", 3: "3"},
				numberzp(gauntlet.NumberzEight),
				useridp(42),
			},
			Want: &gauntlet.Xtruct{
				StringThing: ptr.String("Hello2"),
				ByteThing:   ptr.Int8(100),
				I32Thing:    ptr.Int32(200),
				I64Thing:    ptr.Int64(300),
			},
		},
		{
			Function: "TestMultiException",
			Details:  "Xception",
			Give:     []interface{}{ptr.String("Xception"), ptr.String("foo")},
			WantError: &gauntlet.Xception{
				ErrorCode: ptr.Int32(1001),
				Message:   ptr.String("This is an Xception"),
			},
		},
		{
			Function: "TestMultiException",
			Details:  "Xception2",
			Give:     []interface{}{ptr.String("Xception2"), ptr.String("foo")},
			WantError: &gauntlet.Xception2{
				ErrorCode:   ptr.Int32(2002),
				StructThing: &gauntlet.Xtruct{StringThing: ptr.String("foo")},
			},
		},
		{
			Function: "TestMultiException",
			Details:  "no error",
			Give:     []interface{}{ptr.String("hello"), ptr.String("foo")},
			Want:     &gauntlet.Xtruct{StringThing: ptr.String("foo")},
		},
		{
			Function: "TestNest",
			Give: []interface{}{
				&gauntlet.Xtruct2{
					ByteThing: ptr.Int8(-1),
					I32Thing:  ptr.Int32(-1234),
					StructThing: &gauntlet.Xtruct{
						StringThing: ptr.String("0"),
						ByteThing:   ptr.Int8(1),
						I32Thing:    ptr.Int32(2),
						I64Thing:    ptr.Int64(3),
					},
				},
			},
			Want: &gauntlet.Xtruct2{
				ByteThing: ptr.Int8(-1),
				I32Thing:  ptr.Int32(-1234),
				StructThing: &gauntlet.Xtruct{
					StringThing: ptr.String("0"),
					ByteThing:   ptr.Int8(1),
					I32Thing:    ptr.Int32(2),
					I64Thing:    ptr.Int64(3),
				},
			},
		},
		{
			Function: "TestSet",
			Give: []interface{}{
				map[int32]struct{}{
					1:  {},
					2:  {},
					-1: {},
					-2: {},
				},
			},
			Want: map[int32]struct{}{
				1:  {},
				2:  {},
				-1: {},
				-2: {},
			},
		},
		{
			Function: "TestString",
			Give:     []interface{}{ptr.String("hello")},
			Want:     "hello",
		},
		{
			Function: "TestStringMap",
			Give: []interface{}{
				map[string]string{
					"foo":   "bar",
					"hello": "world",
				},
			},
			Want: map[string]string{
				"foo":   "bar",
				"hello": "world",
			},
		},
		{
			Function: "TestStruct",
			Give: []interface{}{
				&gauntlet.Xtruct{
					StringThing: ptr.String("0"),
					ByteThing:   ptr.Int8(1),
					I32Thing:    ptr.Int32(2),
					I64Thing:    ptr.Int64(3),
				},
			},
			Want: &gauntlet.Xtruct{
				StringThing: ptr.String("0"),
				ByteThing:   ptr.Int8(1),
				I32Thing:    ptr.Int32(2),
				I64Thing:    ptr.Int64(3),
			},
		},
		{
			Function: "TestTypedef",
			Give:     []interface{}{useridp(42)},
			Want:     gauntlet.UserId(42),
		},
		{
			Function: "TestVoid",
			Give:     []interface{}{},
		},
		{
			Function:  "TestOneway",
			Oneway:    true,
			Give:      []interface{}{ptr.Int32(123)},
			WantError: nil,
		},
		{
			Service:  "SecondService",
			Function: "BlahBlah",
			Give:     []interface{}{},
		},
		{
			Service:  "SecondService",
			Function: "SecondtestString",
			Give:     []interface{}{ptr.String("hello")},
			Want:     "hello",
		},
	}

	for _, tt := range tests {
		if tt.Service == "" {
			tt.Service = "ThriftTest"
		}

		switch tt.Service {
		case "ThriftTest":
			if c.Services&ThriftTest == 0 {
				continue
			}
		case "SecondService":
			if c.Services&SecondService == 0 {
				continue
			}
		}

		t.Tag("service", tt.Service)
		t.Tag("function", tt.Function)

		//only run oneway tests if specified
		if !c.EnableOneway && tt.Oneway {
			continue
		}

		desc := BuildDesc(tt)

		client := buildClient(t, desc, tt.Service, c)
		f := client.MethodByName(tt.Function)
		if !checks.True(f.IsValid(), "%v: invalid function", desc) {
			continue
		}

		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		args := []reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(yarpc.NewReqMeta())}
		if give, ok := BuildArgs(t, desc, f.Type(), tt.Give, 2); ok {
			args = append(args, give...)
		} else {
			continue
		}

		got, err := extractCallResponse(t, desc, f.Call(args))
		if isUnrecognizedProcedure(err) {
			t.Skipf("%v: procedure not defined", desc)
			continue
		}
		Assert(t, tt, desc, got, err)
	}
}
Beispiel #7
0
func TestTransportHandleHandshakeError(t *testing.T) {
	tests := []struct {
		desc      string
		name      string
		response  *api.HandshakeResponse
		wantError string
	}{
		{
			desc: "name mismatch",
			name: "foo",
			response: &api.HandshakeResponse{
				Name:           "bar",
				APIVersion:     api.APIVersion,
				LibraryVersion: ptr.String(version.Version),
				Features:       []api.Feature{},
			},
			wantError: `handshake with plugin "foo" failed: ` +
				`plugin name mismatch: expected "foo" but got "bar"`,
		},
		{
			desc: "version mismatch",
			name: "foo",
			response: &api.HandshakeResponse{
				Name:           "foo",
				APIVersion:     42,
				LibraryVersion: ptr.String(version.Version),
				Features:       []api.Feature{},
			},
			wantError: `handshake with plugin "foo" failed: ` +
				fmt.Sprintf("plugin API version mismatch: expected %d but got 42", api.APIVersion),
		},
		{
			desc: "missing version",
			name: "foo",
			response: &api.HandshakeResponse{
				Name:           "foo",
				APIVersion:     api.APIVersion,
				LibraryVersion: nil,
				Features:       []api.Feature{},
			},
			wantError: `handshake with plugin "foo" failed: Version is required`,
		},
		{
			desc: "unparseable version",
			name: "foo",
			response: &api.HandshakeResponse{
				Name:           "foo",
				APIVersion:     api.APIVersion,
				LibraryVersion: ptr.String("hello"),
				Features:       []api.Feature{},
			},
			wantError: `handshake with plugin "foo" failed: ` +
				`cannot parse as semantic version: "hello"`,
		},
		{
			desc: "semver mismatch",
			name: "foo",
			response: &api.HandshakeResponse{
				Name:           "foo",
				APIVersion:     api.APIVersion,
				LibraryVersion: ptr.String("12.3.4"),
				Features:       []api.Feature{},
			},
			wantError: `handshake with plugin "foo" failed: ` +
				"plugin compiled with the wrong version of ThriftRW: " +
				fmt.Sprintf("expected >=%v and <%v but got 12.3.4", &compatRange.Begin, &compatRange.End),
		},
	}

	for _, tt := range tests {
		func() {
			mockCtrl := gomock.NewController(t)
			defer mockCtrl.Finish()

			server := newFakePluginServer(mockCtrl)
			defer server.Close()

			server.Plugin.EXPECT().Handshake(&api.HandshakeRequest{}).Return(tt.response, nil)
			_, err := NewTransportHandle(tt.name, server.ClientTransport)
			if assert.Error(t, err, tt.desc) {
				assert.Equal(t, err.Error(), tt.wantError, tt.desc)
			}
		}()
	}
}
Beispiel #8
0
	"go.uber.org/thriftrw/gen/testdata/containers"
	"go.uber.org/thriftrw/gen/testdata/enums"
	"go.uber.org/thriftrw/gen/testdata/exceptions"
	"go.uber.org/thriftrw/gen/testdata/structs"
	"go.uber.org/thriftrw/gen/testdata/typedefs"
	"go.uber.org/thriftrw/gen/testdata/unions"
	"go.uber.org/thriftrw/ptr"
)

const Home enums.RecordType = enums.RecordTypeHomeAddress

const Name enums.RecordType = enums.RecordTypeName

const WorkAddress enums.RecordType = enums.RecordTypeWorkAddress

var ArbitraryValue *unions.ArbitraryValue = &unions.ArbitraryValue{ListValue: []*unions.ArbitraryValue{&unions.ArbitraryValue{BoolValue: ptr.Bool(true)}, &unions.ArbitraryValue{Int64Value: ptr.Int64(2)}, &unions.ArbitraryValue{StringValue: ptr.String("hello")}, &unions.ArbitraryValue{MapValue: map[string]*unions.ArbitraryValue{"foo": &unions.ArbitraryValue{StringValue: ptr.String("bar")}}}}}

const BeginningOfTime typedefs.Timestamp = typedefs.Timestamp(0)

var ContainersOfContainers *containers.ContainersOfContainers = &containers.ContainersOfContainers{ListOfLists: [][]int32{[]int32{1, 2, 3}, []int32{4, 5, 6}}, ListOfMaps: []map[int32]int32{map[int32]int32{1: 2, 3: 4, 5: 6}, map[int32]int32{7: 8, 9: 10, 11: 12}}, ListOfSets: []map[int32]struct{}{map[int32]struct{}{1: struct{}{}, 2: struct{}{}, 3: struct{}{}}, map[int32]struct{}{4: struct{}{}, 5: struct{}{}, 6: struct{}{}}}, MapOfListToSet: []struct {
	Key   []int32
	Value map[int64]struct{}
}{{Key: []int32{1, 2, 3}, Value: map[int64]struct{}{1: struct{}{}, 2: struct{}{}, 3: struct{}{}}}, {Key: []int32{4, 5, 6}, Value: map[int64]struct{}{4: struct{}{}, 5: struct{}{}, 6: struct{}{}}}}, MapOfMapToInt: []struct {
	Key   map[string]int32
	Value int64
}{{Key: map[string]int32{"1": 1, "2": 2, "3": 3}, Value: 100}, {Key: map[string]int32{"4": 4, "5": 5, "6": 6}, Value: 200}}, MapOfSetToListOfDouble: []struct {
	Key   map[int32]struct{}
	Value []float64
}{{Key: map[int32]struct{}{1: struct{}{}, 2: struct{}{}, 3: struct{}{}}, Value: []float64{1.2, 3.4}}, {Key: map[int32]struct{}{4: struct{}{}, 5: struct{}{}, 6: struct{}{}}, Value: []float64{5.6, 7.8}}}, SetOfLists: [][]string{[]string{"1", "2", "3"}, []string{"4", "5", "6"}}, SetOfMaps: []map[string]string{map[string]string{"1": "2", "3": "4", "5": "6"}, map[string]string{"7": "8", "9": "10", "11": "12"}}, SetOfSets: []map[string]struct{}{map[string]struct{}{"1": struct{}{}, "2": struct{}{}, "3": struct{}{}}, map[string]struct{}{"4": struct{}{}, "5": struct{}{}, "6": struct{}{}}}}

var EmptyException *exceptions.EmptyException = &exceptions.EmptyException{}
Beispiel #9
0
// Helper to build TApplicationException wire.Values
func tappExc(err error, typ exception.ExceptionType) (wire.Value, error) {
	return (&exception.TApplicationException{
		Message: ptr.String(err.Error()),
		Type:    &typ,
	}).ToWire()
}