Files
odo/pkg/dev/podmandev/pod_test.go
Armel Soro ec747b4ab3 Allow using imageName as a selector (#6768)
* Add integration tests highlighting our expectations

* Bump Devfile library to latest commit

f041d79870

* Expose preference that allows users to globally configure an image registry

* Return the effective Devfile view by default from the initial context

This is supposed to be read-only, so that tools can rely on it
and to the operations they need to perform right away.

Raw Devfile objects can still be obtained upon request
if there is need to update them (for example via 'odo add/remove
binding' commands.

* Pass the image registry preference to the Devfile parser to build the effective view

* Fix 'odo init' integration tests

- The test spec was actually not doing what it was supposed to do
- Now 'odo init' returns a complete Devfile, where the parent is flattened,
  because the goal of 'odo init' is to bootstrap a Devfile.
  Previously, 'odo init' would not download the parent referenced,
  making it hard to understand the resulting Devfile.

* Document how odo now handles relative image names as selectors

* fixup! Document how odo now handles relative image names as selectors

Co-authored-by: Philippe Martin <phmartin@redhat.com>

* Revert "Fix 'odo init' integration tests"

This reverts commit 78868b03fd.

Co-authored-by: Philippe Martin <phmartin@redhat.com>

* Do not make `odo init` return an effective Devfile as a result

This would change the behavior of `odo init`.

Furthermore, due to an issue [1] in the Devfile library,
it is not possible to parse some Devfiles with parents linked as GitHub URLs (like GitHub release artifacts).

[1] https://github.com/devfile/api/issues/1119

Co-authored-by: Philippe Martin <phmartin@redhat.com>

* fixup! Document how odo now handles relative image names as selectors

---------

Co-authored-by: Philippe Martin <phmartin@redhat.com>
2023-05-22 10:45:27 -04:00

1444 lines
41 KiB
Go

package podmandev
import (
"context"
"testing"
"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"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/redhat-developer/odo/pkg/api"
"github.com/redhat-developer/odo/pkg/labels"
"github.com/redhat-developer/odo/pkg/libdevfile/generator"
odocontext "github.com/redhat-developer/odo/pkg/odo/context"
"github.com/redhat-developer/odo/pkg/version"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/pointer"
)
var (
devfileName = "mycmp"
appName = "app"
command = generator.GetExecCommand(generator.ExecCommandParams{
Id: "run",
Component: "mycomponent",
CommandLine: "./run",
IsDefault: pointer.Bool(true),
Kind: v1alpha2.RunCommandGroupKind,
})
baseComponent = generator.GetContainerComponent(generator.ContainerComponentParams{
Name: "mycomponent",
Container: v1alpha2.Container{
Image: "myimage",
Args: []string{"-f", "/dev/null"},
Command: []string{"tail"},
},
})
volume = generator.GetVolumeComponent(generator.VolumeComponentParams{
Name: "myvolume",
})
)
func buildBasePod(withPfContainer bool) *corev1.Pod {
basePod := corev1.Pod{
TypeMeta: v1.TypeMeta{
APIVersion: "v1",
Kind: "Pod",
},
ObjectMeta: v1.ObjectMeta{
Name: "mycmp-app",
Labels: map[string]string{
"app": appName,
"app.kubernetes.io/instance": devfileName,
"app.kubernetes.io/managed-by": "odo",
"app.kubernetes.io/managed-by-version": version.VERSION,
"app.kubernetes.io/part-of": appName,
"component": devfileName,
"odo.dev/mode": labels.ComponentDevMode,
"odo.dev/project-type": "Not available",
},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Args: []string{"-f", "/dev/null"},
Command: []string{"tail"},
Env: []corev1.EnvVar{
{
Name: "PROJECTS_ROOT",
Value: "/projects",
},
{
Name: "PROJECT_SOURCE",
Value: "/projects",
},
},
Image: "myimage",
ImagePullPolicy: "Always",
Name: "mycomponent",
VolumeMounts: []corev1.VolumeMount{
{
MountPath: "/projects",
Name: "odo-projects",
},
{
MountPath: "/opt/odo/",
Name: "odo-shared-data",
},
},
},
},
Volumes: []corev1.Volume{
{
Name: "odo-projects",
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: "odo-projects-mycmp-app",
},
},
},
{
Name: "odo-shared-data",
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: "odo-shared-data-mycmp-app",
},
},
},
},
},
}
if withPfContainer {
basePod.Spec.Containers = append(basePod.Spec.Containers, corev1.Container{
Args: []string{"-f", "/dev/null"},
Command: []string{"tail"},
Image: portForwardingHelperImage,
Name: portForwardingHelperContainerName,
})
}
return &basePod
}
func Test_createPodFromComponent(t *testing.T) {
type args struct {
devfileObj func() parser.DevfileObj
componentName string
appName string
debug bool
buildCommand string
runCommand string
debugCommand string
forwardLocalhost bool
customForwardedPorts []api.ForwardedPort
customAddress string
}
tests := []struct {
name string
args args
wantPod func(basePod *corev1.Pod) *corev1.Pod
wantFwPorts []api.ForwardedPort
wantErr bool
}{
{
name: "basic component without command / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
_ = data.AddComponents([]v1alpha2.Component{baseComponent})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
return basePod.DeepCopy()
},
},
{
name: "basic component without command / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
_ = data.AddComponents([]v1alpha2.Component{baseComponent})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
return pod
},
},
{
name: "basic component with command / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Command = []string{"./cmd"}
cmp.Container.Args = []string{"arg1", "arg2"}
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Command = []string{"./cmd"}
pod.Spec.Containers[0].Args = []string{"arg1", "arg2"}
return pod
},
},
{
name: "basic component with command / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Command = []string{"./cmd"}
cmp.Container.Args = []string{"arg1", "arg2"}
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Command = []string{"./cmd"}
pod.Spec.Containers[0].Args = []string{"arg1", "arg2"}
return pod
},
},
{
name: "basic component + memory limit / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.MemoryLimit = "1Gi"
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Resources.Limits = corev1.ResourceList{
"memory": resource.MustParse("1Gi"),
}
return pod
},
},
{
name: "basic component + memory limit / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.MemoryLimit = "1Gi"
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Resources.Limits = corev1.ResourceList{
"memory": resource.MustParse("1Gi"),
}
return pod
},
},
{
name: "basic component + application endpoint / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 8080,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 8080,
HostPort: 20001,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 8080,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 8080,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20001,
HostPort: 20001,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 8080,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint - without debug / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 8080,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 5858,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 8080,
HostPort: 20001,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 8080,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint - without debug / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 8080,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 5858,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20001,
HostPort: 20001,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 8080,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint - with debug / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 8080,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 5858,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 8080,
HostPort: 20001,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "debug",
ContainerPort: 5858,
HostPort: 20002,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 8080,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug",
LocalAddress: "127.0.0.1",
LocalPort: 20002,
ContainerPort: 5858,
IsDebug: true,
},
},
},
{
name: "basic component + application endpoint + debug endpoint - with debug / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 8080,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 5858,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20001,
HostPort: 20001,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "debug",
ContainerPort: 20002,
HostPort: 20002,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 8080,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug",
LocalAddress: "127.0.0.1",
LocalPort: 20002,
ContainerPort: 5858,
IsDebug: true,
},
},
},
{
name: "basic component with volume mount / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
_ = data.AddComponents([]v1alpha2.Component{baseComponent, volume})
_ = data.AddVolumeMounts(baseComponent.Name, []v1alpha2.VolumeMount{
{
Name: volume.Name,
Path: "/path/to/mount",
},
})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
Name: volume.Name,
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: volume.Name + "-" + devfileName + "-" + appName,
},
},
})
pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
Name: volume.Name,
MountPath: "/path/to/mount",
})
return pod
},
},
{
name: "basic component with volume mount / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
_ = data.AddComponents([]v1alpha2.Component{baseComponent, volume})
_ = data.AddVolumeMounts(baseComponent.Name, []v1alpha2.VolumeMount{
{
Name: volume.Name,
Path: "/path/to/mount",
},
})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
Name: volume.Name,
VolumeSource: corev1.VolumeSource{
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
ClaimName: volume.Name + "-" + devfileName + "-" + appName,
},
},
})
pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
Name: volume.Name,
MountPath: "/path/to/mount",
})
return pod
},
},
{
name: "basic component + application endpoint + debug endpoint + container ports known - with debug / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 20001,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 20002,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug-1",
TargetPort: 5858,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20001,
HostPort: 20003,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "debug",
ContainerPort: 20002,
HostPort: 20004,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "debug-1",
ContainerPort: 5858,
HostPort: 20005,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20003,
ContainerPort: 20001,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug",
LocalAddress: "127.0.0.1",
LocalPort: 20004,
ContainerPort: 20002,
IsDebug: true,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug-1",
LocalAddress: "127.0.0.1",
LocalPort: 20005,
ContainerPort: 5858,
IsDebug: true,
},
},
},
{
name: "basic component + application endpoint + debug endpoint + container ports known - with debug / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 20001,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 20002,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug-1",
TargetPort: 5858,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20003,
HostPort: 20003,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "debug",
ContainerPort: 20004,
HostPort: 20004,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "debug-1",
ContainerPort: 20005,
HostPort: 20005,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20003,
ContainerPort: 20001,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug",
LocalAddress: "127.0.0.1",
LocalPort: 20004,
ContainerPort: 20002,
IsDebug: true,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug-1",
LocalAddress: "127.0.0.1",
LocalPort: 20005,
ContainerPort: 5858,
IsDebug: true,
},
},
},
{
name: "basic component + application endpoint + debug endpoint + container ports known - without debug / forwardLocalhost=false",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 20001,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 20002,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug-1",
TargetPort: 5858,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http-1",
TargetPort: 8080,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: false,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20001,
HostPort: 20002,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "http-1",
ContainerPort: 8080,
HostPort: 20003,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20002,
ContainerPort: 20001,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http-1",
LocalAddress: "127.0.0.1",
LocalPort: 20003,
ContainerPort: 8080,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint + container ports known - without debug / forwardLocalhost=true",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 20001,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 20002,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug-1",
TargetPort: 5858,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http-1",
TargetPort: 8080,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: false,
forwardLocalhost: true,
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20002,
HostPort: 20002,
HostIP: "127.0.0.1",
})
pod.Spec.Containers[1].Ports = append(pod.Spec.Containers[1].Ports, corev1.ContainerPort{
Name: "http-1",
ContainerPort: 20003,
HostPort: 20003,
HostIP: "127.0.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "127.0.0.1",
LocalPort: 20002,
ContainerPort: 20001,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http-1",
LocalAddress: "127.0.0.1",
LocalPort: 20003,
ContainerPort: 8080,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint - with debug / custom mapping for port forwarding with container name (customForwardedPorts)",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Name = "runtime"
cmp.Container.Endpoints = []v1alpha2.Endpoint{
{
Name: "http-8080",
TargetPort: 8080,
},
{
Name: "debug",
TargetPort: 5858,
},
}
cmp2 := baseComponent.DeepCopy()
cmp2.Name = "tools"
cmp2.Container.Endpoints = []v1alpha2.Endpoint{
{
Name: "http-5000",
TargetPort: 5000,
},
}
_ = data.AddComponents([]v1alpha2.Component{*cmp, *cmp2})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
customForwardedPorts: []api.ForwardedPort{
{
ContainerName: "runtime",
LocalPort: 8080,
ContainerPort: 8080,
},
},
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Name = "runtime"
pod.Spec.Containers[0].Ports = []corev1.ContainerPort{
{
Name: "http-8080",
ContainerPort: 8080,
HostPort: 8080,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
{
Name: "debug",
ContainerPort: 5858,
HostPort: 20001,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
}
container2 := pod.Spec.Containers[0].DeepCopy()
container2.Name = "tools"
container2.Ports = []corev1.ContainerPort{
{
Name: "http-5000",
ContainerPort: 5000,
HostPort: 20002,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
}
pod.Spec.Containers = append(pod.Spec.Containers, *container2)
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "runtime",
PortName: "http-8080",
LocalAddress: "127.0.0.1",
LocalPort: 8080,
ContainerPort: 8080,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "runtime",
PortName: "debug",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 5858,
IsDebug: true,
},
{
Platform: "podman",
ContainerName: "tools",
PortName: "http-5000",
LocalAddress: "127.0.0.1",
LocalPort: 20002,
ContainerPort: 5000,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint - with debug / custom mapping for port forwarding without container name (customForwardedPorts)",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Name = "runtime"
cmp.Container.Endpoints = []v1alpha2.Endpoint{
{
Name: "http-8080",
TargetPort: 8080,
},
{
Name: "debug",
TargetPort: 5858,
},
}
cmp2 := baseComponent.DeepCopy()
cmp2.Name = "tools"
cmp2.Container.Endpoints = []v1alpha2.Endpoint{
{
Name: "http-5000",
TargetPort: 5000,
},
}
_ = data.AddComponents([]v1alpha2.Component{*cmp, *cmp2})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
customForwardedPorts: []api.ForwardedPort{
{
LocalPort: 8080,
ContainerPort: 8080,
},
{
LocalPort: 5000,
ContainerPort: 5000,
},
},
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Name = "runtime"
pod.Spec.Containers[0].Ports = []corev1.ContainerPort{
{
Name: "http-8080",
ContainerPort: 8080,
HostPort: 8080,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
}, {
Name: "debug",
ContainerPort: 5858,
HostPort: 20001,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
}
container2 := pod.Spec.Containers[0].DeepCopy()
container2.Name = "tools"
container2.Ports = []corev1.ContainerPort{
{
Name: "http-5000",
ContainerPort: 5000,
HostPort: 5000,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
}
pod.Spec.Containers = append(pod.Spec.Containers, *container2)
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "runtime",
PortName: "http-8080",
LocalAddress: "127.0.0.1",
LocalPort: 8080,
ContainerPort: 8080,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "runtime",
PortName: "debug",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 5858,
IsDebug: true,
},
{
Platform: "podman",
ContainerName: "tools",
PortName: "http-5000",
LocalAddress: "127.0.0.1",
LocalPort: 5000,
ContainerPort: 5000,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint - with debug / custom mapping for port forwarding with local port in ranged [20001-30001] ports (customForwardedPorts)",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Name = "runtime"
cmp.Container.Endpoints = []v1alpha2.Endpoint{
{
Name: "http-8080",
TargetPort: 8080,
},
{
Name: "debug",
TargetPort: 5858,
},
}
cmp2 := baseComponent.DeepCopy()
cmp2.Name = "tools"
cmp2.Container.Endpoints = []v1alpha2.Endpoint{
{
Name: "http-9000",
TargetPort: 9000,
},
{
Name: "http-5000",
TargetPort: 5000,
},
}
_ = data.AddComponents([]v1alpha2.Component{*cmp, *cmp2})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
customForwardedPorts: []api.ForwardedPort{
{
LocalPort: 20001,
ContainerPort: 8080,
},
{
LocalPort: 20002,
ContainerPort: 9000,
},
{
LocalPort: 5000,
ContainerPort: 5000,
},
},
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Name = "runtime"
pod.Spec.Containers[0].Ports = []corev1.ContainerPort{
{
Name: "http-8080",
ContainerPort: 8080,
HostPort: 20001,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
{
Name: "debug",
ContainerPort: 5858,
HostPort: 20003,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
}
container2 := pod.Spec.Containers[0].DeepCopy()
container2.Name = "tools"
container2.Ports = []corev1.ContainerPort{
{
Name: "http-9000",
ContainerPort: 9000,
HostPort: 20002,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
{
Name: "http-5000",
ContainerPort: 5000,
HostPort: 5000,
Protocol: corev1.ProtocolTCP,
HostIP: "127.0.0.1",
},
}
pod.Spec.Containers = append(pod.Spec.Containers, *container2)
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "runtime",
PortName: "http-8080",
LocalAddress: "127.0.0.1",
LocalPort: 20001,
ContainerPort: 8080,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "runtime",
PortName: "debug",
LocalAddress: "127.0.0.1",
LocalPort: 20003,
ContainerPort: 5858,
IsDebug: true,
},
{
Platform: "podman",
ContainerName: "tools",
PortName: "http-9000",
LocalAddress: "127.0.0.1",
LocalPort: 20002,
ContainerPort: 9000,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "tools",
PortName: "http-5000",
LocalAddress: "127.0.0.1",
LocalPort: 5000,
ContainerPort: 5000,
IsDebug: false,
},
},
},
{
name: "basic component + application endpoint + debug endpoint + container ports known - with debug / using customAddress",
args: args{
devfileObj: func() parser.DevfileObj {
data, _ := data.NewDevfileData(string(data.APISchemaVersion200))
_ = data.AddCommands([]v1alpha2.Command{command})
cmp := baseComponent.DeepCopy()
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "http",
TargetPort: 20001,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug",
TargetPort: 20002,
})
cmp.Container.Endpoints = append(cmp.Container.Endpoints, v1alpha2.Endpoint{
Name: "debug-1",
TargetPort: 5858,
})
_ = data.AddComponents([]v1alpha2.Component{*cmp})
return parser.DevfileObj{
Data: data,
}
},
componentName: devfileName,
appName: appName,
debug: true,
customAddress: "192.168.0.1",
},
wantPod: func(basePod *corev1.Pod) *corev1.Pod {
pod := basePod.DeepCopy()
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "http",
ContainerPort: 20001,
HostPort: 20003,
Protocol: corev1.ProtocolTCP,
HostIP: "192.168.0.1",
})
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "debug",
ContainerPort: 20002,
HostPort: 20004,
Protocol: corev1.ProtocolTCP,
HostIP: "192.168.0.1",
})
pod.Spec.Containers[0].Ports = append(pod.Spec.Containers[0].Ports, corev1.ContainerPort{
Name: "debug-1",
ContainerPort: 5858,
HostPort: 20005,
Protocol: corev1.ProtocolTCP,
HostIP: "192.168.0.1",
})
return pod
},
wantFwPorts: []api.ForwardedPort{
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "http",
LocalAddress: "192.168.0.1",
LocalPort: 20003,
ContainerPort: 20001,
IsDebug: false,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug",
LocalAddress: "192.168.0.1",
LocalPort: 20004,
ContainerPort: 20002,
IsDebug: true,
},
{
Platform: "podman",
ContainerName: "mycomponent",
PortName: "debug-1",
LocalAddress: "192.168.0.1",
LocalPort: 20005,
ContainerPort: 5858,
IsDebug: true,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
devfileObj := tt.args.devfileObj()
ctx = odocontext.WithEffectiveDevfileObj(ctx, &devfileObj)
ctx = odocontext.WithApplication(ctx, tt.args.appName)
ctx = odocontext.WithComponentName(ctx, tt.args.componentName)
ctx = odocontext.WithWorkingDirectory(ctx, "/tmp/dir")
got, gotFwPorts, err := createPodFromComponent(
ctx,
tt.args.debug,
tt.args.buildCommand,
tt.args.runCommand,
tt.args.debugCommand,
tt.args.forwardLocalhost,
false,
tt.args.customForwardedPorts,
[]int{20001, 20002, 20003, 20004, 20005},
tt.args.customAddress,
devfileObj,
)
if (err != nil) != tt.wantErr {
t.Errorf("createPodFromComponent() error = %v, wantErr %v", err, tt.wantErr)
return
}
basePod := buildBasePod(tt.args.forwardLocalhost)
if diff := cmp.Diff(tt.wantPod(basePod), got, cmpopts.EquateEmpty()); diff != "" {
t.Errorf("createPodFromComponent() pod mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(tt.wantFwPorts, gotFwPorts, cmpopts.EquateEmpty(), cmpopts.SortSlices(func(x, y api.ForwardedPort) bool { return x.ContainerName < y.ContainerName })); diff != "" {
t.Errorf("createPodFromComponent() fwPorts mismatch (-want +got):\n%s", diff)
}
})
}
}