diff --git a/.ibm/pipelines/openshift-unauth-tests.sh b/.ibm/pipelines/openshift-unauth-tests.sh new file mode 100755 index 00000000000..7545855f972 --- /dev/null +++ b/.ibm/pipelines/openshift-unauth-tests.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +LOGFILE="pr-${GIT_PR_NUMBER}-openshift-tests-${BUILD_NUMBER}" + +source .ibm/pipelines/functions.sh + +ibmcloud login --apikey "${API_KEY_QE}" +ibmcloud target -r eu-de +ibmcloud oc cluster config -c "${CLUSTER_ID}" + +( + set -e + make install + make test-integration-openshift-unauth +) |& tee "/tmp/${LOGFILE}" + +RESULT=${PIPESTATUS[0]} + +save_logs "${LOGFILE}" "OpenShift Unauthenticated Tests" ${RESULT} + +exit ${RESULT} diff --git a/Makefile b/Makefile index 5cfbf23bc69..396c29d22bd 100644 --- a/Makefile +++ b/Makefile @@ -192,7 +192,11 @@ openshiftci-presubmit-unittests: .PHONY: test-integration-cluster test-integration-cluster: - $(RUN_GINKGO) $(GINKGO_FLAGS) --junit-report="test-integration.xml" --label-filter="!nocluster && !podman" tests/integration + $(RUN_GINKGO) $(GINKGO_FLAGS) --junit-report="test-integration.xml" --label-filter="!unauth && !nocluster && !podman" tests/integration + +.PHONY: test-integration-openshift-unauth +test-integration-openshift-unauth: + $(RUN_GINKGO) $(GINKGO_FLAGS) --junit-report="test-integration-unauth.xml" --label-filter="unauth" tests/integration .PHONY: test-integration-no-cluster test-integration-no-cluster: diff --git a/tests/helper/helper_cli.go b/tests/helper/helper_cli.go index 58bd62f7bfc..cd1b1533912 100644 --- a/tests/helper/helper_cli.go +++ b/tests/helper/helper_cli.go @@ -56,4 +56,5 @@ type CliRunner interface { AssertContainsLabel(kind, namespace, componentName, appName, mode, key, value string) AssertNoContainsLabel(kind, namespace, componentName, appName, mode, key string) EnsurePodIsUp(namespace, podName string) + AssertNonAuthenticated() } diff --git a/tests/helper/helper_generic.go b/tests/helper/helper_generic.go index a934de23f93..95ff5352aad 100644 --- a/tests/helper/helper_generic.go +++ b/tests/helper/helper_generic.go @@ -197,7 +197,11 @@ func CommonBeforeEach() CommonVar { commonVar.OriginalKubeconfig = os.Getenv("KUBECONFIG") if NeedsCluster(CurrentSpecReport().Labels()) { LocalKubeconfigSet(commonVar.ConfigDir) - commonVar.Project = commonVar.CliRunner.CreateAndSetRandNamespaceProject() + if IsAuth(CurrentSpecReport().Labels()) { + commonVar.Project = commonVar.CliRunner.CreateAndSetRandNamespaceProject() + } else { + commonVar.CliRunner.AssertNonAuthenticated() + } } else { // Disable the use of in-cluster configuration (seen in IBM Cloud pipeline) os.Unsetenv("KUBERNETES_SERVICE_HOST") diff --git a/tests/helper/helper_kubectl.go b/tests/helper/helper_kubectl.go index dee0805eed0..3a03a051ab8 100644 --- a/tests/helper/helper_kubectl.go +++ b/tests/helper/helper_kubectl.go @@ -431,3 +431,7 @@ func (kubectl KubectlRunner) AssertNoContainsLabel(kind, namespace, componentNam all := Cmd(kubectl.path, "get", kind, selector, "-n", namespace, "-o", "jsonpath={.items[0].metadata.labels}").ShouldPass().Out() Expect(all).ToNot(ContainSubstring(fmt.Sprintf(`"%s"`, key))) } + +func (kubectl KubectlRunner) AssertNonAuthenticated() { + // Nothing to do +} diff --git a/tests/helper/helper_oc.go b/tests/helper/helper_oc.go index f9fe8ae9467..2ae7986fb6e 100644 --- a/tests/helper/helper_oc.go +++ b/tests/helper/helper_oc.go @@ -623,3 +623,7 @@ func (oc OcRunner) EnsurePodIsUp(namespace, podName string) { return strings.Contains(output, podName) }) } + +func (oc OcRunner) AssertNonAuthenticated() { + Cmd(oc.path, "whoami").ShouldFail() +} diff --git a/tests/helper/labels.go b/tests/helper/labels.go index e8c5b4470fb..af71d89e8f4 100644 --- a/tests/helper/labels.go +++ b/tests/helper/labels.go @@ -6,6 +6,7 @@ import ( const ( LabelNoCluster = "nocluster" + LabelUnauth = "unauth" LabelPodman = "podman" ) @@ -21,6 +22,15 @@ func NeedsCluster(labels []string) bool { return true } +func IsAuth(labels []string) bool { + for _, label := range labels { + if label == LabelUnauth { + return false + } + } + return true +} + func LabelPodmanIf(value bool, args ...interface{}) []interface{} { res := []interface{}{} if value { diff --git a/tests/integration/cmd_analyze_test.go b/tests/integration/cmd_analyze_test.go index 9653d2e36cf..ef9b295549d 100644 --- a/tests/integration/cmd_analyze_test.go +++ b/tests/integration/cmd_analyze_test.go @@ -9,45 +9,54 @@ import ( "github.com/redhat-developer/odo/tests/helper" ) -var _ = Describe("odo analyze command tests", Label(helper.LabelNoCluster), func() { - var commonVar helper.CommonVar - - // This is run before every Spec (It) - var _ = BeforeEach(func() { - commonVar = helper.CommonBeforeEach() - helper.Chdir(commonVar.Context) - }) - - // This is run after every Spec (It) - var _ = AfterEach(func() { - helper.CommonAfterEach(commonVar) - }) - - When("source files are in the directory", func() { - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), commonVar.Context) +var _ = Describe("odo analyze command tests", func() { + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + var _ = Context("label "+label, Label(label), func() { + var commonVar helper.CommonVar + + // This is run before every Spec (It) + var _ = BeforeEach(func() { + commonVar = helper.CommonBeforeEach() + helper.Chdir(commonVar.Context) + }) + + // This is run after every Spec (It) + var _ = AfterEach(func() { + helper.CommonAfterEach(commonVar) + }) + + When("source files are in the directory", func() { + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "devfiles", "nodejs", "project"), commonVar.Context) + }) + + It("analyze should return correct value", func() { + res := helper.Cmd("odo", "analyze", "-o", "json").ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(stderr).To(BeEmpty()) + Expect(helper.IsJSON(stdout)).To(BeTrue()) + helper.JsonPathContentIs(stdout, "0.devfile", "nodejs") + helper.JsonPathContentIs(stdout, "0.devfileRegistry", "DefaultDevfileRegistry") + }) + }) + + It("analyze should fail in an empty directory", func() { + res := helper.Cmd("odo", "analyze", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(helper.IsJSON(stderr)).To(BeTrue()) + helper.JsonPathContentContain(stderr, "message", "No valid devfile found for project in") + }) + + It("analyze should fail without json output", func() { + stderr := helper.Cmd("odo", "analyze").ShouldFail().Err() + Expect(stderr).To(ContainSubstring("this command can be run with json output only")) + }) }) - It("analyze should return correct value", func() { - res := helper.Cmd("odo", "analyze", "-o", "json").ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(stderr).To(BeEmpty()) - Expect(helper.IsJSON(stdout)).To(BeTrue()) - helper.JsonPathContentIs(stdout, "0.devfile", "nodejs") - helper.JsonPathContentIs(stdout, "0.devfileRegistry", "DefaultDevfileRegistry") - }) - }) - - It("analyze should fail in an empty directory", func() { - res := helper.Cmd("odo", "analyze", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(helper.IsJSON(stderr)).To(BeTrue()) - helper.JsonPathContentContain(stderr, "message", "No valid devfile found for project in") - }) - - It("analyze should fail without json output", func() { - stderr := helper.Cmd("odo", "analyze").ShouldFail().Err() - Expect(stderr).To(ContainSubstring("this command can be run with json output only")) - }) + } + }) diff --git a/tests/integration/cmd_describe_component_test.go b/tests/integration/cmd_describe_component_test.go index f88fa7daffa..65ed144bb8a 100644 --- a/tests/integration/cmd_describe_component_test.go +++ b/tests/integration/cmd_describe_component_test.go @@ -28,38 +28,43 @@ var _ = Describe("odo describe component command tests", func() { helper.CommonAfterEach(commonVar) }) - It("should fail, without cluster", Label(helper.LabelNoCluster), func() { - By("running odo describe component -o json with namespace flag without name flag", func() { - res := helper.Cmd("odo", "describe", "component", "--namespace", "default", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(helper.IsJSON(stderr)).To(BeTrue()) - Expect(stdout).To(BeEmpty()) - helper.JsonPathContentContain(stderr, "message", "--namespace can be used only with --name") - }) + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + It("should fail, without cluster", Label(label), func() { + By("running odo describe component -o json with namespace flag without name flag", func() { + res := helper.Cmd("odo", "describe", "component", "--namespace", "default", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stderr)).To(BeTrue()) + Expect(stdout).To(BeEmpty()) + helper.JsonPathContentContain(stderr, "message", "--namespace can be used only with --name") + }) - By("running odo describe component -o json without name and without devfile in the current directory", func() { - res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(helper.IsJSON(stderr)).To(BeTrue()) - Expect(stdout).To(BeEmpty()) - helper.JsonPathContentContain(stderr, "message", "The current directory does not represent an odo component") - }) + By("running odo describe component -o json without name and without devfile in the current directory", func() { + res := helper.Cmd("odo", "describe", "component", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stderr)).To(BeTrue()) + Expect(stdout).To(BeEmpty()) + helper.JsonPathContentContain(stderr, "message", "The current directory does not represent an odo component") + }) - By("running odo describe component with namespace flag without name flag", func() { - res := helper.Cmd("odo", "describe", "component", "--namespace", "default").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(stderr).To(ContainSubstring("--namespace can be used only with --name")) - }) + By("running odo describe component with namespace flag without name flag", func() { + res := helper.Cmd("odo", "describe", "component", "--namespace", "default").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(stderr).To(ContainSubstring("--namespace can be used only with --name")) + }) - By("running odo describe component without name and without devfile in the current directory", func() { - res := helper.Cmd("odo", "describe", "component").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(stderr).To(ContainSubstring("The current directory does not represent an odo component")) - }) + By("running odo describe component without name and without devfile in the current directory", func() { + res := helper.Cmd("odo", "describe", "component").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(stderr).To(ContainSubstring("The current directory does not represent an odo component")) + }) - }) + }) + } It("should fail, with cluster", func() { By("running odo describe component -o json with an unknown name", func() { diff --git a/tests/integration/cmd_devfile_build_images_test.go b/tests/integration/cmd_devfile_build_images_test.go index 30f5ed1aa0c..b106af3ca02 100644 --- a/tests/integration/cmd_devfile_build_images_test.go +++ b/tests/integration/cmd_devfile_build_images_test.go @@ -14,251 +14,257 @@ import ( "github.com/redhat-developer/odo/tests/helper" ) -var _ = Describe("odo devfile build-images command tests", Label(helper.LabelNoCluster), func() { - - var commonVar helper.CommonVar - - var _ = BeforeEach(func() { - commonVar = helper.CommonBeforeEach() - helper.Chdir(commonVar.Context) - }) - - // This is run after every Spec (It) - var _ = AfterEach(func() { - helper.CommonAfterEach(commonVar) - }) - - When("using a devfile.yaml containing an Image component", func() { - - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-outerloop.yaml")).ShouldPass() - helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) - }) - It("should run odo build-images without push", func() { - stdout := helper.Cmd("odo", "build-images").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() - Expect(stdout).To(ContainSubstring("build -t quay.io/unknown-account/myimage -f " + filepath.Join(commonVar.Context, "Dockerfile ") + commonVar.Context)) - }) - - It("should run odo build-images --push", func() { - stdout := helper.Cmd("odo", "build-images", "--push").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() - Expect(stdout).To(ContainSubstring("build -t quay.io/unknown-account/myimage -f " + filepath.Join(commonVar.Context, "Dockerfile ") + commonVar.Context)) - Expect(stdout).To(ContainSubstring("push quay.io/unknown-account/myimage")) - }) - }) - - When("using a devfile.yaml with no Image component", func() { - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.Cmd("odo", "init", "--name", "aname", - "--devfile-path", - helper.GetExamplePath("source", "devfiles", "nodejs", "devfile.yaml")).ShouldPass() - helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) - }) - It("should not be able to run odo build-images", func() { - stdout, stderr := helper.Cmd("odo", "build-images").AddEnv("PODMAN_CMD=echo").ShouldFail().OutAndErr() - // Make sure no "{podman,docker} build -t ..." command gets executed - imageBuildCmd := "build -t " - Expect(stdout).ShouldNot(ContainSubstring(imageBuildCmd)) - Expect(stderr).ShouldNot(ContainSubstring(imageBuildCmd)) - Expect(stderr).To(ContainSubstring("no component with type \"Image\" found in Devfile")) - }) - }) - - When("using a devfile.yaml containing an Image component with Dockerfile args", func() { - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-outerloop-args.yaml")).ShouldPass() - helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) - }) +var _ = Describe("odo devfile build-images command tests", func() { + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + var _ = Context("label "+label, Label(label), func() { - It("should use args to build image when running odo build-images", func() { - stdout := helper.Cmd("odo", "build-images").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() - Expect(stdout).To(ContainSubstring("--unknown-flag value")) - }) + var commonVar helper.CommonVar - }) + var _ = BeforeEach(func() { + commonVar = helper.CommonBeforeEach() + helper.Chdir(commonVar.Context) + }) - When("using a devfile.yaml containing an Image component with a build context", func() { + // This is run after every Spec (It) + var _ = AfterEach(func() { + helper.CommonAfterEach(commonVar) + }) - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.Cmd("odo", "init", "--name", "aname", - "--devfile-path", - helper.GetExamplePath("source", "devfiles", "nodejs", - "devfile-outerloop-project_source-in-docker-build-context.yaml")).ShouldPass() - helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) - }) + When("using a devfile.yaml containing an Image component", func() { - for _, scope := range []struct { - name string - envvars []string - }{ - { - name: "Podman", - envvars: []string{"PODMAN_CMD=echo"}, - }, - { - name: "Docker", - envvars: []string{ - "PODMAN_CMD=a-command-not-found-for-podman-should-make-odo-fallback-to-docker", - "DOCKER_CMD=echo", - }, - }, - } { - // this is a workaround to ensure that the for loop works with `It` blocks - scope := scope - It(fmt.Sprintf("should build image via %s if build context references PROJECT_SOURCE env var", scope.name), func() { - stdout := helper.Cmd("odo", "build-images").AddEnv(scope.envvars...).ShouldPass().Out() - lines, err := helper.ExtractLines(stdout) - Expect(err).ShouldNot(HaveOccurred()) - nbLines := len(lines) - Expect(nbLines).To(BeNumerically(">", 2)) - containerImage := "localhost:5000/devfile-nodejs-deploy:0.1.0" // from Devfile yaml file - dockerfilePath := filepath.Join(commonVar.Context, "Dockerfile") - buildCtx := commonVar.Context - Expect(lines[nbLines-2]).To(BeEquivalentTo( - fmt.Sprintf("build -t %s -f %s %s", containerImage, dockerfilePath, buildCtx))) - }) - } - }) - - When("using a devfile.yaml containing an Image component with no build context", func() { - - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.CopyExampleDevFile( - filepath.Join("source", "devfiles", "nodejs", - "issue-5600-devfile-with-image-component-and-no-buildContext.yaml"), - filepath.Join(commonVar.Context, "devfile.yaml")) - helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) - }) + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-outerloop.yaml")).ShouldPass() + helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) + }) + It("should run odo build-images without push", func() { + stdout := helper.Cmd("odo", "build-images").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() + Expect(stdout).To(ContainSubstring("build -t quay.io/unknown-account/myimage -f " + filepath.Join(commonVar.Context, "Dockerfile ") + commonVar.Context)) + }) - for _, scope := range []struct { - name string - envvars []string - }{ - { - name: "Podman", - envvars: []string{"PODMAN_CMD=echo"}, - }, - { - name: "Docker", - envvars: []string{ - "PODMAN_CMD=a-command-not-found-for-podman-should-make-odo-fallback-to-docker", - "DOCKER_CMD=echo", - }, - }, - } { - // this is a workaround to ensure that the for loop works with `It` blocks - scope := scope - It(fmt.Sprintf("should build image via %s by defaulting build context to devfile path", scope.name), func() { - stdout := helper.Cmd("odo", "build-images").AddEnv(scope.envvars...).ShouldPass().Out() - lines, err := helper.ExtractLines(stdout) - Expect(err).ShouldNot(HaveOccurred()) - nbLines := len(lines) - Expect(nbLines).To(BeNumerically(">", 2)) - containerImage := "localhost:5000/devfile-nodejs-deploy:0.1.0" // from Devfile yaml file - dockerfilePath := filepath.Join(commonVar.Context, "Dockerfile") - buildCtx := commonVar.Context - Expect(lines[nbLines-2]).To(BeEquivalentTo( - fmt.Sprintf("build -t %s -f %s %s", containerImage, dockerfilePath, buildCtx))) + It("should run odo build-images --push", func() { + stdout := helper.Cmd("odo", "build-images", "--push").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() + Expect(stdout).To(ContainSubstring("build -t quay.io/unknown-account/myimage -f " + filepath.Join(commonVar.Context, "Dockerfile ") + commonVar.Context)) + Expect(stdout).To(ContainSubstring("push quay.io/unknown-account/myimage")) + }) }) - } - }) - - for _, env := range [][]string{ - {"PODMAN_CMD=echo"}, - { - "PODMAN_CMD=a-command-not-found-for-podman-should-make-odo-fallback-to-docker", - "DOCKER_CMD=echo", - }, - } { - env := env - Describe("using a Devfile with an image component using a remote Dockerfile", func() { - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-outerloop.yaml"), - path.Join(commonVar.Context, "devfile.yaml")) + When("using a devfile.yaml with no Image component", func() { + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.Cmd("odo", "init", "--name", "aname", + "--devfile-path", + helper.GetExamplePath("source", "devfiles", "nodejs", "devfile.yaml")).ShouldPass() + helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) + }) + It("should not be able to run odo build-images", func() { + stdout, stderr := helper.Cmd("odo", "build-images").AddEnv("PODMAN_CMD=echo").ShouldFail().OutAndErr() + // Make sure no "{podman,docker} build -t ..." command gets executed + imageBuildCmd := "build -t " + Expect(stdout).ShouldNot(ContainSubstring(imageBuildCmd)) + Expect(stderr).ShouldNot(ContainSubstring(imageBuildCmd)) + Expect(stderr).To(ContainSubstring("no component with type \"Image\" found in Devfile")) + }) }) - When("remote server returns an error", func() { - var server *httptest.Server - var url string + When("using a devfile.yaml containing an Image component with Dockerfile args", func() { BeforeEach(func() { - server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotFound) - })) - url = server.URL - - helper.ReplaceString(filepath.Join(commonVar.Context, "devfile.yaml"), "./Dockerfile", url) + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-outerloop-args.yaml")).ShouldPass() + helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) }) - AfterEach(func() { - server.Close() + It("should use args to build image when running odo build-images", func() { + stdout := helper.Cmd("odo", "build-images").AddEnv("PODMAN_CMD=echo").ShouldPass().Out() + Expect(stdout).To(ContainSubstring("--unknown-flag value")) }) - It("should not build images", func() { - cmdWrapper := helper.Cmd("odo", "build-images").AddEnv(env...).ShouldFail() - stderr := cmdWrapper.Err() - stdout := cmdWrapper.Out() - Expect(stderr).To(ContainSubstring("failed to retrieve " + url)) - Expect(stdout).NotTo(ContainSubstring("build -t quay.io/unknown-account/myimage -f ")) - }) + }) + + When("using a devfile.yaml containing an Image component with a build context", func() { - It("should not run 'odo build-images --push'", func() { - cmdWrapper := helper.Cmd("odo", "build-images", "--push").AddEnv(env...).ShouldFail() - stderr := cmdWrapper.Err() - stdout := cmdWrapper.Out() - Expect(stderr).To(ContainSubstring("failed to retrieve " + url)) - Expect(stdout).NotTo(ContainSubstring("build -t quay.io/unknown-account/myimage -f ")) - Expect(stdout).NotTo(ContainSubstring("push quay.io/unknown-account/myimage")) + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.Cmd("odo", "init", "--name", "aname", + "--devfile-path", + helper.GetExamplePath("source", "devfiles", "nodejs", + "devfile-outerloop-project_source-in-docker-build-context.yaml")).ShouldPass() + helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) }) + + for _, scope := range []struct { + name string + envvars []string + }{ + { + name: "Podman", + envvars: []string{"PODMAN_CMD=echo"}, + }, + { + name: "Docker", + envvars: []string{ + "PODMAN_CMD=a-command-not-found-for-podman-should-make-odo-fallback-to-docker", + "DOCKER_CMD=echo", + }, + }, + } { + // this is a workaround to ensure that the for loop works with `It` blocks + scope := scope + It(fmt.Sprintf("should build image via %s if build context references PROJECT_SOURCE env var", scope.name), func() { + stdout := helper.Cmd("odo", "build-images").AddEnv(scope.envvars...).ShouldPass().Out() + lines, err := helper.ExtractLines(stdout) + Expect(err).ShouldNot(HaveOccurred()) + nbLines := len(lines) + Expect(nbLines).To(BeNumerically(">", 2)) + containerImage := "localhost:5000/devfile-nodejs-deploy:0.1.0" // from Devfile yaml file + dockerfilePath := filepath.Join(commonVar.Context, "Dockerfile") + buildCtx := commonVar.Context + Expect(lines[nbLines-2]).To(BeEquivalentTo( + fmt.Sprintf("build -t %s -f %s %s", containerImage, dockerfilePath, buildCtx))) + }) + } }) - When("remote server returns a valid file", func() { - var buildRegexp string - var server *httptest.Server - var url string + When("using a devfile.yaml containing an Image component with no build context", func() { BeforeEach(func() { - buildRegexp = regexp.QuoteMeta("build -t quay.io/unknown-account/myimage -f ") + - ".*\\.dockerfile " + regexp.QuoteMeta(commonVar.Context) - server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, `# Dockerfile + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.CopyExampleDevFile( + filepath.Join("source", "devfiles", "nodejs", + "issue-5600-devfile-with-image-component-and-no-buildContext.yaml"), + filepath.Join(commonVar.Context, "devfile.yaml")) + helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) + }) + + for _, scope := range []struct { + name string + envvars []string + }{ + { + name: "Podman", + envvars: []string{"PODMAN_CMD=echo"}, + }, + { + name: "Docker", + envvars: []string{ + "PODMAN_CMD=a-command-not-found-for-podman-should-make-odo-fallback-to-docker", + "DOCKER_CMD=echo", + }, + }, + } { + // this is a workaround to ensure that the for loop works with `It` blocks + scope := scope + It(fmt.Sprintf("should build image via %s by defaulting build context to devfile path", scope.name), func() { + stdout := helper.Cmd("odo", "build-images").AddEnv(scope.envvars...).ShouldPass().Out() + lines, err := helper.ExtractLines(stdout) + Expect(err).ShouldNot(HaveOccurred()) + nbLines := len(lines) + Expect(nbLines).To(BeNumerically(">", 2)) + containerImage := "localhost:5000/devfile-nodejs-deploy:0.1.0" // from Devfile yaml file + dockerfilePath := filepath.Join(commonVar.Context, "Dockerfile") + buildCtx := commonVar.Context + Expect(lines[nbLines-2]).To(BeEquivalentTo( + fmt.Sprintf("build -t %s -f %s %s", containerImage, dockerfilePath, buildCtx))) + }) + } + }) + + for _, env := range [][]string{ + {"PODMAN_CMD=echo"}, + { + "PODMAN_CMD=a-command-not-found-for-podman-should-make-odo-fallback-to-docker", + "DOCKER_CMD=echo", + }, + } { + env := env + Describe("using a Devfile with an image component using a remote Dockerfile", func() { + + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-outerloop.yaml"), + path.Join(commonVar.Context, "devfile.yaml")) + }) + + When("remote server returns an error", func() { + var server *httptest.Server + var url string + BeforeEach(func() { + server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + })) + url = server.URL + + helper.ReplaceString(filepath.Join(commonVar.Context, "devfile.yaml"), "./Dockerfile", url) + }) + + AfterEach(func() { + server.Close() + }) + + It("should not build images", func() { + cmdWrapper := helper.Cmd("odo", "build-images").AddEnv(env...).ShouldFail() + stderr := cmdWrapper.Err() + stdout := cmdWrapper.Out() + Expect(stderr).To(ContainSubstring("failed to retrieve " + url)) + Expect(stdout).NotTo(ContainSubstring("build -t quay.io/unknown-account/myimage -f ")) + }) + + It("should not run 'odo build-images --push'", func() { + cmdWrapper := helper.Cmd("odo", "build-images", "--push").AddEnv(env...).ShouldFail() + stderr := cmdWrapper.Err() + stdout := cmdWrapper.Out() + Expect(stderr).To(ContainSubstring("failed to retrieve " + url)) + Expect(stdout).NotTo(ContainSubstring("build -t quay.io/unknown-account/myimage -f ")) + Expect(stdout).NotTo(ContainSubstring("push quay.io/unknown-account/myimage")) + }) + }) + + When("remote server returns a valid file", func() { + var buildRegexp string + var server *httptest.Server + var url string + + BeforeEach(func() { + buildRegexp = regexp.QuoteMeta("build -t quay.io/unknown-account/myimage -f ") + + ".*\\.dockerfile " + regexp.QuoteMeta(commonVar.Context) + server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, `# Dockerfile FROM node:8.11.1-alpine COPY . /app WORKDIR /app RUN npm install CMD ["npm", "start"] `) - })) - url = server.URL - - helper.ReplaceString(filepath.Join(commonVar.Context, "devfile.yaml"), "./Dockerfile", url) - }) - - AfterEach(func() { - server.Close() + })) + url = server.URL + + helper.ReplaceString(filepath.Join(commonVar.Context, "devfile.yaml"), "./Dockerfile", url) + }) + + AfterEach(func() { + server.Close() + }) + + It("should build images", func() { + stdout := helper.Cmd("odo", "build-images").AddEnv(env...).ShouldPass().Out() + lines, _ := helper.ExtractLines(stdout) + _, ok := helper.FindFirstElementIndexMatchingRegExp(lines, buildRegexp) + Expect(ok).To(BeTrue(), "build regexp not found in output: "+buildRegexp) + }) + + It("should run 'odo build-images --push'", func() { + stdout := helper.Cmd("odo", "build-images", "--push").AddEnv(env...).ShouldPass().Out() + lines, _ := helper.ExtractLines(stdout) + _, ok := helper.FindFirstElementIndexMatchingRegExp(lines, buildRegexp) + Expect(ok).To(BeTrue(), "build regexp not found in output: "+buildRegexp) + Expect(stdout).To(ContainSubstring("push quay.io/unknown-account/myimage")) + }) + }) }) - - It("should build images", func() { - stdout := helper.Cmd("odo", "build-images").AddEnv(env...).ShouldPass().Out() - lines, _ := helper.ExtractLines(stdout) - _, ok := helper.FindFirstElementIndexMatchingRegExp(lines, buildRegexp) - Expect(ok).To(BeTrue(), "build regexp not found in output: "+buildRegexp) - }) - - It("should run 'odo build-images --push'", func() { - stdout := helper.Cmd("odo", "build-images", "--push").AddEnv(env...).ShouldPass().Out() - lines, _ := helper.ExtractLines(stdout) - _, ok := helper.FindFirstElementIndexMatchingRegExp(lines, buildRegexp) - Expect(ok).To(BeTrue(), "build regexp not found in output: "+buildRegexp) - Expect(stdout).To(ContainSubstring("push quay.io/unknown-account/myimage")) - }) - }) + } }) } - }) diff --git a/tests/integration/cmd_devfile_init_test.go b/tests/integration/cmd_devfile_init_test.go index abfe59d1af2..9efb087e5fd 100644 --- a/tests/integration/cmd_devfile_init_test.go +++ b/tests/integration/cmd_devfile_init_test.go @@ -22,500 +22,507 @@ import ( "github.com/redhat-developer/odo/tests/helper" ) -var _ = Describe("odo devfile init command tests", Label(helper.LabelNoCluster), func() { +var _ = Describe("odo devfile init command tests", func() { + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + var _ = Context("label "+label, Label(label), func() { + + var commonVar helper.CommonVar + + var _ = BeforeEach(func() { + commonVar = helper.CommonBeforeEach() + helper.Chdir(commonVar.Context) + Expect(helper.VerifyFileExists(".odo/env/env.yaml")).To(BeFalse()) + }) - var commonVar helper.CommonVar + var _ = AfterEach(func() { + helper.CommonAfterEach(commonVar) + }) - var _ = BeforeEach(func() { - commonVar = helper.CommonBeforeEach() - helper.Chdir(commonVar.Context) - Expect(helper.VerifyFileExists(".odo/env/env.yaml")).To(BeFalse()) - }) + It("should fail", func() { + By("running odo init with incomplete flags", func() { + helper.Cmd("odo", "init", "--name", "aname").ShouldFail() + }) - var _ = AfterEach(func() { - helper.CommonAfterEach(commonVar) - }) + By("using an invalid component name", func() { + helper.Cmd("odo", "init", "--devfile", "go", "--name", "123").ShouldFail() + }) - It("should fail", func() { - By("running odo init with incomplete flags", func() { - helper.Cmd("odo", "init", "--name", "aname").ShouldFail() - }) + By("running odo init with json and no other flags", func() { + res := helper.Cmd("odo", "init", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(helper.IsJSON(stderr)).To(BeTrue()) + helper.JsonPathContentIs(stderr, "message", "parameters are expected to select a devfile") + }) - By("using an invalid component name", func() { - helper.Cmd("odo", "init", "--devfile", "go", "--name", "123").ShouldFail() - }) + By("running odo init with incomplete flags and JSON output", func() { + res := helper.Cmd("odo", "init", "--name", "aname", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(helper.IsJSON(stderr)).To(BeTrue()) + helper.JsonPathContentContain(stderr, "message", "either --devfile or --devfile-path parameter should be specified") + }) - By("running odo init with json and no other flags", func() { - res := helper.Cmd("odo", "init", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(helper.IsJSON(stderr)).To(BeTrue()) - helper.JsonPathContentIs(stderr, "message", "parameters are expected to select a devfile") - }) + By("keeping an empty directory when running odo init with wrong starter name", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go", "--starter", "wrongname").ShouldFail() + files := helper.ListFilesInDir(commonVar.Context) + Expect(len(files)).To(Equal(0)) + }) + By("using an invalid devfile name", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "invalid").ShouldFail() + }) + By("running odo init in a directory containing a devfile.yaml", func() { + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"), filepath.Join(commonVar.Context, "devfile.yaml")) + defer os.Remove(filepath.Join(commonVar.Context, "devfile.yaml")) + err := helper.Cmd("odo", "init").ShouldFail().Err() + Expect(err).To(ContainSubstring("a devfile already exists in the current directory")) + }) - By("running odo init with incomplete flags and JSON output", func() { - res := helper.Cmd("odo", "init", "--name", "aname", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(helper.IsJSON(stderr)).To(BeTrue()) - helper.JsonPathContentContain(stderr, "message", "either --devfile or --devfile-path parameter should be specified") - }) + By("running odo init in a directory containing a .devfile.yaml", func() { + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"), filepath.Join(commonVar.Context, ".devfile.yaml")) + defer helper.DeleteFile(filepath.Join(commonVar.Context, ".devfile.yaml")) + err := helper.Cmd("odo", "init").ShouldFail().Err() + Expect(err).To(ContainSubstring("a devfile already exists in the current directory")) + }) - By("keeping an empty directory when running odo init with wrong starter name", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go", "--starter", "wrongname").ShouldFail() - files := helper.ListFilesInDir(commonVar.Context) - Expect(len(files)).To(Equal(0)) - }) - By("using an invalid devfile name", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "invalid").ShouldFail() - }) - By("running odo init in a directory containing a devfile.yaml", func() { - helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"), filepath.Join(commonVar.Context, "devfile.yaml")) - defer os.Remove(filepath.Join(commonVar.Context, "devfile.yaml")) - err := helper.Cmd("odo", "init").ShouldFail().Err() - Expect(err).To(ContainSubstring("a devfile already exists in the current directory")) - }) + By("running odo init with wrong local file path given to --devfile-path", func() { + err := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "/some/path/devfile.yaml").ShouldFail().Err() + Expect(err).To(ContainSubstring("unable to download devfile")) + }) + By("running odo init with wrong URL path given to --devfile-path", func() { + err := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://github.com/path/to/devfile.yaml").ShouldFail().Err() + Expect(err).To(ContainSubstring("unable to download devfile")) + }) + By("running odo init multiple times", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs").ShouldPass() + defer helper.DeleteFile(filepath.Join(commonVar.Context, "devfile.yaml")) + output := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs").ShouldFail().Err() + Expect(output).To(ContainSubstring("a devfile already exists in the current directory")) + }) - By("running odo init in a directory containing a .devfile.yaml", func() { - helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"), filepath.Join(commonVar.Context, ".devfile.yaml")) - defer helper.DeleteFile(filepath.Join(commonVar.Context, ".devfile.yaml")) - err := helper.Cmd("odo", "init").ShouldFail().Err() - Expect(err).To(ContainSubstring("a devfile already exists in the current directory")) - }) + By("running odo init with --devfile-path and --devfile-registry", func() { + errOut := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://github.com/path/to/devfile.yaml", "--devfile-registry", "DefaultDevfileRegistry").ShouldFail().Err() + Expect(errOut).To(ContainSubstring("--devfile-registry parameter cannot be used with --devfile-path")) + }) + By("running odo init with invalid --devfile-registry value", func() { + fakeRegistry := "fake" + errOut := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://github.com/path/to/devfile.yaml", "--devfile-registry", fakeRegistry).ShouldFail().Err() + Expect(errOut).To(ContainSubstring(fmt.Sprintf("%q not found", fakeRegistry))) + }) + }) - By("running odo init with wrong local file path given to --devfile-path", func() { - err := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "/some/path/devfile.yaml").ShouldFail().Err() - Expect(err).To(ContainSubstring("unable to download devfile")) - }) - By("running odo init with wrong URL path given to --devfile-path", func() { - err := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://github.com/path/to/devfile.yaml").ShouldFail().Err() - Expect(err).To(ContainSubstring("unable to download devfile")) - }) - By("running odo init multiple times", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs").ShouldPass() - defer helper.DeleteFile(filepath.Join(commonVar.Context, "devfile.yaml")) - output := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs").ShouldFail().Err() - Expect(output).To(ContainSubstring("a devfile already exists in the current directory")) - }) + Context("running odo init with valid flags", func() { + When("using --devfile flag", func() { + compName := "aname" + var output string + BeforeEach(func() { + output = helper.Cmd("odo", "init", "--name", compName, "--devfile", "go").ShouldPass().Out() + }) - By("running odo init with --devfile-path and --devfile-registry", func() { - errOut := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://github.com/path/to/devfile.yaml", "--devfile-registry", "DefaultDevfileRegistry").ShouldFail().Err() - Expect(errOut).To(ContainSubstring("--devfile-registry parameter cannot be used with --devfile-path")) - }) - By("running odo init with invalid --devfile-registry value", func() { - fakeRegistry := "fake" - errOut := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://github.com/path/to/devfile.yaml", "--devfile-registry", fakeRegistry).ShouldFail().Err() - Expect(errOut).To(ContainSubstring(fmt.Sprintf("%q not found", fakeRegistry))) - }) - }) - - Context("running odo init with valid flags", func() { - When("using --devfile flag", func() { - compName := "aname" - var output string - BeforeEach(func() { - output = helper.Cmd("odo", "init", "--name", compName, "--devfile", "go").ShouldPass().Out() - }) + It("should download a devfile.yaml file and correctly set the component name in it", func() { + By("not showing the interactive mode notice message", func() { + Expect(output).ShouldNot(ContainSubstring(messages.InteractiveModeEnabled)) + }) + files := helper.ListFilesInDir(commonVar.Context) + Expect(files).To(SatisfyAll( + HaveLen(2), + ContainElements("devfile.yaml", util.DotOdoDirectory))) + metadata := helper.GetMetadataFromDevfile(filepath.Join(commonVar.Context, "devfile.yaml")) + Expect(metadata.Name).To(BeEquivalentTo(compName)) + }) + }) + When("using --devfile flag and JSON output", func() { + compName := "aname" + var res *helper.CmdWrapper + BeforeEach(func() { + res = helper.Cmd("odo", "init", "--name", compName, "--devfile", "go", "-o", "json").ShouldPass() + }) - It("should download a devfile.yaml file and correctly set the component name in it", func() { - By("not showing the interactive mode notice message", func() { - Expect(output).ShouldNot(ContainSubstring(messages.InteractiveModeEnabled)) + It("should return correct values in output", func() { + stdout, stderr := res.Out(), res.Err() + Expect(stderr).To(BeEmpty()) + Expect(helper.IsJSON(stdout)).To(BeTrue()) + helper.JsonPathContentIs(stdout, "devfilePath", filepath.Join(commonVar.Context, "devfile.yaml")) + helper.JsonPathContentIs(stdout, "devfileData.devfile.metadata.name", compName) + helper.JsonPathContentIs(stdout, "devfileData.supportedOdoFeatures.dev", "true") + helper.JsonPathContentIs(stdout, "devfileData.supportedOdoFeatures.debug", "false") + helper.JsonPathContentIs(stdout, "devfileData.supportedOdoFeatures.deploy", "false") + helper.JsonPathContentIs(stdout, "managedBy", "odo") + }) }) - files := helper.ListFilesInDir(commonVar.Context) - Expect(files).To(SatisfyAll( - HaveLen(2), - ContainElements("devfile.yaml", util.DotOdoDirectory))) - metadata := helper.GetMetadataFromDevfile(filepath.Join(commonVar.Context, "devfile.yaml")) - Expect(metadata.Name).To(BeEquivalentTo(compName)) - }) - }) - When("using --devfile flag and JSON output", func() { - compName := "aname" - var res *helper.CmdWrapper - BeforeEach(func() { - res = helper.Cmd("odo", "init", "--name", compName, "--devfile", "go", "-o", "json").ShouldPass() - }) + When("using --devfile-path flag with a local devfile", func() { + var newContext string + BeforeEach(func() { + newContext = helper.CreateNewContext() + newDevfilePath := filepath.Join(newContext, "devfile.yaml") + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"), newDevfilePath) + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", newDevfilePath).ShouldPass() + }) + AfterEach(func() { + helper.DeleteDir(newContext) + }) + It("should copy the devfile.yaml file", func() { + files := helper.ListFilesInDir(commonVar.Context) + Expect(files).To(SatisfyAll( + HaveLen(2), + ContainElements(util.DotOdoDirectory, "devfile.yaml"))) + }) + }) + When("using --devfile-path flag with a URL", func() { + BeforeEach(func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://raw.githubusercontent.com/odo-devfiles/registry/master/devfiles/nodejs/devfile.yaml").ShouldPass() + }) + It("should copy the devfile.yaml file", func() { + files := helper.ListFilesInDir(commonVar.Context) + Expect(files).To(SatisfyAll( + HaveLen(2), + ContainElements("devfile.yaml", util.DotOdoDirectory))) + }) + }) + When("using --devfile-registry flag", func() { + It("should successfully run odo init if specified registry is valid", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go", "--devfile-registry", "DefaultDevfileRegistry").ShouldPass() + }) - It("should return correct values in output", func() { - stdout, stderr := res.Out(), res.Err() - Expect(stderr).To(BeEmpty()) - Expect(helper.IsJSON(stdout)).To(BeTrue()) - helper.JsonPathContentIs(stdout, "devfilePath", filepath.Join(commonVar.Context, "devfile.yaml")) - helper.JsonPathContentIs(stdout, "devfileData.devfile.metadata.name", compName) - helper.JsonPathContentIs(stdout, "devfileData.supportedOdoFeatures.dev", "true") - helper.JsonPathContentIs(stdout, "devfileData.supportedOdoFeatures.debug", "false") - helper.JsonPathContentIs(stdout, "devfileData.supportedOdoFeatures.deploy", "false") - helper.JsonPathContentIs(stdout, "managedBy", "odo") - }) - }) - When("using --devfile-path flag with a local devfile", func() { - var newContext string - BeforeEach(func() { - newContext = helper.CreateNewContext() - newDevfilePath := filepath.Join(newContext, "devfile.yaml") - helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-registry.yaml"), newDevfilePath) - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", newDevfilePath).ShouldPass() - }) - AfterEach(func() { - helper.DeleteDir(newContext) - }) - It("should copy the devfile.yaml file", func() { - files := helper.ListFilesInDir(commonVar.Context) - Expect(files).To(SatisfyAll( - HaveLen(2), - ContainElements(util.DotOdoDirectory, "devfile.yaml"))) - }) - }) - When("using --devfile-path flag with a URL", func() { - BeforeEach(func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", "https://raw.githubusercontent.com/odo-devfiles/registry/master/devfiles/nodejs/devfile.yaml").ShouldPass() - }) - It("should copy the devfile.yaml file", func() { - files := helper.ListFilesInDir(commonVar.Context) - Expect(files).To(SatisfyAll( - HaveLen(2), - ContainElements("devfile.yaml", util.DotOdoDirectory))) + }) }) - }) - When("using --devfile-registry flag", func() { - It("should successfully run odo init if specified registry is valid", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go", "--devfile-registry", "DefaultDevfileRegistry").ShouldPass() + When("a dangling env file exists in the working directory", func() { + BeforeEach(func() { + helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) + }) + It("should successfully create a devfile component and remove the dangling env file", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go").ShouldPass() + }) }) - }) - }) - When("a dangling env file exists in the working directory", func() { - BeforeEach(func() { - helper.CreateLocalEnv(commonVar.Context, "aname", commonVar.Project) - }) - It("should successfully create a devfile component and remove the dangling env file", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go").ShouldPass() - }) - }) - - When("a devfile is provided which has a starter that has its own devfile", func() { - BeforeEach(func() { - helper.Cmd("odo", "init", "--name", "aname", "--starter", "nodejs-starter", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-starter-with-devfile.yaml")).ShouldPass() - }) - It("should pass and keep the devfile in starter", func() { - devfileContent, err := helper.ReadFile(filepath.Join(commonVar.Context, "devfile.yaml")) - Expect(err).To(Not(HaveOccurred())) - helper.MatchAllInOutput(devfileContent, []string{"2.2.0", "kubernetes-deploy", "deployk8s", "image-build"}) - }) - }) - - When("running odo init with a devfile that has a subDir starter project", func() { - BeforeEach(func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "springboot", "devfile-with-subDir.yaml"), "--starter", "springbootproject").ShouldPass() - }) - - It("should successfully extract the project in the specified subDir path", func() { - var found, notToBeFound int - pathsToValidate := map[string]bool{ - filepath.Join(commonVar.Context, "java", "com"): true, - filepath.Join(commonVar.Context, "java", "com", "example"): true, - filepath.Join(commonVar.Context, "java", "com", "example", "demo"): true, - filepath.Join(commonVar.Context, "java", "com", "example", "demo", "DemoApplication.java"): true, - filepath.Join(commonVar.Context, "resources", "application.properties"): true, - } - pathsNotToBePresent := map[string]bool{ - filepath.Join(commonVar.Context, "src"): true, - filepath.Join(commonVar.Context, "main"): true, - } - err := filepath.Walk(commonVar.Context, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if ok := pathsToValidate[path]; ok { - found++ - } - if ok := pathsNotToBePresent[path]; ok { - notToBeFound++ - } - return nil + When("a devfile is provided which has a starter that has its own devfile", func() { + BeforeEach(func() { + helper.Cmd("odo", "init", "--name", "aname", "--starter", "nodejs-starter", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-starter-with-devfile.yaml")).ShouldPass() + }) + It("should pass and keep the devfile in starter", func() { + devfileContent, err := helper.ReadFile(filepath.Join(commonVar.Context, "devfile.yaml")) + Expect(err).To(Not(HaveOccurred())) + helper.MatchAllInOutput(devfileContent, []string{"2.2.0", "kubernetes-deploy", "deployk8s", "image-build"}) + }) }) - Expect(err).To(BeNil()) - Expect(found).To(Equal(len(pathsToValidate))) - Expect(notToBeFound).To(Equal(0)) - }) - }) - - It("should successfully run odo init for devfile with starter project from the specified branch", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-branch.yaml"), "--starter", "nodejs-starter").ShouldPass() - expectedFiles := []string{"package.json", "package-lock.json", "README.md", "devfile.yaml", "test"} - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements(expectedFiles)) - }) - - It("should successfully run odo init for devfile with starter project from the specified tag", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-tag.yaml"), "--starter", "nodejs-starter").ShouldPass() - expectedFiles := []string{"package.json", "package-lock.json", "README.md", "devfile.yaml", "app"} - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements(expectedFiles)) - }) - - It("should successfully run odo init for devfile with starter project on git with main default branch", func() { - helper.Cmd("odo", "init", - "--name", "vertx", - "--devfile-path", helper.GetExamplePath("source", "devfiles", "java", "devfile-with-git-main-branch.yaml"), - "--starter", "vertx-http-example-redhat", - ).ShouldPass() - }) - - When("running odo init from a directory with sources", func() { - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - }) - It("should work without --starter flag", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs").ShouldPass() - }) - It("should not accept --starter flag", func() { - err := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs", "--starter", "nodejs-starter").ShouldFail().Err() - Expect(err).To(ContainSubstring("--starter parameter cannot be used when the directory is not empty")) - }) - }) - Context("checking odo init final output message", func() { - var newContext, devfilePath string + When("running odo init with a devfile that has a subDir starter project", func() { + BeforeEach(func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "springboot", "devfile-with-subDir.yaml"), "--starter", "springbootproject").ShouldPass() + }) - BeforeEach(func() { - newContext = helper.CreateNewContext() - devfilePath = filepath.Join(newContext, "devfile.yaml") - }) + It("should successfully extract the project in the specified subDir path", func() { + var found, notToBeFound int + pathsToValidate := map[string]bool{ + filepath.Join(commonVar.Context, "java", "com"): true, + filepath.Join(commonVar.Context, "java", "com", "example"): true, + filepath.Join(commonVar.Context, "java", "com", "example", "demo"): true, + filepath.Join(commonVar.Context, "java", "com", "example", "demo", "DemoApplication.java"): true, + filepath.Join(commonVar.Context, "resources", "application.properties"): true, + } + pathsNotToBePresent := map[string]bool{ + filepath.Join(commonVar.Context, "src"): true, + filepath.Join(commonVar.Context, "main"): true, + } + err := filepath.Walk(commonVar.Context, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if ok := pathsToValidate[path]; ok { + found++ + } + if ok := pathsNotToBePresent[path]; ok { + notToBeFound++ + } + return nil + }) + Expect(err).To(BeNil()) - AfterEach(func() { - helper.DeleteDir(newContext) - }) + Expect(found).To(Equal(len(pathsToValidate))) + Expect(notToBeFound).To(Equal(0)) + }) + }) - When("the devfile used by `odo init` does not contain a deploy command", func() { - var out string + It("should successfully run odo init for devfile with starter project from the specified branch", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-branch.yaml"), "--starter", "nodejs-starter").ShouldPass() + expectedFiles := []string{"package.json", "package-lock.json", "README.md", "devfile.yaml", "test"} + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements(expectedFiles)) + }) - BeforeEach(func() { - helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), devfilePath) - out = helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", devfilePath).ShouldPass().Out() + It("should successfully run odo init for devfile with starter project from the specified tag", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-tag.yaml"), "--starter", "nodejs-starter").ShouldPass() + expectedFiles := []string{"package.json", "package-lock.json", "README.md", "devfile.yaml", "app"} + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements(expectedFiles)) }) - It("should only show information about `odo dev`, and not `odo deploy`", func() { - Expect(out).To(ContainSubstring("odo dev")) - Expect(out).ToNot(ContainSubstring("odo deploy")) + It("should successfully run odo init for devfile with starter project on git with main default branch", func() { + helper.Cmd("odo", "init", + "--name", "vertx", + "--devfile-path", helper.GetExamplePath("source", "devfiles", "java", "devfile-with-git-main-branch.yaml"), + "--starter", "vertx-http-example-redhat", + ).ShouldPass() }) - It("should not show the interactive mode notice message", func() { - Expect(out).ShouldNot(ContainSubstring(messages.InteractiveModeEnabled)) + When("running odo init from a directory with sources", func() { + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + }) + It("should work without --starter flag", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs").ShouldPass() + }) + It("should not accept --starter flag", func() { + err := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs", "--starter", "nodejs-starter").ShouldFail().Err() + Expect(err).To(ContainSubstring("--starter parameter cannot be used when the directory is not empty")) + }) }) - }) + Context("checking odo init final output message", func() { + var newContext, devfilePath string - When("the devfile used by `odo init` contains a deploy command", func() { - var out string + BeforeEach(func() { + newContext = helper.CreateNewContext() + devfilePath = filepath.Join(newContext, "devfile.yaml") + }) - BeforeEach(func() { - helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-deploy.yaml"), devfilePath) - out = helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", devfilePath).ShouldPass().Out() - }) + AfterEach(func() { + helper.DeleteDir(newContext) + }) - It("should show information about both `odo dev`, and `odo deploy`", func() { - Expect(out).To(ContainSubstring("odo dev")) - Expect(out).To(ContainSubstring("odo deploy")) - }) + When("the devfile used by `odo init` does not contain a deploy command", func() { + var out string - It("should not show the interactive mode notice message", func() { - Expect(out).ShouldNot(ContainSubstring(messages.InteractiveModeEnabled)) - }) - }) - }) - - When("devfile contains parent URI", func() { - var originalKeyList []string - var srcDevfile string - - BeforeEach(func() { - var err error - srcDevfile = helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-parent.yaml") - originalDevfileContent, err := ioutil.ReadFile(srcDevfile) - Expect(err).To(BeNil()) - var content map[string]interface{} - Expect(yaml.Unmarshal(originalDevfileContent, &content)).To(BeNil()) - for k := range content { - originalKeyList = append(originalKeyList, k) - } - }) + BeforeEach(func() { + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile.yaml"), devfilePath) + out = helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", devfilePath).ShouldPass().Out() + }) - It("should not replace the original devfile", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", srcDevfile).ShouldPass() - devfileContent, err := ioutil.ReadFile(filepath.Join(commonVar.Context, "devfile.yaml")) - Expect(err).To(BeNil()) - var content map[string]interface{} - Expect(yaml.Unmarshal(devfileContent, &content)).To(BeNil()) - for k := range content { - Expect(k).To(BeElementOf(originalKeyList)) - } - }) - }) + It("should only show information about `odo dev`, and not `odo deploy`", func() { + Expect(out).To(ContainSubstring("odo dev")) + Expect(out).ToNot(ContainSubstring("odo deploy")) + }) - When("source directory is empty", func() { - BeforeEach(func() { - Expect(helper.ListFilesInDir(commonVar.Context)).To(HaveLen(0)) - }) + It("should not show the interactive mode notice message", func() { + Expect(out).ShouldNot(ContainSubstring(messages.InteractiveModeEnabled)) + }) + }) - It("name in devfile is personalized in non-interactive mode", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", - filepath.Join(helper.GetExamplePath(), "source", "devfiles", "nodejs", - "devfile-with-starter-with-devfile.yaml")).ShouldPass() + When("the devfile used by `odo init` contains a deploy command", func() { + var out string - metadata := helper.GetMetadataFromDevfile(filepath.Join(commonVar.Context, "devfile.yaml")) - Expect(metadata.Name).To(BeEquivalentTo("aname")) - Expect(metadata.Language).To(BeEquivalentTo("nodejs")) - }) - }) - - Describe("telemetry", func() { - - for _, tt := range []struct { - name string - env map[string]string - }{ - { - name: "ODO_DISABLE_TELEMETRY=true and ODO_TRACKING_CONSENT=yes", - env: map[string]string{ - //lint:ignore SA1019 We deprecated this env var, but until it is removed, we still want to test it - segment.DisableTelemetryEnv: "true", - segment.TrackingConsentEnv: "yes", - }, - }, - { - name: "ODO_DISABLE_TELEMETRY=false and ODO_TRACKING_CONSENT=no", - env: map[string]string{ - //lint:ignore SA1019 We deprecated this env var, but until it is removed, we still want to test it - segment.DisableTelemetryEnv: "false", - segment.TrackingConsentEnv: "no", - }, - }, - } { - tt := tt - It("should error out if "+tt.name, func() { - cmd := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go") - for k, v := range tt.env { - cmd = cmd.AddEnv(fmt.Sprintf("%s=%s", k, v)) - } - stderr := cmd.ShouldFail().Err() + BeforeEach(func() { + helper.CopyExampleDevFile(filepath.Join("source", "devfiles", "nodejs", "devfile-deploy.yaml"), devfilePath) + out = helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", devfilePath).ShouldPass().Out() + }) - //lint:ignore SA1019 We deprecated this env var, but until it is removed, we still want to test it - Expect(stderr).To(ContainSubstring("%s and %s values are in conflict.", segment.DisableTelemetryEnv, segment.TrackingConsentEnv)) - }) - } - - type telemetryTest struct { - title string - env map[string]string - setupFunc func(cfg preference.Client) - callerChecker func(stdout, stderr string, data segment.TelemetryData) - } - allowedTelemetryCallers := []string{segmentContext.VSCode, segmentContext.IntelliJ, segmentContext.JBoss} - telemetryTests := []telemetryTest{ - { - title: "no caller env var", - callerChecker: func(_, _ string, td segment.TelemetryData) { - cmdProperties := td.Properties.CmdProperties - Expect(cmdProperties).Should(HaveKey(segmentContext.Caller)) - Expect(cmdProperties[segmentContext.Caller]).To(BeEmpty()) - }, - }, - { - title: "empty caller env var", - env: map[string]string{ - helper.TelemetryCaller: "", - }, - callerChecker: func(_, _ string, td segment.TelemetryData) { - cmdProperties := td.Properties.CmdProperties - Expect(cmdProperties).Should(HaveKey(segmentContext.Caller)) - Expect(cmdProperties[segmentContext.Caller]).To(BeEmpty()) - }, - }, - { - title: "invalid caller env var", - env: map[string]string{ - helper.TelemetryCaller: "an-invalid-caller", - }, - callerChecker: func(stdout, stderr string, td segment.TelemetryData) { - By("not disclosing list of allowed values", func() { - helper.DontMatchAllInOutput(stdout, allowedTelemetryCallers) - helper.DontMatchAllInOutput(stderr, allowedTelemetryCallers) + It("should show information about both `odo dev`, and `odo deploy`", func() { + Expect(out).To(ContainSubstring("odo dev")) + Expect(out).To(ContainSubstring("odo deploy")) }) - By("setting the value as caller property in telemetry even if it is invalid", func() { - Expect(td.Properties.CmdProperties[segmentContext.Caller]).To(Equal("an-invalid-caller")) + It("should not show the interactive mode notice message", func() { + Expect(out).ShouldNot(ContainSubstring(messages.InteractiveModeEnabled)) }) - }, - }, - { - title: "ODO_TRACKING_CONSENT=yes env var should take precedence over ConsentTelemetry preference", - env: map[string]string{segment.TrackingConsentEnv: "yes"}, - callerChecker: func(_, _ string, td segment.TelemetryData) { - cmdProperties := td.Properties.CmdProperties - Expect(cmdProperties).Should(HaveKey(segmentContext.Caller)) - Expect(cmdProperties[segmentContext.Caller]).To(BeEmpty()) - }, - setupFunc: func(cfg preference.Client) { - err := cfg.SetConfiguration(preference.ConsentTelemetrySetting, "false") - Expect(err).ShouldNot(HaveOccurred()) - }, - }, - } - for _, c := range allowedTelemetryCallers { - c := c - telemetryTests = append(telemetryTests, telemetryTest{ - title: fmt.Sprintf("valid caller env var: %s", c), - env: map[string]string{ - helper.TelemetryCaller: c, - }, - callerChecker: func(_, _ string, td segment.TelemetryData) { - Expect(td.Properties.CmdProperties[segmentContext.Caller]).To(Equal(c)) - }, + }) }) - } - for _, tt := range telemetryTests { - tt := tt - When("recording telemetry data with "+tt.title, func() { - var stdout string - var stderr string - BeforeEach(func() { - helper.EnableTelemetryDebug() - ctx := context.Background() - envConfig, err := config.GetConfiguration() - Expect(err).To(BeNil()) - ctx = envcontext.WithEnvConfig(ctx, *envConfig) + When("devfile contains parent URI", func() { + var originalKeyList []string + var srcDevfile string - cfg, err := preference.NewClient(ctx) - Expect(err).ShouldNot(HaveOccurred()) - if tt.setupFunc != nil { - tt.setupFunc(cfg) + BeforeEach(func() { + var err error + srcDevfile = helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-parent.yaml") + originalDevfileContent, err := ioutil.ReadFile(srcDevfile) + Expect(err).To(BeNil()) + var content map[string]interface{} + Expect(yaml.Unmarshal(originalDevfileContent, &content)).To(BeNil()) + for k := range content { + originalKeyList = append(originalKeyList, k) } + }) - cmd := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go") - for k, v := range tt.env { - cmd = cmd.AddEnv(fmt.Sprintf("%s=%s", k, v)) + It("should not replace the original devfile", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", srcDevfile).ShouldPass() + devfileContent, err := ioutil.ReadFile(filepath.Join(commonVar.Context, "devfile.yaml")) + Expect(err).To(BeNil()) + var content map[string]interface{} + Expect(yaml.Unmarshal(devfileContent, &content)).To(BeNil()) + for k := range content { + Expect(k).To(BeElementOf(originalKeyList)) } - stdout, stderr = cmd.ShouldPass().OutAndErr() }) + }) - AfterEach(func() { - helper.ResetTelemetry() + When("source directory is empty", func() { + BeforeEach(func() { + Expect(helper.ListFilesInDir(commonVar.Context)).To(HaveLen(0)) }) - It("should record the telemetry data correctly", func() { - td := helper.GetTelemetryDebugData() - Expect(td.Event).To(ContainSubstring("odo init")) - Expect(td.Properties.Success).To(BeTrue()) - Expect(td.Properties.Error == "").To(BeTrue()) - Expect(td.Properties.ErrorType == "").To(BeTrue()) - Expect(td.Properties.CmdProperties[segmentContext.DevfileName]).To(ContainSubstring("aname")) - Expect(td.Properties.CmdProperties[segmentContext.ComponentType]).To(ContainSubstring("Go")) - Expect(td.Properties.CmdProperties[segmentContext.Language]).To(ContainSubstring("Go")) - Expect(td.Properties.CmdProperties[segmentContext.ProjectType]).To(ContainSubstring("Go")) - Expect(td.Properties.CmdProperties[segmentContext.Flags]).To(ContainSubstring("devfile name")) - tt.callerChecker(stdout, stderr, td) + It("name in devfile is personalized in non-interactive mode", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", + filepath.Join(helper.GetExamplePath(), "source", "devfiles", "nodejs", + "devfile-with-starter-with-devfile.yaml")).ShouldPass() + + metadata := helper.GetMetadataFromDevfile(filepath.Join(commonVar.Context, "devfile.yaml")) + Expect(metadata.Name).To(BeEquivalentTo("aname")) + Expect(metadata.Language).To(BeEquivalentTo("nodejs")) }) + }) + + Describe("telemetry", func() { + + for _, tt := range []struct { + name string + env map[string]string + }{ + { + name: "ODO_DISABLE_TELEMETRY=true and ODO_TRACKING_CONSENT=yes", + env: map[string]string{ + //lint:ignore SA1019 We deprecated this env var, but until it is removed, we still want to test it + segment.DisableTelemetryEnv: "true", + segment.TrackingConsentEnv: "yes", + }, + }, + { + name: "ODO_DISABLE_TELEMETRY=false and ODO_TRACKING_CONSENT=no", + env: map[string]string{ + //lint:ignore SA1019 We deprecated this env var, but until it is removed, we still want to test it + segment.DisableTelemetryEnv: "false", + segment.TrackingConsentEnv: "no", + }, + }, + } { + tt := tt + It("should error out if "+tt.name, func() { + cmd := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go") + for k, v := range tt.env { + cmd = cmd.AddEnv(fmt.Sprintf("%s=%s", k, v)) + } + stderr := cmd.ShouldFail().Err() + + //lint:ignore SA1019 We deprecated this env var, but until it is removed, we still want to test it + Expect(stderr).To(ContainSubstring("%s and %s values are in conflict.", segment.DisableTelemetryEnv, segment.TrackingConsentEnv)) + }) + } + type telemetryTest struct { + title string + env map[string]string + setupFunc func(cfg preference.Client) + callerChecker func(stdout, stderr string, data segment.TelemetryData) + } + allowedTelemetryCallers := []string{segmentContext.VSCode, segmentContext.IntelliJ, segmentContext.JBoss} + telemetryTests := []telemetryTest{ + { + title: "no caller env var", + callerChecker: func(_, _ string, td segment.TelemetryData) { + cmdProperties := td.Properties.CmdProperties + Expect(cmdProperties).Should(HaveKey(segmentContext.Caller)) + Expect(cmdProperties[segmentContext.Caller]).To(BeEmpty()) + }, + }, + { + title: "empty caller env var", + env: map[string]string{ + helper.TelemetryCaller: "", + }, + callerChecker: func(_, _ string, td segment.TelemetryData) { + cmdProperties := td.Properties.CmdProperties + Expect(cmdProperties).Should(HaveKey(segmentContext.Caller)) + Expect(cmdProperties[segmentContext.Caller]).To(BeEmpty()) + }, + }, + { + title: "invalid caller env var", + env: map[string]string{ + helper.TelemetryCaller: "an-invalid-caller", + }, + callerChecker: func(stdout, stderr string, td segment.TelemetryData) { + By("not disclosing list of allowed values", func() { + helper.DontMatchAllInOutput(stdout, allowedTelemetryCallers) + helper.DontMatchAllInOutput(stderr, allowedTelemetryCallers) + }) + + By("setting the value as caller property in telemetry even if it is invalid", func() { + Expect(td.Properties.CmdProperties[segmentContext.Caller]).To(Equal("an-invalid-caller")) + }) + }, + }, + { + title: "ODO_TRACKING_CONSENT=yes env var should take precedence over ConsentTelemetry preference", + env: map[string]string{segment.TrackingConsentEnv: "yes"}, + callerChecker: func(_, _ string, td segment.TelemetryData) { + cmdProperties := td.Properties.CmdProperties + Expect(cmdProperties).Should(HaveKey(segmentContext.Caller)) + Expect(cmdProperties[segmentContext.Caller]).To(BeEmpty()) + }, + setupFunc: func(cfg preference.Client) { + err := cfg.SetConfiguration(preference.ConsentTelemetrySetting, "false") + Expect(err).ShouldNot(HaveOccurred()) + }, + }, + } + for _, c := range allowedTelemetryCallers { + c := c + telemetryTests = append(telemetryTests, telemetryTest{ + title: fmt.Sprintf("valid caller env var: %s", c), + env: map[string]string{ + helper.TelemetryCaller: c, + }, + callerChecker: func(_, _ string, td segment.TelemetryData) { + Expect(td.Properties.CmdProperties[segmentContext.Caller]).To(Equal(c)) + }, + }) + } + for _, tt := range telemetryTests { + tt := tt + When("recording telemetry data with "+tt.title, func() { + var stdout string + var stderr string + BeforeEach(func() { + helper.EnableTelemetryDebug() + + ctx := context.Background() + envConfig, err := config.GetConfiguration() + Expect(err).To(BeNil()) + ctx = envcontext.WithEnvConfig(ctx, *envConfig) + + cfg, err := preference.NewClient(ctx) + Expect(err).ShouldNot(HaveOccurred()) + if tt.setupFunc != nil { + tt.setupFunc(cfg) + } + + cmd := helper.Cmd("odo", "init", "--name", "aname", "--devfile", "go") + for k, v := range tt.env { + cmd = cmd.AddEnv(fmt.Sprintf("%s=%s", k, v)) + } + stdout, stderr = cmd.ShouldPass().OutAndErr() + }) + + AfterEach(func() { + helper.ResetTelemetry() + }) + + It("should record the telemetry data correctly", func() { + td := helper.GetTelemetryDebugData() + Expect(td.Event).To(ContainSubstring("odo init")) + Expect(td.Properties.Success).To(BeTrue()) + Expect(td.Properties.Error == "").To(BeTrue()) + Expect(td.Properties.ErrorType == "").To(BeTrue()) + Expect(td.Properties.CmdProperties[segmentContext.DevfileName]).To(ContainSubstring("aname")) + Expect(td.Properties.CmdProperties[segmentContext.ComponentType]).To(ContainSubstring("Go")) + Expect(td.Properties.CmdProperties[segmentContext.Language]).To(ContainSubstring("Go")) + Expect(td.Properties.CmdProperties[segmentContext.ProjectType]).To(ContainSubstring("Go")) + Expect(td.Properties.CmdProperties[segmentContext.Flags]).To(ContainSubstring("devfile name")) + tt.callerChecker(stdout, stderr, td) + }) + + }) + } }) - } - }) + }) + } }) diff --git a/tests/integration/cmd_devfile_list_test.go b/tests/integration/cmd_devfile_list_test.go index 774a511e6ae..d1fdd3dd6dc 100644 --- a/tests/integration/cmd_devfile_list_test.go +++ b/tests/integration/cmd_devfile_list_test.go @@ -104,6 +104,27 @@ var _ = Describe("odo list with devfile", func() { helper.Chdir(commonVar.Context) }) + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + It("should list the local component when no authenticated", Label(label), func() { + By("checking the normal output", func() { + stdOut := helper.Cmd("odo", "list", "component").ShouldPass().Out() + Expect(stdOut).To(ContainSubstring(componentName)) + }) + + By("checking the JSON output", func() { + res := helper.Cmd("odo", "list", "component", "-o", "json").ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(helper.IsJSON(stdout)).To(BeTrue()) + Expect(stderr).To(BeEmpty()) + helper.JsonPathContentIs(stdout, "componentInDevfile", componentName) + helper.JsonPathContentIs(stdout, "components.0.name", componentName) + }) + }) + } + When("dev is running on cluster", func() { BeforeEach(func() { var err error @@ -314,6 +335,11 @@ var _ = Describe("odo list with devfile", func() { It("should show the language for 'Type' in odo list", Label(helper.LabelNoCluster), func() { checkList(metadata.Language) }) + + It("should show the language for 'Type' in odo list", Label(helper.LabelUnauth), func() { + checkList(metadata.Language) + }) + When("the component is pushed in dev mode", func() { var devSession helper.DevSession BeforeEach(func() { @@ -341,6 +367,9 @@ var _ = Describe("odo list with devfile", func() { It("should show 'Not available' for 'Type' in odo list", Label(helper.LabelNoCluster), func() { checkList("Not available") }) + It("should show 'Not available' for 'Type' in odo list", Label(helper.LabelUnauth), func() { + checkList("Not available") + }) When("the component is pushed", func() { var devSession helper.DevSession BeforeEach(func() { diff --git a/tests/integration/cmd_devfile_registry_test.go b/tests/integration/cmd_devfile_registry_test.go index 87ae9848384..cdca960885f 100644 --- a/tests/integration/cmd_devfile_registry_test.go +++ b/tests/integration/cmd_devfile_registry_test.go @@ -9,139 +9,146 @@ import ( "github.com/redhat-developer/odo/tests/helper" ) -var _ = Describe("odo devfile registry command tests", Label(helper.LabelNoCluster), func() { - const registryName string = "RegistryName" - - // Use staging OCI-based registry for tests to avoid overload - var addRegistryURL string = "https://registry.stage.devfile.io" - proxy := os.Getenv("DEVFILE_PROXY") - if proxy != "" { - addRegistryURL = "http://" + proxy - } - - var commonVar helper.CommonVar - - // This is run before every Spec (It) - var _ = BeforeEach(func() { - commonVar = helper.CommonBeforeEach() - helper.Chdir(commonVar.Context) - }) - - // This is run after every Spec (It) - var _ = AfterEach(func() { - helper.CommonAfterEach(commonVar) - }) - - It("Should list all default registries", func() { - output := helper.Cmd("odo", "preference", "view").ShouldPass().Out() - helper.MatchAllInOutput(output, []string{"DefaultDevfileRegistry"}) - }) - - It("Should list at least one nodejs component from the default registry", func() { - output := helper.Cmd("odo", "registry").ShouldPass().Out() - helper.MatchAllInOutput(output, []string{"nodejs"}) - }) - - It("Should list detailed information regarding nodejs", func() { - args := []string{"registry", "--details", "--devfile", "nodejs", "--devfile-registry", "DefaultDevfileRegistry"} - - By("using human readable output", func() { - output := helper.Cmd("odo", args...).ShouldPass().Out() - helper.MatchAllInOutput(output, []string{"nodejs-starter", "JavaScript", "Node.js Runtime", "Dev: Y"}) - }) - By("using JSON output", func() { - args = append(args, "-o", "json") - res := helper.Cmd("odo", args...).ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(stderr).To(BeEmpty()) - Expect(helper.IsJSON(stdout)).To(BeTrue()) - helper.JsonPathContentIs(stdout, "0.name", "nodejs") - helper.JsonPathContentContain(stdout, "0.displayName", "Node") - helper.JsonPathContentContain(stdout, "0.description", "Node") - helper.JsonPathContentContain(stdout, "0.language", "JavaScript") - helper.JsonPathContentContain(stdout, "0.projectType", "Node.js") - helper.JsonPathContentContain(stdout, "0.starterProjects.0", "nodejs-starter") - helper.JsonPathContentContain(stdout, "0.devfileData.devfile.metadata.name", "nodejs") - helper.JsonPathContentContain(stdout, "0.devfileData.supportedOdoFeatures.dev", "true") - }) - }) - - It("Should list python specifically", func() { - args := []string{"registry", "--devfile", "python", "--devfile-registry", "DefaultDevfileRegistry"} - By("using human readable output", func() { - output := helper.Cmd("odo", args...).ShouldPass().Out() - helper.MatchAllInOutput(output, []string{"python"}) - }) - By("using JSON output", func() { - args = append(args, "-o", "json") - res := helper.Cmd("odo", args...).ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(stderr).To(BeEmpty()) - Expect(helper.IsJSON(stdout)).To(BeTrue()) - helper.JsonPathContentIs(stdout, "0.name", "python") - helper.JsonPathContentContain(stdout, "0.displayName", "Python") - helper.JsonPathContentContain(stdout, "0.description", "Python is an interpreted") - helper.JsonPathContentContain(stdout, "0.language", "Python") - helper.JsonPathContentContain(stdout, "0.projectType", "Python") - helper.JsonPathContentContain(stdout, "0.starterProjects.0", "flask-example") - helper.JsonPathContentContain(stdout, "0.devfileData", "") - - }) - }) - - It("Should fail with an error with no registries", func() { - helper.Cmd("odo", "preference", "remove", "registry", "DefaultDevfileRegistry", "-f").ShouldPass() - output := helper.Cmd("odo", "preference", "view").ShouldRun().Err() - helper.MatchAllInOutput(output, []string{"No devfile registries added to the configuration. Refer to `odo preference add registry -h` to add one"}) - }) +var _ = Describe("odo devfile registry command tests", func() { + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + var _ = Context("label "+label, Label(label), func() { + + const registryName string = "RegistryName" + + // Use staging OCI-based registry for tests to avoid overload + var addRegistryURL string = "https://registry.stage.devfile.io" + proxy := os.Getenv("DEVFILE_PROXY") + if proxy != "" { + addRegistryURL = "http://" + proxy + } + + var commonVar helper.CommonVar + + // This is run before every Spec (It) + var _ = BeforeEach(func() { + commonVar = helper.CommonBeforeEach() + helper.Chdir(commonVar.Context) + }) - It("Should fail to delete the registry, when registry is not present", func() { - helper.Cmd("odo", "preference", "remove", "registry", registryName, "-f").ShouldFail() - }) + // This is run after every Spec (It) + var _ = AfterEach(func() { + helper.CommonAfterEach(commonVar) + }) - When("adding a registry", func() { - BeforeEach(func() { - helper.Cmd("odo", "preference", "add", "registry", registryName, addRegistryURL).ShouldPass() - }) + It("Should list all default registries", func() { + output := helper.Cmd("odo", "preference", "view").ShouldPass().Out() + helper.MatchAllInOutput(output, []string{"DefaultDevfileRegistry"}) + }) - It("should list newly added registry", func() { - output := helper.Cmd("odo", "preference", "view").ShouldPass().Out() - helper.MatchAllInOutput(output, []string{registryName, addRegistryURL}) - }) + It("Should list at least one nodejs component from the default registry", func() { + output := helper.Cmd("odo", "registry").ShouldPass().Out() + helper.MatchAllInOutput(output, []string{"nodejs"}) + }) - It("should pass, when doing odo init with --devfile-registry flag", func() { - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs", "--devfile-registry", registryName).ShouldPass() - }) + It("Should list detailed information regarding nodejs", func() { + args := []string{"registry", "--details", "--devfile", "nodejs", "--devfile-registry", "DefaultDevfileRegistry"} + + By("using human readable output", func() { + output := helper.Cmd("odo", args...).ShouldPass().Out() + helper.MatchAllInOutput(output, []string{"nodejs-starter", "JavaScript", "Node.js Runtime", "Dev: Y"}) + }) + By("using JSON output", func() { + args = append(args, "-o", "json") + res := helper.Cmd("odo", args...).ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(stderr).To(BeEmpty()) + Expect(helper.IsJSON(stdout)).To(BeTrue()) + helper.JsonPathContentIs(stdout, "0.name", "nodejs") + helper.JsonPathContentContain(stdout, "0.displayName", "Node") + helper.JsonPathContentContain(stdout, "0.description", "Node") + helper.JsonPathContentContain(stdout, "0.language", "JavaScript") + helper.JsonPathContentContain(stdout, "0.projectType", "Node.js") + helper.JsonPathContentContain(stdout, "0.starterProjects.0", "nodejs-starter") + helper.JsonPathContentContain(stdout, "0.devfileData.devfile.metadata.name", "nodejs") + helper.JsonPathContentContain(stdout, "0.devfileData.supportedOdoFeatures.dev", "true") + }) + }) - It("should fail, when adding same registry", func() { - helper.Cmd("odo", "preference", "add", "registry", registryName, addRegistryURL).ShouldFail() - }) + It("Should list python specifically", func() { + args := []string{"registry", "--devfile", "python", "--devfile-registry", "DefaultDevfileRegistry"} + By("using human readable output", func() { + output := helper.Cmd("odo", args...).ShouldPass().Out() + helper.MatchAllInOutput(output, []string{"python"}) + }) + By("using JSON output", func() { + args = append(args, "-o", "json") + res := helper.Cmd("odo", args...).ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(stderr).To(BeEmpty()) + Expect(helper.IsJSON(stdout)).To(BeTrue()) + helper.JsonPathContentIs(stdout, "0.name", "python") + helper.JsonPathContentContain(stdout, "0.displayName", "Python") + helper.JsonPathContentContain(stdout, "0.description", "Python is an interpreted") + helper.JsonPathContentContain(stdout, "0.language", "Python") + helper.JsonPathContentContain(stdout, "0.projectType", "Python") + helper.JsonPathContentContain(stdout, "0.starterProjects.0", "flask-example") + helper.JsonPathContentContain(stdout, "0.devfileData", "") + + }) + }) - It("should successfully delete registry", func() { - helper.Cmd("odo", "preference", "remove", "registry", registryName, "-f").ShouldPass() - }) + It("Should fail with an error with no registries", func() { + helper.Cmd("odo", "preference", "remove", "registry", "DefaultDevfileRegistry", "-f").ShouldPass() + output := helper.Cmd("odo", "preference", "view").ShouldRun().Err() + helper.MatchAllInOutput(output, []string{"No devfile registries added to the configuration. Refer to `odo preference add registry -h` to add one"}) + }) - It("deleting registry and creating component with registry flag ", func() { - helper.Cmd("odo", "preference", "remove", "registry", registryName, "-f").ShouldPass() - helper.Cmd("odo", "init", "--name", "aname", "--devfile", "java-maven", "--devfile-registry", registryName).ShouldFail() - }) + It("Should fail to delete the registry, when registry is not present", func() { + helper.Cmd("odo", "preference", "remove", "registry", registryName, "-f").ShouldFail() + }) - It("should list registry with recently added registry on top", func() { - By("for json output", func() { - output := helper.Cmd("odo", "preference", "view", "-o", "json").ShouldPass().Out() - Expect(helper.IsJSON(output)).To(BeTrue()) - helper.JsonPathContentIs(output, "registries.0.name", registryName) - helper.JsonPathContentIs(output, "registries.0.url", addRegistryURL) - helper.JsonPathContentIs(output, "registries.1.name", "DefaultDevfileRegistry") - helper.JsonPathContentIs(output, "registries.1.url", addRegistryURL) // as we are using its updated in case of Proxy + When("adding a registry", func() { + BeforeEach(func() { + helper.Cmd("odo", "preference", "add", "registry", registryName, addRegistryURL).ShouldPass() + }) + + It("should list newly added registry", func() { + output := helper.Cmd("odo", "preference", "view").ShouldPass().Out() + helper.MatchAllInOutput(output, []string{registryName, addRegistryURL}) + }) + + It("should pass, when doing odo init with --devfile-registry flag", func() { + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "nodejs", "--devfile-registry", registryName).ShouldPass() + }) + + It("should fail, when adding same registry", func() { + helper.Cmd("odo", "preference", "add", "registry", registryName, addRegistryURL).ShouldFail() + }) + + It("should successfully delete registry", func() { + helper.Cmd("odo", "preference", "remove", "registry", registryName, "-f").ShouldPass() + }) + + It("deleting registry and creating component with registry flag ", func() { + helper.Cmd("odo", "preference", "remove", "registry", registryName, "-f").ShouldPass() + helper.Cmd("odo", "init", "--name", "aname", "--devfile", "java-maven", "--devfile-registry", registryName).ShouldFail() + }) + + It("should list registry with recently added registry on top", func() { + By("for json output", func() { + output := helper.Cmd("odo", "preference", "view", "-o", "json").ShouldPass().Out() + Expect(helper.IsJSON(output)).To(BeTrue()) + helper.JsonPathContentIs(output, "registries.0.name", registryName) + helper.JsonPathContentIs(output, "registries.0.url", addRegistryURL) + helper.JsonPathContentIs(output, "registries.1.name", "DefaultDevfileRegistry") + helper.JsonPathContentIs(output, "registries.1.url", addRegistryURL) // as we are using its updated in case of Proxy + }) + + }) }) + It("should fail when adding a git based registry", func() { + err := helper.Cmd("odo", "preference", "add", "registry", "RegistryFromGitHub", "https://github.com/devfile/registry").ShouldFail().Err() + helper.MatchAllInOutput(err, []string{"github", "no", "supported", "https://github.com/devfile/registry-support"}) + }) }) - }) - - It("should fail when adding a git based registry", func() { - err := helper.Cmd("odo", "preference", "add", "registry", "RegistryFromGitHub", "https://github.com/devfile/registry").ShouldFail().Err() - helper.MatchAllInOutput(err, []string{"github", "no", "supported", "https://github.com/devfile/registry-support"}) - }) - + } }) diff --git a/tests/integration/cmd_namespace_test.go b/tests/integration/cmd_namespace_test.go index aefd8a4a7c4..4af96f7d3ac 100644 --- a/tests/integration/cmd_namespace_test.go +++ b/tests/integration/cmd_namespace_test.go @@ -183,6 +183,10 @@ ComponentSettings: Expect(out).To(ContainSubstring("Please ensure you have an active kubernetes context to your cluster.")) }) + It("should fail, with unauth cluster", Label(helper.LabelUnauth), func() { + _ = helper.Cmd("odo", "list", commandName).ShouldFail() + }) + It(fmt.Sprintf("should successfully list all the %ss", commandName), func() { Eventually(func() string { out := helper.Cmd("odo", "list", commandName).ShouldPass().Out() diff --git a/tests/integration/cmd_pref_config_test.go b/tests/integration/cmd_pref_config_test.go index 5ec072bcb55..4f61e8c585d 100644 --- a/tests/integration/cmd_pref_config_test.go +++ b/tests/integration/cmd_pref_config_test.go @@ -13,118 +13,125 @@ import ( const promptMessageSubString = "Help odo improve by allowing it to collect usage data." -var _ = Describe("odo preference and config command tests", Label(helper.LabelNoCluster), func() { - // TODO: A neater way to provide odo path. Currently we assume odo and oc in $PATH already. - var commonVar helper.CommonVar - - // This is run before every Spec (It) - var _ = BeforeEach(func() { - commonVar = helper.CommonBeforeEach() - }) - - // Clean up after the test - // This is run after every Spec (It) - var _ = AfterEach(func() { - helper.CommonAfterEach(commonVar) - }) - - Context("check that help works", func() { - It("should display help info", func() { - helpArgs := []string{"-h", "help", "--help"} - for _, helpArg := range helpArgs { - appHelp := helper.Cmd("odo", helpArg).ShouldPass().Out() - Expect(appHelp).To(ContainSubstring(`Use "odo [command] --help" for more information about a command.`)) - } - }) - }) - - Context("when running help for preference command", func() { - It("should display the help", func() { - appHelp := helper.Cmd("odo", "preference", "-h").ShouldPass().Out() - Expect(appHelp).To(ContainSubstring("Modifies odo specific configuration settings")) - }) - }) - - Context("When viewing global config", func() { - var newContext string - // ConsentTelemetry is set to false in helper.CommonBeforeEach so that it does not prompt to set a value - // during the tests, but we want to check preference values as they would be in real time and hence - // we set the GLOBALODOCONFIG variable to a value in new context - var _ = JustBeforeEach(func() { - newContext = helper.CreateNewContext() - os.Setenv("GLOBALODOCONFIG", filepath.Join(newContext, "preference.yaml")) - }) - var _ = JustAfterEach(func() { - helper.DeleteDir(newContext) - }) - It("should get the default global config keys", func() { - configOutput := helper.Cmd("odo", "preference", "view").ShouldPass().Out() - preferences := []string{"UpdateNotification", "Timeout", "PushTimeout", "RegistryCacheTime", "Ephemeral", "ConsentTelemetry"} - helper.MatchAllInOutput(configOutput, preferences) - for _, key := range preferences { - value := helper.GetPreferenceValue(key) - Expect(value).To(BeEmpty()) - } - }) - It("should get the default global config keys in JSON output", func() { - res := helper.Cmd("odo", "preference", "view", "-o", "json").ShouldPass() - stdout, stderr := res.Out(), res.Err() - Expect(stderr).To(BeEmpty()) - Expect(helper.IsJSON(stdout)).To(BeTrue()) - preferences := []string{"UpdateNotification", "Timeout", "PushTimeout", "RegistryCacheTime", "ConsentTelemetry", "Ephemeral"} - for i, pref := range preferences { - helper.JsonPathContentIs(stdout, fmt.Sprintf("preferences.%d.name", i), pref) - } - helper.JsonPathContentIs(stdout, "registries.#", "1") - helper.JsonPathContentIs(stdout, "registries.0.name", "DefaultDevfileRegistry") - }) - }) - - Context("When configuring global config values", func() { - preferences := []struct { - name string - value string - updateValue string - invalidValue string - firstSetWithForce bool - }{ - {"UpdateNotification", "false", "true", "foo", false}, - {"Timeout", "5s", "6s", "foo", false}, - // !! Do not test ConsentTelemetry with true because it sends out the telemetry data and messes up the statistics !! - {"ConsentTelemetry", "false", "false", "foo", false}, - {"PushTimeout", "4s", "6s", "foo", false}, - {"RegistryCacheTime", "4m", "6m", "foo", false}, - {"Ephemeral", "false", "true", "foo", true}, - } - - It("should successfully updated", func() { - for _, pref := range preferences { - // construct arguments for the first command - firstCmdArgs := []string{"preference", "set"} - if pref.firstSetWithForce { - firstCmdArgs = append(firstCmdArgs, "-f") +var _ = Describe("odo preference and config command tests", func() { + + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + var _ = Context("label "+label, Label(label), func() { + + // TODO: A neater way to provide odo path. Currently we assume odo and oc in $PATH already. + var commonVar helper.CommonVar + + // This is run before every Spec (It) + var _ = BeforeEach(func() { + commonVar = helper.CommonBeforeEach() + }) + + // Clean up after the test + // This is run after every Spec (It) + var _ = AfterEach(func() { + helper.CommonAfterEach(commonVar) + }) + + Context("check that help works", func() { + It("should display help info", func() { + helpArgs := []string{"-h", "help", "--help"} + for _, helpArg := range helpArgs { + appHelp := helper.Cmd("odo", helpArg).ShouldPass().Out() + Expect(appHelp).To(ContainSubstring(`Use "odo [command] --help" for more information about a command.`)) + } + }) + }) + + Context("when running help for preference command", func() { + It("should display the help", func() { + appHelp := helper.Cmd("odo", "preference", "-h").ShouldPass().Out() + Expect(appHelp).To(ContainSubstring("Modifies odo specific configuration settings")) + }) + }) + + Context("When viewing global config", func() { + var newContext string + // ConsentTelemetry is set to false in helper.CommonBeforeEach so that it does not prompt to set a value + // during the tests, but we want to check preference values as they would be in real time and hence + // we set the GLOBALODOCONFIG variable to a value in new context + var _ = JustBeforeEach(func() { + newContext = helper.CreateNewContext() + os.Setenv("GLOBALODOCONFIG", filepath.Join(newContext, "preference.yaml")) + }) + var _ = JustAfterEach(func() { + helper.DeleteDir(newContext) + }) + It("should get the default global config keys", func() { + configOutput := helper.Cmd("odo", "preference", "view").ShouldPass().Out() + preferences := []string{"UpdateNotification", "Timeout", "PushTimeout", "RegistryCacheTime", "Ephemeral", "ConsentTelemetry"} + helper.MatchAllInOutput(configOutput, preferences) + for _, key := range preferences { + value := helper.GetPreferenceValue(key) + Expect(value).To(BeEmpty()) + } + }) + It("should get the default global config keys in JSON output", func() { + res := helper.Cmd("odo", "preference", "view", "-o", "json").ShouldPass() + stdout, stderr := res.Out(), res.Err() + Expect(stderr).To(BeEmpty()) + Expect(helper.IsJSON(stdout)).To(BeTrue()) + preferences := []string{"UpdateNotification", "Timeout", "PushTimeout", "RegistryCacheTime", "ConsentTelemetry", "Ephemeral"} + for i, pref := range preferences { + helper.JsonPathContentIs(stdout, fmt.Sprintf("preferences.%d.name", i), pref) + } + helper.JsonPathContentIs(stdout, "registries.#", "1") + helper.JsonPathContentIs(stdout, "registries.0.name", "DefaultDevfileRegistry") + }) + }) + + Context("When configuring global config values", func() { + preferences := []struct { + name string + value string + updateValue string + invalidValue string + firstSetWithForce bool + }{ + {"UpdateNotification", "false", "true", "foo", false}, + {"Timeout", "5s", "6s", "foo", false}, + // !! Do not test ConsentTelemetry with true because it sends out the telemetry data and messes up the statistics !! + {"ConsentTelemetry", "false", "false", "foo", false}, + {"PushTimeout", "4s", "6s", "foo", false}, + {"RegistryCacheTime", "4m", "6m", "foo", false}, + {"Ephemeral", "false", "true", "foo", true}, } - firstCmdArgs = append(firstCmdArgs, pref.name, pref.value) - - helper.Cmd("odo", firstCmdArgs...).ShouldPass() - value := helper.GetPreferenceValue(pref.name) - Expect(value).To(ContainSubstring(pref.value)) - - helper.Cmd("odo", "preference", "set", "-f", pref.name, pref.updateValue).ShouldPass() - value = helper.GetPreferenceValue(pref.name) - Expect(value).To(ContainSubstring(pref.updateValue)) - - helper.Cmd("odo", "preference", "unset", "-f", pref.name).ShouldPass() - value = helper.GetPreferenceValue(pref.name) - Expect(value).To(BeEmpty()) - } - globalConfPath := os.Getenv("HOME") - os.RemoveAll(filepath.Join(globalConfPath, ".odo")) - }) - }) - When("when preference.yaml contains an int value for Timeout", func() { - BeforeEach(func() { - preference := ` + + It("should successfully updated", func() { + for _, pref := range preferences { + // construct arguments for the first command + firstCmdArgs := []string{"preference", "set"} + if pref.firstSetWithForce { + firstCmdArgs = append(firstCmdArgs, "-f") + } + firstCmdArgs = append(firstCmdArgs, pref.name, pref.value) + + helper.Cmd("odo", firstCmdArgs...).ShouldPass() + value := helper.GetPreferenceValue(pref.name) + Expect(value).To(ContainSubstring(pref.value)) + + helper.Cmd("odo", "preference", "set", "-f", pref.name, pref.updateValue).ShouldPass() + value = helper.GetPreferenceValue(pref.name) + Expect(value).To(ContainSubstring(pref.updateValue)) + + helper.Cmd("odo", "preference", "unset", "-f", pref.name).ShouldPass() + value = helper.GetPreferenceValue(pref.name) + Expect(value).To(BeEmpty()) + } + globalConfPath := os.Getenv("HOME") + os.RemoveAll(filepath.Join(globalConfPath, ".odo")) + }) + }) + When("when preference.yaml contains an int value for Timeout", func() { + BeforeEach(func() { + preference := ` kind: Preference apiversion: odo.dev/v1alpha1 OdoSettings: @@ -136,61 +143,62 @@ OdoSettings: ConsentTelemetry: true Timeout: 10 ` - preferencePath := filepath.Join(commonVar.Context, "preference.yaml") - err := helper.CreateFileWithContent(preferencePath, preference) - Expect(err).To(BeNil()) - os.Setenv("GLOBALODOCONFIG", preferencePath) + preferencePath := filepath.Join(commonVar.Context, "preference.yaml") + err := helper.CreateFileWithContent(preferencePath, preference) + Expect(err).To(BeNil()) + os.Setenv("GLOBALODOCONFIG", preferencePath) + }) + It("should show warning about incompatible Timeout value when viewing preferences", func() { + errOut := helper.Cmd("odo", "preference", "view").ShouldPass().Err() + Expect(helper.GetPreferenceValue("Timeout")).To(ContainSubstring("10ns")) + Expect(errOut).To(ContainSubstring("Please change the preference value for Timeout")) + }) + }) + + It("should fail to set an incompatible format for a preference that accepts duration", func() { + errOut := helper.Cmd("odo", "preference", "set", "RegistryCacheTime", "1d").ShouldFail().Err() + Expect(errOut).To(ContainSubstring("unable to set \"registrycachetime\" to \"1d\"")) + }) + + Context("When no ConsentTelemetry preference value is set", func() { + var _ = JustBeforeEach(func() { + // unset the preference in case it is already set + helper.Cmd("odo", "preference", "unset", "ConsentTelemetry", "-f").ShouldPass() + }) + + It("should not prompt when user calls for help", func() { + output := helper.Cmd("odo", "init", "--help").ShouldPass().Out() + Expect(output).ToNot(ContainSubstring(promptMessageSubString)) + }) + + It("should not prompt when preference command is run", func() { + output := helper.Cmd("odo", "preference", "view").ShouldPass().Out() + Expect(output).ToNot(ContainSubstring(promptMessageSubString)) + + output = helper.Cmd("odo", "preference", "set", "timeout", "5s", "-f").ShouldPass().Out() + Expect(output).ToNot(ContainSubstring(promptMessageSubString)) + + output = helper.Cmd("odo", "preference", "unset", "timeout", "-f").ShouldPass().Out() + Expect(output).ToNot(ContainSubstring(promptMessageSubString)) + }) + }) + + Context("When ConsentTelemetry preference value is set", func() { + // !! Do not test with true because it sends out the telemetry data and messes up the statistics !! + var workingDir string + BeforeEach(func() { + workingDir = helper.Getwd() + helper.Chdir(commonVar.Context) + }) + AfterEach(func() { + helper.Chdir(workingDir) + }) + It("should not prompt the user", func() { + helper.Cmd("odo", "preference", "set", "ConsentTelemetry", "false", "-f").ShouldPass() + output := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-registry.yaml")).ShouldPass().Out() + Expect(output).ToNot(ContainSubstring(promptMessageSubString)) + }) + }) }) - It("should show warning about incompatible Timeout value when viewing preferences", func() { - errOut := helper.Cmd("odo", "preference", "view").ShouldPass().Err() - Expect(helper.GetPreferenceValue("Timeout")).To(ContainSubstring("10ns")) - Expect(errOut).To(ContainSubstring("Please change the preference value for Timeout")) - }) - }) - - It("should fail to set an incompatible format for a preference that accepts duration", func() { - errOut := helper.Cmd("odo", "preference", "set", "RegistryCacheTime", "1d").ShouldFail().Err() - Expect(errOut).To(ContainSubstring("unable to set \"registrycachetime\" to \"1d\"")) - }) - - Context("When no ConsentTelemetry preference value is set", func() { - var _ = JustBeforeEach(func() { - // unset the preference in case it is already set - helper.Cmd("odo", "preference", "unset", "ConsentTelemetry", "-f").ShouldPass() - }) - - It("should not prompt when user calls for help", func() { - output := helper.Cmd("odo", "init", "--help").ShouldPass().Out() - Expect(output).ToNot(ContainSubstring(promptMessageSubString)) - }) - - It("should not prompt when preference command is run", func() { - output := helper.Cmd("odo", "preference", "view").ShouldPass().Out() - Expect(output).ToNot(ContainSubstring(promptMessageSubString)) - - output = helper.Cmd("odo", "preference", "set", "timeout", "5s", "-f").ShouldPass().Out() - Expect(output).ToNot(ContainSubstring(promptMessageSubString)) - - output = helper.Cmd("odo", "preference", "unset", "timeout", "-f").ShouldPass().Out() - Expect(output).ToNot(ContainSubstring(promptMessageSubString)) - }) - }) - - Context("When ConsentTelemetry preference value is set", func() { - // !! Do not test with true because it sends out the telemetry data and messes up the statistics !! - var workingDir string - BeforeEach(func() { - workingDir = helper.Getwd() - helper.Chdir(commonVar.Context) - }) - AfterEach(func() { - helper.Chdir(workingDir) - }) - It("should not prompt the user", func() { - helper.Cmd("odo", "preference", "set", "ConsentTelemetry", "false", "-f").ShouldPass() - output := helper.Cmd("odo", "init", "--name", "aname", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-registry.yaml")).ShouldPass().Out() - Expect(output).ToNot(ContainSubstring(promptMessageSubString)) - }) - }) - + } }) diff --git a/tests/integration/cmd_remove_binding_test.go b/tests/integration/cmd_remove_binding_test.go index 5c4959b22d4..a2a5f35e2e5 100644 --- a/tests/integration/cmd_remove_binding_test.go +++ b/tests/integration/cmd_remove_binding_test.go @@ -29,18 +29,25 @@ var _ = Describe("odo remove binding command tests", func() { helper.Cmd("odo", "init", "--name", "mynode", "--devfile-path", helper.GetExamplePath("source", "devfiles", "nodejs", "devfile-with-service-binding-files.yaml")).ShouldPass() }) - When("removing the binding", Label(helper.LabelNoCluster), func() { - BeforeEach(func() { - helper.Cmd("odo", "remove", "binding", "--name", bindingName).ShouldPass() + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + When("removing the binding", Label(label), func() { + BeforeEach(func() { + helper.Cmd("odo", "remove", "binding", "--name", bindingName).ShouldPass() + }) + It("should successfully remove binding between component and service in the devfile", func() { + components := helper.GetDevfileComponents(filepath.Join(commonVar.Context, "devfile.yaml"), bindingName) + Expect(components).To(BeNil()) + }) }) - It("should successfully remove binding between component and service in the devfile", func() { - components := helper.GetDevfileComponents(filepath.Join(commonVar.Context, "devfile.yaml"), bindingName) - Expect(components).To(BeNil()) + + It("should fail to remove binding that does not exist", func() { + helper.Cmd("odo", "remove", "binding", "--name", "my-binding").ShouldFail() }) - }) - It("should fail to remove binding that does not exist", Label(helper.LabelNoCluster), func() { - helper.Cmd("odo", "remove", "binding", "--name", "my-binding").ShouldFail() - }) + } + When("odo dev is running", func() { var session helper.DevSession BeforeEach(func() { diff --git a/tests/integration/generic_test.go b/tests/integration/generic_test.go index 587993c7584..373aa1a3e8d 100644 --- a/tests/integration/generic_test.go +++ b/tests/integration/generic_test.go @@ -26,66 +26,73 @@ var _ = Describe("odo generic", func() { helper.CommonAfterEach(commonVar) }) - When("running odo --help", Label(helper.LabelNoCluster), func() { - var output string - BeforeEach(func() { - output = helper.Cmd("odo", "--help").ShouldPass().Out() - }) - It("retuns full help contents including usage, examples, commands, utility commands, component shortcuts, and flags sections", func() { - helper.MatchAllInOutput(output, []string{"Usage:", "Examples:", "Main Commands:", "OpenShift Commands:", "Utility Commands:", "Flags:"}) - }) + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + Context("label "+label, Label(label), func() { + When("running odo --help", func() { + var output string + BeforeEach(func() { + output = helper.Cmd("odo", "--help").ShouldPass().Out() + }) + It("retuns full help contents including usage, examples, commands, utility commands, component shortcuts, and flags sections", func() { + helper.MatchAllInOutput(output, []string{"Usage:", "Examples:", "Main Commands:", "OpenShift Commands:", "Utility Commands:", "Flags:"}) + }) - }) + }) - When("running odo without subcommand and flags", Label(helper.LabelNoCluster), func() { - var output string - BeforeEach(func() { - output = helper.Cmd("odo").ShouldPass().Out() - }) - It("a short vesion of help contents is returned, an error is not expected", func() { - Expect(output).To(ContainSubstring("To see a full list of commands, run 'odo --help'")) - }) - }) + When("running odo without subcommand and flags", func() { + var output string + BeforeEach(func() { + output = helper.Cmd("odo").ShouldPass().Out() + }) + It("a short vesion of help contents is returned, an error is not expected", func() { + Expect(output).To(ContainSubstring("To see a full list of commands, run 'odo --help'")) + }) + }) - It("returns error when using an invalid command", Label(helper.LabelNoCluster), func() { - output := helper.Cmd("odo", "hello").ShouldFail().Err() - Expect(output).To(ContainSubstring("Invalid command - see available commands/subcommands above")) - }) + It("returns error when using an invalid command", func() { + output := helper.Cmd("odo", "hello").ShouldFail().Err() + Expect(output).To(ContainSubstring("Invalid command - see available commands/subcommands above")) + }) - It("returns JSON error", Label(helper.LabelNoCluster), func() { - By("using an invalid command with JSON output", func() { - res := helper.Cmd("odo", "unknown-command", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(helper.IsJSON(stderr)).To(BeTrue()) - }) + It("returns JSON error", func() { + By("using an invalid command with JSON output", func() { + res := helper.Cmd("odo", "unknown-command", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(helper.IsJSON(stderr)).To(BeTrue()) + }) - By("using an invalid describe sub-command with JSON output", func() { - res := helper.Cmd("odo", "describe", "unknown-sub-command", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(helper.IsJSON(stderr)).To(BeTrue()) - }) + By("using an invalid describe sub-command with JSON output", func() { + res := helper.Cmd("odo", "describe", "unknown-sub-command", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(helper.IsJSON(stderr)).To(BeTrue()) + }) - By("using an invalid list sub-command with JSON output", func() { - res := helper.Cmd("odo", "list", "unknown-sub-command", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(helper.IsJSON(stderr)).To(BeTrue()) - }) + By("using an invalid list sub-command with JSON output", func() { + res := helper.Cmd("odo", "list", "unknown-sub-command", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(helper.IsJSON(stderr)).To(BeTrue()) + }) - By("omitting required subcommand with JSON output", func() { - res := helper.Cmd("odo", "describe", "-o", "json").ShouldFail() - stdout, stderr := res.Out(), res.Err() - Expect(stdout).To(BeEmpty()) - Expect(helper.IsJSON(stderr)).To(BeTrue()) - }) - }) + By("omitting required subcommand with JSON output", func() { + res := helper.Cmd("odo", "describe", "-o", "json").ShouldFail() + stdout, stderr := res.Out(), res.Err() + Expect(stdout).To(BeEmpty()) + Expect(helper.IsJSON(stderr)).To(BeTrue()) + }) + }) - It("returns error when using an invalid command with --help", Label(helper.LabelNoCluster), func() { - output := helper.Cmd("odo", "hello", "--help").ShouldFail().Err() - Expect(output).To(ContainSubstring("unknown command 'hello', type --help for a list of all commands")) - }) + It("returns error when using an invalid command with --help", func() { + output := helper.Cmd("odo", "hello", "--help").ShouldFail().Err() + Expect(output).To(ContainSubstring("unknown command 'hello', type --help for a list of all commands")) + }) + }) + } Context("When deleting two project one after the other", func() { It("should be able to delete sequentially", func() { @@ -124,6 +131,10 @@ var _ = Describe("odo generic", func() { reOdoVersion := `^odo\s*v[0-9]+.[0-9]+.[0-9]+(?:-\w+)?\s*\(\w+\)` Expect(odoVersion).Should(MatchRegexp(reOdoVersion)) }) + It("should show the version of odo major components", Label(helper.LabelUnauth), func() { + reOdoVersion := `^odo\s*v[0-9]+.[0-9]+.[0-9]+(?:-\w+)?\s*\(\w+\)` + Expect(odoVersion).Should(MatchRegexp(reOdoVersion)) + }) }) Describe("Experimental Mode", func() { diff --git a/tests/integration/interactive_init_test.go b/tests/integration/interactive_init_test.go index 8245d5949b7..46ff5025853 100644 --- a/tests/integration/interactive_init_test.go +++ b/tests/integration/interactive_init_test.go @@ -23,498 +23,504 @@ import ( "github.com/redhat-developer/odo/tests/helper" ) -var _ = Describe("odo init interactive command tests", Label(helper.LabelNoCluster), func() { +var _ = Describe("odo init interactive command tests", func() { + for _, label := range []string{ + helper.LabelNoCluster, helper.LabelUnauth, + } { + label := label + var _ = Context("label "+label, Label(label), func() { + var commonVar helper.CommonVar + + // This is run before every Spec (It) + var _ = BeforeEach(func() { + commonVar = helper.CommonBeforeEach() + helper.Chdir(commonVar.Context) + + // We make EXPLICITLY sure that we are outputting with NO COLOR + // this is because in some cases we are comparing the output with a colorized one + os.Setenv("NO_COLOR", "true") + }) + + // Clean up after the test + // This is run after every Spec (It) + var _ = AfterEach(func() { + helper.CommonAfterEach(commonVar) + }) + + It("should not fail when using -v flag", func() { + command := []string{"odo", "init", "-v", "4"} + output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { + + By("showing the interactive mode notice message", func() { + helper.ExpectString(ctx, messages.InteractiveModeEnabled) + }) - var commonVar helper.CommonVar + helper.ExpectString(ctx, "Select language") + helper.SendLine(ctx, "Go") - // This is run before every Spec (It) - var _ = BeforeEach(func() { - commonVar = helper.CommonBeforeEach() - helper.Chdir(commonVar.Context) + helper.ExpectString(ctx, "Select project type") + helper.SendLine(ctx, "") + + helper.ExpectString(ctx, "Select container for which you want to change configuration?") + helper.SendLine(ctx, "") - // We make EXPLICITLY sure that we are outputting with NO COLOR - // this is because in some cases we are comparing the output with a colorized one - os.Setenv("NO_COLOR", "true") - }) + helper.ExpectString(ctx, "Which starter project do you want to use") + helper.SendLine(ctx, "") - // Clean up after the test - // This is run after every Spec (It) - var _ = AfterEach(func() { - helper.CommonAfterEach(commonVar) - }) + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "my-go-app") - It("should not fail when using -v flag", func() { - command := []string{"odo", "init", "-v", "4"} - output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { + helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") - By("showing the interactive mode notice message", func() { - helper.ExpectString(ctx, messages.InteractiveModeEnabled) + }) + Expect(err).To(BeNil()) + Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) }) - helper.ExpectString(ctx, "Select language") - helper.SendLine(ctx, "Go") + It("should ask to re-enter the component name when an invalid value is passed", func() { + command := []string{"odo", "init"} + _, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Select project type") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select language") + helper.SendLine(ctx, "Go") - helper.ExpectString(ctx, "Select container for which you want to change configuration?") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select project type") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Which starter project do you want to use") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select container for which you want to change configuration?") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "my-go-app") + helper.ExpectString(ctx, "Which starter project do you want to use") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "myapp-") - }) - Expect(err).To(BeNil()) - Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) - }) + helper.ExpectString(ctx, "name \"myapp-\" is not valid, name should conform the following requirements") - It("should ask to re-enter the component name when an invalid value is passed", func() { - command := []string{"odo", "init"} - _, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "my-go-app") - helper.ExpectString(ctx, "Select language") - helper.SendLine(ctx, "Go") + helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") + }) + Expect(err).To(BeNil()) + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) + }) - helper.ExpectString(ctx, "Select project type") - helper.SendLine(ctx, "") + It("should print automation command with proper values", func() { - helper.ExpectString(ctx, "Select container for which you want to change configuration?") - helper.SendLine(ctx, "") + // This test fails on Windows because of terminal emulator behaviour + if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" { + Skip("This is a Unix specific scenario, skipping") + } - helper.ExpectString(ctx, "Which starter project do you want to use") - helper.SendLine(ctx, "") + command := []string{"odo", "init"} + starter := "go-starter" + componentName := "my-go-app" + devfileName := "go" - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "myapp-") + output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "name \"myapp-\" is not valid, name should conform the following requirements") + helper.ExpectString(ctx, "Select language") + helper.SendLine(ctx, "Go") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "my-go-app") + helper.ExpectString(ctx, "Select project type") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") - }) - Expect(err).To(BeNil()) - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) - }) + helper.ExpectString(ctx, "Select container for which you want to change configuration?") + helper.SendLine(ctx, "") - It("should print automation command with proper values", func() { + helper.ExpectString(ctx, "Which starter project do you want to use") + helper.SendLine(ctx, starter) - // This test fails on Windows because of terminal emulator behaviour - if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" { - Skip("This is a Unix specific scenario, skipping") - } + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, componentName) - command := []string{"odo", "init"} - starter := "go-starter" - componentName := "my-go-app" - devfileName := "go" + helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") - output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { + }) - helper.ExpectString(ctx, "Select language") - helper.SendLine(ctx, "Go") + Expect(err).To(BeNil()) + Expect(output).To(ContainSubstring("odo init --name %s --devfile %s --devfile-registry DefaultDevfileRegistry --starter %s", componentName, devfileName, starter)) + Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) + }) - helper.ExpectString(ctx, "Select project type") - helper.SendLine(ctx, "") + It("should download correct devfile", func() { - helper.ExpectString(ctx, "Select container for which you want to change configuration?") - helper.SendLine(ctx, "") + command := []string{"odo", "init"} + output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Which starter project do you want to use") - helper.SendLine(ctx, starter) + By("showing the interactive mode notice message", func() { + helper.ExpectString(ctx, messages.InteractiveModeEnabled) + }) - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, componentName) + helper.ExpectString(ctx, "Select language") + helper.SendLine(ctx, "Go") - helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") + helper.ExpectString(ctx, "Select project type") + helper.SendLine(ctx, "") - }) + helper.ExpectString(ctx, "Select container for which you want to change configuration?") + helper.SendLine(ctx, "") - Expect(err).To(BeNil()) - Expect(output).To(ContainSubstring("odo init --name %s --devfile %s --devfile-registry DefaultDevfileRegistry --starter %s", componentName, devfileName, starter)) - Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) - }) + helper.ExpectString(ctx, "Which starter project do you want to use") + helper.SendLine(ctx, "") + + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "my-go-app") - It("should download correct devfile", func() { + helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") - command := []string{"odo", "init"} - output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { + }) - By("showing the interactive mode notice message", func() { - helper.ExpectString(ctx, messages.InteractiveModeEnabled) + Expect(err).To(BeNil()) + Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) }) - helper.ExpectString(ctx, "Select language") - helper.SendLine(ctx, "Go") + It("should download correct devfile-starter", func() { - helper.ExpectString(ctx, "Select project type") - helper.SendLine(ctx, "") + command := []string{"odo", "init"} + output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Select container for which you want to change configuration?") - helper.SendLine(ctx, "") + By("showing the interactive mode notice message", func() { + helper.ExpectString(ctx, messages.InteractiveModeEnabled) + }) - helper.ExpectString(ctx, "Which starter project do you want to use") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select language") + helper.SendLine(ctx, "java") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "my-go-app") + helper.ExpectString(ctx, "Select project type") + helper.SendLine(ctx, "Vert.x Java") - helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory") + helper.ExpectString(ctx, "Select container for which you want to change configuration?") + helper.SendLine(ctx, "") - }) + helper.ExpectString(ctx, "Which starter project do you want to use") + helper.SendLine(ctx, "vertx-cache-example-redhat") - Expect(err).To(BeNil()) - Expect(output).To(ContainSubstring("Your new component 'my-go-app' is ready in the current directory")) - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) - }) + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "my-app") - It("should download correct devfile-starter", func() { + helper.ExpectString(ctx, "Your new component 'my-app' is ready in the current directory") - command := []string{"odo", "init"} - output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) { + }) - By("showing the interactive mode notice message", func() { - helper.ExpectString(ctx, messages.InteractiveModeEnabled) + Expect(err).To(BeNil()) + Expect(output).To(ContainSubstring("Downloading starter project \"vertx-cache-example-redhat\"")) }) - helper.ExpectString(ctx, "Select language") - helper.SendLine(ctx, "java") - - helper.ExpectString(ctx, "Select project type") - helper.SendLine(ctx, "Vert.x Java") + Describe("displaying welcoming messages", func() { - helper.ExpectString(ctx, "Select container for which you want to change configuration?") - helper.SendLine(ctx, "") + // testFunc is a function that returns a `Tester` function (intended to be used via `helper.RunInteractive`), + // which first expects all messages in `welcomingMsgs` to be read from the console, + // then runs an `additionalTester` and finally expects the asking of a component name + // (based on the `language` specified) + testFunc := func(language string, welcomingMsgs []string, additionalTester helper.Tester) helper.Tester { + return func(ctx helper.InteractiveContext) { + for _, msg := range welcomingMsgs { + helper.ExpectString(ctx, msg) + } - helper.ExpectString(ctx, "Which starter project do you want to use") - helper.SendLine(ctx, "vertx-cache-example-redhat") + if additionalTester != nil { + additionalTester(ctx) + } - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "my-app") + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, fmt.Sprintf("my-%s-app", language)) - helper.ExpectString(ctx, "Your new component 'my-app' is ready in the current directory") + helper.ExpectString(ctx, + fmt.Sprintf("Your new component 'my-%s-app' is ready in the current directory", language)) + } + } - }) + assertBehavior := func(language string, output string, err error, msgs []string, additionalAsserter func()) { + Expect(err).To(BeNil()) - Expect(err).To(BeNil()) - Expect(output).To(ContainSubstring("Downloading starter project \"vertx-cache-example-redhat\"")) - }) + lines, err := helper.ExtractLines(output) + if err != nil { + log.Fatal(err) + } + Expect(len(lines)).To(BeNumerically(">", len(msgs))) + Expect(lines[0:len(msgs)]).To(Equal(msgs)) + Expect(lines).To( + ContainElement(fmt.Sprintf("Your new component 'my-%s-app' is ready in the current directory", strings.ToLower(language)))) - Describe("displaying welcoming messages", func() { + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) - // testFunc is a function that returns a `Tester` function (intended to be used via `helper.RunInteractive`), - // which first expects all messages in `welcomingMsgs` to be read from the console, - // then runs an `additionalTester` and finally expects the asking of a component name - // (based on the `language` specified) - testFunc := func(language string, welcomingMsgs []string, additionalTester helper.Tester) helper.Tester { - return func(ctx helper.InteractiveContext) { - for _, msg := range welcomingMsgs { - helper.ExpectString(ctx, msg) + if additionalAsserter != nil { + additionalAsserter() + } } - if additionalTester != nil { - additionalTester(ctx) + testRunner := func(language string, welcomingMsgs []string, tester helper.Tester) (string, error) { + command := []string{"odo", "init"} + return helper.RunInteractive(command, + // Setting verbosity level to 0, because we would be asserting the welcoming message is the first + // message displayed to the end user. So we do not want any potential debug lines to be printed first. + // Using envvars here (and not via the -v flag), because of https://github.com/redhat-developer/odo/issues/5513 + []string{"ODO_LOG_LEVEL=0"}, + testFunc(strings.ToLower(language), welcomingMsgs, tester)) } - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, fmt.Sprintf("my-%s-app", language)) - - helper.ExpectString(ctx, - fmt.Sprintf("Your new component 'my-%s-app' is ready in the current directory", language)) - } - } - - assertBehavior := func(language string, output string, err error, msgs []string, additionalAsserter func()) { - Expect(err).To(BeNil()) - - lines, err := helper.ExtractLines(output) - if err != nil { - log.Fatal(err) - } - Expect(len(lines)).To(BeNumerically(">", len(msgs))) - Expect(lines[0:len(msgs)]).To(Equal(msgs)) - Expect(lines).To( - ContainElement(fmt.Sprintf("Your new component 'my-%s-app' is ready in the current directory", strings.ToLower(language)))) - - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) - - if additionalAsserter != nil { - additionalAsserter() - } - } - - testRunner := func(language string, welcomingMsgs []string, tester helper.Tester) (string, error) { - command := []string{"odo", "init"} - return helper.RunInteractive(command, - // Setting verbosity level to 0, because we would be asserting the welcoming message is the first - // message displayed to the end user. So we do not want any potential debug lines to be printed first. - // Using envvars here (and not via the -v flag), because of https://github.com/redhat-developer/odo/issues/5513 - []string{"ODO_LOG_LEVEL=0"}, - testFunc(strings.ToLower(language), welcomingMsgs, tester)) - } - - When("directory is empty", func() { - - BeforeEach(func() { - Expect(helper.ListFilesInDir(commonVar.Context)).To(HaveLen(0)) - }) + When("directory is empty", func() { - It("should display appropriate welcoming messages", func() { + BeforeEach(func() { + Expect(helper.ListFilesInDir(commonVar.Context)).To(HaveLen(0)) + }) - if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" { - Skip("This is a Unix specific scenario, skipping") - } + It("should display appropriate welcoming messages", func() { - language := "java" + if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" { + Skip("This is a Unix specific scenario, skipping") + } - // The first output is welcoming message / paragraph / banner output - welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.NoSourceCodeDetected, "odo version: "+version.VERSION), "\n") + language := "java" - output, err := testRunner(language, welcomingMsgs, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Select language") - helper.SendLine(ctx, language) + // The first output is welcoming message / paragraph / banner output + welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.NoSourceCodeDetected, "odo version: "+version.VERSION), "\n") - helper.ExpectString(ctx, "Select project type") - helper.SendLine(ctx, "") + output, err := testRunner(language, welcomingMsgs, func(ctx helper.InteractiveContext) { + helper.ExpectString(ctx, "Select language") + helper.SendLine(ctx, language) - helper.ExpectString(ctx, "Select container for which you want to change configuration?") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select project type") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Which starter project do you want to use") - helper.SendLine(ctx, "") - }) + helper.ExpectString(ctx, "Select container for which you want to change configuration?") + helper.SendLine(ctx, "") - assertBehavior(strings.ToLower(language), output, err, welcomingMsgs, nil) - }) - }) + helper.ExpectString(ctx, "Which starter project do you want to use") + helper.SendLine(ctx, "") + }) - When("directory is not empty", func() { + assertBehavior(strings.ToLower(language), output, err, welcomingMsgs, nil) + }) + }) - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "python"), commonVar.Context) - Expect(helper.ListFilesInDir(commonVar.Context)).To( - SatisfyAll( - HaveLen(2), - ContainElements("requirements.txt", "wsgi.py"))) - }) + When("directory is not empty", func() { - It("should display appropriate welcoming messages", func() { + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "python"), commonVar.Context) + Expect(helper.ListFilesInDir(commonVar.Context)).To( + SatisfyAll( + HaveLen(2), + ContainElements("requirements.txt", "wsgi.py"))) + }) - if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" { - Skip("This is a Unix specific scenario, skipping") - } + It("should display appropriate welcoming messages", func() { - language := "Python" - projectType := "Python" - devfileName := "python" - welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.SourceCodeDetected, "odo version: "+version.VERSION), "\n") + if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" { + Skip("This is a Unix specific scenario, skipping") + } - output, err := testRunner(language, welcomingMsgs, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Based on the files in the current directory odo detected") + language := "Python" + projectType := "Python" + devfileName := "python" + welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.SourceCodeDetected, "odo version: "+version.VERSION), "\n") - helper.ExpectString(ctx, fmt.Sprintf("Language: %s", language)) + output, err := testRunner(language, welcomingMsgs, func(ctx helper.InteractiveContext) { + helper.ExpectString(ctx, "Based on the files in the current directory odo detected") - helper.ExpectString(ctx, fmt.Sprintf("Project type: %s", projectType)) + helper.ExpectString(ctx, fmt.Sprintf("Language: %s", language)) - helper.ExpectString(ctx, - fmt.Sprintf("The devfile \"%s\" from the registry \"DefaultDevfileRegistry\" will be downloaded.", devfileName)) + helper.ExpectString(ctx, fmt.Sprintf("Project type: %s", projectType)) - helper.ExpectString(ctx, "Is this correct") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, + fmt.Sprintf("The devfile \"%s\" from the registry \"DefaultDevfileRegistry\" will be downloaded.", devfileName)) - helper.ExpectString(ctx, "Select container for which you want to change configuration") - helper.SendLine(ctx, "") - }) + helper.ExpectString(ctx, "Is this correct") + helper.SendLine(ctx, "") + + helper.ExpectString(ctx, "Select container for which you want to change configuration") + helper.SendLine(ctx, "") + }) - assertBehavior(strings.ToLower(language), output, err, welcomingMsgs, func() { - // Make sure the original source code files are still present - Expect(helper.ListFilesInDir(commonVar.Context)).To( - SatisfyAll( - HaveLen(4), - ContainElements("devfile.yaml", "requirements.txt", "wsgi.py", util.DotOdoDirectory))) + assertBehavior(strings.ToLower(language), output, err, welcomingMsgs, func() { + // Make sure the original source code files are still present + Expect(helper.ListFilesInDir(commonVar.Context)).To( + SatisfyAll( + HaveLen(4), + ContainElements("devfile.yaml", "requirements.txt", "wsgi.py", util.DotOdoDirectory))) + }) + }) }) - }) - }) - When("alizer detection of javascript name", func() { + When("alizer detection of javascript name", func() { - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - Expect(helper.ListFilesInDir(commonVar.Context)).To( - SatisfyAll( - HaveLen(3), - ContainElements("Dockerfile", "package.json", "server.js"))) - }) + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + Expect(helper.ListFilesInDir(commonVar.Context)).To( + SatisfyAll( + HaveLen(3), + ContainElements("Dockerfile", "package.json", "server.js"))) + }) - It("should display node-echo name", func() { - language := "JavaScript" - projectType := "Node.js" - projectName := "node-echo" - devfileName := "nodejs" + It("should display node-echo name", func() { + language := "JavaScript" + projectType := "Node.js" + projectName := "node-echo" + devfileName := "nodejs" - output, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Based on the files in the current directory odo detected") + output, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { + helper.ExpectString(ctx, "Based on the files in the current directory odo detected") - helper.ExpectString(ctx, fmt.Sprintf("Language: %s", language)) + helper.ExpectString(ctx, fmt.Sprintf("Language: %s", language)) - helper.ExpectString(ctx, fmt.Sprintf("Project type: %s", projectType)) + helper.ExpectString(ctx, fmt.Sprintf("Project type: %s", projectType)) - helper.ExpectString(ctx, - fmt.Sprintf("The devfile \"%s\" from the registry \"DefaultDevfileRegistry\" will be downloaded.", devfileName)) + helper.ExpectString(ctx, + fmt.Sprintf("The devfile \"%s\" from the registry \"DefaultDevfileRegistry\" will be downloaded.", devfileName)) - helper.ExpectString(ctx, "Is this correct") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Is this correct") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Select container for which you want to change configuration") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select container for which you want to change configuration") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, fmt.Sprintf("Your new component '%s' is ready in the current directory", projectName)) - }) - Expect(err).To(BeNil()) + helper.ExpectString(ctx, fmt.Sprintf("Your new component '%s' is ready in the current directory", projectName)) + }) + Expect(err).To(BeNil()) - lines, err := helper.ExtractLines(output) - Expect(err).To(BeNil()) - Expect(len(lines)).To(BeNumerically(">", 2)) - Expect(lines[len(lines)-1]).To(Equal(fmt.Sprintf("Your new component '%s' is ready in the current directory", projectName))) + lines, err := helper.ExtractLines(output) + Expect(err).To(BeNil()) + Expect(len(lines)).To(BeNumerically(">", 2)) + Expect(lines[len(lines)-1]).To(Equal(fmt.Sprintf("Your new component '%s' is ready in the current directory", projectName))) - }) - It("should ask to re-enter the component name if invalid value is passed by the user", func() { - language := "JavaScript" - projectType := "Node.js" - projectName := "node-echo" - devfileName := "nodejs" + }) + It("should ask to re-enter the component name if invalid value is passed by the user", func() { + language := "JavaScript" + projectType := "Node.js" + projectName := "node-echo" + devfileName := "nodejs" - _, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Based on the files in the current directory odo detected") + _, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { + helper.ExpectString(ctx, "Based on the files in the current directory odo detected") - helper.ExpectString(ctx, fmt.Sprintf("Language: %s", language)) + helper.ExpectString(ctx, fmt.Sprintf("Language: %s", language)) - helper.ExpectString(ctx, fmt.Sprintf("Project type: %s", projectType)) + helper.ExpectString(ctx, fmt.Sprintf("Project type: %s", projectType)) - helper.ExpectString(ctx, - fmt.Sprintf("The devfile \"%s\" from the registry \"DefaultDevfileRegistry\" will be downloaded.", devfileName)) + helper.ExpectString(ctx, + fmt.Sprintf("The devfile \"%s\" from the registry \"DefaultDevfileRegistry\" will be downloaded.", devfileName)) - helper.ExpectString(ctx, "Is this correct") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Is this correct") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Select container for which you want to change configuration") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select container for which you want to change configuration") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "myapp-") + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "myapp-") - helper.ExpectString(ctx, "name \"myapp-\" is not valid, name should conform the following requirements") + helper.ExpectString(ctx, "name \"myapp-\" is not valid, name should conform the following requirements") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, fmt.Sprintf("Your new component '%s' is ready in the current directory", projectName)) + helper.ExpectString(ctx, fmt.Sprintf("Your new component '%s' is ready in the current directory", projectName)) + }) + Expect(err).To(BeNil()) + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) + }) }) - Expect(err).To(BeNil()) - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) }) - }) - }) - - It("should start downloading starter project only after all interactive questions have been asked", func() { - output, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { + It("should start downloading starter project only after all interactive questions have been asked", func() { - helper.ExpectString(ctx, "Select language") - helper.SendLine(ctx, ".NET") + output, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, "Select project type") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select language") + helper.SendLine(ctx, ".NET") - helper.ExpectString(ctx, "Select container for which you want to change configuration?") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select project type") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Which starter project do you want to use") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select container for which you want to change configuration?") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "my-dotnet-app") + helper.ExpectString(ctx, "Which starter project do you want to use") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Your new component 'my-dotnet-app' is ready in the current directory") - }) + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "my-dotnet-app") - Expect(err).To(BeNil()) + helper.ExpectString(ctx, "Your new component 'my-dotnet-app' is ready in the current directory") + }) - lines, err := helper.ExtractLines(output) - Expect(err).To(BeNil()) - Expect(len(lines)).To(BeNumerically(">", 2)) - Expect(lines[len(lines)-1]).To(Equal("Your new component 'my-dotnet-app' is ready in the current directory")) + Expect(err).To(BeNil()) - componentNameQuestionIdx, ok := helper.FindFirstElementIndexMatchingRegExp(lines, ".*Enter component name:.*") - Expect(ok).To(BeTrue()) - starterProjectDownloadActionIdx, found := helper.FindFirstElementIndexMatchingRegExp(lines, - ".*Downloading starter project \"([^\\s]+)\" \\[.*") - Expect(found).To(BeTrue()) - Expect(starterProjectDownloadActionIdx).To(SatisfyAll( - Not(BeZero()), - // #5495: component name question should be displayed before starter project is actually downloaded - BeNumerically(">", componentNameQuestionIdx), - ), "Action 'Downloading starter project' should have been displayed after the last interactive question ('Enter component name')") + lines, err := helper.ExtractLines(output) + Expect(err).To(BeNil()) + Expect(len(lines)).To(BeNumerically(">", 2)) + Expect(lines[len(lines)-1]).To(Equal("Your new component 'my-dotnet-app' is ready in the current directory")) + + componentNameQuestionIdx, ok := helper.FindFirstElementIndexMatchingRegExp(lines, ".*Enter component name:.*") + Expect(ok).To(BeTrue()) + starterProjectDownloadActionIdx, found := helper.FindFirstElementIndexMatchingRegExp(lines, + ".*Downloading starter project \"([^\\s]+)\" \\[.*") + Expect(found).To(BeTrue()) + Expect(starterProjectDownloadActionIdx).To(SatisfyAll( + Not(BeZero()), + // #5495: component name question should be displayed before starter project is actually downloaded + BeNumerically(">", componentNameQuestionIdx), + ), "Action 'Downloading starter project' should have been displayed after the last interactive question ('Enter component name')") - Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) - }) + Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml")) + }) - Context("Automatic port detection via Alizer", func() { + Context("Automatic port detection via Alizer", func() { - When("starting with an existing project", func() { - const appPort = 34567 + When("starting with an existing project", func() { + const appPort = 34567 - BeforeEach(func() { - helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) - helper.ReplaceString(filepath.Join(commonVar.Context, "Dockerfile"), "EXPOSE 8080", fmt.Sprintf("EXPOSE %d", appPort)) - }) + BeforeEach(func() { + helper.CopyExample(filepath.Join("source", "nodejs"), commonVar.Context) + helper.ReplaceString(filepath.Join(commonVar.Context, "Dockerfile"), "EXPOSE 8080", fmt.Sprintf("EXPOSE %d", appPort)) + }) - It("should display ports detected", func() { - _, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { - helper.ExpectString(ctx, fmt.Sprintf("Application ports: %d", appPort)) + It("should display ports detected", func() { + _, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) { + helper.ExpectString(ctx, fmt.Sprintf("Application ports: %d", appPort)) - helper.SendLine(ctx, "Is this correct") - helper.SendLine(ctx, "") + helper.SendLine(ctx, "Is this correct") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Select container for which you want to change configuration") - helper.SendLine(ctx, "") + helper.ExpectString(ctx, "Select container for which you want to change configuration") + helper.SendLine(ctx, "") - helper.ExpectString(ctx, "Enter component name") - helper.SendLine(ctx, "my-nodejs-app-with-port-detected") + helper.ExpectString(ctx, "Enter component name") + helper.SendLine(ctx, "my-nodejs-app-with-port-detected") - helper.ExpectString(ctx, "Your new component 'my-nodejs-app-with-port-detected' is ready in the current directory") - }) - Expect(err).ShouldNot(HaveOccurred()) + helper.ExpectString(ctx, "Your new component 'my-nodejs-app-with-port-detected' is ready in the current directory") + }) + Expect(err).ShouldNot(HaveOccurred()) - // Now make sure the Devfile contains a single container component with the right endpoint - d, err := parser.ParseDevfile(parser.ParserArgs{Path: filepath.Join(commonVar.Context, "devfile.yaml"), FlattenedDevfile: pointer.BoolPtr(false)}) - Expect(err).ShouldNot(HaveOccurred()) + // Now make sure the Devfile contains a single container component with the right endpoint + d, err := parser.ParseDevfile(parser.ParserArgs{Path: filepath.Join(commonVar.Context, "devfile.yaml"), FlattenedDevfile: pointer.BoolPtr(false)}) + Expect(err).ShouldNot(HaveOccurred()) - containerComponents, err := d.Data.GetDevfileContainerComponents(common.DevfileOptions{}) - Expect(err).ShouldNot(HaveOccurred()) + containerComponents, err := d.Data.GetDevfileContainerComponents(common.DevfileOptions{}) + Expect(err).ShouldNot(HaveOccurred()) - allPortsExtracter := func(comps []v1alpha2.Component) []int { - var ports []int - for _, c := range comps { - for _, ep := range c.Container.Endpoints { - ports = append(ports, ep.TargetPort) + allPortsExtracter := func(comps []v1alpha2.Component) []int { + var ports []int + for _, c := range comps { + for _, ep := range c.Container.Endpoints { + ports = append(ports, ep.TargetPort) + } + } + return ports } - } - return ports - } - Expect(containerComponents).Should(WithTransform(allPortsExtracter, ContainElements(appPort))) + Expect(containerComponents).Should(WithTransform(allPortsExtracter, ContainElements(appPort))) + }) + }) }) }) - }) + } })