Files
odo/tests/integration/interactive_init_test.go
Parthvi Vala 0cdc2e5542 Fix: odo init overwrites personalized configuration when downloading starter project (#6800)
* Fix personalized configuration overwritten by starter project

Signed-off-by: Parthvi Vala <pvala@redhat.com>

* Update pkg/registry/registry_test.go

Co-authored-by: Armel Soro <armel@rm3l.org>
Signed-off-by: Parthvi Vala <pvala@redhat.com>

* Adding intergration tests for personalizing configurations with odo init

Signed-off-by: Ritu Deshmukh <rideshmu@redhat.com>

Modified changes

Signed-off-by: Ritu Deshmukh <rideshmu@redhat.com>

Update tests/integration/interactive_init_test.go

Co-authored-by: Parthvi Vala <pvala@redhat.com>

Update tests/integration/interactive_init_test.go

Co-authored-by: Parthvi Vala <pvala@redhat.com>

Update interactive_init_test.go

Update interactive_init_test.go

Update interactive_init_test.go

Update tests/integration/interactive_init_test.go

Co-authored-by: Parthvi Vala <pvala@redhat.com>

Update interactive_init_test.go

* Updated changes

Signed-off-by: Ritu Deshmukh <rideshmu@redhat.com>

* Attempt at fixing interactive tests

Signed-off-by: Parthvi Vala <pvala@redhat.com>

* Add multiple devfile version check

Co-authored-by: Armel Soro <asoro@redhat.com>
Signed-off-by: Parthvi Vala <pvala@redhat.com>

---------

Signed-off-by: Parthvi Vala <pvala@redhat.com>
Signed-off-by: Ritu Deshmukh <rideshmu@redhat.com>
Co-authored-by: Armel Soro <armel@rm3l.org>
Co-authored-by: Ritu Deshmukh <rideshmu@redhat.com>
Co-authored-by: Armel Soro <asoro@redhat.com>
2023-05-11 16:06:49 -04:00

750 lines
28 KiB
Go

package integration
import (
"fmt"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
"github.com/devfile/library/v2/pkg/devfile/parser"
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
"k8s.io/utils/pointer"
"github.com/redhat-developer/odo/pkg/odo/cli/messages"
"github.com/redhat-developer/odo/pkg/util"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
odolog "github.com/redhat-developer/odo/pkg/log"
"github.com/redhat-developer/odo/pkg/version"
"github.com/redhat-developer/odo/tests/helper"
)
var _ = Describe("odo init interactive command tests", 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)
})
for _, label := range []string{
helper.LabelNoCluster, helper.LabelUnauth,
} {
label := label
var _ = Context("label "+label, Label(label), func() {
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)
})
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "Go")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
helper.ExpectString(ctx, "Select version")
helper.SendLine(ctx, "")
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, "")
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, "my-go-app")
helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory")
})
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"))
})
Context("personalizing Devfile configuration", func() {
var hasMultipleVersions bool
BeforeEach(func() {
out := helper.Cmd("odo", "registry", "--devfile", "nodejs", "--devfile-registry", "DefaultDevfileRegistry").ShouldPass().Out()
// Version pattern has always been in the form of X.X.X
vMatch := regexp.MustCompile(`(\d.\d.\d)`)
if matches := vMatch.FindAll([]byte(out), -1); len(matches) > 1 {
hasMultipleVersions = true
}
})
It("should allow for personalizing configurations", func() {
command := []string{"odo", "init"}
output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) {
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "Javascript")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
if hasMultipleVersions {
helper.ExpectString(ctx, "Select version")
helper.SendLine(ctx, "")
}
helper.ExpectString(ctx, "Select container for which you want to change configuration?")
helper.ExpectString(ctx, "runtime")
helper.SendLine(ctx, "runtime")
helper.ExpectString(ctx, "What configuration do you want change")
helper.SendLine(ctx, "Add new port")
helper.ExpectString(ctx, "Enter port number:")
helper.SendLine(ctx, "5000")
helper.ExpectString(ctx, "What configuration do you want change")
helper.SendLine(ctx, "Delete port \"3000\"")
helper.ExpectString(ctx, "What configuration do you want change")
helper.SendLine(ctx, "Add new environment variable")
helper.ExpectString(ctx, "Enter new environment variable name: ")
helper.SendLine(ctx, "DEBUG_PROJECT_PORT")
helper.ExpectString(ctx, "Enter value for \"DEBUG_PROJECT_PORT\" environment variable:")
helper.SendLine(ctx, "5858")
helper.ExpectString(ctx, "What configuration do you want change")
helper.SendLine(ctx, "Delete environment variable \"DEBUG_PORT\"")
helper.ExpectString(ctx, "What configuration do you want change")
helper.SendLine(ctx, "NOTHING - configuration is correct")
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, "nodejs-starter")
helper.ExpectString(ctx, "Enter component name:")
helper.SendLine(ctx, "my-nodejs-app")
helper.ExpectString(ctx, "Your new component 'my-nodejs-app' is ready in the current directory.")
})
Expect(err).To(BeNil())
Expect(output).To(ContainSubstring("Your new component 'my-nodejs-app' is ready in the current directory."))
Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml"))
helper.FileShouldContainSubstring(filepath.Join(commonVar.Context, "devfile.yaml"), "5000")
helper.FileShouldNotContainSubstring(filepath.Join(commonVar.Context, "devfile.yaml"), "3000")
helper.FileShouldContainSubstring(filepath.Join(commonVar.Context, "devfile.yaml"), "DEBUG_PROJECT_PORT")
helper.FileShouldNotContainSubstring(filepath.Join(commonVar.Context, "devfile.yaml"), "DEBUG_PORT")
})
})
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 language")
helper.SendLine(ctx, "Go")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
helper.ExpectString(ctx, "Select version")
helper.SendLine(ctx, "")
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, "")
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, "myapp-<script>alert('Injected!');</script>")
helper.ExpectString(ctx, "name \"myapp-<script>alert('Injected!');</script>\" is not valid, name should conform the following requirements")
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, "my-go-app")
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"))
})
It("should print automation command with proper values", func() {
// 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")
}
command := []string{"odo", "init"}
starter := "go-starter"
componentName := "my-go-app"
devfileName := "go"
devfileVersion := "1.0.2"
output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) {
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "Go")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
helper.ExpectString(ctx, "Select version")
helper.SendLine(ctx, "")
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, starter)
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, componentName)
helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory")
})
Expect(err).To(BeNil())
Expect(output).To(ContainSubstring("odo init --name %s --devfile %s --devfile-registry DefaultDevfileRegistry --devfile-version %s --starter %s", componentName, devfileName, devfileVersion, 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"))
})
It("should download correct devfile", func() {
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)
})
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "Go")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
helper.ExpectString(ctx, "Select version")
helper.SendLine(ctx, "")
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, "")
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, "my-go-app")
helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory")
})
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"))
})
It("should ask to download the starter project when the devfile stack has extra files", func() {
command := []string{"odo", "init"}
starter := "go-starter"
componentName := "my-go-app"
devfileVersion := "2.0.0"
output, err := helper.RunInteractive(command, nil, func(ctx helper.InteractiveContext) {
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "Go")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
helper.ExpectString(ctx, "Select version")
helper.SendLine(ctx, devfileVersion)
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, starter)
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, componentName)
helper.ExpectString(ctx, "Your new component 'my-go-app' is ready in the current directory")
})
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", "kubernetes", "docker", "go.mod", "main.go"))
})
It("should download correct devfile-starter", func() {
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)
})
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "java")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "Vert.x Java")
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")
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, "my-app")
helper.ExpectString(ctx, "Your new component 'my-app' is ready in the current directory")
})
Expect(err).To(BeNil())
Expect(output).To(ContainSubstring("Downloading starter project \"vertx-cache-example-redhat\""))
})
Describe("displaying welcoming messages", func() {
// 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 additionalTester != nil {
additionalTester(ctx)
}
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))
})
It("should display appropriate welcoming messages", func() {
if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" {
Skip("This is a Unix specific scenario, skipping")
}
language := "java"
// The first output is welcoming message / paragraph / banner output
welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.NoSourceCodeDetected, "odo version: "+version.VERSION), "\n")
output, err := testRunner(language, welcomingMsgs, func(ctx helper.InteractiveContext) {
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, language)
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
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, "")
})
assertBehavior(strings.ToLower(language), output, err, welcomingMsgs, nil)
})
})
When("directory is not empty", 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")))
})
It("should display appropriate welcoming messages", func() {
if os.Getenv("SKIP_WELCOMING_MESSAGES") == "true" {
Skip("This is a Unix specific scenario, skipping")
}
language := "Python"
projectType := "Python"
versionedDevfileName := "python:2.1.0"
welcomingMsgs := strings.Split(odolog.Stitle(messages.InitializingNewComponent, messages.SourceCodeDetected, "odo version: "+version.VERSION), "\n")
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("Language: %s", language))
helper.ExpectString(ctx, fmt.Sprintf("Project type: %s", projectType))
helper.ExpectString(ctx,
fmt.Sprintf("The devfile %q from the registry \"DefaultDevfileRegistry\" will be downloaded.", versionedDevfileName))
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)))
})
})
})
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")))
})
It("should display node-echo name", func() {
language := "JavaScript"
projectType := "Node.js"
projectName := "node-echo"
versionedDevfileName := "nodejs:2.1.1"
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("Project type: %s", projectType))
helper.ExpectString(ctx,
fmt.Sprintf("The devfile %q from the registry \"DefaultDevfileRegistry\" will be downloaded.", versionedDevfileName))
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, "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())
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"
versionedDevfileName := "nodejs:2.1.1"
_, 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("Project type: %s", projectType))
helper.ExpectString(ctx,
fmt.Sprintf("The devfile %q from the registry \"DefaultDevfileRegistry\" will be downloaded.", versionedDevfileName))
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, "Enter component name")
helper.SendLine(ctx, "myapp-<script>alert('Injected!');</script>")
helper.ExpectString(ctx, "name \"myapp-<script>alert('Injected!');</script>\" is not valid, name should conform the following requirements")
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())
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) {
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, ".NET")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
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, "")
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, "my-dotnet-app")
helper.ExpectString(ctx, "Your new component 'my-dotnet-app' is ready in the current directory")
})
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("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"))
})
Context("Automatic port detection via Alizer", func() {
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))
})
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.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, "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.Bool(false)})
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)
}
}
return ports
}
Expect(containerComponents).Should(WithTransform(allPortsExtracter, ContainElements(appPort)))
})
})
})
When("Alizer cannot determine a Devfile based on the current source code", func() {
BeforeEach(func() {
helper.CreateSimpleFile(commonVar.Context, "some-file-", ".ext")
})
It("should not fail but fallback to the interactive mode", func() {
output, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) {
helper.ExpectString(ctx, "Could not determine a Devfile based on the files in the current directory")
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "PHP")
helper.ExpectString(ctx, "Select project type")
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-php-app")
helper.ExpectString(ctx, "Your new component 'my-php-app' is ready in the current directory")
})
Expect(err).ShouldNot(HaveOccurred())
Expect(output).ShouldNot(ContainSubstring("Which starter project do you want to use"))
Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElement("devfile.yaml"))
})
})
})
}
When("DevfileRegistriesList CRD is installed on cluster", func() {
BeforeEach(func() {
if !helper.IsKubernetesCluster() {
Skip("skipped on non Kubernetes clusters")
}
devfileRegistriesLists := commonVar.CliRunner.Run("apply", "-f", helper.GetExamplePath("manifests", "devfileregistrieslists.yaml"))
Expect(devfileRegistriesLists.ExitCode()).To(BeEquivalentTo(0))
})
When("CR for devfileregistrieslists is installed in namespace", func() {
const devfileRegistryName = "ns-devfile-reg"
BeforeEach(func() {
manifestFilePath := filepath.Join(commonVar.ConfigDir, "devfileRegistryListCR.yaml")
// NOTE: Use reachable URLs as we might be on a cluster with the registry operator installed, which would perform validations.
err := helper.CreateFileWithContent(manifestFilePath, fmt.Sprintf(`
apiVersion: registry.devfile.io/v1alpha1
kind: DevfileRegistriesList
metadata:
name: namespace-list
spec:
devfileRegistries:
- name: %s
url: %q
`, devfileRegistryName, helper.GetDevfileRegistryURL()))
Expect(err).ToNot(HaveOccurred())
command := commonVar.CliRunner.Run("-n", commonVar.Project, "apply", "-f", manifestFilePath)
Expect(command.ExitCode()).To(BeEquivalentTo(0))
})
It("should download correct devfile from the first in-cluster registry", func() {
// 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")
}
output, err := helper.RunInteractive([]string{"odo", "init"}, nil, func(ctx helper.InteractiveContext) {
helper.ExpectString(ctx, "Select language")
helper.SendLine(ctx, "Java")
helper.ExpectString(ctx, "Select project type")
helper.SendLine(ctx, "")
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, "")
helper.ExpectString(ctx, "Enter component name")
helper.SendLine(ctx, "my-java-maven-app")
helper.ExpectString(ctx, "Your new component 'my-java-maven-app' is ready in the current directory")
})
Expect(err).ShouldNot(HaveOccurred())
By("displaying automation command with the in-cluster registry", func() {
Expect(output).Should(ContainSubstring(
"odo init --name my-java-maven-app --devfile java-maven --devfile-registry %s --starter springbootproject", devfileRegistryName))
})
By("actually downloading the Devfile", func() {
Expect(helper.ListFilesInDir(commonVar.Context)).To(ContainElements("devfile.yaml"))
})
})
})
})
})