From 06b3038643527acb9ed5564a04f288303fc6a6f3 Mon Sep 17 00:00:00 2001 From: Poonam Jadhav Date: Thu, 7 Dec 2023 13:12:45 -0500 Subject: [PATCH] Net-6730/namespace intg test (#19798) test: add intg test for namespace lifecycle --- test-integ/tenancy/common.go | 84 +++++++++++++++++++++++++ test-integ/tenancy/namespace_ce_test.go | 84 +++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 test-integ/tenancy/common.go create mode 100644 test-integ/tenancy/namespace_ce_test.go diff --git a/test-integ/tenancy/common.go b/test-integ/tenancy/common.go new file mode 100644 index 0000000000..4fea2c472b --- /dev/null +++ b/test-integ/tenancy/common.go @@ -0,0 +1,84 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package tenancy + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" + pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" + "github.com/hashicorp/consul/test-integ/topoutil" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" + "github.com/hashicorp/consul/testing/deployer/topology" +) + +const ( + DefaultNamespaceName = "default" + DefaultPartitionName = "default" +) + +func newConfig(t *testing.T) *topology.Config { + const clusterName = "cluster1" + servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName}, nil) + + cluster := &topology.Cluster{ + Enterprise: utils.IsEnterprise(), + Name: clusterName, + Nodes: servers, + EnableV2: true, + EnableV2Tenancy: true, + } + + return &topology.Config{ + Images: utils.TargetImages(), + Networks: []*topology.Network{{Name: clusterName}}, + Clusters: []*topology.Cluster{cluster}, + } +} + +func createNamespaces(t *testing.T, resourceServiceClient *Client, numNamespaces int, ap string) []*pbresource.Resource { + namespaces := []*pbresource.Resource{} + for i := 0; i < numNamespaces; i++ { + namespace := &pbresource.Resource{ + Id: &pbresource.ID{ + Name: fmt.Sprintf("namespace-%d", i), + Type: pbtenancy.NamespaceType, + Tenancy: &pbresource.Tenancy{Partition: ap}, + }, + } + rsp, err := resourceServiceClient.Write(context.Background(), &pbresource.WriteRequest{Resource: namespace}) + require.NoError(t, err) + namespace = resourceServiceClient.WaitForResourceExists(t, rsp.Resource.Id) + namespaces = append(namespaces, namespace) + } + return namespaces +} + +func createServices(t *testing.T, resourceServiceClient *Client, numServices int, ap string, ns string) []*pbresource.Resource { + services := []*pbresource.Resource{} + for i := 0; i < numServices; i++ { + service := &pbresource.Resource{ + Id: &pbresource.ID{ + Name: fmt.Sprintf("service-%d", i), + Type: pbcatalog.ServiceType, + Tenancy: &pbresource.Tenancy{Partition: ap, Namespace: ns}, + }, + } + service = sprawltest.MustSetResourceData(t, service, &pbcatalog.Service{ + Workloads: &pbcatalog.WorkloadSelector{}, + Ports: []*pbcatalog.ServicePort{}, + }) + rsp, err := resourceServiceClient.Write(context.Background(), &pbresource.WriteRequest{Resource: service}) + require.NoError(t, err) + service = resourceServiceClient.WaitForResourceExists(t, rsp.Resource.Id) + services = append(services, service) + } + return services +} diff --git a/test-integ/tenancy/namespace_ce_test.go b/test-integ/tenancy/namespace_ce_test.go new file mode 100644 index 0000000000..5f82436c9c --- /dev/null +++ b/test-integ/tenancy/namespace_ce_test.go @@ -0,0 +1,84 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +//go:build !consulent + +package tenancy + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/proto-public/pbresource" + pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" + "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" +) + +// TestNamespaceLifecycle sets up the following: +// +// - 1 cluster +// - 3 servers in that cluster +// - v2 resources and v2 tenancy are activated +// +// When this test is executed it tests the full lifecycle for a +// small number of namespaces: +// - creation of namespaces in the default partition +// - populating resources under namespaces +// - finally deleting everything +func TestNamespaceLifecycle(t *testing.T) { + t.Parallel() + + cfg := newConfig(t) + sp := sprawltest.Launch(t, cfg) + cluster := sp.Topology().Clusters["cluster1"] + client := NewClient(sp.ResourceServiceClientForCluster(cluster.Name)) + + // 3 namespaces + // @ 3 services per namespace + // ============================== + // 9 resources total + tenants := []*pbresource.Resource{} + numNamespaces := 3 + numServices := 3 + + // Default namespace is expected to exist + // when we boostrap a cluster + client.RequireResourceExists(t, &pbresource.ID{ + Name: DefaultNamespaceName, + Type: pbtenancy.NamespaceType, + Tenancy: &pbresource.Tenancy{Partition: DefaultPartitionName}, + }) + + // Namespaces are created in default partition + namespaces := createNamespaces(t, client, numNamespaces, DefaultPartitionName) + + for _, namespace := range namespaces { + services := createServices(t, client, numServices, DefaultPartitionName, namespace.Id.Name) + tenants = append(tenants, services...) + } + + // Verify test setup + require.Equal(t, len(tenants), numNamespaces*numServices) + + // List namespaces + listRsp, err := client.List(client.Context(t), &pbresource.ListRequest{ + Type: pbtenancy.NamespaceType, + Tenancy: &pbresource.Tenancy{}, + NamePrefix: "namespace-", + }) + require.NoError(t, err) + require.Equal(t, len(namespaces), len(listRsp.Resources)) + + // Delete all namespaces + for _, namespace := range namespaces { + _, err := client.Delete(client.Context(t), &pbresource.DeleteRequest{Id: namespace.Id}) + require.NoError(t, err) + client.WaitForDeletion(t, namespace.Id) + } + + // Make sure no namespace tenants left behind + for _, tenant := range tenants { + client.RequireResourceNotFound(t, tenant.Id) + } +}