github.com/renbou/grpcbridge@v0.0.2-0.20240416012907-bcbd8b12648a/routing/routing_test.go (about) 1 package routing 2 3 import ( 4 "fmt" 5 "math/rand" 6 "testing" 7 8 "github.com/renbou/grpcbridge/bridgedesc" 9 "github.com/renbou/grpcbridge/grpcadapter" 10 "go.uber.org/goleak" 11 "google.golang.org/protobuf/reflect/protoreflect" 12 ) 13 14 // nilConnPool implements ConnPool without returning any connection for tests. 15 type nilConnPool struct{} 16 17 func (nilConnPool) Get(target string) (grpcadapter.ClientConn, bool) { 18 return nil, true 19 } 20 21 var testTarget = bridgedesc.Target{ 22 Name: "routing-testsvc", 23 Services: []bridgedesc.Service{ 24 { 25 Name: "grpcbridge.routing.v1.PureGRPCSvc", 26 Methods: []bridgedesc.Method{ 27 {RPCName: "/grpcbridge.routing.v1.PureGRPCSvc/Get"}, 28 {RPCName: "/grpcbridge.routing.v1.PureGRPCSvc/List"}, 29 }, 30 }, 31 { 32 Name: "grpcbridge.routing.v1.RestSvc", 33 Methods: []bridgedesc.Method{ 34 { 35 RPCName: "/grpcbridge.routing.v1.RestSvc/CreateEntity", 36 Bindings: []bridgedesc.Binding{ 37 {HTTPMethod: "POST", Pattern: "/api/v1/entities"}, 38 {HTTPMethod: "POST", Pattern: "/api/v1/entity"}, 39 }, 40 }, 41 { 42 RPCName: "/grpcbridge.routing.v1.RestSvc/GetEntity", 43 Bindings: []bridgedesc.Binding{ 44 {HTTPMethod: "GET", Pattern: "/api/v1/entity/{entity_id=*}"}, // equivalent to {entity_id} 45 }, 46 }, 47 { 48 RPCName: "/grpcbridge.routing.v1.RestSvc/ListEntities", 49 Bindings: []bridgedesc.Binding{ 50 {HTTPMethod: "GET", Pattern: "/api/v1/entities"}, 51 }, 52 }, 53 { 54 RPCName: "/grpcbridge.routing.v1.RestSvc/UpdateEntity", 55 Bindings: []bridgedesc.Binding{ 56 {HTTPMethod: "PUT", Pattern: "/api/v1/entity/{entity_id}"}, 57 {HTTPMethod: "PATCH", Pattern: "/api/v1/entity/{entity_id}"}, 58 }, 59 }, 60 { 61 RPCName: "/grpcbridge.routing.v1.RestSvc/DeleteEntity", 62 Bindings: []bridgedesc.Binding{ 63 {HTTPMethod: "DELETE", Pattern: "/api/v1/entity/{entity_id}"}, 64 }, 65 }, 66 }, 67 }, 68 { 69 Name: "grpcbridge.routing.v2.RestSvc", 70 Methods: []bridgedesc.Method{ 71 { 72 RPCName: "/grpcbridge.routing.v2.RestSvc/CreateEntity", 73 Bindings: []bridgedesc.Binding{ 74 {HTTPMethod: "POST", Pattern: "/api/v2/entity:create"}, 75 }, 76 }, 77 { 78 RPCName: "/grpcbridge.routing.v2.RestSvc/GetEntity", 79 Bindings: []bridgedesc.Binding{ 80 {HTTPMethod: "GET", Pattern: "/api/v2/entity/{entity_id}"}, 81 }, 82 }, 83 { 84 RPCName: "/grpcbridge.routing.v2.RestSvc/WatchEntity", 85 Bindings: []bridgedesc.Binding{ 86 {HTTPMethod: "POST", Pattern: "/api/v2/entity/{entity_id}/{path=**}:watch"}, 87 {HTTPMethod: "POST", Pattern: "/api/v2/entities/{path=all/**}:watch"}, 88 }, 89 }, 90 }, 91 }, 92 }, 93 } 94 95 type templateTargetInfo struct { 96 template int 97 name string 98 } 99 100 func buildTemplateTargets(n int, seed int64, templates [][]bridgedesc.Target) []templateTargetInfo { 101 rnd := rand.New(rand.NewSource(seed)) 102 targets := make([]templateTargetInfo, n) 103 104 for i := range targets { 105 targets[i] = templateTargetInfo{template: rnd.Intn(len(templates)), name: fmt.Sprintf("target_%d", i)} 106 } 107 108 return targets 109 } 110 111 // buildDescTemplate builds a target description from a template, 112 // used in router tests for generating multiple different targets with unique names based on a few templates. 113 func buildDescTemplate(template *bridgedesc.Target, dest *bridgedesc.Target, targetName string, targetIdx int) { 114 dest.Name = targetName 115 dest.Services = make([]bridgedesc.Service, len(template.Services)) 116 117 for svcIdx := range template.Services { 118 templateSvc := &template.Services[svcIdx] 119 destSvc := &dest.Services[svcIdx] 120 121 destSvc.Name = protoreflect.FullName(fmt.Sprintf(string(templateSvc.Name), targetIdx)) 122 destSvc.Methods = make([]bridgedesc.Method, len(templateSvc.Methods)) 123 124 for methodIdx := range templateSvc.Methods { 125 templateMethod := &templateSvc.Methods[methodIdx] 126 destMethod := &destSvc.Methods[methodIdx] 127 128 destMethod.RPCName = fmt.Sprintf(templateMethod.RPCName, targetIdx) 129 destMethod.Bindings = make([]bridgedesc.Binding, len(templateMethod.Bindings)) 130 131 for bindingIdx := range templateMethod.Bindings { 132 templateBinding := &templateMethod.Bindings[bindingIdx] 133 destBinding := &destMethod.Bindings[bindingIdx] 134 135 destBinding.HTTPMethod = templateBinding.HTTPMethod 136 destBinding.Pattern = fmt.Sprintf(templateBinding.Pattern, targetIdx) 137 } 138 } 139 } 140 } 141 142 func TestMain(m *testing.M) { 143 goleak.VerifyTestMain(m) 144 }