package resource import ( "testing" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" kresource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ( audacityName = "audacity" audacity = "audacity" audacityImage = "docker.io/linuxserver/firefox:latest" ) func TestAddAudioRequestResourcesToPod(t *testing.T) { tcs := []struct { Pod *corev1.Pod ExpectedPod *corev1.Pod }{ { // test case 1: pod requesting audio has label, volume and envvars added Pod: &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: audacityName, Namespace: audacityName, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: audacity, Image: audacityImage, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ AudioRequestResource.ResourceName(): kresource.MustParse("1"), }, }, }, }, }, }, ExpectedPod: &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: audacityName, Namespace: audacityName, Labels: map[string]string{AudioRequestResource.String(): "true"}, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: audacity, Image: audacityImage, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ AudioRequestResource.ResourceName(): kresource.MustParse("1"), }, }, Env: []corev1.EnvVar{ {Name: xdgRuntimeDirEnvVar, Value: xdgRuntimeDir}, {Name: pulseServerEnvVar, Value: pulseServerPath}, }, VolumeMounts: []corev1.VolumeMount{ { Name: xdgRuntimeVol, MountPath: xdgRuntimeDir, ReadOnly: false, }, }, }, }, Volumes: []corev1.Volume{ { Name: xdgRuntimeVol, VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{Path: xdgRuntimeDir, Type: &hostPathDir}, }, }, }, }, }, }, { // test case 2: pod's existing xdg-runtime volume and envvars are not changed Pod: &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: audacityName, Namespace: audacityName, Labels: map[string]string{AudioRequestResource.String(): labelValue}, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: audacity, Image: audacityImage, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ AudioRequestResource.ResourceName(): kresource.MustParse("1"), }, }, Env: []corev1.EnvVar{ {Name: xdgRuntimeDirEnvVar, Value: xdgRuntimeDir}, {Name: pulseServerEnvVar, Value: pulseServerPath}, }, VolumeMounts: []corev1.VolumeMount{ { Name: xdgRuntimeVol, MountPath: xdgRuntimeDir, ReadOnly: false, }, }, }, }, Volumes: []corev1.Volume{ { Name: xdgRuntimeVol, VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{Path: xdgRuntimeDir, Type: &hostPathDir}, }, }, }, }, }, ExpectedPod: &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: audacityName, Namespace: audacityName, Labels: map[string]string{AudioRequestResource.String(): labelValue}, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: audacity, Image: audacityImage, Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ AudioRequestResource.ResourceName(): kresource.MustParse("1"), }, }, Env: []corev1.EnvVar{ {Name: xdgRuntimeDirEnvVar, Value: xdgRuntimeDir}, {Name: pulseServerEnvVar, Value: pulseServerPath}, }, VolumeMounts: []corev1.VolumeMount{ { Name: xdgRuntimeVol, MountPath: xdgRuntimeDir, ReadOnly: false, }, }, }, }, Volumes: []corev1.Volume{ { Name: xdgRuntimeVol, VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{Path: xdgRuntimeDir, Type: &hostPathDir}, }, }, }, }, }, }, { // test case 3: multiple containers, only containers with requests mutated, existing fields ignored Pod: &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: audacityName, Namespace: audacityName, Labels: map[string]string{ AudioRequestResource.String(): labelValue, "app.kubernetes.io/name": audacityName, }, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: audacity, Image: audacityImage, }, { Name: "chromium", Image: "docker.io/linuxserver/chromium", Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ AudioRequestResource.ResourceName(): kresource.MustParse("1"), }, }, }, { Name: "ubuntu", Image: "docker.io/ubuntu", }, }, }, }, ExpectedPod: &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: audacityName, Namespace: audacityName, Labels: map[string]string{ AudioRequestResource.String(): labelValue, "app.kubernetes.io/name": audacityName, }, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: audacity, Image: audacityImage, }, { Name: "chromium", Image: "docker.io/linuxserver/chromium", Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ AudioRequestResource.ResourceName(): kresource.MustParse("1"), }, }, Env: []corev1.EnvVar{ {Name: xdgRuntimeDirEnvVar, Value: xdgRuntimeDir}, {Name: pulseServerEnvVar, Value: pulseServerPath}, }, VolumeMounts: []corev1.VolumeMount{ { Name: xdgRuntimeVol, MountPath: xdgRuntimeDir, ReadOnly: false, }, }, }, { Name: "ubuntu", Image: "docker.io/ubuntu", }, }, Volumes: []corev1.Volume{ { Name: xdgRuntimeVol, VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{Path: xdgRuntimeDir, Type: &hostPathDir}, }, }, }, }, }, }, } for idx, tc := range tcs { pod := tc.Pod.DeepCopy() podTemplate := corev1.PodTemplateSpec{Spec: pod.Spec} podTemplate = InjectResourceIntoPod(podTemplate, AudioRequestResource) require.Equal(t, tc.ExpectedPod.Spec, podTemplate.Spec, "test case %d failed: pod not as expected", idx+1) } }