diff --git a/tests/e2e/e2e_suite_test.go b/tests/e2e/e2e_suite_test.go index 64c581d17..b54f66e75 100644 --- a/tests/e2e/e2e_suite_test.go +++ b/tests/e2e/e2e_suite_test.go @@ -16,6 +16,7 @@ import ( "time" "code.cloudfoundry.org/korifi/tests/helpers" + "code.cloudfoundry.org/korifi/tests/helpers/broker" "code.cloudfoundry.org/korifi/tests/helpers/fail_handler" "code.cloudfoundry.org/go-loggregator/v8/rpc/loggregator_v2" @@ -25,14 +26,11 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "gopkg.in/yaml.v3" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/client-go/rest" - controllerruntime "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" ) @@ -1143,24 +1141,7 @@ func pushSampleBroker(brokerBitsFile string) string { brokerAppGUID, _ := pushTestApp(spaceGUID, brokerBitsFile) body := curlApp(brokerAppGUID, "") Expect(body).To(ContainSubstring("Hi, I'm the sample broker!")) - return getBrokerInClusterURL(brokerAppGUID) -} - -func getBrokerInClusterURL(brokerAppGUID string) string { - config, err := controllerruntime.GetConfig() - Expect(err).NotTo(HaveOccurred()) - - k8sClient, err := client.New(config, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - - services := &corev1.ServiceList{} - Expect(k8sClient.List(context.Background(), services, client.MatchingLabels{ - korifiv1alpha1.CFAppGUIDLabelKey: brokerAppGUID, - })).To(Succeed()) - Expect(services.Items).To(HaveLen(1)) - - brokerService := services.Items[0] - return fmt.Sprintf("http://%s.%s:8080", brokerService.Name, brokerService.Namespace) + return helpers.GetInClusterURL(brokerAppGUID) } func createBrokerAsync(brokerURL, username, password string) (string, string) { @@ -1213,29 +1194,5 @@ func cleanupBroker(brokerGUID string) { Delete("/v3/service_brokers/" + brokerGUID) Expect(err).NotTo(HaveOccurred()) - ctx := context.Background() - - config, err := controllerruntime.GetConfig() - Expect(err).NotTo(HaveOccurred()) - - k8sClient, err := client.New(config, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - - Expect(k8sClient.DeleteAllOf( - ctx, - &korifiv1alpha1.CFServiceOffering{}, - client.InNamespace(rootNamespace), - client.MatchingLabels{ - korifiv1alpha1.RelServiceBrokerGUIDLabel: brokerGUID, - }, - )).To(Succeed()) - - Expect(k8sClient.DeleteAllOf( - ctx, - &korifiv1alpha1.CFServicePlan{}, - client.InNamespace(rootNamespace), - client.MatchingLabels{ - korifiv1alpha1.RelServiceBrokerGUIDLabel: brokerGUID, - }, - )).To(Succeed()) + broker.NewCatalogPurger(rootNamespace).ForBrokerGUID(brokerGUID).Purge() } diff --git a/tests/helpers/apps.go b/tests/helpers/apps.go new file mode 100644 index 000000000..f95599086 --- /dev/null +++ b/tests/helpers/apps.go @@ -0,0 +1,34 @@ +package helpers + +import ( + "context" + "fmt" + + korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + . "github.com/onsi/ginkgo/v2" //lint:ignore ST1001 this is a test file + . "github.com/onsi/gomega" //lint:ignore ST1001 this is a test file + corev1 "k8s.io/api/core/v1" + + "k8s.io/client-go/kubernetes/scheme" + controllerruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func GetInClusterURL(appGUID string) string { + GinkgoHelper() + + config, err := controllerruntime.GetConfig() + Expect(err).NotTo(HaveOccurred()) + + k8sClient, err := client.New(config, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + + services := &corev1.ServiceList{} + Expect(k8sClient.List(context.Background(), services, client.MatchingLabels{ + korifiv1alpha1.CFAppGUIDLabelKey: appGUID, + })).To(Succeed()) + Expect(services.Items).To(HaveLen(1)) + + appService := services.Items[0] + return fmt.Sprintf("http://%s.%s:8080", appService.Name, appService.Namespace) +} diff --git a/tests/helpers/broker/purge.go b/tests/helpers/broker/purge.go new file mode 100644 index 000000000..9c52fa880 --- /dev/null +++ b/tests/helpers/broker/purge.go @@ -0,0 +1,64 @@ +package broker + +import ( + "context" + + korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + . "github.com/onsi/ginkgo/v2" //lint:ignore ST1001 this is a test file + . "github.com/onsi/gomega" //lint:ignore ST1001 this is a test file + + "k8s.io/client-go/kubernetes/scheme" + controllerruntime "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type CatalogPurger struct { + rootNamespace string + catalogLabelSelector client.MatchingLabels +} + +func NewCatalogPurger(rootNamespace string) *CatalogPurger { + return &CatalogPurger{rootNamespace: rootNamespace} +} + +func (p *CatalogPurger) ForBrokerGUID(brokerGUID string) *CatalogPurger { + p.catalogLabelSelector = client.MatchingLabels{ + korifiv1alpha1.RelServiceBrokerGUIDLabel: brokerGUID, + } + + return p +} + +func (p *CatalogPurger) ForBrokerName(brokerName string) *CatalogPurger { + p.catalogLabelSelector = client.MatchingLabels{ + korifiv1alpha1.RelServiceBrokerNameLabel: brokerName, + } + + return p +} + +func (p *CatalogPurger) Purge() { + GinkgoHelper() + + ctx := context.Background() + + config, err := controllerruntime.GetConfig() + Expect(err).NotTo(HaveOccurred()) + + k8sClient, err := client.New(config, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + + Expect(k8sClient.DeleteAllOf( + ctx, + &korifiv1alpha1.CFServiceOffering{}, + client.InNamespace(p.rootNamespace), + p.catalogLabelSelector, + )).To(Succeed()) + + Expect(k8sClient.DeleteAllOf( + ctx, + &korifiv1alpha1.CFServicePlan{}, + client.InNamespace(p.rootNamespace), + p.catalogLabelSelector, + )).To(Succeed()) +} diff --git a/tests/smoke/apps_test.go b/tests/smoke/apps_test.go index 51ecc5dc3..a2d11709e 100644 --- a/tests/smoke/apps_test.go +++ b/tests/smoke/apps_test.go @@ -1,13 +1,10 @@ package smoke_test import ( - "crypto/tls" - "fmt" "net/http" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/onsi/gomega/types" ) var _ = Describe("apps", func() { @@ -32,16 +29,3 @@ var _ = Describe("apps", func() { )) }) }) - -func appResponseShould(appName, requestPath string, matchExpectations types.GomegaMatcher) { - var httpClient http.Client - httpClient.Transport = &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - - Eventually(func(g Gomega) { - resp, err := httpClient.Get(fmt.Sprintf("https://%s.%s%s", appName, appsDomain, requestPath)) - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(resp).To(matchExpectations) - }).Should(Succeed()) -} diff --git a/tests/smoke/catalog_test.go b/tests/smoke/catalog_test.go new file mode 100644 index 000000000..446c3dda4 --- /dev/null +++ b/tests/smoke/catalog_test.go @@ -0,0 +1,116 @@ +package smoke_test + +import ( + "strings" + + "code.cloudfoundry.org/korifi/tests/helpers" + "code.cloudfoundry.org/korifi/tests/helpers/broker" + + "github.com/BooleanCat/go-functional/v2/it" + "github.com/google/uuid" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/onsi/gomega/gexec" + "github.com/onsi/gomega/types" +) + +var _ = Describe("Service Catalog", func() { + var brokerName string + + BeforeEach(func() { + brokerName = uuid.NewString() + Expect(helpers.Cf( + "create-service-broker", + brokerName, + "broker-user", + "broker-password", + helpers.GetInClusterURL(getAppGUID(brokerAppName)), + )).To(Exit(0)) + }) + + AfterEach(func() { + cleanupBroker(brokerName) + }) + + Describe("cf service-brokers", func() { + It("lists service brokers", func() { + session := helpers.Cf("service-brokers") + Expect(session).To(Exit(0)) + + lines, _ := it.Collect2(it.LinesString(session.Out)) + Expect(lines).To(ContainElement( + matchSubstrings(brokerName, helpers.GetInClusterURL(getAppGUID(brokerAppName))))) + }) + }) + + Describe("cf delete-service-broker", func() { + It("deletes the service broker", func() { + session := helpers.Cf("delete-service-broker", "-f", brokerName) + Expect(session).To(Exit(0)) + + session = helpers.Cf("service-brokers") + Expect(session).To(Exit(0)) + + lines, _ := it.Collect2(it.LinesString(session.Out)) + Expect(lines).NotTo(ContainElement(ContainSubstring(brokerName))) + }) + }) + + Describe("cf service-access", func() { + It("lists service access settings", func() { + session := helpers.Cf("service-access", "-b", brokerName) + Expect(session).To(Exit(0)) + + lines, _ := it.Collect2(it.LinesString(session.Out)) + Expect(lines).To(ContainElements( + matchSubstrings("sample-service", "sample", "none"), + )) + }) + }) + + Describe("cf enable-service-access", func() { + It("enables the service access", func() { + session := helpers.Cf("enable-service-access", "sample-service", "-b", brokerName) + Expect(session).To(Exit(0)) + + session = helpers.Cf("service-access") + Expect(session).To(Exit(0)) + + lines, _ := it.Collect2(it.LinesString(session.Out)) + Expect(lines).To(ContainElements( + matchSubstrings("sample-service", "sample", "all"), + )) + }) + }) + + Describe("cf marketplace", func() { + It("lists the service catalog", func() { + session := helpers.Cf("marketplace", "-b", brokerName) + Expect(session).To(Exit(0)) + + lines, _ := it.Collect2(it.LinesString(session.Out)) + Expect(lines).To(ContainElement( + matchSubstrings("sample-service", "A sample service that does nothing", brokerName), + )) + }) + }) +}) + +func getAppGUID(appName string) string { + GinkgoHelper() + + session := helpers.Cf("app", appName, "--guid") + Expect(session).To(Exit(0)) + return string(session.Out.Contents()) +} + +func cleanupBroker(brokerName string) { + GinkgoHelper() + + Expect(helpers.Cf("delete-service-broker", "-f", brokerName)).To(Exit(0)) + broker.NewCatalogPurger(rootNamespace).ForBrokerName(brokerName).Purge() +} + +func matchSubstrings(substrings ...string) types.GomegaMatcher { + return MatchRegexp(strings.Join(substrings, ".*")) +} diff --git a/tests/smoke/suite_test.go b/tests/smoke/suite_test.go index deed8b84d..81b45c0cc 100644 --- a/tests/smoke/suite_test.go +++ b/tests/smoke/suite_test.go @@ -2,7 +2,9 @@ package smoke_test import ( "context" + "crypto/tls" "fmt" + "net/http" "strings" "testing" @@ -14,6 +16,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" + "github.com/onsi/gomega/types" "gopkg.in/yaml.v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilruntime "k8s.io/apimachinery/pkg/util/runtime" @@ -55,6 +58,8 @@ func TestSmoke(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) + rootNamespace = helpers.GetDefaultedEnvVar("ROOT_NAMESPACE", "cf") serviceAccountFactory = helpers.NewServiceAccountFactory(rootNamespace) @@ -99,6 +104,19 @@ func sessionOutput(session *Session) (string, error) { return strings.TrimSpace(string(session.Out.Contents())), nil } +func appResponseShould(appName, requestPath string, matchExpectations types.GomegaMatcher) { + var httpClient http.Client + httpClient.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + + Eventually(func(g Gomega) { + resp, err := httpClient.Get(fmt.Sprintf("https://%s.%s%s", appName, appsDomain, requestPath)) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(resp).To(matchExpectations) + }).Should(Succeed()) +} + func printCfApp(config *rest.Config) { utilruntime.Must(korifiv1alpha1.AddToScheme(scheme.Scheme)) k8sClient, err := client.New(config, client.Options{Scheme: scheme.Scheme})