diff --git a/test/e2e/e2eutils.go b/test/e2e/e2eutils.go new file mode 100644 index 0000000..119b777 --- /dev/null +++ b/test/e2e/e2eutils.go @@ -0,0 +1,43 @@ +package e2e + +import ( + goctx "context" + "fmt" + "time" + + "github.com/operator-framework/operator-sdk/pkg/test" + devconsoleapi "github.com/redhat-developer/devconsole-api/pkg/apis/devconsole/v1alpha1" + + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" +) + +// WaitUntilGitSourceReconcile waits execution until controller finishes reconciling. +func WaitUntilGitSourceReconcile(t *test.Framework, nsd types.NamespacedName) error { + var err error + err = wait.Poll(time.Second*5, time.Minute*2, func() (bool, error) { + var gitSource devconsoleapi.GitSource + err = t.Client.Get(goctx.TODO(), nsd, &gitSource) + fmt.Printf("\nGitSource is %+v and error is %+v", gitSource, err) + if err != nil { + return false, err + } + return (gitSource.Status.Connection.State != ""), nil + }) + return err +} + +// WaitUntilGitSourceAnalyzeReconcile waits execution until controller finishes reconciling. +func WaitUntilGitSourceAnalyzeReconcile(t *test.Framework, nsd types.NamespacedName) error { + var err error + err = wait.Poll(time.Second*5, time.Minute*2, func() (bool, error) { + var gitSourceAnalysis devconsoleapi.GitSourceAnalysis + err = t.Client.Get(goctx.TODO(), nsd, &gitSourceAnalysis) + fmt.Printf("\nGitSource is %+v and error is %+v", gitSourceAnalysis, err) + if err != nil { + return false, err + } + return gitSourceAnalysis.Status.Analyzed, nil + }) + return err +} diff --git a/test/e2e/gitsource_test.go b/test/e2e/gitsource_test.go new file mode 100644 index 0000000..7783b75 --- /dev/null +++ b/test/e2e/gitsource_test.go @@ -0,0 +1,119 @@ +package e2e + +import ( + "context" + "fmt" + "os" + "testing" + + framework "github.com/operator-framework/operator-sdk/pkg/test" + "github.com/operator-framework/operator-sdk/pkg/test/e2eutil" + + devconsole "github.com/redhat-developer/devconsole-api/pkg/apis" + devconsoleapi "github.com/redhat-developer/devconsole-api/pkg/apis/devconsole/v1alpha1" + + "github.com/stretchr/testify/require" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// GitSourceTest does e2e test as per operator-sdk documentation +// https://github.com/operator-framework/operator-sdk/blob/cc7b175/doc/test-framework/writing-e2e-tests.md +func TestGitsource(t *testing.T) { + var err error + gitSourceList := &devconsoleapi.GitSourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: "GitSource", + APIVersion: "devconsole.openshift.io/v1alpha1", + }, + } + + err = framework.AddToFrameworkScheme(devconsole.AddToScheme, gitSourceList) + if err != nil { + t.Fatalf("failed to add custom resource scheme to framework: %v", err) + } + + ctx := framework.NewTestCtx(t) + defer ctx.Cleanup() + err = ctx.InitializeClusterResources(&framework.CleanupOptions{TestContext: ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) + require.NoError(t, err, "failed to initialize cluster resources") + t.Log("Initialized cluster resources") + + namespace, err := ctx.GetNamespace() + require.NoError(t, err, "failed to get namespace where operator needs to run") + + // get global framework variables + f := framework.Global + t.Log(fmt.Sprintf("namespace: %s", namespace)) + + // wait for component-operator to be ready + err = e2eutil.WaitForOperatorDeployment(t, f.KubeClient, os.Getenv("DEPLOYED_NAMESPACE"), "devconsole-operator", 1, retryInterval, timeout) + require.NoError(t, err, "failed while waiting for operator deployment") + + t.Log("operator is ready and running") + + t.Run("check exisiting repo connection should yield OK", func(t *testing.T) { + gs := &devconsoleapi.GitSource{ + TypeMeta: metav1.TypeMeta{ + Kind: "GitSource", + APIVersion: "devconsole.openshift.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-git-source-1", + Namespace: namespace, + }, + Spec: devconsoleapi.GitSourceSpec{ + URL: "https://github.com/fabric8-services/build-tool-detector", + Ref: "master", + }, + } + // use TestCtx's create helper to create the object and add a cleanup function for the new object + err = f.Client.Create(context.TODO(), gs, &framework.CleanupOptions{TestContext: ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) + require.NoError(t, err, "failed to create custom resource of kind `GitSource`") + + err = WaitUntilGitSourceReconcile(f, types.NamespacedName{Name: "my-git-source-1", Namespace: namespace}) + if err != nil { + t.Log("Failed to wait for gitsource reconcile") + require.NoError(t, err, "Failed to wait for gitsource reconcile") + } + outputGS := &devconsoleapi.GitSource{} + err = f.Client.Get(context.TODO(), types.NamespacedName{Name: "my-git-source-1", Namespace: namespace}, outputGS) + require.NoError(t, err, "failed to retrieve custom resource of kind `GitSource`") + require.Equal(t, "my-git-source-1", outputGS.ObjectMeta.Name) + require.Equal(t, devconsoleapi.OK, outputGS.Status.Connection.State) + require.Equal(t, namespace, outputGS.ObjectMeta.Namespace) + }) + + t.Run("check non-existing repo connection should yield FAILED", func(t *testing.T) { + gs := &devconsoleapi.GitSource{ + TypeMeta: metav1.TypeMeta{ + Kind: "GitSource", + APIVersion: "devconsole.openshift.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-git-source-2", + Namespace: namespace, + }, + Spec: devconsoleapi.GitSourceSpec{ + URL: "https://example.abc/non-exisiting-repo", + Ref: "master", + }, + } + // use TestCtx's create helper to create the object and add a cleanup function for the new object + err = f.Client.Create(context.TODO(), gs, &framework.CleanupOptions{TestContext: ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) + require.NoError(t, err, "failed to create custom resource of kind `GitSource`") + + err = WaitUntilGitSourceReconcile(f, types.NamespacedName{Name: "my-git-source-2", Namespace: namespace}) + if err != nil { + t.Log("Failed to wait for gitsource reconcile ", err) + require.NoError(t, err, "Failed to wait for gitsource reconcile") + } + outputGS := &devconsoleapi.GitSource{} + err = f.Client.Get(context.TODO(), types.NamespacedName{Name: "my-git-source-2", Namespace: namespace}, outputGS) + require.NoError(t, err, "failed to retrieve custom resource of kind `GitSource`") + require.Equal(t, "my-git-source-2", outputGS.ObjectMeta.Name) + require.Equal(t, devconsoleapi.Failed, outputGS.Status.Connection.State) + require.Equal(t, namespace, outputGS.ObjectMeta.Namespace) + }) +} diff --git a/test/e2e/gitsourceanalysis_test.go b/test/e2e/gitsourceanalysis_test.go new file mode 100644 index 0000000..a2eca71 --- /dev/null +++ b/test/e2e/gitsourceanalysis_test.go @@ -0,0 +1,136 @@ +package e2e + +import ( + "context" + "fmt" + "os" + "testing" + + framework "github.com/operator-framework/operator-sdk/pkg/test" + "github.com/operator-framework/operator-sdk/pkg/test/e2eutil" + + devconsole "github.com/redhat-developer/devconsole-api/pkg/apis" + devconsoleapi "github.com/redhat-developer/devconsole-api/pkg/apis/devconsole/v1alpha1" + + "github.com/stretchr/testify/require" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// ComponentTest does e2e test as per operator-sdk documentation +// https://github.com/operator-framework/operator-sdk/blob/cc7b175/doc/test-framework/writing-e2e-tests.md +func TestGitsourceAnalysis(t *testing.T) { + var err error + gitSourceList := &devconsoleapi.GitSourceList{ + TypeMeta: metav1.TypeMeta{ + Kind: "GitSource", + APIVersion: "devconsole.openshift.io/v1alpha1", + }, + } + + gitSourceAnalysisList := &devconsoleapi.GitSourceAnalysisList{ + TypeMeta: metav1.TypeMeta{ + Kind: "GitSourceAnalysis", + APIVersion: "devconsole.openshift.io/v1alpha1", + }, + } + + err = framework.AddToFrameworkScheme(devconsole.AddToScheme, gitSourceList) + if err != nil { + t.Fatalf("failed to add custom resource scheme to framework: %v", err) + } + + err = framework.AddToFrameworkScheme(devconsole.AddToScheme, gitSourceAnalysisList) + if err != nil { + t.Fatalf("failed to add custom resource scheme to framework: %v", err) + } + + ctx := framework.NewTestCtx(t) + defer ctx.Cleanup() + err = ctx.InitializeClusterResources(&framework.CleanupOptions{TestContext: ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) + require.NoError(t, err, "failed to initialize cluster resources") + t.Log("Initialized cluster resources") + + namespace, err := ctx.GetNamespace() + require.NoError(t, err, "failed to get namespace where operator needs to run") + + // get global framework variables + f := framework.Global + t.Log(fmt.Sprintf("namespace: %s", namespace)) + + // wait for component-operator to be ready + err = e2eutil.WaitForOperatorDeployment(t, f.KubeClient, os.Getenv("DEPLOYED_NAMESPACE"), "devconsole-operator", 1, retryInterval, timeout) + require.NoError(t, err, "failed while waiting for operator deployment") + + t.Log("operator is ready and running") + + gs := &devconsoleapi.GitSource{ + TypeMeta: metav1.TypeMeta{ + Kind: "GitSource", + APIVersion: "devconsole.openshift.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-git-source", + Namespace: namespace, + }, + Spec: devconsoleapi.GitSourceSpec{ + URL: "https://github.com/fabric8-services/build-tool-detector", + Ref: "master", + }, + } + + gsa := &devconsoleapi.GitSourceAnalysis{ + TypeMeta: metav1.TypeMeta{ + Kind: "GitSourceAnanlysis", + APIVersion: "devconsole.openshift.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gitsource-analysis", + Namespace: namespace, + }, + Spec: devconsoleapi.GitSourceAnalysisSpec{ + GitSourceRef: devconsoleapi.GitSourceRef{ + Name: "my-git-source", + }, + }, + } + + // use TestCtx's create helper to create the object and add a cleanup function for the new object + err = f.Client.Create(context.TODO(), gs, &framework.CleanupOptions{TestContext: ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) + require.NoError(t, err, "failed to create custom resource of kind `GitSource`") + + // use TestCtx's create helper to create the object and add a cleanup function for the new object + err = f.Client.Create(context.TODO(), gsa, &framework.CleanupOptions{TestContext: ctx, Timeout: cleanupTimeout, RetryInterval: cleanupRetryInterval}) + require.NoError(t, err, "failed to create custom resource of kind `GitSourceAnalysis`") + + err = WaitUntilGitSourceReconcile(f, types.NamespacedName{Name: "my-git-source", Namespace: namespace}) + if err != nil { + t.Log("Failed to wait for gitsource reconcile") + t.Fail() + } + + err = WaitUntilGitSourceAnalyzeReconcile(f, types.NamespacedName{Name: "gitsource-analysis", Namespace: namespace}) + if err != nil { + t.Log("Failed to wait for gitsource analyze reconcile") + t.Fail() + } + + t.Run("retrieve component and verify related resources are created", func(t *testing.T) { + outputCR := &devconsoleapi.GitSource{} + err = f.Client.Get(context.TODO(), types.NamespacedName{Name: "my-git-source", Namespace: namespace}, outputCR) + require.NoError(t, err, "failed to retrieve custom resource of kind `GitSource`") + require.Equal(t, "my-git-source", outputCR.ObjectMeta.Name) + require.Equal(t, namespace, outputCR.ObjectMeta.Namespace) + }) + + t.Run("check if gitsourceanalysis has referrence to gitsource and if build env stats are correct", func(t *testing.T) { + outputGsa := &devconsoleapi.GitSourceAnalysis{} + err = f.Client.Get(context.TODO(), types.NamespacedName{Name: "gitsource-analysis", Namespace: namespace}, outputGsa) + require.NoError(t, err, "failed to retrieve custom resource of kind `GitSourceAnalysis`") + require.Equal(t, "my-git-source", outputGsa.Spec.GitSourceRef.Name) + require.Equal(t, true, outputGsa.Status.Analyzed) + require.NotZero(t, len(outputGsa.Status.BuildEnvStatistics.DetectedBuildTypes), "build type has not been detected") + require.Equal(t, "go", outputGsa.Status.BuildEnvStatistics.DetectedBuildTypes[0].Language) + }) +}