mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 18:24:07 +00:00
Refactor AddPodToVolume unit tests with a single pod
Refactor existing tests that run AddPodToVolume with a single pod / volume to a table. And add few extra tests, covering existing ReadWriteOncePod functionality.
This commit is contained in:
parent
e4eedfe105
commit
db3d995c2a
@ -23,6 +23,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/component-base/featuregate"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
@ -605,170 +606,6 @@ func Test_AddPodToVolume_WithEmptyDirSizeLimit(t *testing.T) {
|
||||
verifyDesiredSizeLimitInVolumeDsw(t, pod2Name, pod2DesiredSizeLimitMap, dsw)
|
||||
}
|
||||
|
||||
// Calls AddPodToVolume() with a volume that support SELinux, but is ReadWriteMany.
|
||||
// Verifies newly added pod/volume exists via PodExistsInVolume() without SELinux context
|
||||
// VolumeExists() and GetVolumesToMount() and no errors.
|
||||
func Test_AddPodToVolume_Positive_SELinuxNoRWOP(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)
|
||||
// Arrange
|
||||
plugins := []volume.VolumePlugin{
|
||||
&volumetesting.FakeDeviceMountableVolumePlugin{
|
||||
FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{
|
||||
Plugin: volumetesting.FakeVolumePlugin{
|
||||
PluginName: "basic",
|
||||
SupportsSELinux: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
volumePluginMgr := volume.VolumePluginMgr{}
|
||||
fakeVolumeHost := volumetesting.NewFakeVolumeHost(t,
|
||||
"", /* rootDir */
|
||||
nil, /* kubeClient */
|
||||
nil, /* plugins */
|
||||
)
|
||||
volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost)
|
||||
seLinuxTranslator := util.NewFakeSELinuxLabelTranslator()
|
||||
dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator)
|
||||
seLinux := v1.SELinuxOptions{
|
||||
User: "system_u",
|
||||
Role: "object_r",
|
||||
Type: "container_t",
|
||||
Level: "s0:c1,c2",
|
||||
}
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod1",
|
||||
UID: "pod1uid",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: &v1.PodSecurityContext{
|
||||
SELinuxOptions: &seLinux,
|
||||
},
|
||||
Volumes: []v1.Volume{
|
||||
{
|
||||
Name: "volume-name",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: "myClaim",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
volumeSpec := &volume.Spec{
|
||||
PersistentVolume: &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "basicPV",
|
||||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteMany},
|
||||
},
|
||||
},
|
||||
}
|
||||
podName := util.GetUniquePodName(pod)
|
||||
seLinuxContainerContexts := []*v1.SELinuxOptions{&seLinux}
|
||||
|
||||
// Act
|
||||
generatedVolumeName, err := dsw.AddPodToVolume(
|
||||
podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts)
|
||||
|
||||
// Assert
|
||||
if err != nil {
|
||||
t.Fatalf("AddPodToVolume failed. Expected: <no error> Actual: <%v>", err)
|
||||
}
|
||||
|
||||
verifyVolumeExistsDsw(t, generatedVolumeName, "" /* SELinux */, dsw)
|
||||
verifyVolumeExistsInVolumesToMount(
|
||||
t, generatedVolumeName, false /* expectReportedInUse */, dsw)
|
||||
verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "" /* SELinux */, dsw)
|
||||
verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw)
|
||||
}
|
||||
|
||||
// Calls AddPodToVolume() with a volume that does not support SELinux.
|
||||
// Verifies newly added pod/volume exists via PodExistsInVolume() without SELinux context
|
||||
// VolumeExists() and GetVolumesToMount() and no errors.
|
||||
func Test_AddPodToVolume_Positive_NoSELinuxPlugin(t *testing.T) {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxMountReadWriteOncePod, true)
|
||||
// Arrange
|
||||
plugins := []volume.VolumePlugin{
|
||||
&volumetesting.FakeDeviceMountableVolumePlugin{
|
||||
FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{
|
||||
Plugin: volumetesting.FakeVolumePlugin{
|
||||
PluginName: "basic",
|
||||
SupportsSELinux: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
volumePluginMgr := volume.VolumePluginMgr{}
|
||||
fakeVolumeHost := volumetesting.NewFakeVolumeHost(t,
|
||||
"", /* rootDir */
|
||||
nil, /* kubeClient */
|
||||
nil, /* plugins */
|
||||
)
|
||||
volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost)
|
||||
seLinuxTranslator := util.NewFakeSELinuxLabelTranslator()
|
||||
dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator)
|
||||
seLinux := v1.SELinuxOptions{
|
||||
User: "system_u",
|
||||
Role: "object_r",
|
||||
Type: "container_t",
|
||||
Level: "s0:c1,c2",
|
||||
}
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod1",
|
||||
UID: "pod1uid",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: &v1.PodSecurityContext{
|
||||
SELinuxOptions: &seLinux,
|
||||
},
|
||||
Volumes: []v1.Volume{
|
||||
{
|
||||
Name: "volume-name",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: "myClaim",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
volumeSpec := &volume.Spec{
|
||||
PersistentVolume: &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "basicPV",
|
||||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOncePod},
|
||||
},
|
||||
},
|
||||
}
|
||||
podName := util.GetUniquePodName(pod)
|
||||
seLinuxContainerContexts := []*v1.SELinuxOptions{&seLinux}
|
||||
|
||||
// Act
|
||||
generatedVolumeName, err := dsw.AddPodToVolume(
|
||||
podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts)
|
||||
|
||||
// Assert
|
||||
if err != nil {
|
||||
t.Fatalf("AddPodToVolume failed. Expected: <no error> Actual: <%v>", err)
|
||||
}
|
||||
|
||||
verifyVolumeExistsDsw(t, generatedVolumeName, "" /* SELinux */, dsw)
|
||||
verifyVolumeExistsInVolumesToMount(
|
||||
t, generatedVolumeName, false /* expectReportedInUse */, dsw)
|
||||
verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "" /* SELinux */, dsw)
|
||||
verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw)
|
||||
}
|
||||
|
||||
// Calls AddPodToVolume() twice to add two pods with the same SELinuxContext
|
||||
// to the same ReadWriteOncePod PV.
|
||||
// Verifies newly added pod/volume exists via PodExistsInVolume()
|
||||
@ -978,6 +815,160 @@ func Test_AddPodToVolume_Negative_ExistingPodDifferentSELinuxRWOP(t *testing.T)
|
||||
verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, "system_u:object_r:container_file_t:s0:c1,c2", dsw)
|
||||
}
|
||||
|
||||
// Calls AddPodToVolume() in an empty DSW with various SELinux settings / access modes.
|
||||
func Test_AddPodToVolume_SELinuxSinglePod(t *testing.T) {
|
||||
completeSELinuxOpts := v1.SELinuxOptions{
|
||||
User: "system_u",
|
||||
Role: "object_r",
|
||||
Type: "container_t",
|
||||
Level: "s0:c1,c2",
|
||||
}
|
||||
completeSELinuxLabel := "system_u:object_r:container_file_t:s0:c1,c2"
|
||||
|
||||
incompleteSELinuxOpts := v1.SELinuxOptions{
|
||||
Level: "s0:c1,c2",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
featureGates []featuregate.Feature
|
||||
volumePluginSupportsSELinux bool
|
||||
volumeAccessMode v1.PersistentVolumeAccessMode
|
||||
podSELinuxOptions *v1.SELinuxOptions
|
||||
|
||||
expectError bool
|
||||
expectedSELinuxLabel string
|
||||
}{
|
||||
{
|
||||
name: "ReadWriteOncePod with plugin that supports SELinux mount",
|
||||
featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod},
|
||||
volumePluginSupportsSELinux: true,
|
||||
volumeAccessMode: v1.ReadWriteOncePod,
|
||||
podSELinuxOptions: &completeSELinuxOpts,
|
||||
|
||||
expectError: false,
|
||||
expectedSELinuxLabel: completeSELinuxLabel,
|
||||
},
|
||||
{
|
||||
name: "ReadWriteOncePod incomplete SELinuxOptions",
|
||||
featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod},
|
||||
volumePluginSupportsSELinux: true,
|
||||
volumeAccessMode: v1.ReadWriteOncePod,
|
||||
podSELinuxOptions: &incompleteSELinuxOpts,
|
||||
|
||||
expectError: false,
|
||||
expectedSELinuxLabel: completeSELinuxLabel, // kubelet files the missing SELinuxOptions fields
|
||||
},
|
||||
{
|
||||
name: "ReadWriteOncePod with plugin that does not support SELinux mount",
|
||||
featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod},
|
||||
volumePluginSupportsSELinux: false,
|
||||
volumeAccessMode: v1.ReadWriteOncePod,
|
||||
podSELinuxOptions: &completeSELinuxOpts,
|
||||
|
||||
expectError: false,
|
||||
expectedSELinuxLabel: "", // The plugin does not support SELinux
|
||||
},
|
||||
{
|
||||
name: "ReadWriteMany with plugin that supports SELinux mount",
|
||||
featureGates: []featuregate.Feature{features.SELinuxMountReadWriteOncePod},
|
||||
volumePluginSupportsSELinux: true,
|
||||
volumeAccessMode: v1.ReadWriteMany,
|
||||
podSELinuxOptions: &completeSELinuxOpts,
|
||||
|
||||
expectError: false,
|
||||
expectedSELinuxLabel: "", // The plugin does not support SELinux
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
for _, feature := range tc.featureGates {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, feature, true)
|
||||
}
|
||||
// Arrange
|
||||
plugins := []volume.VolumePlugin{
|
||||
&volumetesting.FakeDeviceMountableVolumePlugin{
|
||||
FakeBasicVolumePlugin: volumetesting.FakeBasicVolumePlugin{
|
||||
Plugin: volumetesting.FakeVolumePlugin{
|
||||
PluginName: "basic",
|
||||
SupportsSELinux: tc.volumePluginSupportsSELinux,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
volumePluginMgr := volume.VolumePluginMgr{}
|
||||
fakeVolumeHost := volumetesting.NewFakeVolumeHost(t,
|
||||
"", /* rootDir */
|
||||
nil, /* kubeClient */
|
||||
nil, /* plugins */
|
||||
)
|
||||
err := volumePluginMgr.InitPlugins(plugins, nil /* prober */, fakeVolumeHost)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to init volume plugins: %v", err)
|
||||
}
|
||||
seLinuxTranslator := util.NewFakeSELinuxLabelTranslator()
|
||||
dsw := NewDesiredStateOfWorld(&volumePluginMgr, seLinuxTranslator)
|
||||
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod1",
|
||||
UID: "pod1uid",
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
SecurityContext: &v1.PodSecurityContext{
|
||||
SELinuxOptions: tc.podSELinuxOptions,
|
||||
},
|
||||
Volumes: []v1.Volume{
|
||||
{
|
||||
Name: "volume-name",
|
||||
VolumeSource: v1.VolumeSource{
|
||||
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{
|
||||
ClaimName: "myClaim",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
volumeSpec := &volume.Spec{
|
||||
PersistentVolume: &v1.PersistentVolume{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "basicPV",
|
||||
},
|
||||
Spec: v1.PersistentVolumeSpec{
|
||||
AccessModes: []v1.PersistentVolumeAccessMode{tc.volumeAccessMode},
|
||||
},
|
||||
},
|
||||
}
|
||||
podName := util.GetUniquePodName(pod)
|
||||
seLinuxContainerContexts := []*v1.SELinuxOptions{tc.podSELinuxOptions}
|
||||
|
||||
// Act
|
||||
generatedVolumeName, err := dsw.AddPodToVolume(
|
||||
podName, pod, volumeSpec, volumeSpec.Name(), "" /* volumeGidValue */, seLinuxContainerContexts)
|
||||
|
||||
// Assert
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
t.Errorf("Expected AddPodToVolume to return error, got nil")
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("AddPodToVolume failed. Expected: <no error> Actual: %v", err)
|
||||
}
|
||||
|
||||
verifyVolumeExistsDsw(t, generatedVolumeName, tc.expectedSELinuxLabel, dsw)
|
||||
verifyVolumeExistsInVolumesToMount(
|
||||
t, generatedVolumeName, false /* expectReportedInUse */, dsw)
|
||||
verifyPodExistsInVolumeDsw(t, podName, generatedVolumeName, tc.expectedSELinuxLabel, dsw)
|
||||
verifyVolumeExistsWithSpecNameInVolumeDsw(t, podName, volumeSpec.Name(), dsw)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func verifyVolumeExistsDsw(
|
||||
t *testing.T, expectedVolumeName v1.UniqueVolumeName, expectedSELinuxContext string, dsw DesiredStateOfWorld) {
|
||||
volumeExists := dsw.VolumeExists(expectedVolumeName, expectedSELinuxContext)
|
||||
|
Loading…
Reference in New Issue
Block a user