diff --git a/pkg/kubelet/userns/userns_manager_test.go b/pkg/kubelet/userns/userns_manager_test.go index b2f6fc1eabc..251eee94bb1 100644 --- a/pkg/kubelet/userns/userns_manager_test.go +++ b/pkg/kubelet/userns/userns_manager_test.go @@ -43,10 +43,12 @@ const ( ) type testUserNsPodsManager struct { - podDir string - podList []types.UID - userns bool - maxPods int + podDir string + podList []types.UID + userns bool + maxPods int + mappingFirstID uint32 + mappingLen uint32 } func (m *testUserNsPodsManager) GetPodDir(podUID types.UID) string { @@ -71,6 +73,9 @@ func (m *testUserNsPodsManager) HandlerSupportsUserNamespaces(runtimeHandler str } func (m *testUserNsPodsManager) GetKubeletMappings() (uint32, uint32, error) { + if m.mappingFirstID != 0 { + return m.mappingFirstID, m.mappingLen, nil + } return minimumMappingUID, mappingLen, nil } @@ -133,6 +138,60 @@ func TestUserNsManagerAllocate(t *testing.T) { } } +func TestMakeUserNsManager(t *testing.T) { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.UserNamespacesSupport, true)() + + cases := []struct { + name string + mappingFirstID uint32 + mappingLen uint32 + maxPods int + success bool + }{ + { + name: "default", + success: true, + }, + { + name: "firstID not multiple", + mappingFirstID: 65536 + 1, + }, + { + name: "firstID is less than 65535", + mappingFirstID: 1, + }, + { + name: "mappingLen not multiple", + mappingFirstID: 65536, + mappingLen: 65536 + 1, + }, + { + name: "range can't fit maxPods", + mappingFirstID: 65536, + mappingLen: 65536, + maxPods: 2, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + testUserNsPodsManager := &testUserNsPodsManager{ + podDir: t.TempDir(), + mappingFirstID: tc.mappingFirstID, + mappingLen: tc.mappingLen, + maxPods: tc.maxPods, + } + _, err := MakeUserNsManager(testUserNsPodsManager) + + if tc.success { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } + }) + } +} + func TestUserNsManagerParseUserNsFile(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.UserNamespacesSupport, true)() @@ -404,3 +463,25 @@ func TestMakeUserNsManagerFailsListPod(t *testing.T) { assert.Error(t, err) assert.ErrorContains(t, err, "read pods from disk") } + +func TestRecordBounds(t *testing.T) { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.UserNamespacesSupport, true)() + + // Allow exactly for 1 pod + testUserNsPodsManager := &testUserNsPodsManager{ + mappingFirstID: 65536, + mappingLen: 65536, + maxPods: 1, + } + m, err := MakeUserNsManager(testUserNsPodsManager) + require.NoError(t, err) + + // The first pod allocation should succeed. + err = m.record(types.UID(fmt.Sprintf("%d", 0)), 65536, 65536) + require.NoError(t, err) + + // The next allocation should fail, as there is no space left. + err = m.record(types.UID(fmt.Sprintf("%d", 2)), uint32(2*65536), 65536) + assert.Error(t, err) + assert.ErrorContains(t, err, "out of range") +}