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) } }
func TestAddRootService(t *testing.T) { tests := []struct { desc string spec *compile.ServiceSpec want *api.GenerateServiceRequest }{ { desc: "empty service", spec: &compile.ServiceSpec{ Name: "EmptyService", File: "idl/empty.thrift", }, want: &api.GenerateServiceRequest{ RootServices: []api.ServiceID{1}, Services: map[api.ServiceID]*api.Service{ 1: { Name: "EmptyService", ThriftName: "EmptyService", Functions: []*api.Function{}, // must be non-nil ModuleID: 1, }, }, Modules: map[api.ModuleID]*api.Module{ 1: { ImportPath: "go.uber.org/thriftrw/gen/testdata/empty", Directory: "empty", }, }, }, }, { desc: "Non standard names", spec: &compile.ServiceSpec{ Name: "non_standard_service_name", File: "idl/service.thrift", }, want: &api.GenerateServiceRequest{ RootServices: []api.ServiceID{1}, Services: map[api.ServiceID]*api.Service{ 1: { Name: "NonStandardServiceName", ThriftName: "non_standard_service_name", Functions: []*api.Function{}, // must be non-nil ModuleID: 1, }, }, Modules: map[api.ModuleID]*api.Module{ 1: { ImportPath: "go.uber.org/thriftrw/gen/testdata/service", Directory: "service", }, }, }, }, { desc: "service with a parent", spec: &compile.ServiceSpec{ Name: "KeyValue", File: "idl/kv.thrift", Parent: &compile.ServiceSpec{ Name: "AbstractService", File: "idl/common/abstract.thrift", }, }, want: &api.GenerateServiceRequest{ RootServices: []api.ServiceID{2}, Services: map[api.ServiceID]*api.Service{ 1: { Name: "AbstractService", ThriftName: "AbstractService", Functions: []*api.Function{}, // must be non-nil ModuleID: 1, }, 2: { Name: "KeyValue", ThriftName: "KeyValue", ParentID: (*api.ServiceID)(ptr.Int32(1)), Functions: []*api.Function{}, // must be non-nil ModuleID: 2, }, }, Modules: map[api.ModuleID]*api.Module{ 1: { ImportPath: "go.uber.org/thriftrw/gen/testdata/common/abstract", Directory: "common/abstract", }, 2: { ImportPath: "go.uber.org/thriftrw/gen/testdata/kv", Directory: "kv", }, }, }, }, } for _, tt := range tests { spec := tt.spec err := spec.Link(compile.EmptyScope("foo")) if !assert.NoError(t, err, "%v: invalid test: scope must link", tt.desc) { continue } importer := thriftPackageImporter{ ImportPrefix: "go.uber.org/thriftrw/gen/testdata", ThriftRoot: "idl", } g := newGenerateServiceBuilder(importer) if _, err := g.AddRootService(spec); assert.NoError(t, err, tt.desc) { assert.Equal(t, tt.want, g.Build(), tt.desc) } } }
func TestServiceGenerator(t *testing.T) { transport, done := fakeEnvelopeClient() defer done() mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() serviceGenerator := plugintest.NewMockServiceGenerator(mockCtrl) go Main(&Plugin{ Name: "hello", ServiceGenerator: serviceGenerator, }) pluginClient := api.NewPluginClient(multiplex.NewClient("Plugin", transport)) defer pluginClient.Goodbye() handshake, err := pluginClient.Handshake(&api.HandshakeRequest{}) require.NoError(t, err) assert.Equal(t, api.APIVersion, handshake.APIVersion) assert.Equal(t, version.Version, *handshake.LibraryVersion) assert.Equal(t, "hello", handshake.Name) assert.Contains(t, handshake.Features, api.FeatureServiceGenerator) sgClient := api.NewServiceGeneratorClient(multiplex.NewClient("ServiceGenerator", transport)) req := &api.GenerateServiceRequest{ RootServices: []api.ServiceID{1}, Services: map[api.ServiceID]*api.Service{ 1: { Name: "MyService", ThriftName: "MyService", Functions: []*api.Function{}, ParentID: (*api.ServiceID)(ptr.Int32(2)), ModuleID: 1, }, 2: { Name: "BaseService", ThriftName: "BaseService", Functions: []*api.Function{ { Name: "Healthy", ThriftName: "healthy", Arguments: []*api.Argument{}, }, }, ModuleID: 1, }, }, Modules: map[api.ModuleID]*api.Module{ 1: { ImportPath: "go.uber.org/thriftrw/plugin/fake", Directory: "fake", }, }, } res := &api.GenerateServiceResponse{ Files: map[string][]byte{ "fake/myservice/foo.go": {1, 2, 3}, "fake/baseservice/bar.go": {4, 5, 6}, "fake/baz.go": {7, 8, 9}, }, } serviceGenerator.EXPECT().Generate(req).Return(res, nil) gotRes, err := sgClient.Generate(req) if assert.NoError(t, err) { assert.Equal(t, res, gotRes) } }
func (v *DefaultsStruct) FromWire(w wire.Value) error { var err error for _, field := range w.GetStruct().Fields { switch field.ID { case 1: if field.Value.Type() == wire.TI32 { var x int32 x, err = field.Value.GetI32(), error(nil) v.RequiredPrimitive = &x if err != nil { return err } } case 2: if field.Value.Type() == wire.TI32 { var x int32 x, err = field.Value.GetI32(), error(nil) v.OptionalPrimitive = &x if err != nil { return err } } case 3: if field.Value.Type() == wire.TI32 { var x enums.EnumDefault x, err = _EnumDefault_Read(field.Value) v.RequiredEnum = &x if err != nil { return err } } case 4: if field.Value.Type() == wire.TI32 { var x enums.EnumDefault x, err = _EnumDefault_Read(field.Value) v.OptionalEnum = &x if err != nil { return err } } case 5: if field.Value.Type() == wire.TList { v.RequiredList, err = _List_String_Read(field.Value.GetList()) if err != nil { return err } } case 6: if field.Value.Type() == wire.TList { v.OptionalList, err = _List_Double_Read(field.Value.GetList()) if err != nil { return err } } case 7: if field.Value.Type() == wire.TStruct { v.RequiredStruct, err = _Frame_Read(field.Value) if err != nil { return err } } case 8: if field.Value.Type() == wire.TStruct { v.OptionalStruct, err = _Edge_Read(field.Value) if err != nil { return err } } } } if v.RequiredPrimitive == nil { v.RequiredPrimitive = ptr.Int32(100) } if v.OptionalPrimitive == nil { v.OptionalPrimitive = ptr.Int32(200) } if v.RequiredEnum == nil { v.RequiredEnum = _EnumDefault_ptr(enums.EnumDefaultBar) } if v.OptionalEnum == nil { v.OptionalEnum = _EnumDefault_ptr(enums.EnumDefaultBaz) } if v.RequiredList == nil { v.RequiredList = []string{"hello", "world"} } if v.OptionalList == nil { v.OptionalList = []float64{1, 2, 3} } if v.RequiredStruct == nil { v.RequiredStruct = &Frame{Size: &Size{Height: 200, Width: 100}, TopLeft: &Point{X: 1, Y: 2}} } if v.OptionalStruct == nil { v.OptionalStruct = &Edge{EndPoint: &Point{X: 3, Y: 4}, StartPoint: &Point{X: 1, Y: 2}} } return nil }
func (v *DefaultsStruct) ToWire() (wire.Value, error) { var ( fields [8]wire.Field i int = 0 w wire.Value err error ) if v.RequiredPrimitive == nil { v.RequiredPrimitive = ptr.Int32(100) } { w, err = wire.NewValueI32(*(v.RequiredPrimitive)), error(nil) if err != nil { return w, err } fields[i] = wire.Field{ID: 1, Value: w} i++ } if v.OptionalPrimitive == nil { v.OptionalPrimitive = ptr.Int32(200) } { w, err = wire.NewValueI32(*(v.OptionalPrimitive)), error(nil) if err != nil { return w, err } fields[i] = wire.Field{ID: 2, Value: w} i++ } if v.RequiredEnum == nil { v.RequiredEnum = _EnumDefault_ptr(enums.EnumDefaultBar) } { w, err = v.RequiredEnum.ToWire() if err != nil { return w, err } fields[i] = wire.Field{ID: 3, Value: w} i++ } if v.OptionalEnum == nil { v.OptionalEnum = _EnumDefault_ptr(enums.EnumDefaultBaz) } { w, err = v.OptionalEnum.ToWire() if err != nil { return w, err } fields[i] = wire.Field{ID: 4, Value: w} i++ } if v.RequiredList == nil { v.RequiredList = []string{"hello", "world"} } { w, err = wire.NewValueList(_List_String_ValueList(v.RequiredList)), error(nil) if err != nil { return w, err } fields[i] = wire.Field{ID: 5, Value: w} i++ } if v.OptionalList == nil { v.OptionalList = []float64{1, 2, 3} } { w, err = wire.NewValueList(_List_Double_ValueList(v.OptionalList)), error(nil) if err != nil { return w, err } fields[i] = wire.Field{ID: 6, Value: w} i++ } if v.RequiredStruct == nil { v.RequiredStruct = &Frame{Size: &Size{Height: 200, Width: 100}, TopLeft: &Point{X: 1, Y: 2}} } { w, err = v.RequiredStruct.ToWire() if err != nil { return w, err } fields[i] = wire.Field{ID: 7, Value: w} i++ } if v.OptionalStruct == nil { v.OptionalStruct = &Edge{EndPoint: &Point{X: 3, Y: 4}, StartPoint: &Point{X: 1, Y: 2}} } { w, err = v.OptionalStruct.ToWire() if err != nil { return w, err } fields[i] = wire.Field{ID: 8, Value: w} i++ } return wire.NewValueStruct(wire.Struct{Fields: fields[:i]}), nil }
// 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) } }