mirror of
https://github.com/redhat-developer/odo.git
synced 2025-10-19 03:06:19 +03:00
* Introduce new 'pkg/remotecmd' package This package allows to execute commands in remote packages and exposes an interface for managing processes associated to given Devfile commands. * Rely on 'pkg/libdevfile' as much as possible for Devfile command execution This requires passing a handler at the odo side, which in turns uses the 'pkg/remotecmd' package to run commands in remote containers. * Switch to running without Supervisord as PID 1 in containers To do this, the idea is to start the container component: 1- using the command/args defined in the Devfile 2- using whatever was defined in the container image if there is no command/args defined in the Devfile Then, once the container is started, we would execute the Devfile commands directly in the container component, just like a simple 'kubectl exec' command would do. Since this is a long-running command (and potentially never ending), we would need to run it in the background, i.e. in a side goroutine. Point 2) above requires implementing a temporary hack (as discussed in [1]), without us having to wait for [2] to be merged on the Devfile side. This temporary hack overrides the container entrypoint with "tail -f /dev/null" if the component defines no command or args (in which case we should have used whatever is defined in the image, per the specification). [1] https://github.com/redhat-developer/odo/pull/5768#issuecomment-1147190409 [2] https://github.com/devfile/registry/pull/102 * Rename K8s adapter struct 'client' field into 'kubeClient', as suggested in review * Rename sync adapter struct 'client' fields to better distinguish between them * Make sure messages displayed to users running 'odo dev' are the same * Update temporary hack log message Co-authored-by: Philippe Martin <contact@elol.fr> * Make sure to handle process output line by line, for performance purposes * Handle remote process output and errors in the Devfile command handler The implementation in kubeexec.go should remain as generic as possible * Keep retrying remote process status until timeout, rather than just waiting for 1 sec Now that the command is run via a goroutine, there might be some situations where we were checking the status just before the goroutine had a chance to start. * Handle remote process output and errors in the Devfile command handler The implementation in kubeexec.go should remain as generic as possible * Update kubeexec StopProcessForCommand implementation such that it relies on /proc to kill the parent children processes * Ignore missing children file in getProcessChildren * Unit-test methods in kubexec.go * Fix missing logs when build command does not pass when running 'odo dev' Also add integration test case * Fix spinner status when commands passed to exec_handler do not pass * Make sure to check process status right after stopping it The process just stopped might take longer to exit (it might have caught the signal and is performing additional cleanup) * Keep retrying remote process status until timeout, rather than just waiting for 1 sec Now that the command is run via a goroutine, there might be some situations where we were checking the status just before the goroutine had a chance to start. * Fix potential deadlock when reading output from remotecmd#ExecuteCommandAndGetOutput Rely on the same logic in ExecuteCommand * Add more unit tests * Remove block that used to check debug port from env info As commented out in [1], we don't store anymore the debug port value in the ENV file. [1] https://github.com/redhat-developer/odo/pull/5768#discussion_r893163382 * Rename 'getCommandFromFlag' into 'getCommandByName', as suggested in review * Make remotecmd package more generic This package no longer depends on Devfile-related packages. * Fix comments in libdevfile.go * Move errorIfTimeout struct field as parameter of RetryWithSchedule This boolean is tied to the given retry schedule, so it makes sense for it to be passed with the schedule. * Expose a single ExecuteCommand function that returns both stdout and stderr Co-authored-by: Philippe Martin <contact@elol.fr>
2565 lines
70 KiB
Go
2565 lines
70 KiB
Go
package libdevfile
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
|
"github.com/devfile/library/pkg/devfile/parser"
|
|
"github.com/devfile/library/pkg/devfile/parser/data"
|
|
devfileFileSystem "github.com/devfile/library/pkg/testingutil/filesystem"
|
|
dfutil "github.com/devfile/library/pkg/util"
|
|
"github.com/golang/mock/gomock"
|
|
"github.com/kylelemons/godebug/pretty"
|
|
"k8s.io/utils/pointer"
|
|
|
|
"github.com/redhat-developer/odo/pkg/libdevfile/generator"
|
|
"github.com/redhat-developer/odo/pkg/testingutil"
|
|
"github.com/redhat-developer/odo/pkg/util"
|
|
)
|
|
|
|
var buildGroup = v1alpha2.BuildCommandGroupKind
|
|
var runGroup = v1alpha2.RunCommandGroupKind
|
|
var debugGroup = v1alpha2.DebugCommandGroupKind
|
|
|
|
func TestGetDefaultCommand(t *testing.T) {
|
|
|
|
runDefault1 := generator.GetExecCommand(generator.ExecCommandParams{
|
|
Kind: v1alpha2.RunCommandGroupKind,
|
|
Id: "run-default-1",
|
|
IsDefault: pointer.BoolPtr(true),
|
|
})
|
|
deployDefault1 := generator.GetCompositeCommand(generator.CompositeCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "deploy-default-1",
|
|
IsDefault: pointer.BoolPtr(true),
|
|
})
|
|
deployDefault2 := generator.GetExecCommand(generator.ExecCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "deploy-default-2",
|
|
IsDefault: pointer.BoolPtr(true),
|
|
})
|
|
deployNoDefault1 := generator.GetApplyCommand(generator.ApplyCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "deploy-no-default-1",
|
|
IsDefault: pointer.BoolPtr(false),
|
|
})
|
|
deployUnspecDefault1 := generator.GetCompositeCommand(generator.CompositeCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "deploy-unspec-default-1",
|
|
IsDefault: nil,
|
|
})
|
|
|
|
type args struct {
|
|
devfileObj func() parser.DevfileObj
|
|
kind v1alpha2.CommandGroupKind
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want v1alpha2.Command
|
|
wantErr error
|
|
}{
|
|
{
|
|
name: "a single deploy command, default",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{runDefault1, deployDefault1})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
kind: v1alpha2.DeployCommandGroupKind,
|
|
},
|
|
wantErr: nil,
|
|
want: deployDefault1,
|
|
},
|
|
{
|
|
name: "a single deploy command, not default",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{runDefault1, deployNoDefault1})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
kind: v1alpha2.DeployCommandGroupKind,
|
|
},
|
|
wantErr: nil,
|
|
want: deployNoDefault1,
|
|
},
|
|
{
|
|
name: "a single deploy command, unspecified default",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{runDefault1, deployUnspecDefault1})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
kind: v1alpha2.DeployCommandGroupKind,
|
|
},
|
|
wantErr: nil,
|
|
want: deployUnspecDefault1,
|
|
},
|
|
{
|
|
name: "several deploy commands, only one is default",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{runDefault1, deployDefault1, deployNoDefault1, deployUnspecDefault1})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
kind: v1alpha2.DeployCommandGroupKind,
|
|
},
|
|
wantErr: nil,
|
|
want: deployDefault1,
|
|
},
|
|
{
|
|
name: "no deploy command",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{runDefault1})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
kind: v1alpha2.DeployCommandGroupKind,
|
|
},
|
|
wantErr: NewNoCommandFoundError(v1alpha2.DeployCommandGroupKind),
|
|
},
|
|
{
|
|
name: "two deploy default commands",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{runDefault1, deployDefault1, deployDefault2})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
kind: v1alpha2.DeployCommandGroupKind,
|
|
},
|
|
wantErr: NewMoreThanOneDefaultCommandFoundError(v1alpha2.DeployCommandGroupKind),
|
|
},
|
|
{
|
|
name: "two deploy commands, no one is default",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{runDefault1, deployNoDefault1, deployUnspecDefault1})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
kind: v1alpha2.DeployCommandGroupKind,
|
|
},
|
|
wantErr: NewNoDefaultCommandFoundError(v1alpha2.DeployCommandGroupKind),
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := GetDefaultCommand(tt.args.devfileObj(), tt.args.kind)
|
|
if err != tt.wantErr {
|
|
t.Errorf("GetDefaultCommand() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("GetDefaultCommand() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeploy(t *testing.T) {
|
|
deployDefault1 := generator.GetCompositeCommand(generator.CompositeCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "deploy-default-1",
|
|
IsDefault: pointer.BoolPtr(true),
|
|
Commands: []string{"image-command", "deployment-command", "service-command"},
|
|
})
|
|
applyImageCommand := generator.GetApplyCommand(generator.ApplyCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "image-command",
|
|
IsDefault: pointer.BoolPtr(false),
|
|
Component: "image-component",
|
|
})
|
|
applyDeploymentCommand := generator.GetApplyCommand(generator.ApplyCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "deployment-command",
|
|
IsDefault: pointer.BoolPtr(false),
|
|
Component: "deployment-component",
|
|
})
|
|
applyServiceCommand := generator.GetApplyCommand(generator.ApplyCommandParams{
|
|
Kind: v1alpha2.DeployCommandGroupKind,
|
|
Id: "service-command",
|
|
IsDefault: pointer.BoolPtr(false),
|
|
Component: "service-component",
|
|
})
|
|
|
|
imageComponent := generator.GetImageComponent(generator.ImageComponentParams{
|
|
Name: "image-component",
|
|
Image: v1alpha2.Image{
|
|
ImageName: "an-image-name",
|
|
},
|
|
})
|
|
deploymentComponent := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: "deployment-component",
|
|
Kubernetes: &v1alpha2.KubernetesComponent{},
|
|
})
|
|
serviceComponent := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: "service-component",
|
|
Kubernetes: &v1alpha2.KubernetesComponent{},
|
|
})
|
|
|
|
type args struct {
|
|
devfileObj func() parser.DevfileObj
|
|
handler func(ctrl *gomock.Controller) Handler
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "deploy an image and two kubernetes components",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddCommands([]v1alpha2.Command{deployDefault1, applyImageCommand, applyDeploymentCommand, applyServiceCommand})
|
|
_ = data.AddComponents([]v1alpha2.Component{imageComponent, deploymentComponent, serviceComponent})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
handler: func(ctrl *gomock.Controller) Handler {
|
|
h := NewMockHandler(ctrl)
|
|
h.EXPECT().ApplyImage(imageComponent)
|
|
h.EXPECT().ApplyKubernetes(deploymentComponent)
|
|
h.EXPECT().ApplyKubernetes(serviceComponent)
|
|
return h
|
|
},
|
|
},
|
|
},
|
|
// TODO: Add test cases.
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
if err := Deploy(tt.args.devfileObj(), tt.args.handler(ctrl)); (err != nil) != tt.wantErr {
|
|
t.Errorf("Deploy() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetContainerEndpointMapping(t *testing.T) {
|
|
type args struct {
|
|
containers []v1alpha2.Component
|
|
}
|
|
|
|
imageComponent := generator.GetImageComponent(generator.ImageComponentParams{
|
|
Name: "image-component",
|
|
Image: v1alpha2.Image{
|
|
ImageName: "an-image-name",
|
|
},
|
|
})
|
|
|
|
containerWithNoEndpoints := generator.GetContainerComponent(generator.ContainerComponentParams{
|
|
Name: "container 1",
|
|
Endpoints: nil,
|
|
})
|
|
|
|
containerWithOnePublicEndpoint := generator.GetContainerComponent(generator.ContainerComponentParams{
|
|
Name: "container 2",
|
|
Endpoints: []v1alpha2.Endpoint{
|
|
{
|
|
Name: "ep1",
|
|
TargetPort: 8080,
|
|
Exposure: v1alpha2.PublicEndpointExposure,
|
|
},
|
|
},
|
|
})
|
|
|
|
containerWithOneInternalEndpoint := generator.GetContainerComponent(generator.ContainerComponentParams{
|
|
Name: "container 3",
|
|
Endpoints: []v1alpha2.Endpoint{
|
|
{
|
|
Name: "ep2",
|
|
TargetPort: 9090,
|
|
Exposure: v1alpha2.InternalEndpointExposure,
|
|
},
|
|
},
|
|
})
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want map[string][]int
|
|
}{
|
|
{
|
|
name: "invalid input - image components instead of container components",
|
|
args: args{
|
|
containers: []v1alpha2.Component{imageComponent},
|
|
},
|
|
want: map[string][]int{},
|
|
},
|
|
{
|
|
name: "one container with no endpoints exposed",
|
|
args: args{
|
|
containers: []v1alpha2.Component{containerWithNoEndpoints},
|
|
},
|
|
want: map[string][]int{containerWithNoEndpoints.Name: {}},
|
|
},
|
|
{
|
|
name: "multiple containers with varying types of endpoints",
|
|
args: args{
|
|
containers: []v1alpha2.Component{containerWithNoEndpoints, containerWithOnePublicEndpoint, containerWithOneInternalEndpoint},
|
|
},
|
|
want: map[string][]int{containerWithNoEndpoints.Name: {}, containerWithOnePublicEndpoint.Name: {8080}, containerWithOneInternalEndpoint.Name: {9090}},
|
|
},
|
|
{
|
|
name: "invalid input - one image component with rest being containers",
|
|
args: args{
|
|
containers: []v1alpha2.Component{containerWithNoEndpoints, containerWithOnePublicEndpoint, containerWithOneInternalEndpoint, imageComponent},
|
|
},
|
|
want: map[string][]int{containerWithNoEndpoints.Name: {}, containerWithOnePublicEndpoint.Name: {8080}, containerWithOneInternalEndpoint.Name: {9090}},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := GetContainerEndpointMapping(tt.args.containers)
|
|
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("GetContainerEndpointMapping() got = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetEndpointsFromDevfile(t *testing.T) {
|
|
type args struct {
|
|
devfileObj func() parser.DevfileObj
|
|
ignoreExposures []v1alpha2.EndpointExposure
|
|
}
|
|
ep1 := v1alpha2.Endpoint{Name: "ep1", TargetPort: 8080, Exposure: v1alpha2.NoneEndpointExposure}
|
|
ep2 := v1alpha2.Endpoint{Name: "ep2", TargetPort: 9090, Exposure: v1alpha2.InternalEndpointExposure}
|
|
ep3 := v1alpha2.Endpoint{Name: "ep3", TargetPort: 8888, Exposure: v1alpha2.PublicEndpointExposure}
|
|
|
|
container := generator.GetContainerComponent(generator.ContainerComponentParams{
|
|
Name: "container-1",
|
|
Endpoints: []v1alpha2.Endpoint{ep1, ep2, ep3},
|
|
})
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []v1alpha2.Endpoint
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Ignore exposure of type none",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddComponents([]v1alpha2.Component{container})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
ignoreExposures: []v1alpha2.EndpointExposure{v1alpha2.NoneEndpointExposure},
|
|
},
|
|
want: []v1alpha2.Endpoint{ep2, ep3},
|
|
},
|
|
{
|
|
name: "Ignore exposure of type public",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddComponents([]v1alpha2.Component{container})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
ignoreExposures: []v1alpha2.EndpointExposure{v1alpha2.PublicEndpointExposure},
|
|
},
|
|
want: []v1alpha2.Endpoint{ep1, ep2},
|
|
},
|
|
{
|
|
name: "Ignore exposure of type internal",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddComponents([]v1alpha2.Component{container})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
ignoreExposures: []v1alpha2.EndpointExposure{v1alpha2.InternalEndpointExposure},
|
|
},
|
|
want: []v1alpha2.Endpoint{ep1, ep3},
|
|
},
|
|
{
|
|
name: "Ignore none",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddComponents([]v1alpha2.Component{container})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
ignoreExposures: []v1alpha2.EndpointExposure{},
|
|
},
|
|
want: []v1alpha2.Endpoint{ep1, ep2, ep3},
|
|
},
|
|
{
|
|
name: "Ignore all exposure types",
|
|
args: args{
|
|
devfileObj: func() parser.DevfileObj {
|
|
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
_ = data.AddComponents([]v1alpha2.Component{container})
|
|
return parser.DevfileObj{
|
|
Data: data,
|
|
}
|
|
},
|
|
ignoreExposures: []v1alpha2.EndpointExposure{v1alpha2.InternalEndpointExposure, v1alpha2.NoneEndpointExposure, v1alpha2.PublicEndpointExposure},
|
|
},
|
|
want: nil,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := GetEndpointsFromDevfile(tt.args.devfileObj(), tt.args.ignoreExposures)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("GetEndpointsFromDevfile() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("GetEndpointsFromDevfile() got = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetK8sManifestWithVariablesSubstituted(t *testing.T) {
|
|
fakeFs := devfileFileSystem.NewFakeFs()
|
|
cmpName := "my-cmp-1"
|
|
for _, tt := range []struct {
|
|
name string
|
|
setupFunc func() error
|
|
devfileObjFunc func() parser.DevfileObj
|
|
wantErr bool
|
|
want string
|
|
}{
|
|
{
|
|
name: "Missing Component",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetContainerComponent(generator.ContainerComponentParams{
|
|
Name: "a-different-component",
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Multiple Components with the same name",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp1 := generator.GetContainerComponent(generator.ContainerComponentParams{
|
|
Name: cmpName,
|
|
})
|
|
cmp2 := generator.GetImageComponent(generator.ImageComponentParams{
|
|
Name: cmpName,
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Components: []v1alpha2.Component{cmp1, cmp2},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Container Component",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetContainerComponent(generator.ContainerComponentParams{
|
|
Name: cmpName,
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Image Component",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetImageComponent(generator.ImageComponentParams{
|
|
Name: cmpName,
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Kubernetes Component - Inlined with no variables",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: cmpName,
|
|
Kubernetes: &v1alpha2.KubernetesComponent{
|
|
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
|
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
|
Inlined: "some-text-inlined",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: false,
|
|
want: "some-text-inlined",
|
|
},
|
|
{
|
|
name: "Kubernetes Component - Inlined with variables",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: cmpName,
|
|
Kubernetes: &v1alpha2.KubernetesComponent{
|
|
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
|
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
|
Inlined: "image: {{MY_CONTAINER_IMAGE}}",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Variables: map[string]string{
|
|
"MY_CONTAINER_IMAGE": "quay.io/unknown-account/my-image:1.2.3",
|
|
},
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: false,
|
|
want: "image: quay.io/unknown-account/my-image:1.2.3",
|
|
},
|
|
{
|
|
name: "Kubernetes Component - Inlined with unknown variables",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: cmpName,
|
|
Kubernetes: &v1alpha2.KubernetesComponent{
|
|
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
|
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
|
Inlined: "image: {{MY_CONTAINER_IMAGE}}:{{ MY_CONTAINER_IMAGE_VERSION_UNKNOWN }}",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Variables: map[string]string{
|
|
"MY_CONTAINER_IMAGE": "quay.io/unknown-account/my-image",
|
|
},
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: true,
|
|
want: "image: quay.io/unknown-account/my-image:{{ MY_CONTAINER_IMAGE_VERSION_UNKNOWN }}",
|
|
},
|
|
{
|
|
name: "Kubernetes Component - non-existing external file",
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: cmpName,
|
|
Kubernetes: &v1alpha2.KubernetesComponent{
|
|
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
|
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
|
Uri: "kubernetes/my-external-file-with-should-not-exist",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Kubernetes Component - URI with no variables",
|
|
setupFunc: func() error {
|
|
return fakeFs.WriteFile("kubernetes/my-external-file",
|
|
[]byte("some-text-with-no-variables"),
|
|
os.ModePerm)
|
|
},
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: cmpName,
|
|
Kubernetes: &v1alpha2.KubernetesComponent{
|
|
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
|
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
|
Uri: "kubernetes/my-external-file",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: false,
|
|
want: "some-text-with-no-variables",
|
|
},
|
|
{
|
|
name: "Kubernetes Component - URI with variables",
|
|
setupFunc: func() error {
|
|
return fakeFs.WriteFile("kubernetes/my-deployment.yaml",
|
|
[]byte("image: {{ MY_CONTAINER_IMAGE }}:{{MY_CONTAINER_IMAGE_VERSION}}"),
|
|
os.ModePerm)
|
|
},
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: cmpName,
|
|
Kubernetes: &v1alpha2.KubernetesComponent{
|
|
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
|
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
|
Uri: "kubernetes/my-deployment.yaml",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Variables: map[string]string{
|
|
"MY_CONTAINER_IMAGE": "quay.io/unknown-account/my-image",
|
|
"MY_CONTAINER_IMAGE_VERSION": "1.2.3",
|
|
},
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: false,
|
|
want: "image: quay.io/unknown-account/my-image:1.2.3",
|
|
},
|
|
{
|
|
name: "Kubernetes Component - URI with unknown variables",
|
|
setupFunc: func() error {
|
|
return fakeFs.WriteFile("kubernetes/my-external-file.yaml",
|
|
[]byte("image: {{MY_CONTAINER_IMAGE}}:{{ MY_CONTAINER_IMAGE_VERSION_UNKNOWN }}"),
|
|
os.ModePerm)
|
|
},
|
|
devfileObjFunc: func() parser.DevfileObj {
|
|
devfileData, _ := data.NewDevfileData(string(data.APISchemaVersion220))
|
|
cmp := generator.GetKubernetesComponent(generator.KubernetesComponentParams{
|
|
Name: cmpName,
|
|
Kubernetes: &v1alpha2.KubernetesComponent{
|
|
K8sLikeComponent: v1alpha2.K8sLikeComponent{
|
|
K8sLikeComponentLocation: v1alpha2.K8sLikeComponentLocation{
|
|
Uri: "kubernetes/my-external-file.yaml",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
s := v1alpha2.DevWorkspaceTemplateSpec{
|
|
DevWorkspaceTemplateSpecContent: v1alpha2.DevWorkspaceTemplateSpecContent{
|
|
Variables: map[string]string{
|
|
"MY_CONTAINER_IMAGE": "quay.io/unknown-account/my-image",
|
|
},
|
|
Components: []v1alpha2.Component{cmp},
|
|
},
|
|
}
|
|
devfileData.SetDevfileWorkspaceSpec(s)
|
|
return parser.DevfileObj{
|
|
Data: devfileData,
|
|
}
|
|
},
|
|
wantErr: true,
|
|
want: "image: quay.io/unknown-account/my-image:{{ MY_CONTAINER_IMAGE_VERSION_UNKNOWN }}",
|
|
},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setupFunc != nil {
|
|
if err := tt.setupFunc(); err != nil {
|
|
t.Errorf("setup function returned an error: %v", err)
|
|
return
|
|
}
|
|
}
|
|
if tt.devfileObjFunc == nil {
|
|
t.Error("devfileObjFunc function not defined for test case")
|
|
return
|
|
}
|
|
|
|
got, err := GetK8sManifestWithVariablesSubstituted(tt.devfileObjFunc(), cmpName, "", fakeFs)
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("GetK8sManifestWithVariablesSubstituted() error = %v, wantErr %v",
|
|
err, tt.wantErr)
|
|
return
|
|
}
|
|
if got != tt.want {
|
|
t.Errorf("GetK8sManifestWithVariablesSubstituted() got = %v, want %v",
|
|
got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetCommand(t *testing.T) {
|
|
|
|
commands := [...]string{"ls -la", "pwd"}
|
|
components := [...]string{"alias1", "alias2"}
|
|
|
|
tests := []struct {
|
|
name string
|
|
requestedType []v1alpha2.CommandGroupKind
|
|
execCommands []v1alpha2.Command
|
|
compCommands []v1alpha2.Command
|
|
reqCommandName string
|
|
retCommandName string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Valid devfile",
|
|
execCommands: []v1alpha2.Command{
|
|
getExecCommand("build", buildGroup),
|
|
getExecCommand("run", runGroup),
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup, runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Valid devfile with devrun and devbuild",
|
|
execCommands: []v1alpha2.Command{
|
|
getExecCommand("build", buildGroup),
|
|
getExecCommand("run", runGroup),
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup, runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 3: Valid devfile with empty workdir",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 4: Mismatched command type",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "build command",
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 5: Default command is returned",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "defaultRunCommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "runCommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
retCommandName: "defaultRunCommand",
|
|
requestedType: []v1alpha2.CommandGroupKind{runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 6: Composite command is returned",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(false)},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "run",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
compCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "myComposite",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Composite: &v1alpha2.CompositeCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
Commands: []string{"build", "run"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
retCommandName: "myComposite",
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
components := []v1alpha2.Component{testingutil.GetFakeContainerComponent(tt.execCommands[0].Exec.Component)}
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.compCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents(components)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
for _, gtype := range tt.requestedType {
|
|
cmd, err := getCommand(devObj.Data, tt.reqCommandName, gtype)
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("TestGetCommand unexpected error for command: %v wantErr: %v err: %v", gtype, tt.wantErr, err)
|
|
return
|
|
} else if tt.wantErr {
|
|
return
|
|
}
|
|
|
|
if len(tt.retCommandName) > 0 && cmd.Id != tt.retCommandName {
|
|
t.Errorf("TestGetCommand error: command names do not match expected: %v actual: %v", tt.retCommandName, cmd.Id)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func Test_getCommandAssociatedToGroup(t *testing.T) {
|
|
|
|
commands := [...]string{"ls -la", "pwd"}
|
|
components := [...]string{"alias1", "alias2"}
|
|
|
|
tests := []struct {
|
|
name string
|
|
requestedType []v1alpha2.CommandGroupKind
|
|
execCommands []v1alpha2.Command
|
|
compCommands []v1alpha2.Command
|
|
retCommandName string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Valid devfile",
|
|
execCommands: []v1alpha2.Command{
|
|
getExecCommand("", buildGroup),
|
|
getExecCommand("", runGroup),
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup, runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Valid devfile with devrun and devbuild",
|
|
execCommands: []v1alpha2.Command{
|
|
getExecCommand("", buildGroup),
|
|
getExecCommand("", runGroup),
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup, runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 3: Valid devfile with empty workdir",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 4: Default command is returned",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "defaultruncommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "runcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
retCommandName: "defaultruncommand",
|
|
requestedType: []v1alpha2.CommandGroupKind{runGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 5: Valid devfile, has composite command",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build1",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "build2",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "run",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
compCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "mycomp",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Composite: &v1alpha2.CompositeCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
Commands: []string{"build1", "run"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
retCommandName: "mycomp",
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 6: Default composite command",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(false)},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "run",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
compCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "mycomp",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Composite: &v1alpha2.CompositeCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
Commands: []string{"build", "run"},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "mycomp2",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Composite: &v1alpha2.CompositeCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(false)},
|
|
},
|
|
},
|
|
Commands: []string{"build", "run"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
retCommandName: "mycomp",
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 7: no build and debug commands",
|
|
execCommands: []v1alpha2.Command{
|
|
getExecCommand("", runGroup),
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup, debugGroup},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 8: no default build and debug commands",
|
|
execCommands: []v1alpha2.Command{
|
|
getExecCommand("build-0", buildGroup),
|
|
getExecCommand("build-1", buildGroup),
|
|
getExecCommand("debug-0", debugGroup),
|
|
getExecCommand("debug-1", debugGroup),
|
|
getExecCommand("", runGroup),
|
|
},
|
|
requestedType: []v1alpha2.CommandGroupKind{buildGroup, debugGroup},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
components := []v1alpha2.Component{testingutil.GetFakeContainerComponent(tt.execCommands[0].Exec.Component)}
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.compCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents(components)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
for _, gtype := range tt.requestedType {
|
|
cmd, err := getCommandAssociatedToGroup(devObj.Data, gtype)
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("TestGetCommandFromDevfile unexpected error for command: %v wantErr: %v err: %v", gtype, tt.wantErr, err)
|
|
return
|
|
} else if tt.wantErr {
|
|
return
|
|
}
|
|
|
|
if len(tt.retCommandName) > 0 && cmd.Id != tt.retCommandName {
|
|
t.Errorf("TestGetCommandFromDevfile error: command names do not match expected: %v actual: %v", tt.retCommandName, cmd.Id)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func Test_getCommandByName(t *testing.T) {
|
|
|
|
commands := [...]string{"ls -la", "pwd"}
|
|
components := [...]string{"alias1", "alias2"}
|
|
invalidComponent := "garbagealias"
|
|
|
|
tests := []struct {
|
|
name string
|
|
requestedType v1alpha2.CommandGroupKind
|
|
execCommands []v1alpha2.Command
|
|
compCommands []v1alpha2.Command
|
|
reqCommandName string
|
|
retCommandName string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Valid devfile",
|
|
execCommands: []v1alpha2.Command{
|
|
getExecCommand("a", buildGroup),
|
|
getExecCommand("b", runGroup),
|
|
},
|
|
reqCommandName: "b",
|
|
retCommandName: "b",
|
|
requestedType: runGroup,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Valid devfile with empty workdir",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "build command",
|
|
retCommandName: "build command",
|
|
requestedType: runGroup,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 3: Invalid command",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: invalidComponent,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "build command wrong",
|
|
requestedType: runGroup,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 4: Mismatched command type",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "build command",
|
|
requestedType: buildGroup,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 5: Multiple default commands but should be with the flag",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "defaultruncommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "runcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "defaultruncommand",
|
|
retCommandName: "defaultruncommand",
|
|
requestedType: runGroup,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 6: No default command but should be with the flag",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "defaultruncommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "runcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "defaultruncommand",
|
|
retCommandName: "defaultruncommand",
|
|
requestedType: runGroup,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 7: No Command Group",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "defaultruncommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "defaultruncommand",
|
|
retCommandName: "defaultruncommand",
|
|
requestedType: runGroup,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 8: Valid devfile with composite commands",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(false)},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "run",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
compCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "mycomp",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Composite: &v1alpha2.CompositeCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
Commands: []string{"build", "run"},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "mycomp2",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Composite: &v1alpha2.CompositeCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(false)},
|
|
},
|
|
},
|
|
Commands: []string{"build", "run"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
reqCommandName: "mycomp",
|
|
retCommandName: "mycomp",
|
|
requestedType: buildGroup,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
components := []v1alpha2.Component{testingutil.GetFakeContainerComponent(tt.execCommands[0].Exec.Component)}
|
|
if tt.execCommands[0].Exec.Component == invalidComponent {
|
|
components = []v1alpha2.Component{testingutil.GetFakeContainerComponent("randomComponent")}
|
|
}
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.compCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents(components)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
cmd, err := getCommandByName(devObj.Data, tt.requestedType, tt.reqCommandName)
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("TestGetCommand unexpected error for command: %v wantErr: %v err: %v", tt.requestedType, tt.wantErr, err)
|
|
return
|
|
} else if tt.wantErr {
|
|
return
|
|
}
|
|
|
|
if cmd.Exec != nil {
|
|
if cmd.Id != tt.retCommandName {
|
|
t.Errorf("TestGetCommand error: command names do not match expected: %v actual: %v", tt.retCommandName, cmd.Id)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestGetBuildCommand(t *testing.T) {
|
|
|
|
command := "ls -la"
|
|
component := "alias1"
|
|
workDir := "/"
|
|
emptyString := ""
|
|
|
|
tests := []struct {
|
|
name string
|
|
commandName string
|
|
execCommands []v1alpha2.Command
|
|
wantCommand v1alpha2.Command
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Default Build Command",
|
|
commandName: emptyString,
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantCommand: v1alpha2.Command{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Build Command passed through the odo flag",
|
|
commandName: "flagcommand",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "flagcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "build command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantCommand: v1alpha2.Command{
|
|
Id: "flagcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 3: Build Command not found",
|
|
commandName: "customcommand123",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "build command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents([]v1alpha2.Component{testingutil.GetFakeContainerComponent(component)})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
command, err := GetBuildCommand(devObj.Data, tt.commandName)
|
|
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("TestGetBuildCommand: unexpected error for command \"%v\" expected: %v actual: %v", tt.commandName, tt.wantErr, err)
|
|
} else if !tt.wantErr && !reflect.DeepEqual(tt.wantCommand, command) {
|
|
t.Errorf("TestGetBuildCommand: unexpected command returned: %v", pretty.Compare(tt.wantCommand, command))
|
|
}
|
|
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestGetDebugCommand(t *testing.T) {
|
|
|
|
command := "ls -la"
|
|
component := "alias1"
|
|
workDir := "/"
|
|
emptyString := ""
|
|
|
|
var emptyCommand v1alpha2.Command
|
|
|
|
tests := []struct {
|
|
name string
|
|
commandName string
|
|
execCommands []v1alpha2.Command
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case: Default Debug Command",
|
|
commandName: emptyString,
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(true),
|
|
Kind: v1alpha2.DebugCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: Custom Debug Command",
|
|
commandName: "customdebugcommand",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "customdebugcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(false),
|
|
Kind: v1alpha2.DebugCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: Missing Debug Command",
|
|
commandName: "customcommand123",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(true),
|
|
Kind: v1alpha2.BuildCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents([]v1alpha2.Component{testingutil.GetFakeContainerComponent(component)})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
command, err := GetDebugCommand(devObj.Data, tt.commandName)
|
|
|
|
if tt.wantErr && err == nil {
|
|
t.Errorf("Error was expected but got no error")
|
|
} else if !tt.wantErr {
|
|
if err != nil {
|
|
t.Errorf("TestGetDebugCommand: unexpected error for command \"%v\" expected: %v actual: %v", tt.commandName, tt.wantErr, err)
|
|
} else if reflect.DeepEqual(emptyCommand, command) {
|
|
t.Errorf("TestGetDebugCommand: unexpected empty command returned for command: %v", tt.commandName)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetTestCommand(t *testing.T) {
|
|
|
|
command := "ls -la"
|
|
component := "alias1"
|
|
workDir := "/"
|
|
emptyString := ""
|
|
|
|
var emptyCommand v1alpha2.Command
|
|
|
|
tests := []struct {
|
|
name string
|
|
commandName string
|
|
execCommands []v1alpha2.Command
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case: Default Test Command",
|
|
commandName: emptyString,
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(true),
|
|
Kind: v1alpha2.TestCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: Custom Test Command",
|
|
commandName: "customtestcommand",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "customtestcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(false),
|
|
Kind: v1alpha2.TestCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: Missing Test Command",
|
|
commandName: "customcommand123",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(true),
|
|
Kind: v1alpha2.BuildCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents([]v1alpha2.Component{testingutil.GetFakeContainerComponent(component)})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
command, err := GetTestCommand(devObj.Data, tt.commandName)
|
|
|
|
if tt.wantErr && err == nil {
|
|
t.Errorf("Error was expected but got no error")
|
|
} else if !tt.wantErr {
|
|
if err != nil {
|
|
t.Errorf("TestGetTestCommand: unexpected error for command \"%v\" expected: %v actual: %v", tt.commandName, tt.wantErr, err)
|
|
} else if reflect.DeepEqual(emptyCommand, command) {
|
|
t.Errorf("TestGetTestCommand: unexpected empty command returned for command: %v", tt.commandName)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetRunCommand(t *testing.T) {
|
|
|
|
command := "ls -la"
|
|
component := "alias1"
|
|
workDir := "/"
|
|
emptyString := ""
|
|
|
|
var emptyCommand v1alpha2.Command
|
|
|
|
tests := []struct {
|
|
name string
|
|
commandName string
|
|
execCommands []v1alpha2.Command
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Default Run Command",
|
|
commandName: emptyString,
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup, IsDefault: util.GetBoolPtr(true)},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Run Command passed through odo flag",
|
|
commandName: "flagcommand",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "flagcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "run command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 3: Missing Run Command",
|
|
commandName: "",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents([]v1alpha2.Component{testingutil.GetFakeContainerComponent(component)})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
command, err := GetRunCommand(devObj.Data, tt.commandName)
|
|
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("TestGetRunCommand: unexpected error for command \"%v\" expected: %v actual: %v", tt.commandName, tt.wantErr, err)
|
|
} else if !tt.wantErr && reflect.DeepEqual(emptyCommand, command) {
|
|
t.Errorf("TestGetRunCommand: unexpected empty command returned for command: %v", tt.commandName)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestValidateAndGetDebugCommands(t *testing.T) {
|
|
|
|
command := "ls -la"
|
|
component := "alias1"
|
|
workDir := "/"
|
|
emptyString := ""
|
|
|
|
execCommands := []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(true),
|
|
Kind: v1alpha2.DebugCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "customdebugcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(false),
|
|
Kind: v1alpha2.DebugCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
debugCommand string
|
|
componentType v1alpha2.ComponentType
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case: Default Devfile Commands",
|
|
debugCommand: emptyString,
|
|
componentType: v1alpha2.ContainerComponentType,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: provided debug Command",
|
|
debugCommand: "customdebugcommand",
|
|
componentType: v1alpha2.ContainerComponentType,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: invalid debug Command",
|
|
debugCommand: "invaliddebugcommand",
|
|
componentType: v1alpha2.ContainerComponentType,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents([]v1alpha2.Component{testingutil.GetFakeContainerComponent(component)})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
debugCommand, err := ValidateAndGetDebugCommands(devObj.Data, tt.debugCommand)
|
|
|
|
if tt.wantErr {
|
|
if err == nil {
|
|
t.Errorf("Error was expected but got no error")
|
|
} else {
|
|
return
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("TestValidateAndGetDebugDevfileCommands: unexpected error %v", err)
|
|
}
|
|
}
|
|
|
|
if !reflect.DeepEqual(nil, debugCommand) && debugCommand.Id != tt.debugCommand {
|
|
t.Errorf("TestValidateAndGetDebugDevfileCommands name of debug command is wrong want: %v got: %v", tt.debugCommand, debugCommand.Id)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateAndGetPushCommands(t *testing.T) {
|
|
|
|
command := "ls -la"
|
|
component := "alias1"
|
|
workDir := "/"
|
|
emptyString := ""
|
|
|
|
execCommands := []v1alpha2.Command{
|
|
{
|
|
Id: "run command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
Kind: runGroup,
|
|
IsDefault: util.GetBoolPtr(true),
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
Id: "build command",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: buildGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
Id: "customcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
wrongCompTypeCmd := v1alpha2.Command{
|
|
|
|
Id: "wrong",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: "",
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
buildCommand string
|
|
runCommand string
|
|
execCommands []v1alpha2.Command
|
|
numberOfCommands int
|
|
missingBuildCommand bool
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case 1: Default Devfile Commands",
|
|
buildCommand: emptyString,
|
|
runCommand: emptyString,
|
|
execCommands: execCommands,
|
|
numberOfCommands: 2,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 2: Default Build Command, and Provided Run Command",
|
|
buildCommand: emptyString,
|
|
runCommand: "customcommand",
|
|
execCommands: execCommands,
|
|
numberOfCommands: 2,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case 3: Empty Component",
|
|
buildCommand: "customcommand",
|
|
runCommand: "customcommand",
|
|
execCommands: append(execCommands, wrongCompTypeCmd),
|
|
numberOfCommands: 0,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 4: Provided Wrong Build Command and Provided Run Command",
|
|
buildCommand: "customcommand123",
|
|
runCommand: "customcommand",
|
|
execCommands: execCommands,
|
|
numberOfCommands: 1,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Case 5: Missing Build Command, and Provided Run Command",
|
|
buildCommand: emptyString,
|
|
runCommand: "customcommand",
|
|
execCommands: []v1alpha2.Command{
|
|
{
|
|
Id: "customcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: runGroup},
|
|
},
|
|
},
|
|
Component: component,
|
|
CommandLine: command,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
numberOfCommands: 1,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(tt.execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents(([]v1alpha2.Component{testingutil.GetFakeContainerComponent(component)}))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
pushCommands, err := ValidateAndGetPushCommands(devObj.Data, tt.buildCommand, tt.runCommand)
|
|
if !tt.wantErr == (err != nil) {
|
|
t.Errorf("TestValidateAndGetPushDevfileCommands unexpected error when validating commands wantErr: %v err: %v", tt.wantErr, err)
|
|
} else if tt.wantErr && err != nil {
|
|
return
|
|
}
|
|
|
|
if len(pushCommands) != tt.numberOfCommands {
|
|
t.Errorf("TestValidateAndGetPushDevfileCommands error: wrong number of validated commands expected: %v actual :%v", tt.numberOfCommands, len(pushCommands))
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestValidateAndGetTestCommands(t *testing.T) {
|
|
|
|
command := "ls -la"
|
|
component := "alias1"
|
|
workDir := "/"
|
|
emptyString := ""
|
|
|
|
execCommands := []v1alpha2.Command{
|
|
{
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(true),
|
|
Kind: v1alpha2.TestCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Id: "customtestcommand",
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{
|
|
IsDefault: util.GetBoolPtr(false),
|
|
Kind: v1alpha2.TestCommandGroupKind,
|
|
},
|
|
},
|
|
},
|
|
CommandLine: command,
|
|
Component: component,
|
|
WorkingDir: workDir,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
testCommand string
|
|
componentType v1alpha2.ComponentType
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Case: Default Devfile Commands",
|
|
testCommand: emptyString,
|
|
componentType: v1alpha2.ContainerComponentType,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: provided test Command",
|
|
testCommand: "customtestcommand",
|
|
componentType: v1alpha2.ContainerComponentType,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Case: invalid test Command",
|
|
testCommand: "invalidtestcommand",
|
|
componentType: v1alpha2.ContainerComponentType,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
devObj := parser.DevfileObj{
|
|
Data: func() data.DevfileData {
|
|
devfileData, err := data.NewDevfileData(string(data.APISchemaVersion200))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddComponents([]v1alpha2.Component{testingutil.GetFakeContainerComponent(component)})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
err = devfileData.AddCommands(execCommands)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
return devfileData
|
|
}(),
|
|
}
|
|
|
|
testCommand, err := ValidateAndGetTestCommands(devObj.Data, tt.testCommand)
|
|
|
|
if tt.wantErr {
|
|
if err == nil {
|
|
t.Errorf("Error was expected but got no error")
|
|
} else {
|
|
return
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("TestValidateAndGetTestDevfileCommands: unexpected error %v", err)
|
|
}
|
|
}
|
|
|
|
if !reflect.DeepEqual(nil, testCommand) && testCommand.Id != tt.testCommand {
|
|
t.Errorf("TestValidateAndGetTestDevfileCommands name of test command is wrong want: %v got: %v", tt.testCommand, testCommand.Id)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestShouldExecCommandRunOnContainer(t *testing.T) {
|
|
for _, tt := range []struct {
|
|
name string
|
|
execCommand *v1alpha2.ExecCommand
|
|
container string
|
|
want bool
|
|
}{
|
|
{
|
|
name: "nil exec command",
|
|
},
|
|
{
|
|
name: "exec component not matching container name",
|
|
execCommand: &v1alpha2.ExecCommand{
|
|
Component: "runtime",
|
|
},
|
|
container: "my-cont",
|
|
want: false,
|
|
},
|
|
{
|
|
name: "exec component matching container name",
|
|
execCommand: &v1alpha2.ExecCommand{
|
|
Component: "runtime",
|
|
},
|
|
container: "runtime",
|
|
want: true,
|
|
},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := ShouldExecCommandRunOnContainer(tt.execCommand, tt.container)
|
|
if tt.want != got {
|
|
t.Errorf("expected=%v, got %v", tt.want, got)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func getExecCommand(id string, group v1alpha2.CommandGroupKind) v1alpha2.Command {
|
|
if len(id) == 0 {
|
|
id = fmt.Sprintf("%s-%s", "cmd", dfutil.GenerateRandomString(10))
|
|
}
|
|
commands := [...]string{"ls -la", "pwd"}
|
|
components := [...]string{"alias1", "alias2"}
|
|
workDir := [...]string{"/", "/root"}
|
|
|
|
return v1alpha2.Command{
|
|
Id: id,
|
|
CommandUnion: v1alpha2.CommandUnion{
|
|
Exec: &v1alpha2.ExecCommand{
|
|
LabeledCommand: v1alpha2.LabeledCommand{
|
|
BaseCommand: v1alpha2.BaseCommand{
|
|
Group: &v1alpha2.CommandGroup{Kind: group},
|
|
},
|
|
},
|
|
CommandLine: commands[0],
|
|
Component: components[0],
|
|
WorkingDir: workDir[0],
|
|
},
|
|
},
|
|
}
|
|
|
|
}
|