Merge pull request #111023 from pohly/dynamic-resource-allocation
dynamic resource allocation
This commit is contained in:
@@ -5385,7 +5385,7 @@ func TestAlphaLocalStorageCapacityIsolation(t *testing.T) {
|
||||
resource.BinarySI),
|
||||
},
|
||||
}
|
||||
if errs := ValidateResourceRequirements(&containerLimitCase, field.NewPath("resources"), PodValidationOptions{}); len(errs) != 0 {
|
||||
if errs := ValidateResourceRequirements(&containerLimitCase, nil, field.NewPath("resources"), PodValidationOptions{}); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
@@ -6855,7 +6855,7 @@ func TestValidateEphemeralContainers(t *testing.T) {
|
||||
},
|
||||
},
|
||||
} {
|
||||
if errs := validateEphemeralContainers(ephemeralContainers, containers, initContainers, vols, field.NewPath("ephemeralContainers"), PodValidationOptions{}); len(errs) != 0 {
|
||||
if errs := validateEphemeralContainers(ephemeralContainers, containers, initContainers, vols, nil, field.NewPath("ephemeralContainers"), PodValidationOptions{}); len(errs) != 0 {
|
||||
t.Errorf("expected success for '%s' but got errors: %v", title, errs)
|
||||
}
|
||||
}
|
||||
@@ -7137,7 +7137,7 @@ func TestValidateEphemeralContainers(t *testing.T) {
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.title+"__@L"+tc.line, func(t *testing.T) {
|
||||
errs := validateEphemeralContainers(tc.ephemeralContainers, containers, initContainers, vols, field.NewPath("ephemeralContainers"), PodValidationOptions{})
|
||||
errs := validateEphemeralContainers(tc.ephemeralContainers, containers, initContainers, vols, nil, field.NewPath("ephemeralContainers"), PodValidationOptions{})
|
||||
if len(errs) == 0 {
|
||||
t.Fatal("expected error but received none")
|
||||
}
|
||||
@@ -7416,7 +7416,7 @@ func TestValidateContainers(t *testing.T) {
|
||||
TerminationMessagePolicy: "File",
|
||||
},
|
||||
}
|
||||
if errs := validateContainers(successCase, volumeDevices, field.NewPath("field"), PodValidationOptions{}); len(errs) != 0 {
|
||||
if errs := validateContainers(successCase, volumeDevices, nil, field.NewPath("field"), PodValidationOptions{}); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
|
||||
@@ -8040,7 +8040,7 @@ func TestValidateContainers(t *testing.T) {
|
||||
}
|
||||
for _, tc := range errorCases {
|
||||
t.Run(tc.title+"__@L"+tc.line, func(t *testing.T) {
|
||||
errs := validateContainers(tc.containers, volumeDevices, field.NewPath("containers"), PodValidationOptions{})
|
||||
errs := validateContainers(tc.containers, volumeDevices, nil, field.NewPath("containers"), PodValidationOptions{})
|
||||
if len(errs) == 0 {
|
||||
t.Fatal("expected error but received none")
|
||||
}
|
||||
@@ -8090,7 +8090,7 @@ func TestValidateInitContainers(t *testing.T) {
|
||||
TerminationMessagePolicy: "File",
|
||||
},
|
||||
}
|
||||
if errs := validateInitContainers(successCase, containers, volumeDevices, field.NewPath("field"), PodValidationOptions{}); len(errs) != 0 {
|
||||
if errs := validateInitContainers(successCase, containers, volumeDevices, nil, field.NewPath("field"), PodValidationOptions{}); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
|
||||
@@ -8282,7 +8282,7 @@ func TestValidateInitContainers(t *testing.T) {
|
||||
}
|
||||
for _, tc := range errorCases {
|
||||
t.Run(tc.title+"__@L"+tc.line, func(t *testing.T) {
|
||||
errs := validateInitContainers(tc.initContainers, containers, volumeDevices, field.NewPath("initContainers"), PodValidationOptions{})
|
||||
errs := validateInitContainers(tc.initContainers, containers, volumeDevices, nil, field.NewPath("initContainers"), PodValidationOptions{})
|
||||
if len(errs) == 0 {
|
||||
t.Fatal("expected error but received none")
|
||||
}
|
||||
@@ -18625,6 +18625,9 @@ func TestValidateOSFields(t *testing.T) {
|
||||
"Priority",
|
||||
"PriorityClassName",
|
||||
"ReadinessGates",
|
||||
"ResourceClaims[*].Name",
|
||||
"ResourceClaims[*].Source.ResourceClaimName",
|
||||
"ResourceClaims[*].Source.ResourceClaimTemplateName",
|
||||
"RestartPolicy",
|
||||
"RuntimeClassName",
|
||||
"SchedulerName",
|
||||
@@ -20928,7 +20931,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if errs := ValidateResourceRequirements(&tc.requirements, path, tc.opts); len(errs) != 0 {
|
||||
if errs := ValidateResourceRequirements(&tc.requirements, nil, path, tc.opts); len(errs) != 0 {
|
||||
t.Errorf("unexpected errors: %v", errs)
|
||||
}
|
||||
})
|
||||
@@ -20955,7 +20958,7 @@ func TestValidateResourceRequirements(t *testing.T) {
|
||||
|
||||
for _, tc := range errTests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if errs := ValidateResourceRequirements(&tc.requirements, path, tc.opts); len(errs) == 0 {
|
||||
if errs := ValidateResourceRequirements(&tc.requirements, nil, path, tc.opts); len(errs) == 0 {
|
||||
t.Error("expected errors")
|
||||
}
|
||||
})
|
||||
@@ -21695,3 +21698,220 @@ func TestValidatePVSecretReference(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateDynamicResourceAllocation(t *testing.T) {
|
||||
externalClaimName := "some-claim"
|
||||
externalClaimTemplateName := "some-claim-template"
|
||||
goodClaimSource := core.ClaimSource{
|
||||
ResourceClaimName: &externalClaimName,
|
||||
}
|
||||
|
||||
successCases := map[string]core.PodSpec{
|
||||
"resource claim reference": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: core.ClaimSource{
|
||||
ResourceClaimName: &externalClaimName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"resource claim template": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: core.ClaimSource{
|
||||
ResourceClaimTemplateName: &externalClaimTemplateName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"multiple claims": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}, {Name: "another-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
{
|
||||
Name: "another-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"init container": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
InitContainers: []core.Container{{Name: "ctr-init", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, v := range successCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
if errs := ValidatePodSpec(&v, nil, field.NewPath("field"), PodValidationOptions{}); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
failureCases := map[string]core.PodSpec{
|
||||
"pod claim name with prefix": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "../my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"pod claim name with path": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my/claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"pod claim name empty": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"duplicate pod claim entries": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"resource claim source empty": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: core.ClaimSource{},
|
||||
},
|
||||
},
|
||||
},
|
||||
"resource claim reference and template": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: core.ClaimSource{
|
||||
ResourceClaimName: &externalClaimName,
|
||||
ResourceClaimTemplateName: &externalClaimTemplateName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"claim not found": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "no-such-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"claim name empty": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: ""}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"pod claim name duplicates": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}, {Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"no claims defined": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
"duplicate pod claim name": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
"ephemeral container don't support resource requirements": {
|
||||
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}},
|
||||
EphemeralContainers: []core.EphemeralContainer{{EphemeralContainerCommon: core.EphemeralContainerCommon{Name: "ctr-ephemeral", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File", Resources: core.ResourceRequirements{Claims: []core.ResourceClaim{{Name: "my-claim"}}}}, TargetContainerName: "ctr"}},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
ResourceClaims: []core.PodResourceClaim{
|
||||
{
|
||||
Name: "my-claim",
|
||||
Source: goodClaimSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, v := range failureCases {
|
||||
if errs := ValidatePodSpec(&v, nil, field.NewPath("field"), PodValidationOptions{}); len(errs) == 0 {
|
||||
t.Errorf("expected failure for %q", k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user