diff --git a/internal/mesh/internal/controllers/routes/controller_test.go b/internal/mesh/internal/controllers/routes/controller_test.go index e8cb1d64c2..72d2dce283 100644 --- a/internal/mesh/internal/controllers/routes/controller_test.go +++ b/internal/mesh/internal/controllers/routes/controller_test.go @@ -6,6 +6,7 @@ package routes import ( "context" "fmt" + "sort" "testing" "github.com/stretchr/testify/require" @@ -32,6 +33,14 @@ type controllerSuite struct { client *rtest.Client rt controller.Runtime tenancies []*pbresource.Tenancy + + refs *testResourceRef +} + +type testResourceRef struct { + apiServiceRef *pbresource.Reference + fooServiceRef *pbresource.Reference + barServiceRef *pbresource.Reference } func (suite *controllerSuite) SetupTest() { @@ -55,25 +64,19 @@ func (suite *controllerSuite) TestController() { mgr.SetRaftLeader(true) go mgr.Run(suite.ctx) - suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { + suite.runTestCaseWithTenancies(func(refs *testResourceRef) { - backendName := func(name, port string) string { + backendName := func(name, port string, tenancy *pbresource.Tenancy) string { return fmt.Sprintf("catalog.v2beta1.Service/%s.local.%s/%s?port=%s", tenancy.Partition, tenancy.Namespace, name, port) } var ( - apiServiceRef = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(tenancy). - Reference("") - fooServiceRef = rtest.Resource(pbcatalog.ServiceType, "foo"). - WithTenancy(tenancy). - Reference("") - barServiceRef = rtest.Resource(pbcatalog.ServiceType, "bar"). - WithTenancy(tenancy). - Reference("") + apiServiceRef = refs.apiServiceRef + fooServiceRef = refs.fooServiceRef + barServiceRef = refs.barServiceRef computedRoutesID = rtest.Resource(pbmesh.ComputedRoutesType, "api"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). ID() ) @@ -92,7 +95,7 @@ func (suite *controllerSuite) TestController() { } _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), apiServiceData). Write(suite.T(), suite.client) @@ -110,7 +113,7 @@ func (suite *controllerSuite) TestController() { Tcp: &pbmesh.ComputedTCPRoute{ Rules: []*pbmesh.ComputedTCPRouteRule{{ BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("api", "tcp"), + BackendTarget: backendName("api", "tcp", apiServiceRef.Tenancy), }}, }}, }, @@ -118,7 +121,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "tcp"), Protocol: pbcatalog.Protocol_PROTOCOL_TCP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "tcp"): { + backendName("api", "tcp", apiServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(apiServiceRef, "tcp", ""), @@ -148,7 +151,7 @@ func (suite *controllerSuite) TestController() { } _ = rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), apiServiceData). Write(suite.T(), suite.client) @@ -167,7 +170,7 @@ func (suite *controllerSuite) TestController() { } fooService := rtest.Resource(pbcatalog.ServiceType, "foo"). - WithTenancy(tenancy). + WithTenancy(fooServiceRef.Tenancy). WithData(suite.T(), fooServiceData). Write(suite.T(), suite.client) @@ -183,7 +186,7 @@ func (suite *controllerSuite) TestController() { Tcp: &pbmesh.ComputedTCPRoute{ Rules: []*pbmesh.ComputedTCPRouteRule{{ BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("api", "tcp"), + BackendTarget: backendName("api", "tcp", apiServiceRef.Tenancy), }}, }}, }, @@ -191,7 +194,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "tcp"), Protocol: pbcatalog.Protocol_PROTOCOL_TCP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "tcp"): { + backendName("api", "tcp", apiServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(apiServiceRef, "tcp", ""), @@ -211,7 +214,7 @@ func (suite *controllerSuite) TestController() { }, }}, BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), + BackendTarget: backendName("api", "http", apiServiceRef.Tenancy), }}, }}, }, @@ -219,7 +222,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { + backendName("api", "http", apiServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(apiServiceRef, "http", ""), @@ -239,7 +242,7 @@ func (suite *controllerSuite) TestController() { }, }}, BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http2"), + BackendTarget: backendName("api", "http2", apiServiceRef.Tenancy), }}, }}, }, @@ -247,7 +250,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http2"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http2"): { + backendName("api", "http2", apiServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(apiServiceRef, "http2", ""), @@ -262,7 +265,7 @@ func (suite *controllerSuite) TestController() { Rules: []*pbmesh.ComputedGRPCRouteRule{{ Matches: []*pbmesh.GRPCRouteMatch{{}}, BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("api", "grpc"), + BackendTarget: backendName("api", "grpc", apiServiceRef.Tenancy), }}, }}, }, @@ -270,7 +273,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "grpc"), Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "grpc"): { + backendName("api", "grpc", apiServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(apiServiceRef, "grpc", ""), @@ -288,7 +291,7 @@ func (suite *controllerSuite) TestController() { tcpRoute1 := &pbmesh.TCPRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "tcp"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "tcp"), }, Rules: []*pbmesh.TCPRouteRule{{ BackendRefs: []*pbmesh.TCPBackendRef{{ @@ -297,15 +300,15 @@ func (suite *controllerSuite) TestController() { }}, } tcpRoute1ID := rtest.Resource(pbmesh.TCPRouteType, "api-tcp-route1"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), tcpRoute1). Write(suite.T(), suite.client). Id httpRoute1 := &pbmesh.HTTPRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http"), - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http2"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http2"), }, Rules: []*pbmesh.HTTPRouteRule{{ BackendRefs: []*pbmesh.HTTPBackendRef{{ @@ -314,14 +317,14 @@ func (suite *controllerSuite) TestController() { }}, } httpRoute1ID := rtest.Resource(pbmesh.HTTPRouteType, "api-http-route1"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), httpRoute1). Write(suite.T(), suite.client). Id grpcRoute1 := &pbmesh.GRPCRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "grpc"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "grpc"), }, Rules: []*pbmesh.GRPCRouteRule{{ BackendRefs: []*pbmesh.GRPCBackendRef{{ @@ -330,27 +333,32 @@ func (suite *controllerSuite) TestController() { }}, } grpcRoute1ID := rtest.Resource(pbmesh.GRPCRouteType, "api-grpc-route1"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), grpcRoute1). Write(suite.T(), suite.client). Id testutil.RunStep(suite.T(), "one of each", func(t *testing.T) { + boundRefs := []*pbresource.Reference{ + fooServiceRef, + apiServiceRef, + resource.Reference(grpcRoute1ID, ""), + resource.Reference(httpRoute1ID, ""), + resource.Reference(tcpRoute1ID, ""), + } + sort.Slice(boundRefs, func(i, j int) bool { + return resource.LessReference(boundRefs[i], boundRefs[j]) + }) + expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(tcpRoute1ID, ""), - }, + BoundReferences: boundRefs, PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ "tcp": { Config: &pbmesh.ComputedPortRoutes_Tcp{ Tcp: &pbmesh.ComputedTCPRoute{ Rules: []*pbmesh.ComputedTCPRouteRule{{ BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), + BackendTarget: backendName("foo", "tcp", fooServiceRef.Tenancy), }}, }}, }, @@ -358,7 +366,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "tcp"), Protocol: pbcatalog.Protocol_PROTOCOL_TCP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { + backendName("foo", "tcp", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "tcp", ""), @@ -373,7 +381,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), + BackendTarget: backendName("foo", "http", fooServiceRef.Tenancy), }}, }, { @@ -388,7 +396,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { + backendName("foo", "http", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http", ""), @@ -403,7 +411,7 @@ func (suite *controllerSuite) TestController() { { Matches: []*pbmesh.GRPCRouteMatch{{}}, BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), + BackendTarget: backendName("foo", "grpc", fooServiceRef.Tenancy), }}, }, { @@ -418,7 +426,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "grpc"), Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { + backendName("foo", "grpc", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "grpc", ""), @@ -433,7 +441,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), + BackendTarget: backendName("foo", "http2", fooServiceRef.Tenancy), }}, }, { @@ -448,7 +456,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http2"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { + backendName("foo", "http2", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http2", ""), @@ -470,7 +478,7 @@ func (suite *controllerSuite) TestController() { tcpRoute2 := &pbmesh.TCPRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "tcp"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "tcp"), }, Rules: []*pbmesh.TCPRouteRule{{ BackendRefs: []*pbmesh.TCPBackendRef{{ @@ -479,15 +487,15 @@ func (suite *controllerSuite) TestController() { }}, } tcpRoute2ID := rtest.Resource(pbmesh.TCPRouteType, "api-tcp-route2"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), tcpRoute2). Write(suite.T(), suite.client). Id httpRoute2 := &pbmesh.HTTPRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http"), - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http2"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http2"), }, Rules: []*pbmesh.HTTPRouteRule{{ Matches: []*pbmesh.HTTPRouteMatch{{ @@ -502,14 +510,14 @@ func (suite *controllerSuite) TestController() { }}, } httpRoute2ID := rtest.Resource(pbmesh.HTTPRouteType, "api-http-route2"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), httpRoute2). Write(suite.T(), suite.client). Id grpcRoute2 := &pbmesh.GRPCRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "grpc"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "grpc"), }, Rules: []*pbmesh.GRPCRouteRule{{ Matches: []*pbmesh.GRPCRouteMatch{{ @@ -525,23 +533,28 @@ func (suite *controllerSuite) TestController() { }}, } grpcRoute2ID := rtest.Resource(pbmesh.GRPCRouteType, "api-grpc-route2"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), grpcRoute2). Write(suite.T(), suite.client). Id testutil.RunStep(suite.T(), "one good one bad route", func(t *testing.T) { + boundRefs := []*pbresource.Reference{ + fooServiceRef, + apiServiceRef, + resource.Reference(grpcRoute1ID, ""), + resource.Reference(grpcRoute2ID, ""), + resource.Reference(httpRoute1ID, ""), + resource.Reference(httpRoute2ID, ""), + resource.Reference(tcpRoute1ID, ""), + resource.Reference(tcpRoute2ID, ""), + } + sort.Slice(boundRefs, func(i, j int) bool { + return resource.LessReference(boundRefs[i], boundRefs[j]) + }) + expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(grpcRoute2ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(httpRoute2ID, ""), - resource.Reference(tcpRoute1ID, ""), - resource.Reference(tcpRoute2ID, ""), - }, + BoundReferences: boundRefs, PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ "tcp": { Config: &pbmesh.ComputedPortRoutes_Tcp{ @@ -549,7 +562,7 @@ func (suite *controllerSuite) TestController() { Rules: []*pbmesh.ComputedTCPRouteRule{ { BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), + BackendTarget: backendName("foo", "tcp", fooServiceRef.Tenancy), }}, }, { @@ -563,7 +576,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "tcp"), Protocol: pbcatalog.Protocol_PROTOCOL_TCP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { + backendName("foo", "tcp", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "tcp", ""), @@ -589,7 +602,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), + BackendTarget: backendName("foo", "http", fooServiceRef.Tenancy), }}, }, { @@ -604,7 +617,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { + backendName("foo", "http", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http", ""), @@ -619,7 +632,7 @@ func (suite *controllerSuite) TestController() { { Matches: []*pbmesh.GRPCRouteMatch{{}}, BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), + BackendTarget: backendName("foo", "grpc", fooServiceRef.Tenancy), }}, }, { @@ -646,7 +659,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "grpc"), Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { + backendName("foo", "grpc", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "grpc", ""), @@ -672,7 +685,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), + BackendTarget: backendName("foo", "http2", fooServiceRef.Tenancy), }}, }, { @@ -687,7 +700,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http2"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { + backendName("foo", "http2", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http2", ""), @@ -705,11 +718,11 @@ func (suite *controllerSuite) TestController() { suite.client.WaitForStatusCondition(t, grpcRoute1ID, StatusKey, ConditionXRouteOK) suite.client.WaitForStatusCondition(t, tcpRoute2ID, StatusKey, - ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar", tenancy))) + ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar", barServiceRef.Tenancy))) suite.client.WaitForStatusCondition(t, httpRoute2ID, StatusKey, - ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar", tenancy))) + ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar", barServiceRef.Tenancy))) suite.client.WaitForStatusCondition(t, grpcRoute2ID, StatusKey, - ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar", tenancy))) + ConditionMissingBackendRef(newRef(pbcatalog.ServiceType, "bar", barServiceRef.Tenancy))) }) // Update the route2 routes to point to a real service, but overlap in @@ -723,7 +736,7 @@ func (suite *controllerSuite) TestController() { tcpRoute2 = &pbmesh.TCPRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http"), }, Rules: []*pbmesh.TCPRouteRule{{ BackendRefs: []*pbmesh.TCPBackendRef{{ @@ -732,13 +745,13 @@ func (suite *controllerSuite) TestController() { }}, } rtest.ResourceID(tcpRoute2ID). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), tcpRoute2). Write(suite.T(), suite.client) httpRoute2 = &pbmesh.HTTPRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "grpc"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "grpc"), }, Rules: []*pbmesh.HTTPRouteRule{{ Matches: []*pbmesh.HTTPRouteMatch{{ @@ -753,13 +766,13 @@ func (suite *controllerSuite) TestController() { }}, } rtest.ResourceID(httpRoute2ID). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), httpRoute2). Write(suite.T(), suite.client) grpcRoute2 = &pbmesh.GRPCRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "tcp"), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "tcp"), }, Rules: []*pbmesh.GRPCRouteRule{{ Matches: []*pbmesh.GRPCRouteMatch{{ @@ -775,29 +788,34 @@ func (suite *controllerSuite) TestController() { }}, } rtest.ResourceID(grpcRoute2ID). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), grpcRoute2). Write(suite.T(), suite.client) testutil.RunStep(suite.T(), "overlapping xRoutes generate conflicts", func(t *testing.T) { + boundRefs := []*pbresource.Reference{ + apiServiceRef, + fooServiceRef, + resource.Reference(grpcRoute1ID, ""), + resource.Reference(grpcRoute2ID, ""), + resource.Reference(httpRoute1ID, ""), + resource.Reference(httpRoute2ID, ""), + resource.Reference(tcpRoute1ID, ""), + resource.Reference(tcpRoute2ID, ""), + } + sort.Slice(boundRefs, func(i, j int) bool { + return resource.LessReference(boundRefs[i], boundRefs[j]) + }) + expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(grpcRoute2ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(httpRoute2ID, ""), - resource.Reference(tcpRoute1ID, ""), - resource.Reference(tcpRoute2ID, ""), - }, + BoundReferences: boundRefs, PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ "tcp": { Config: &pbmesh.ComputedPortRoutes_Tcp{ Tcp: &pbmesh.ComputedTCPRoute{ Rules: []*pbmesh.ComputedTCPRouteRule{{ BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), + BackendTarget: backendName("foo", "tcp", fooServiceRef.Tenancy), }}, }}, }, @@ -805,7 +823,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "tcp"), Protocol: pbcatalog.Protocol_PROTOCOL_TCP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { + backendName("foo", "tcp", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "tcp", ""), @@ -820,7 +838,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), + BackendTarget: backendName("foo", "http", fooServiceRef.Tenancy), }}, }, { @@ -835,7 +853,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { + backendName("foo", "http", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http", ""), @@ -850,7 +868,7 @@ func (suite *controllerSuite) TestController() { { Matches: []*pbmesh.GRPCRouteMatch{{}}, BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), + BackendTarget: backendName("foo", "grpc", fooServiceRef.Tenancy), }}, }, { @@ -865,7 +883,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "grpc"), Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { + backendName("foo", "grpc", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "grpc", ""), @@ -880,7 +898,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), + BackendTarget: backendName("foo", "http2", fooServiceRef.Tenancy), }}, }, { @@ -895,7 +913,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http2"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { + backendName("foo", "http2", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http2", ""), @@ -913,11 +931,11 @@ func (suite *controllerSuite) TestController() { suite.client.WaitForStatusCondition(t, grpcRoute1ID, StatusKey, ConditionXRouteOK) suite.client.WaitForStatusCondition(t, tcpRoute2ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http", pbmesh.HTTPRouteType)) + ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http", pbmesh.HTTPRouteType)) suite.client.WaitForStatusCondition(t, httpRoute2ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "grpc", pbmesh.GRPCRouteType)) + ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "grpc", pbmesh.GRPCRouteType)) suite.client.WaitForStatusCondition(t, grpcRoute2ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "tcp", pbmesh.TCPRouteType)) + ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "tcp", pbmesh.TCPRouteType)) }) // - Delete the bad routes @@ -938,7 +956,7 @@ func (suite *controllerSuite) TestController() { // Re-create with newarly the same data (wildcard port now) with a newer name. grpcRoute1 = &pbmesh.GRPCRoute{ ParentRefs: []*pbmesh.ParentReference{ - newParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), ""), + newParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), ""), }, Rules: []*pbmesh.GRPCRouteRule{{ BackendRefs: []*pbmesh.GRPCBackendRef{{ @@ -947,27 +965,32 @@ func (suite *controllerSuite) TestController() { }}, } grpcRoute1ID = rtest.Resource(pbmesh.GRPCRouteType, "zzz-bad-route"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), grpcRoute1). Write(suite.T(), suite.client). Id testutil.RunStep(suite.T(), "overlapping xRoutes due to port wildcarding", func(t *testing.T) { + boundRefs := []*pbresource.Reference{ + apiServiceRef, + fooServiceRef, + resource.Reference(grpcRoute1ID, ""), + resource.Reference(httpRoute1ID, ""), + resource.Reference(tcpRoute1ID, ""), + } + sort.Slice(boundRefs, func(i, j int) bool { + return resource.LessReference(boundRefs[i], boundRefs[j]) + }) + expect := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(grpcRoute1ID, ""), - resource.Reference(httpRoute1ID, ""), - resource.Reference(tcpRoute1ID, ""), - }, + BoundReferences: boundRefs, PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ "tcp": { Config: &pbmesh.ComputedPortRoutes_Tcp{ Tcp: &pbmesh.ComputedTCPRoute{ Rules: []*pbmesh.ComputedTCPRouteRule{{ BackendRefs: []*pbmesh.ComputedTCPBackendRef{{ - BackendTarget: backendName("foo", "tcp"), + BackendTarget: backendName("foo", "tcp", fooServiceRef.Tenancy), }}, }}, }, @@ -975,7 +998,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "tcp"), Protocol: pbcatalog.Protocol_PROTOCOL_TCP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "tcp"): { + backendName("foo", "tcp", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "tcp", ""), @@ -990,7 +1013,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http"), + BackendTarget: backendName("foo", "http", fooServiceRef.Tenancy), }}, }, { @@ -1005,7 +1028,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http"): { + backendName("foo", "http", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http", ""), @@ -1020,7 +1043,7 @@ func (suite *controllerSuite) TestController() { { Matches: []*pbmesh.GRPCRouteMatch{{}}, BackendRefs: []*pbmesh.ComputedGRPCBackendRef{{ - BackendTarget: backendName("foo", "grpc"), + BackendTarget: backendName("foo", "grpc", fooServiceRef.Tenancy), }}, }, { @@ -1035,7 +1058,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "grpc"), Protocol: pbcatalog.Protocol_PROTOCOL_GRPC, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "grpc"): { + backendName("foo", "grpc", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "grpc", ""), @@ -1050,7 +1073,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("foo", "http2"), + BackendTarget: backendName("foo", "http2", fooServiceRef.Tenancy), }}, }, { @@ -1065,7 +1088,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(apiServiceRef, "http2"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("foo", "http2"): { + backendName("foo", "http2", fooServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(fooServiceRef, "http2", ""), @@ -1077,9 +1100,9 @@ func (suite *controllerSuite) TestController() { } suite.client.WaitForStatusConditions(t, grpcRoute1ID, StatusKey, - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http", pbmesh.HTTPRouteType), - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "http2", pbmesh.HTTPRouteType), - ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", tenancy), "tcp", pbmesh.TCPRouteType)) + ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http", pbmesh.HTTPRouteType), + ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "http2", pbmesh.HTTPRouteType), + ConditionConflictNotBoundToParentRef(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy), "tcp", pbmesh.TCPRouteType)) lastVersion = requireNewComputedRoutesVersion(t, suite.client, computedRoutesID, "" /*no change*/, expect) @@ -1103,7 +1126,7 @@ func (suite *controllerSuite) TestController() { } apiService := rtest.Resource(pbcatalog.ServiceType, "api"). - WithTenancy(tenancy). + WithTenancy(apiServiceRef.Tenancy). WithData(suite.T(), apiServiceData). Write(suite.T(), suite.client) @@ -1111,20 +1134,20 @@ func (suite *controllerSuite) TestController() { suite.client.WaitForDeletion(t, computedRoutesID) suite.client.WaitForStatusCondition(t, tcpRoute1ID, StatusKey, - ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api", tenancy))) + ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy))) suite.client.WaitForStatusCondition(t, httpRoute1ID, StatusKey, - ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api", tenancy))) + ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy))) suite.client.WaitForStatusCondition(t, grpcRoute1ID, StatusKey, - ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api", tenancy))) + ConditionParentRefOutsideMesh(newRef(pbcatalog.ServiceType, "api", apiServiceRef.Tenancy))) }) // Get down to just 2 ports for all relevant services. - for _, name := range []string{"foo", "bar", "api"} { - _ = rtest.Resource(pbcatalog.ServiceType, name). - WithTenancy(tenancy). + for _, ref := range []*pbresource.Reference{apiServiceRef, fooServiceRef, barServiceRef} { + _ = rtest.Resource(pbcatalog.ServiceType, ref.Name). + WithTenancy(ref.Tenancy). WithData(suite.T(), &pbcatalog.Service{ Workloads: &pbcatalog.WorkloadSelector{ - Prefixes: []string{name + "-"}, + Prefixes: []string{ref.Name + "-"}, }, Ports: []*pbcatalog.ServicePort{ {TargetPort: "mesh", Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, @@ -1146,7 +1169,7 @@ func (suite *controllerSuite) TestController() { }}, } httpRoute1ID = rtest.Resource(pbmesh.HTTPRouteType, "route1"). - WithTenancy(tenancy). + WithTenancy(fooServiceRef.Tenancy). WithData(suite.T(), httpRoute1). Write(suite.T(), suite.client). Id @@ -1156,20 +1179,37 @@ func (suite *controllerSuite) TestController() { barLastVersion string fooComputedRoutesID = rtest.Resource(pbmesh.ComputedRoutesType, "foo"). - WithTenancy(tenancy). + WithTenancy(fooServiceRef.Tenancy). ID() barComputedRoutesID = rtest.Resource(pbmesh.ComputedRoutesType, "bar"). - WithTenancy(tenancy). + WithTenancy(barServiceRef.Tenancy). ID() ) testutil.RunStep(suite.T(), "create a route linked to two parents", func(t *testing.T) { + boundRefsFoo := []*pbresource.Reference{ + apiServiceRef, + fooServiceRef, + resource.Reference(httpRoute1ID, ""), + } + sort.Slice(boundRefsFoo, func(i, j int) bool { + return resource.LessReference(boundRefsFoo[i], boundRefsFoo[j]) + }) + + boundRefsBar := []*pbresource.Reference{ + apiServiceRef, + barServiceRef, + resource.Reference(httpRoute1ID, ""), + } + sort.Slice(boundRefsFoo, func(i, j int) bool { + return resource.LessReference(boundRefsFoo[i], boundRefsFoo[j]) + }) + sort.Slice(boundRefsBar, func(i, j int) bool { + return resource.LessReference(boundRefsBar[i], boundRefsBar[j]) + }) + expectFoo := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - fooServiceRef, - resource.Reference(httpRoute1ID, ""), - }, + BoundReferences: boundRefsFoo, PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ "http": { Config: &pbmesh.ComputedPortRoutes_Http{ @@ -1178,7 +1218,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), + BackendTarget: backendName("api", "http", apiServiceRef.Tenancy), }}, }, { @@ -1193,7 +1233,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(fooServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { + backendName("api", "http", apiServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(apiServiceRef, "http", ""), @@ -1204,11 +1244,7 @@ func (suite *controllerSuite) TestController() { }, } expectBar := &pbmesh.ComputedRoutes{ - BoundReferences: []*pbresource.Reference{ - apiServiceRef, - barServiceRef, - resource.Reference(httpRoute1ID, ""), - }, + BoundReferences: boundRefsBar, PortedConfigs: map[string]*pbmesh.ComputedPortRoutes{ "http": { Config: &pbmesh.ComputedPortRoutes_Http{ @@ -1217,7 +1253,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("api", "http"), + BackendTarget: backendName("api", "http", apiServiceRef.Tenancy), }}, }, { @@ -1232,7 +1268,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(barServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("api", "http"): { + backendName("api", "http", apiServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(apiServiceRef, "http", ""), @@ -1261,7 +1297,7 @@ func (suite *controllerSuite) TestController() { }}, } httpRoute1ID = rtest.Resource(pbmesh.HTTPRouteType, "route1"). - WithTenancy(tenancy). + WithTenancy(fooServiceRef.Tenancy). WithData(suite.T(), httpRoute1). Write(suite.T(), suite.client). Id @@ -1279,7 +1315,7 @@ func (suite *controllerSuite) TestController() { { Matches: defaultHTTPRouteMatches(), BackendRefs: []*pbmesh.ComputedHTTPBackendRef{{ - BackendTarget: backendName("bar", "http"), + BackendTarget: backendName("bar", "http", barServiceRef.Tenancy), }}, }, }, @@ -1289,7 +1325,7 @@ func (suite *controllerSuite) TestController() { ParentRef: newParentRef(barServiceRef, "http"), Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, Targets: map[string]*pbmesh.BackendTargetDetails{ - backendName("bar", "http"): { + backendName("bar", "http", barServiceRef.Tenancy): { Type: pbmesh.BackendTargetDetailsType_BACKEND_TARGET_DETAILS_TYPE_DIRECT, MeshPort: "mesh", BackendRef: newBackendRef(barServiceRef, "http", ""), @@ -1364,11 +1400,28 @@ func TestController(t *testing.T) { suite.Run(t, new(controllerSuite)) } -func (suite *controllerSuite) runTestCaseWithTenancies(testFunc func(*pbresource.Tenancy)) { - for _, tenancy := range suite.tenancies { - suite.Run(suite.appendTenancyInfo(tenancy), func() { - testFunc(tenancy) - }) +func (suite *controllerSuite) runTestCaseWithTenancies(testFunc func(ref *testResourceRef)) { + for _, mainServiceTenancy := range suite.tenancies { + for _, otherServiceTenancy := range suite.tenancies { + + apiServiceRef := rtest.Resource(pbcatalog.ServiceType, "api"). + WithTenancy(mainServiceTenancy). + Reference("") + fooServiceRef := rtest.Resource(pbcatalog.ServiceType, "foo"). + WithTenancy(otherServiceTenancy). + Reference("") + barServiceRef := rtest.Resource(pbcatalog.ServiceType, "bar"). + WithTenancy(otherServiceTenancy). + Reference("") + + suite.Run(suite.appendTenancyInfo(mainServiceTenancy), func() { + testFunc(&testResourceRef{ + apiServiceRef: apiServiceRef, + fooServiceRef: fooServiceRef, + barServiceRef: barServiceRef, + }) + }) + } } }