Clean up brace whitespace in **/validation_test.go

This was making my eyes bleed as I read over code.

I used the following in vim.  I made them up on the fly, but they seemed
to pass manual inspection.

:g/},\n\s*{$/s//}, {/
:w
:g/{$\n\s*{$/s//{{/
:w
:g/^\(\s*\)},\n\1},$/s//}},/
:w
:g/^\(\s*\)},$\n\1}$/s//}}/
:w
This commit is contained in:
Tim Hockin
2023-05-02 00:36:15 -07:00
parent 19830bf51b
commit d55b67b349
27 changed files with 18026 additions and 22083 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -28,96 +28,84 @@ func TestValidateServerStorageVersion(t *testing.T) {
cases := []struct { cases := []struct {
ssv apiserverinternal.ServerStorageVersion ssv apiserverinternal.ServerStorageVersion
expectedErr string expectedErr string
}{ }{{
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "-fea", APIServerID: "-fea",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
DecodableVersions: []string{"v1alpha1", "v1"}, DecodableVersions: []string{"v1alpha1", "v1"},
}, },
expectedErr: "apiServerID: Invalid value", expectedErr: "apiServerID: Invalid value",
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
DecodableVersions: []string{"v1beta1", "v1"}, DecodableVersions: []string{"v1beta1", "v1"},
}, },
expectedErr: "decodableVersions must include encodingVersion", expectedErr: "decodableVersions must include encodingVersion",
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
DecodableVersions: []string{"v1alpha1", "v1", "-fea"}, DecodableVersions: []string{"v1alpha1", "v1", "-fea"},
}, },
expectedErr: "decodableVersions[2]: Invalid value", expectedErr: "decodableVersions[2]: Invalid value",
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
DecodableVersions: []string{"v1alpha1", "v1"}, DecodableVersions: []string{"v1alpha1", "v1"},
}, },
expectedErr: "", expectedErr: "",
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "mygroup.com/v2", EncodingVersion: "mygroup.com/v2",
DecodableVersions: []string{"v1alpha1", "v1", "mygroup.com/v2"}, DecodableVersions: []string{"v1alpha1", "v1", "mygroup.com/v2"},
}, },
expectedErr: "", expectedErr: "",
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "mygroup.com/v2", EncodingVersion: "mygroup.com/v2",
DecodableVersions: []string{"mygroup.com/v2", "/v3"}, DecodableVersions: []string{"mygroup.com/v2", "/v3"},
}, },
expectedErr: `[].decodableVersions[1]: Invalid value: "/v3": group part: must be non-empty`, expectedErr: `[].decodableVersions[1]: Invalid value: "/v3": group part: must be non-empty`,
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "mygroup.com/v2", EncodingVersion: "mygroup.com/v2",
DecodableVersions: []string{"mygroup.com/v2", "mygroup.com/"}, DecodableVersions: []string{"mygroup.com/v2", "mygroup.com/"},
}, },
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/": version part: must be non-empty`, expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/": version part: must be non-empty`,
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "/v3", EncodingVersion: "/v3",
DecodableVersions: []string{"mygroup.com/v2", "/v3"}, DecodableVersions: []string{"mygroup.com/v2", "/v3"},
}, },
expectedErr: `[].encodingVersion: Invalid value: "/v3": group part: must be non-empty`, expectedErr: `[].encodingVersion: Invalid value: "/v3": group part: must be non-empty`,
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "v1", EncodingVersion: "v1",
DecodableVersions: []string{"v1", "mygroup_com/v2"}, DecodableVersions: []string{"v1", "mygroup_com/v2"},
}, },
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup_com/v2": group part: a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`, expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup_com/v2": group part: a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`,
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "v1", EncodingVersion: "v1",
DecodableVersions: []string{"v1", "mygroup.com/v2_"}, DecodableVersions: []string{"v1", "mygroup.com/v2_"},
}, },
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2_": version part: a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?')`, expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2_": version part: a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?')`,
}, }, {
{
ssv: apiserverinternal.ServerStorageVersion{ ssv: apiserverinternal.ServerStorageVersion{
APIServerID: "fea", APIServerID: "fea",
EncodingVersion: "v1", EncodingVersion: "v1",
DecodableVersions: []string{"v1", "mygroup.com/v2/myresource"}, DecodableVersions: []string{"v1", "mygroup.com/v2/myresource"},
}, },
expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2/myresource": an apiVersion is a DNS-1035 label, which must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyVersion')`, expectedErr: `[].decodableVersions[1]: Invalid value: "mygroup.com/v2/myresource": an apiVersion is a DNS-1035 label, which must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is '[a-z]([-a-z0-9]*[a-z0-9])?') with an optional DNS subdomain prefix and '/' (e.g. 'example.com/MyVersion')`,
}, }}
}
for _, tc := range cases { for _, tc := range cases {
err := validateServerStorageVersion(tc.ssv, field.NewPath("")).ToAggregate() err := validateServerStorageVersion(tc.ssv, field.NewPath("")).ToAggregate()
@@ -142,91 +130,70 @@ func TestValidateCommonVersion(t *testing.T) {
cases := []struct { cases := []struct {
status apiserverinternal.StorageVersionStatus status apiserverinternal.StorageVersionStatus
expectedErr string expectedErr string
}{ }{{
{
status: apiserverinternal.StorageVersionStatus{ status: apiserverinternal.StorageVersionStatus{
StorageVersions: []apiserverinternal.ServerStorageVersion{}, StorageVersions: []apiserverinternal.ServerStorageVersion{},
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(), CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
}, },
expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet", expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet",
}, }, {
{
status: apiserverinternal.StorageVersionStatus{ status: apiserverinternal.StorageVersionStatus{
StorageVersions: []apiserverinternal.ServerStorageVersion{ StorageVersions: []apiserverinternal.ServerStorageVersion{{
{
APIServerID: "1", APIServerID: "1",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }, {
{
APIServerID: "2", APIServerID: "2",
EncodingVersion: "v1", EncodingVersion: "v1",
}, }},
},
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(), CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
}, },
expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet", expectedErr: "should be nil if servers do not agree on the same encoding version, or if there is no server reporting the supported versions yet",
}, }, {
{
status: apiserverinternal.StorageVersionStatus{ status: apiserverinternal.StorageVersionStatus{
StorageVersions: []apiserverinternal.ServerStorageVersion{ StorageVersions: []apiserverinternal.ServerStorageVersion{{
{
APIServerID: "1", APIServerID: "1",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }, {
{
APIServerID: "2", APIServerID: "2",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }},
},
CommonEncodingVersion: nil, CommonEncodingVersion: nil,
}, },
expectedErr: "Invalid value: \"null\": the common encoding version is v1alpha1", expectedErr: "Invalid value: \"null\": the common encoding version is v1alpha1",
}, }, {
{
status: apiserverinternal.StorageVersionStatus{ status: apiserverinternal.StorageVersionStatus{
StorageVersions: []apiserverinternal.ServerStorageVersion{ StorageVersions: []apiserverinternal.ServerStorageVersion{{
{
APIServerID: "1", APIServerID: "1",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }, {
{
APIServerID: "2", APIServerID: "2",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }},
},
CommonEncodingVersion: func() *string { a := "v1"; return &a }(), CommonEncodingVersion: func() *string { a := "v1"; return &a }(),
}, },
expectedErr: "Invalid value: \"v1\": the actual common encoding version is v1alpha1", expectedErr: "Invalid value: \"v1\": the actual common encoding version is v1alpha1",
}, }, {
{
status: apiserverinternal.StorageVersionStatus{ status: apiserverinternal.StorageVersionStatus{
StorageVersions: []apiserverinternal.ServerStorageVersion{ StorageVersions: []apiserverinternal.ServerStorageVersion{{
{
APIServerID: "1", APIServerID: "1",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }, {
{
APIServerID: "2", APIServerID: "2",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }},
},
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(), CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
}, },
expectedErr: "", expectedErr: "",
}, }, {
{
status: apiserverinternal.StorageVersionStatus{ status: apiserverinternal.StorageVersionStatus{
StorageVersions: []apiserverinternal.ServerStorageVersion{ StorageVersions: []apiserverinternal.ServerStorageVersion{{
{
APIServerID: "1", APIServerID: "1",
EncodingVersion: "v1alpha1", EncodingVersion: "v1alpha1",
}, }},
},
CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(), CommonEncodingVersion: func() *string { a := "v1alpha1"; return &a }(),
}, },
expectedErr: "", expectedErr: "",
}, }}
}
for _, tc := range cases { for _, tc := range cases {
err := validateCommonVersion(tc.status, field.NewPath("")) err := validateCommonVersion(tc.status, field.NewPath(""))
if err == nil && len(tc.expectedErr) == 0 { if err == nil && len(tc.expectedErr) == 0 {
@@ -250,78 +217,58 @@ func TestValidateStorageVersionCondition(t *testing.T) {
cases := []struct { cases := []struct {
conditions []apiserverinternal.StorageVersionCondition conditions []apiserverinternal.StorageVersionCondition
expectedErr string expectedErr string
}{ }{{
{ conditions: []apiserverinternal.StorageVersionCondition{{
conditions: []apiserverinternal.StorageVersionCondition{
{
Type: "-fea", Type: "-fea",
Status: "True", Status: "True",
Reason: "unknown", Reason: "unknown",
Message: "unknown", Message: "unknown",
}, }},
},
expectedErr: "type: Invalid value", expectedErr: "type: Invalid value",
}, }, {
{ conditions: []apiserverinternal.StorageVersionCondition{{
conditions: []apiserverinternal.StorageVersionCondition{
{
Type: "fea", Type: "fea",
Status: "-True", Status: "-True",
Reason: "unknown", Reason: "unknown",
Message: "unknown", Message: "unknown",
}, }},
},
expectedErr: "status: Invalid value", expectedErr: "status: Invalid value",
}, }, {
{ conditions: []apiserverinternal.StorageVersionCondition{{
conditions: []apiserverinternal.StorageVersionCondition{
{
Type: "fea", Type: "fea",
Status: "True", Status: "True",
Message: "unknown", Message: "unknown",
}, }},
},
expectedErr: "Required value: reason cannot be empty", expectedErr: "Required value: reason cannot be empty",
}, }, {
{ conditions: []apiserverinternal.StorageVersionCondition{{
conditions: []apiserverinternal.StorageVersionCondition{
{
Type: "fea", Type: "fea",
Status: "True", Status: "True",
Reason: "unknown", Reason: "unknown",
}, }},
},
expectedErr: "Required value: message cannot be empty", expectedErr: "Required value: message cannot be empty",
}, }, {
{ conditions: []apiserverinternal.StorageVersionCondition{{
conditions: []apiserverinternal.StorageVersionCondition{
{
Type: "fea", Type: "fea",
Status: "True", Status: "True",
Reason: "unknown", Reason: "unknown",
Message: "unknown", Message: "unknown",
}, }, {
{
Type: "fea", Type: "fea",
Status: "True", Status: "True",
Reason: "unknown", Reason: "unknown",
Message: "unknown", Message: "unknown",
}, }},
},
expectedErr: `"fea": the type of the condition is not unique, it also appears in conditions[0]`, expectedErr: `"fea": the type of the condition is not unique, it also appears in conditions[0]`,
}, }, {
{ conditions: []apiserverinternal.StorageVersionCondition{{
conditions: []apiserverinternal.StorageVersionCondition{
{
Type: "fea", Type: "fea",
Status: "True", Status: "True",
Reason: "unknown", Reason: "unknown",
Message: "unknown", Message: "unknown",
}, }},
},
expectedErr: "", expectedErr: "",
}, }}
}
for _, tc := range cases { for _, tc := range cases {
err := validateStorageVersionCondition(tc.conditions, field.NewPath("")).ToAggregate() err := validateStorageVersionCondition(tc.conditions, field.NewPath("")).ToAggregate()
if err == nil && len(tc.expectedErr) == 0 { if err == nil && len(tc.expectedErr) == 0 {
@@ -345,40 +292,31 @@ func TestValidateStorageVersionName(t *testing.T) {
cases := []struct { cases := []struct {
name string name string
expectedErr string expectedErr string
}{ }{{
{
name: "", name: "",
expectedErr: `name must be in the form of <group>.<resource>`, expectedErr: `name must be in the form of <group>.<resource>`,
}, }, {
{
name: "pods", name: "pods",
expectedErr: `name must be in the form of <group>.<resource>`, expectedErr: `name must be in the form of <group>.<resource>`,
}, }, {
{
name: "core.pods", name: "core.pods",
expectedErr: "", expectedErr: "",
}, }, {
{
name: "authentication.k8s.io.tokenreviews", name: "authentication.k8s.io.tokenreviews",
expectedErr: "", expectedErr: "",
}, }, {
{
name: strings.Repeat("x", 253) + ".tokenreviews", name: strings.Repeat("x", 253) + ".tokenreviews",
expectedErr: "", expectedErr: "",
}, }, {
{
name: strings.Repeat("x", 254) + ".tokenreviews", name: strings.Repeat("x", 254) + ".tokenreviews",
expectedErr: `the group segment must be no more than 253 characters`, expectedErr: `the group segment must be no more than 253 characters`,
}, }, {
{
name: "authentication.k8s.io." + strings.Repeat("x", 63), name: "authentication.k8s.io." + strings.Repeat("x", 63),
expectedErr: "", expectedErr: "",
}, }, {
{
name: "authentication.k8s.io." + strings.Repeat("x", 64), name: "authentication.k8s.io." + strings.Repeat("x", 64),
expectedErr: `the resource segment must be no more than 63 characters`, expectedErr: `the resource segment must be no more than 63 characters`,
}, }}
}
for _, tc := range cases { for _, tc := range cases {
errs := ValidateStorageVersionName(tc.name, false) errs := ValidateStorageVersionName(tc.name, false)
if errs == nil && len(tc.expectedErr) == 0 { if errs == nil && len(tc.expectedErr) == 0 {

View File

@@ -248,32 +248,26 @@ func TestValidateStatefulSet(t *testing.T) {
errs field.ErrorList errs field.ErrorList
} }
successCases := []testCase{ successCases := []testCase{{
{
name: "alpha name", name: "alpha name",
set: mkStatefulSet(&validPodTemplate, tweakName("abc")), set: mkStatefulSet(&validPodTemplate, tweakName("abc")),
}, }, {
{
name: "alphanumeric name", name: "alphanumeric name",
set: mkStatefulSet(&validPodTemplate, tweakName("abc-123")), set: mkStatefulSet(&validPodTemplate, tweakName("abc-123")),
}, }, {
{
name: "parallel pod management", name: "parallel pod management",
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)), set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)),
}, }, {
{
name: "ordered ready pod management", name: "ordered ready pod management",
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)), set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
}, }, {
{
name: "update strategy", name: "update strategy",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
tweakUpdateStrategyType(apps.RollingUpdateStatefulSetStrategyType), tweakUpdateStrategyType(apps.RollingUpdateStatefulSetStrategyType),
tweakRollingUpdatePartition(2), tweakRollingUpdatePartition(2),
), ),
}, }, {
{
name: "PVC policy " + enableStatefulSetAutoDeletePVC, name: "PVC policy " + enableStatefulSetAutoDeletePVC,
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakPVCPolicy(mkPVCPolicy( tweakPVCPolicy(mkPVCPolicy(
@@ -281,8 +275,7 @@ func TestValidateStatefulSet(t *testing.T) {
tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType), tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType),
)), )),
), ),
}, }, {
{
name: "maxUnavailable with parallel pod management", name: "maxUnavailable with parallel pod management",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -290,8 +283,7 @@ func TestValidateStatefulSet(t *testing.T) {
tweakRollingUpdatePartition(2), tweakRollingUpdatePartition(2),
tweakMaxUnavailable(intstr.FromInt32(2)), tweakMaxUnavailable(intstr.FromInt32(2)),
), ),
}, }, {
{
name: "ordinals.start positive value", name: "ordinals.start positive value",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -300,58 +292,50 @@ func TestValidateStatefulSet(t *testing.T) {
}, },
} }
errorCases := []testCase{ errorCases := []testCase{{
{
name: "zero-length name", name: "zero-length name",
set: mkStatefulSet(&validPodTemplate, tweakName("")), set: mkStatefulSet(&validPodTemplate, tweakName("")),
errs: field.ErrorList{ errs: field.ErrorList{
field.Required(field.NewPath("metadata", "name"), ""), field.Required(field.NewPath("metadata", "name"), ""),
}, },
}, }, {
{
name: "name-with-dots", name: "name-with-dots",
set: mkStatefulSet(&validPodTemplate, tweakName("abc.123")), set: mkStatefulSet(&validPodTemplate, tweakName("abc.123")),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("metadata", "name"), "abc.123", ""), field.Invalid(field.NewPath("metadata", "name"), "abc.123", ""),
}, },
}, }, {
{
name: "long name", name: "long name",
set: mkStatefulSet(&validPodTemplate, tweakName(strings.Repeat("a", 64))), set: mkStatefulSet(&validPodTemplate, tweakName(strings.Repeat("a", 64))),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("metadata", "name"), strings.Repeat("a", 64), ""), field.Invalid(field.NewPath("metadata", "name"), strings.Repeat("a", 64), ""),
}, },
}, }, {
{
name: "missing-namespace", name: "missing-namespace",
set: mkStatefulSet(&validPodTemplate, tweakNamespace("")), set: mkStatefulSet(&validPodTemplate, tweakNamespace("")),
errs: field.ErrorList{ errs: field.ErrorList{
field.Required(field.NewPath("metadata", "namespace"), ""), field.Required(field.NewPath("metadata", "namespace"), ""),
}, },
}, }, {
{
name: "empty selector", name: "empty selector",
set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(nil)), set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(nil)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Required(field.NewPath("spec", "selector"), ""), field.Required(field.NewPath("spec", "selector"), ""),
field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""), // selector is empty, labels are not, so select doesn't match labels field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""), // selector is empty, labels are not, so select doesn't match labels
}, },
}, }, {
{
name: "selector_doesnt_match", name: "selector_doesnt_match",
set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(map[string]string{"foo": "bar"})), set: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(map[string]string{"foo": "bar"})),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""), field.Invalid(field.NewPath("spec", "template", "metadata", "labels"), nil, ""),
}, },
}, }, {
{
name: "negative_replicas", name: "negative_replicas",
set: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)), set: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "replicas"), nil, ""), field.Invalid(field.NewPath("spec", "replicas"), nil, ""),
}, },
}, }, {
{
name: "invalid_label", name: "invalid_label",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"), tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
@@ -359,8 +343,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("metadata", "labels"), nil, ""), field.Invalid(field.NewPath("metadata", "labels"), nil, ""),
}, },
}, }, {
{
name: "invalid_label 2", name: "invalid_label 2",
set: mkStatefulSet(&invalidPodTemplate, set: mkStatefulSet(&invalidPodTemplate,
tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"), tweakLabels("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
@@ -371,8 +354,7 @@ func TestValidateStatefulSet(t *testing.T) {
field.Invalid(field.NewPath("spec", "selector"), nil, ""), field.Invalid(field.NewPath("spec", "selector"), nil, ""),
field.Invalid(field.NewPath("spec", "selector", "matchLabels"), nil, ""), field.Invalid(field.NewPath("spec", "selector", "matchLabels"), nil, ""),
}, },
}, }, {
{
name: "invalid_annotation", name: "invalid_annotation",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakAnnotations("NoUppercaseOrSpecialCharsLike=Equals", "bar"), tweakAnnotations("NoUppercaseOrSpecialCharsLike=Equals", "bar"),
@@ -380,29 +362,25 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("metadata", "annotations"), nil, ""), field.Invalid(field.NewPath("metadata", "annotations"), nil, ""),
}, },
}, }, {
{
name: "invalid restart policy 1", name: "invalid restart policy 1",
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyOnFailure)), set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyOnFailure)),
errs: field.ErrorList{ errs: field.ErrorList{
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil), field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
}, },
}, }, {
{
name: "invalid restart policy 2", name: "invalid restart policy 2",
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyNever)), set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy(api.RestartPolicyNever)),
errs: field.ErrorList{ errs: field.ErrorList{
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil), field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
}, },
}, }, {
{
name: "empty restart policy", name: "empty restart policy",
set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy("")), set: mkStatefulSet(&validPodTemplate, tweakTemplateRestartPolicy("")),
errs: field.ErrorList{ errs: field.ErrorList{
field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil), field.NotSupported(field.NewPath("spec", "template", "spec", "restartPolicy"), nil, nil),
}, },
}, }, {
{
name: "invalid update strategy", name: "invalid update strategy",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -411,8 +389,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "updateStrategy"), nil, ""), field.Invalid(field.NewPath("spec", "updateStrategy"), nil, ""),
}, },
}, }, {
{
name: "empty update strategy", name: "empty update strategy",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -421,8 +398,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Required(field.NewPath("spec", "updateStrategy"), ""), field.Required(field.NewPath("spec", "updateStrategy"), ""),
}, },
}, }, {
{
name: "invalid rolling update", name: "invalid rolling update",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -432,8 +408,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate"), nil, ""), field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate"), nil, ""),
}, },
}, }, {
{
name: "negative parition", name: "negative parition",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -442,8 +417,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "partition"), nil, ""), field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "partition"), nil, ""),
}, },
}, }, {
{
name: "empty pod management policy", name: "empty pod management policy",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakPodManagementPolicy(""), tweakPodManagementPolicy(""),
@@ -452,22 +426,19 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Required(field.NewPath("spec", "podManagementPolicy"), ""), field.Required(field.NewPath("spec", "podManagementPolicy"), ""),
}, },
}, }, {
{
name: "invalid pod management policy", name: "invalid pod management policy",
set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("foo")), set: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("foo")),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "podManagementPolicy"), nil, ""), field.Invalid(field.NewPath("spec", "podManagementPolicy"), nil, ""),
}, },
}, }, {
{
name: "set active deadline seconds", name: "set active deadline seconds",
set: mkStatefulSet(&invalidPodTemplate2, tweakReplicas(3)), set: mkStatefulSet(&invalidPodTemplate2, tweakReplicas(3)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Forbidden(field.NewPath("spec", "template", "spec", "activeDeadlineSeconds"), ""), field.Forbidden(field.NewPath("spec", "template", "spec", "activeDeadlineSeconds"), ""),
}, },
}, }, {
{
name: "empty PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC, name: "empty PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC,
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakPVCPolicy(mkPVCPolicy()), tweakPVCPolicy(mkPVCPolicy()),
@@ -476,8 +447,7 @@ func TestValidateStatefulSet(t *testing.T) {
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil), field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil),
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil), field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil),
}, },
}, }, {
{
name: "invalid PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC, name: "invalid PersistentVolumeClaimRetentionPolicy " + enableStatefulSetAutoDeletePVC,
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakPVCPolicy(mkPVCPolicy( tweakPVCPolicy(mkPVCPolicy(
@@ -489,8 +459,7 @@ func TestValidateStatefulSet(t *testing.T) {
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil), field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenDeleted"), nil, nil),
field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil), field.NotSupported(field.NewPath("spec", "persistentVolumeClaimRetentionPolicy", "whenScaled"), nil, nil),
}, },
}, }, {
{
name: "zero maxUnavailable", name: "zero maxUnavailable",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -500,8 +469,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""), field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
}, },
}, }, {
{
name: "zero percent maxUnavailable", name: "zero percent maxUnavailable",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -511,8 +479,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""), field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
}, },
}, }, {
{
name: "greater than 100 percent maxUnavailable", name: "greater than 100 percent maxUnavailable",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -522,8 +489,7 @@ func TestValidateStatefulSet(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""), field.Invalid(field.NewPath("spec", "updateStrategy", "rollingUpdate", "maxUnavailable"), nil, ""),
}, },
}, }, {
{
name: "invalid ordinals.start", name: "invalid ordinals.start",
set: mkStatefulSet(&validPodTemplate, set: mkStatefulSet(&validPodTemplate,
tweakReplicas(3), tweakReplicas(3),
@@ -635,48 +601,42 @@ func TestValidateStatefulSetStatus(t *testing.T) {
observedGeneration *int64 observedGeneration *int64
collisionCount *int32 collisionCount *int32
expectedErr bool expectedErr bool
}{ }{{
{
name: "valid status", name: "valid status",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: 2, currentReplicas: 2,
updatedReplicas: 1, updatedReplicas: 1,
expectedErr: false, expectedErr: false,
}, }, {
{
name: "invalid replicas", name: "invalid replicas",
replicas: -1, replicas: -1,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: 2, currentReplicas: 2,
updatedReplicas: 1, updatedReplicas: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid readyReplicas", name: "invalid readyReplicas",
replicas: 3, replicas: 3,
readyReplicas: -1, readyReplicas: -1,
currentReplicas: 2, currentReplicas: 2,
updatedReplicas: 1, updatedReplicas: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid currentReplicas", name: "invalid currentReplicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: -1, currentReplicas: -1,
updatedReplicas: 1, updatedReplicas: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid updatedReplicas", name: "invalid updatedReplicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: 2, currentReplicas: 2,
updatedReplicas: -1, updatedReplicas: -1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid observedGeneration", name: "invalid observedGeneration",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
@@ -684,8 +644,7 @@ func TestValidateStatefulSetStatus(t *testing.T) {
updatedReplicas: 1, updatedReplicas: 1,
observedGeneration: &observedGenerationMinusOne, observedGeneration: &observedGenerationMinusOne,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid collisionCount", name: "invalid collisionCount",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
@@ -693,48 +652,42 @@ func TestValidateStatefulSetStatus(t *testing.T) {
updatedReplicas: 1, updatedReplicas: 1,
collisionCount: &collisionCountMinusOne, collisionCount: &collisionCountMinusOne,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "readyReplicas greater than replicas", name: "readyReplicas greater than replicas",
replicas: 3, replicas: 3,
readyReplicas: 4, readyReplicas: 4,
currentReplicas: 2, currentReplicas: 2,
updatedReplicas: 1, updatedReplicas: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "currentReplicas greater than replicas", name: "currentReplicas greater than replicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: 4, currentReplicas: 4,
updatedReplicas: 1, updatedReplicas: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "updatedReplicas greater than replicas", name: "updatedReplicas greater than replicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: 2, currentReplicas: 2,
updatedReplicas: 4, updatedReplicas: 4,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid: number of available replicas", name: "invalid: number of available replicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: 2, currentReplicas: 2,
availableReplicas: int32(-1), availableReplicas: int32(-1),
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid: available replicas greater than replicas", name: "invalid: available replicas greater than replicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
currentReplicas: 2, currentReplicas: 2,
availableReplicas: int32(4), availableReplicas: int32(4),
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid: available replicas greater than ready replicas", name: "invalid: available replicas greater than ready replicas",
replicas: 3, replicas: 3,
readyReplicas: 2, readyReplicas: 2,
@@ -842,23 +795,19 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
errs field.ErrorList errs field.ErrorList
} }
successCases := []testCase{ successCases := []testCase{{
{
name: "update replica count", name: "update replica count",
old: mkStatefulSet(&validPodTemplate), old: mkStatefulSet(&validPodTemplate),
update: mkStatefulSet(&validPodTemplate, tweakReplicas(3)), update: mkStatefulSet(&validPodTemplate, tweakReplicas(3)),
}, }, {
{
name: "update containers 1", name: "update containers 1",
old: mkStatefulSet(&validPodTemplate), old: mkStatefulSet(&validPodTemplate),
update: mkStatefulSet(addContainersValidTemplate), update: mkStatefulSet(addContainersValidTemplate),
}, }, {
{
name: "update containers 2", name: "update containers 2",
old: mkStatefulSet(addContainersValidTemplate), old: mkStatefulSet(addContainersValidTemplate),
update: mkStatefulSet(&validPodTemplate), update: mkStatefulSet(&validPodTemplate),
}, }, {
{
name: "update containers and pvc retention policy 1", name: "update containers and pvc retention policy 1",
old: mkStatefulSet(addContainersValidTemplate), old: mkStatefulSet(addContainersValidTemplate),
update: mkStatefulSet(&validPodTemplate, update: mkStatefulSet(&validPodTemplate,
@@ -867,8 +816,7 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType), tweakPVCScalePolicy(apps.RetainPersistentVolumeClaimRetentionPolicyType),
)), )),
), ),
}, }, {
{
name: "update containers and pvc retention policy 2", name: "update containers and pvc retention policy 2",
old: mkStatefulSet(&validPodTemplate, old: mkStatefulSet(&validPodTemplate,
tweakPVCPolicy(mkPVCPolicy( tweakPVCPolicy(mkPVCPolicy(
@@ -876,54 +824,46 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
)), )),
), ),
update: mkStatefulSet(&validPodTemplate), update: mkStatefulSet(&validPodTemplate),
}, }, {
{
name: "update update strategy", name: "update update strategy",
old: mkStatefulSet(&validPodTemplate), old: mkStatefulSet(&validPodTemplate),
update: mkStatefulSet(&validPodTemplate, update: mkStatefulSet(&validPodTemplate,
tweakUpdateStrategyType(apps.OnDeleteStatefulSetStrategyType), tweakUpdateStrategyType(apps.OnDeleteStatefulSetStrategyType),
), ),
}, }, {
{
name: "update min ready seconds 1", name: "update min ready seconds 1",
old: mkStatefulSet(&validPodTemplate), old: mkStatefulSet(&validPodTemplate),
update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)), update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)),
}, }, {
{
name: "update min ready seconds 2", name: "update min ready seconds 2",
old: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(5)), old: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(5)),
update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)), update: mkStatefulSet(&validPodTemplate, tweakMinReadySeconds(10)),
}, }, {
{
name: "update existing instance with now-invalid name", name: "update existing instance with now-invalid name",
old: mkStatefulSet(&validPodTemplate, tweakFinalizers("final")), old: mkStatefulSet(&validPodTemplate, tweakFinalizers("final")),
update: mkStatefulSet(&validPodTemplate, tweakFinalizers()), update: mkStatefulSet(&validPodTemplate, tweakFinalizers()),
}, }, {
{
name: "update existing instance with .spec.ordinals.start", name: "update existing instance with .spec.ordinals.start",
old: mkStatefulSet(&validPodTemplate), old: mkStatefulSet(&validPodTemplate),
update: mkStatefulSet(&validPodTemplate, tweakOrdinalsStart(3)), update: mkStatefulSet(&validPodTemplate, tweakOrdinalsStart(3)),
}, },
} }
errorCases := []testCase{ errorCases := []testCase{{
{
name: "update name", name: "update name",
old: mkStatefulSet(&validPodTemplate, tweakName("abc")), old: mkStatefulSet(&validPodTemplate, tweakName("abc")),
update: mkStatefulSet(&validPodTemplate, tweakName("abc2")), update: mkStatefulSet(&validPodTemplate, tweakName("abc2")),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("metadata", "name"), nil, ""), field.Invalid(field.NewPath("metadata", "name"), nil, ""),
}, },
}, }, {
{
name: "update namespace", name: "update namespace",
old: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault)), old: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault)),
update: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault+"1")), update: mkStatefulSet(&validPodTemplate, tweakNamespace(metav1.NamespaceDefault+"1")),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("metadata", "namespace"), nil, ""), field.Invalid(field.NewPath("metadata", "namespace"), nil, ""),
}, },
}, }, {
{
name: "update selector", name: "update selector",
old: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(validLabels)), old: mkStatefulSet(&validPodTemplate, tweakSelectorLabels(validLabels)),
update: mkStatefulSet(&validPodTemplate2, update: mkStatefulSet(&validPodTemplate2,
@@ -932,48 +872,42 @@ func TestValidateStatefulSetUpdate(t *testing.T) {
errs: field.ErrorList{ errs: field.ErrorList{
field.Forbidden(field.NewPath("spec"), ""), field.Forbidden(field.NewPath("spec"), ""),
}, },
}, }, {
{
name: "update pod management policy 1", name: "update pod management policy 1",
old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("")), old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy("")),
update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)), update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Forbidden(field.NewPath("spec"), ""), field.Forbidden(field.NewPath("spec"), ""),
}, },
}, }, {
{
name: "update pod management policy 2", name: "update pod management policy 2",
old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)), old: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.ParallelPodManagement)),
update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)), update: mkStatefulSet(&validPodTemplate, tweakPodManagementPolicy(apps.OrderedReadyPodManagement)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Forbidden(field.NewPath("spec"), ""), field.Forbidden(field.NewPath("spec"), ""),
}, },
}, }, {
{
name: "update to negative replicas", name: "update to negative replicas",
old: mkStatefulSet(&validPodTemplate), old: mkStatefulSet(&validPodTemplate),
update: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)), update: mkStatefulSet(&validPodTemplate, tweakReplicas(-1)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Invalid(field.NewPath("spec", "replicas"), nil, ""), field.Invalid(field.NewPath("spec", "replicas"), nil, ""),
}, },
}, }, {
{
name: "update pvc template size", name: "update pvc template size",
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)), old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedSize)), update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedSize)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Forbidden(field.NewPath("spec"), ""), field.Forbidden(field.NewPath("spec"), ""),
}, },
}, }, {
{
name: "update pvc template storage class", name: "update pvc template storage class",
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)), old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedClass)), update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplateChangedClass)),
errs: field.ErrorList{ errs: field.ErrorList{
field.Forbidden(field.NewPath("spec"), ""), field.Forbidden(field.NewPath("spec"), ""),
}, },
}, }, {
{
name: "add new pvc template", name: "add new pvc template",
old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)), old: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate)),
update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate, validPVCTemplate2)), update: mkStatefulSet(&validPodTemplate, tweakPVCTemplate(validPVCTemplate, validPVCTemplate2)),
@@ -1112,26 +1046,22 @@ func TestValidateControllerRevisionUpdate(t *testing.T) {
newHistory apps.ControllerRevision newHistory apps.ControllerRevision
oldHistory apps.ControllerRevision oldHistory apps.ControllerRevision
isValid bool isValid bool
}{ }{{
{
name: "valid", name: "valid",
newHistory: valid, newHistory: valid,
oldHistory: valid, oldHistory: valid,
isValid: true, isValid: true,
}, }, {
{
name: "invalid", name: "invalid",
newHistory: noVersion, newHistory: noVersion,
oldHistory: valid, oldHistory: valid,
isValid: false, isValid: false,
}, }, {
{
name: "changed data", name: "changed data",
newHistory: changedData, newHistory: changedData,
oldHistory: valid, oldHistory: valid,
isValid: false, isValid: false,
}, }, {
{
name: "changed revision", name: "changed revision",
newHistory: changedRevision, newHistory: changedRevision,
oldHistory: valid, oldHistory: valid,
@@ -1158,8 +1088,7 @@ func TestValidateDaemonSetStatusUpdate(t *testing.T) {
update apps.DaemonSet update apps.DaemonSet
} }
successCases := []dsUpdateTest{ successCases := []dsUpdateTest{{
{
old: apps.DaemonSet{ old: apps.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Status: apps.DaemonSetStatus{ Status: apps.DaemonSetStatus{
@@ -2071,8 +2000,7 @@ func TestValidateDaemonSet(t *testing.T) {
}, },
}, },
} }
successCases := []apps.DaemonSet{ successCases := []apps.DaemonSet{{
{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Spec: apps.DaemonSetSpec{ Spec: apps.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: validSelector}, Selector: &metav1.LabelSelector{MatchLabels: validSelector},
@@ -2081,8 +2009,7 @@ func TestValidateDaemonSet(t *testing.T) {
Type: apps.OnDeleteDaemonSetStrategyType, Type: apps.OnDeleteDaemonSetStrategyType,
}, },
}, },
}, }, {
{
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
Spec: apps.DaemonSetSpec{ Spec: apps.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: validSelector}, Selector: &metav1.LabelSelector{MatchLabels: validSelector},
@@ -2290,14 +2217,12 @@ func validDeployment() *apps.Deployment {
Spec: api.PodSpec{ Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSDefault, DNSPolicy: api.DNSDefault,
Containers: []api.Container{ Containers: []api.Container{{
{
Name: "nginx", Name: "nginx",
Image: "image", Image: "image",
ImagePullPolicy: api.PullNever, ImagePullPolicy: api.PullNever,
TerminationMessagePolicy: api.TerminationMessageReadFile, TerminationMessagePolicy: api.TerminationMessageReadFile,
}, }},
},
}, },
}, },
RollbackTo: &apps.RollbackConfig{ RollbackTo: &apps.RollbackConfig{
@@ -2427,8 +2352,7 @@ func TestValidateDeploymentStatus(t *testing.T) {
collisionCount *int32 collisionCount *int32
expectedErr bool expectedErr bool
}{ }{{
{
name: "valid status", name: "valid status",
replicas: 3, replicas: 3,
updatedReplicas: 3, updatedReplicas: 3,
@@ -2436,8 +2360,7 @@ func TestValidateDeploymentStatus(t *testing.T) {
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: false, expectedErr: false,
}, }, {
{
name: "invalid replicas", name: "invalid replicas",
replicas: -1, replicas: -1,
updatedReplicas: 2, updatedReplicas: 2,
@@ -2445,8 +2368,7 @@ func TestValidateDeploymentStatus(t *testing.T) {
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid updatedReplicas", name: "invalid updatedReplicas",
replicas: 2, replicas: 2,
updatedReplicas: -1, updatedReplicas: -1,
@@ -2454,32 +2376,28 @@ func TestValidateDeploymentStatus(t *testing.T) {
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid readyReplicas", name: "invalid readyReplicas",
replicas: 3, replicas: 3,
readyReplicas: -1, readyReplicas: -1,
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid availableReplicas", name: "invalid availableReplicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
availableReplicas: -1, availableReplicas: -1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid observedGeneration", name: "invalid observedGeneration",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
availableReplicas: 3, availableReplicas: 3,
observedGeneration: -1, observedGeneration: -1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "updatedReplicas greater than replicas", name: "updatedReplicas greater than replicas",
replicas: 3, replicas: 3,
updatedReplicas: 4, updatedReplicas: 4,
@@ -2487,32 +2405,28 @@ func TestValidateDeploymentStatus(t *testing.T) {
availableReplicas: 3, availableReplicas: 3,
observedGeneration: 1, observedGeneration: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "readyReplicas greater than replicas", name: "readyReplicas greater than replicas",
replicas: 3, replicas: 3,
readyReplicas: 4, readyReplicas: 4,
availableReplicas: 3, availableReplicas: 3,
observedGeneration: 1, observedGeneration: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "availableReplicas greater than replicas", name: "availableReplicas greater than replicas",
replicas: 3, replicas: 3,
readyReplicas: 3, readyReplicas: 3,
availableReplicas: 4, availableReplicas: 4,
observedGeneration: 1, observedGeneration: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "availableReplicas greater than readyReplicas", name: "availableReplicas greater than readyReplicas",
replicas: 3, replicas: 3,
readyReplicas: 2, readyReplicas: 2,
availableReplicas: 3, availableReplicas: 3,
observedGeneration: 1, observedGeneration: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid collisionCount", name: "invalid collisionCount",
replicas: 3, replicas: 3,
observedGeneration: 1, observedGeneration: 1,
@@ -2548,8 +2462,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
from, to apps.DeploymentStatus from, to apps.DeploymentStatus
expectedErr bool expectedErr bool
}{ }{{
{
name: "increase: valid update", name: "increase: valid update",
from: apps.DeploymentStatus{ from: apps.DeploymentStatus{
CollisionCount: nil, CollisionCount: nil,
@@ -2558,8 +2471,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
CollisionCount: &collisionCount, CollisionCount: &collisionCount,
}, },
expectedErr: false, expectedErr: false,
}, }, {
{
name: "stable: valid update", name: "stable: valid update",
from: apps.DeploymentStatus{ from: apps.DeploymentStatus{
CollisionCount: &collisionCount, CollisionCount: &collisionCount,
@@ -2568,8 +2480,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
CollisionCount: &collisionCount, CollisionCount: &collisionCount,
}, },
expectedErr: false, expectedErr: false,
}, }, {
{
name: "unset: invalid update", name: "unset: invalid update",
from: apps.DeploymentStatus{ from: apps.DeploymentStatus{
CollisionCount: &collisionCount, CollisionCount: &collisionCount,
@@ -2578,8 +2489,7 @@ func TestValidateDeploymentStatusUpdate(t *testing.T) {
CollisionCount: nil, CollisionCount: nil,
}, },
expectedErr: true, expectedErr: true,
}, }, {
{
name: "decrease: invalid update", name: "decrease: invalid update",
from: apps.DeploymentStatus{ from: apps.DeploymentStatus{
CollisionCount: &otherCollisionCount, CollisionCount: &otherCollisionCount,
@@ -2872,8 +2782,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
observedGeneration int64 observedGeneration int64
expectedErr bool expectedErr bool
}{ }{{
{
name: "valid status", name: "valid status",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2881,8 +2790,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: false, expectedErr: false,
}, }, {
{
name: "invalid replicas", name: "invalid replicas",
replicas: -1, replicas: -1,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2890,8 +2798,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid fullyLabeledReplicas", name: "invalid fullyLabeledReplicas",
replicas: 3, replicas: 3,
fullyLabeledReplicas: -1, fullyLabeledReplicas: -1,
@@ -2899,8 +2806,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid readyReplicas", name: "invalid readyReplicas",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2908,8 +2814,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 1, availableReplicas: 1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid availableReplicas", name: "invalid availableReplicas",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2917,8 +2822,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: -1, availableReplicas: -1,
observedGeneration: 2, observedGeneration: 2,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "invalid observedGeneration", name: "invalid observedGeneration",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2926,8 +2830,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 3, availableReplicas: 3,
observedGeneration: -1, observedGeneration: -1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "fullyLabeledReplicas greater than replicas", name: "fullyLabeledReplicas greater than replicas",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 4, fullyLabeledReplicas: 4,
@@ -2935,8 +2838,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 3, availableReplicas: 3,
observedGeneration: 1, observedGeneration: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "readyReplicas greater than replicas", name: "readyReplicas greater than replicas",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2944,8 +2846,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 3, availableReplicas: 3,
observedGeneration: 1, observedGeneration: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "availableReplicas greater than replicas", name: "availableReplicas greater than replicas",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2953,8 +2854,7 @@ func TestValidateReplicaSetStatus(t *testing.T) {
availableReplicas: 4, availableReplicas: 4,
observedGeneration: 1, observedGeneration: 1,
expectedErr: true, expectedErr: true,
}, }, {
{
name: "availableReplicas greater than readyReplicas", name: "availableReplicas greater than readyReplicas",
replicas: 3, replicas: 3,
fullyLabeledReplicas: 3, fullyLabeledReplicas: 3,
@@ -2998,8 +2898,7 @@ func TestValidateReplicaSetStatusUpdate(t *testing.T) {
old apps.ReplicaSet old apps.ReplicaSet
update apps.ReplicaSet update apps.ReplicaSet
} }
successCases := []rcUpdateTest{ successCases := []rcUpdateTest{{
{
old: apps.ReplicaSet{ old: apps.ReplicaSet{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Spec: apps.ReplicaSetSpec{ Spec: apps.ReplicaSetSpec{
@@ -3300,22 +3199,19 @@ func TestValidateReplicaSet(t *testing.T) {
}, },
}, },
} }
successCases := []apps.ReplicaSet{ successCases := []apps.ReplicaSet{{
{
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
Spec: apps.ReplicaSetSpec{ Spec: apps.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: validLabels}, Selector: &metav1.LabelSelector{MatchLabels: validLabels},
Template: validPodTemplate.Template, Template: validPodTemplate.Template,
}, },
}, }, {
{
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
Spec: apps.ReplicaSetSpec{ Spec: apps.ReplicaSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: validLabels}, Selector: &metav1.LabelSelector{MatchLabels: validLabels},
Template: validPodTemplate.Template, Template: validPodTemplate.Template,
}, },
}, }, {
{
ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault}, ObjectMeta: metav1.ObjectMeta{Name: "abc-123", Namespace: metav1.NamespaceDefault},
Spec: apps.ReplicaSetSpec{ Spec: apps.ReplicaSetSpec{
Replicas: 1, Replicas: 1,

View File

@@ -40,13 +40,11 @@ func TestValidateSARSpec(t *testing.T) {
name string name string
obj authorizationapi.SubjectAccessReviewSpec obj authorizationapi.SubjectAccessReviewSpec
msg string msg string
}{ }{{
{
name: "neither request", name: "neither request",
obj: authorizationapi.SubjectAccessReviewSpec{User: "me"}, obj: authorizationapi.SubjectAccessReviewSpec{User: "me"},
msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified", msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
}, }, {
{
name: "both requests", name: "both requests",
obj: authorizationapi.SubjectAccessReviewSpec{ obj: authorizationapi.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationapi.ResourceAttributes{}, ResourceAttributes: &authorizationapi.ResourceAttributes{},
@@ -54,15 +52,13 @@ func TestValidateSARSpec(t *testing.T) {
User: "me", User: "me",
}, },
msg: "cannot be specified in combination with resourceAttributes", msg: "cannot be specified in combination with resourceAttributes",
}, }, {
{
name: "no subject", name: "no subject",
obj: authorizationapi.SubjectAccessReviewSpec{ obj: authorizationapi.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationapi.ResourceAttributes{}, ResourceAttributes: &authorizationapi.ResourceAttributes{},
}, },
msg: `spec.user: Invalid value: "": at least one of user or group must be specified`, msg: `spec.user: Invalid value: "": at least one of user or group must be specified`,
}, }}
}
for _, c := range errorCases { for _, c := range errorCases {
errs := ValidateSubjectAccessReviewSpec(c.obj, field.NewPath("spec")) errs := ValidateSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
@@ -102,21 +98,18 @@ func TestValidateSelfSAR(t *testing.T) {
name string name string
obj authorizationapi.SelfSubjectAccessReviewSpec obj authorizationapi.SelfSubjectAccessReviewSpec
msg string msg string
}{ }{{
{
name: "neither request", name: "neither request",
obj: authorizationapi.SelfSubjectAccessReviewSpec{}, obj: authorizationapi.SelfSubjectAccessReviewSpec{},
msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified", msg: "exactly one of nonResourceAttributes or resourceAttributes must be specified",
}, }, {
{
name: "both requests", name: "both requests",
obj: authorizationapi.SelfSubjectAccessReviewSpec{ obj: authorizationapi.SelfSubjectAccessReviewSpec{
ResourceAttributes: &authorizationapi.ResourceAttributes{}, ResourceAttributes: &authorizationapi.ResourceAttributes{},
NonResourceAttributes: &authorizationapi.NonResourceAttributes{}, NonResourceAttributes: &authorizationapi.NonResourceAttributes{},
}, },
msg: "cannot be specified in combination with resourceAttributes", msg: "cannot be specified in combination with resourceAttributes",
}, }}
}
for _, c := range errorCases { for _, c := range errorCases {
errs := ValidateSelfSubjectAccessReviewSpec(c.obj, field.NewPath("spec")) errs := ValidateSelfSubjectAccessReviewSpec(c.obj, field.NewPath("spec"))
@@ -136,14 +129,12 @@ func TestValidateSelfSAR(t *testing.T) {
} }
func TestValidateLocalSAR(t *testing.T) { func TestValidateLocalSAR(t *testing.T) {
successCases := []authorizationapi.LocalSubjectAccessReview{ successCases := []authorizationapi.LocalSubjectAccessReview{{
{
Spec: authorizationapi.SubjectAccessReviewSpec{ Spec: authorizationapi.SubjectAccessReviewSpec{
ResourceAttributes: &authorizationapi.ResourceAttributes{}, ResourceAttributes: &authorizationapi.ResourceAttributes{},
User: "user", User: "user",
}, },
}, }}
}
for _, successCase := range successCases { for _, successCase := range successCases {
if errs := ValidateLocalSubjectAccessReview(&successCase); len(errs) != 0 { if errs := ValidateLocalSubjectAccessReview(&successCase); len(errs) != 0 {
t.Errorf("expected success: %v", errs) t.Errorf("expected success: %v", errs)
@@ -154,8 +145,7 @@ func TestValidateLocalSAR(t *testing.T) {
name string name string
obj *authorizationapi.LocalSubjectAccessReview obj *authorizationapi.LocalSubjectAccessReview
msg string msg string
}{ }{{
{
name: "name", name: "name",
obj: &authorizationapi.LocalSubjectAccessReview{ obj: &authorizationapi.LocalSubjectAccessReview{
ObjectMeta: metav1.ObjectMeta{Name: "a"}, ObjectMeta: metav1.ObjectMeta{Name: "a"},
@@ -165,8 +155,7 @@ func TestValidateLocalSAR(t *testing.T) {
}, },
}, },
msg: "must be empty except for namespace", msg: "must be empty except for namespace",
}, }, {
{
name: "namespace conflict", name: "namespace conflict",
obj: &authorizationapi.LocalSubjectAccessReview{ obj: &authorizationapi.LocalSubjectAccessReview{
ObjectMeta: metav1.ObjectMeta{Namespace: "a"}, ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
@@ -176,8 +165,7 @@ func TestValidateLocalSAR(t *testing.T) {
}, },
}, },
msg: "must match metadata.namespace", msg: "must match metadata.namespace",
}, }, {
{
name: "nonresource", name: "nonresource",
obj: &authorizationapi.LocalSubjectAccessReview{ obj: &authorizationapi.LocalSubjectAccessReview{
ObjectMeta: metav1.ObjectMeta{Namespace: "a"}, ObjectMeta: metav1.ObjectMeta{Namespace: "a"},
@@ -187,8 +175,7 @@ func TestValidateLocalSAR(t *testing.T) {
}, },
}, },
msg: "disallowed on this kind of request", msg: "disallowed on this kind of request",
}, }}
}
for _, c := range errorCases { for _, c := range errorCases {
errs := ValidateLocalSubjectAccessReview(c.obj) errs := ValidateLocalSubjectAccessReview(c.obj)

File diff suppressed because it is too large Load Diff

View File

@@ -112,49 +112,39 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
}, }, {
},
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.PodConditionType("CustomConditionType"), Type: api.PodConditionType("CustomConditionType"),
Status: api.ConditionFalse, Status: api.ConditionFalse,
}, }},
}, }, {
},
{
Action: batch.PodFailurePolicyActionCount, Action: batch.PodFailurePolicyActionCount,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
ContainerName: pointer.String("abc"), ContainerName: pointer.String("abc"),
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{1, 2, 3}, Values: []int32{1, 2, 3},
}, },
}, }, {
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
ContainerName: pointer.String("def"), ContainerName: pointer.String("def"),
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{4}, Values: []int32{4},
}, },
}, }, {
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpNotIn, Operator: batch.PodFailurePolicyOnExitCodesOpNotIn,
Values: []int32{5, 6, 7}, Values: []int32{5, 6, 7},
}, },
}, }},
},
}, },
}, },
}, },
@@ -314,11 +304,9 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
}, }},
},
}, },
}, },
}, },
@@ -331,15 +319,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{11, 11}, Values: []int32{11, 11},
}, },
}, }},
},
}, },
}, },
}, },
@@ -352,8 +338,7 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
@@ -365,8 +350,7 @@ func TestValidateJob(t *testing.T) {
return tooManyValues return tooManyValues
}(), }(),
}, },
}, }},
},
}, },
}, },
}, },
@@ -404,8 +388,7 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnPodConditions: func() []batch.PodFailurePolicyOnPodConditionsPattern { OnPodConditions: func() []batch.PodFailurePolicyOnPodConditionsPattern {
tooManyPatterns := make([]batch.PodFailurePolicyOnPodConditionsPattern, maxPodFailurePolicyOnPodConditionsPatterns+1) tooManyPatterns := make([]batch.PodFailurePolicyOnPodConditionsPattern, maxPodFailurePolicyOnPodConditionsPatterns+1)
@@ -417,8 +400,7 @@ func TestValidateJob(t *testing.T) {
} }
return tooManyPatterns return tooManyPatterns
}(), }(),
}, }},
},
}, },
}, },
}, },
@@ -431,15 +413,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{12, 13, 13, 13}, Values: []int32{12, 13, 13, 13},
}, },
}, }},
},
}, },
}, },
}, },
@@ -452,15 +432,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{19, 11}, Values: []int32{19, 11},
}, },
}, }},
},
}, },
}, },
}, },
@@ -473,15 +451,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{}, Values: []int32{},
}, },
}, }},
},
}, },
}, },
}, },
@@ -494,15 +470,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: "", Action: "",
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{1, 2, 3}, Values: []int32{1, 2, 3},
}, },
}, }},
},
}, },
}, },
}, },
@@ -515,15 +489,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: "", Operator: "",
Values: []int32{1, 2, 3}, Values: []int32{1, 2, 3},
}, },
}, }},
},
}, },
}, },
}, },
@@ -536,22 +508,18 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
ContainerName: pointer.String("abc"), ContainerName: pointer.String("abc"),
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{1, 2, 3}, Values: []int32{1, 2, 3},
}, },
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
}, }},
},
},
}, },
}, },
}, },
@@ -564,15 +532,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{1, 0, 2}, Values: []int32{1, 0, 2},
}, },
}, }},
},
}, },
}, },
}, },
@@ -585,24 +551,21 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
ContainerName: pointer.String("abc"), ContainerName: pointer.String("abc"),
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{1, 2, 3}, Values: []int32{1, 2, 3},
}, },
}, }, {
{
Action: batch.PodFailurePolicyActionFailJob, Action: batch.PodFailurePolicyActionFailJob,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
ContainerName: pointer.String("xyz"), ContainerName: pointer.String("xyz"),
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{5, 6, 7}, Values: []int32{5, 6, 7},
}, },
}, }},
},
}, },
}, },
}, },
@@ -615,16 +578,14 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: "UnknownAction", Action: "UnknownAction",
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
ContainerName: pointer.String("abc"), ContainerName: pointer.String("abc"),
Operator: batch.PodFailurePolicyOnExitCodesOpIn, Operator: batch.PodFailurePolicyOnExitCodesOpIn,
Values: []int32{1, 2, 3}, Values: []int32{1, 2, 3},
}, },
}, }},
},
}, },
}, },
}, },
@@ -637,15 +598,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{ OnExitCodes: &batch.PodFailurePolicyOnExitCodesRequirement{
Operator: "UnknownOperator", Operator: "UnknownOperator",
Values: []int32{1, 2, 3}, Values: []int32{1, 2, 3},
}, },
}, }},
},
}, },
}, },
}, },
@@ -658,16 +617,12 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
}, }},
}, }},
},
},
}, },
}, },
}, },
@@ -680,17 +635,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
Status: "UnknownStatus", Status: "UnknownStatus",
}, }},
}, }},
},
},
}, },
}, },
}, },
@@ -703,16 +654,12 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
}, }},
},
},
}, },
}, },
}, },
@@ -725,17 +672,13 @@ func TestValidateJob(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.PodConditionType("Invalid Condition Type"), Type: api.PodConditionType("Invalid Condition Type"),
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
}, }},
},
},
}, },
}, },
}, },
@@ -1116,17 +1059,13 @@ func TestValidateJobUpdate(t *testing.T) {
validNodeAffinity := &api.Affinity{ validNodeAffinity := &api.Affinity{
NodeAffinity: &api.NodeAffinity{ NodeAffinity: &api.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{ RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{ NodeSelectorTerms: []api.NodeSelectorTerm{{
{ MatchExpressions: []api.NodeSelectorRequirement{{
MatchExpressions: []api.NodeSelectorRequirement{
{
Key: "foo", Key: "foo",
Operator: api.NodeSelectorOpIn, Operator: api.NodeSelectorOpIn,
Values: []string{"bar", "value2"}, Values: []string{"bar", "value2"},
}, }},
}, }},
},
},
}, },
}, },
} }
@@ -1134,17 +1073,13 @@ func TestValidateJobUpdate(t *testing.T) {
validPodTemplateWithAffinity.Spec.Affinity = &api.Affinity{ validPodTemplateWithAffinity.Spec.Affinity = &api.Affinity{
NodeAffinity: &api.NodeAffinity{ NodeAffinity: &api.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{ RequiredDuringSchedulingIgnoredDuringExecution: &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{ NodeSelectorTerms: []api.NodeSelectorTerm{{
{ MatchExpressions: []api.NodeSelectorRequirement{{
MatchExpressions: []api.NodeSelectorRequirement{
{
Key: "foo", Key: "foo",
Operator: api.NodeSelectorOpIn, Operator: api.NodeSelectorOpIn,
Values: []string{"bar", "value"}, Values: []string{"bar", "value"},
}, }},
}, }},
},
},
}, },
}, },
} }
@@ -1242,17 +1177,13 @@ func TestValidateJobUpdate(t *testing.T) {
}, },
update: func(job *batch.Job) { update: func(job *batch.Job) {
job.Spec.PodFailurePolicy = &batch.PodFailurePolicy{ job.Spec.PodFailurePolicy = &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
}, }},
},
},
} }
}, },
err: &field.Error{ err: &field.Error{
@@ -1267,29 +1198,23 @@ func TestValidateJobUpdate(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
}, }},
},
},
}, },
}, },
}, },
update: func(job *batch.Job) { update: func(job *batch.Job) {
job.Spec.PodFailurePolicy.Rules = append(job.Spec.PodFailurePolicy.Rules, batch.PodFailurePolicyRule{ job.Spec.PodFailurePolicy.Rules = append(job.Spec.PodFailurePolicy.Rules, batch.PodFailurePolicyRule{
Action: batch.PodFailurePolicyActionCount, Action: batch.PodFailurePolicyActionCount,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
},
}) })
}, },
err: &field.Error{ err: &field.Error{
@@ -1304,17 +1229,13 @@ func TestValidateJobUpdate(t *testing.T) {
Selector: validGeneratedSelector, Selector: validGeneratedSelector,
Template: validPodTemplateSpecForGeneratedRestartPolicyNever, Template: validPodTemplateSpecForGeneratedRestartPolicyNever,
PodFailurePolicy: &batch.PodFailurePolicy{ PodFailurePolicy: &batch.PodFailurePolicy{
Rules: []batch.PodFailurePolicyRule{ Rules: []batch.PodFailurePolicyRule{{
{
Action: batch.PodFailurePolicyActionIgnore, Action: batch.PodFailurePolicyActionIgnore,
OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{ OnPodConditions: []batch.PodFailurePolicyOnPodConditionsPattern{{
{
Type: api.DisruptionTarget, Type: api.DisruptionTarget,
Status: api.ConditionTrue, Status: api.ConditionTrue,
}, }},
}, }},
},
},
}, },
}, },
}, },

View File

@@ -413,18 +413,15 @@ func Test_getValidationOptions(t *testing.T) {
newCSR *capi.CertificateSigningRequest newCSR *capi.CertificateSigningRequest
oldCSR *capi.CertificateSigningRequest oldCSR *capi.CertificateSigningRequest
want certificateValidationOptions want certificateValidationOptions
}{ }{{
{
name: "strict create", name: "strict create",
oldCSR: nil, oldCSR: nil,
want: certificateValidationOptions{}, want: certificateValidationOptions{},
}, }, {
{
name: "strict update", name: "strict update",
oldCSR: &capi.CertificateSigningRequest{}, oldCSR: &capi.CertificateSigningRequest{},
want: certificateValidationOptions{}, want: certificateValidationOptions{},
}, }, {
{
name: "compatible update, approved+denied", name: "compatible update, approved+denied",
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateDenied}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateDenied}},
@@ -432,15 +429,13 @@ func Test_getValidationOptions(t *testing.T) {
want: certificateValidationOptions{ want: certificateValidationOptions{
allowBothApprovedAndDenied: true, allowBothApprovedAndDenied: true,
}, },
}, }, {
{
name: "compatible update, legacy signerName", name: "compatible update, legacy signerName",
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{SignerName: capi.LegacyUnknownSignerName}}, oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{SignerName: capi.LegacyUnknownSignerName}},
want: certificateValidationOptions{ want: certificateValidationOptions{
allowLegacySignerName: true, allowLegacySignerName: true,
}, },
}, }, {
{
name: "compatible update, duplicate condition types", name: "compatible update, duplicate condition types",
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateApproved}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved}, {Type: capi.CertificateApproved}},
@@ -448,8 +443,7 @@ func Test_getValidationOptions(t *testing.T) {
want: certificateValidationOptions{ want: certificateValidationOptions{
allowDuplicateConditionTypes: true, allowDuplicateConditionTypes: true,
}, },
}, }, {
{
name: "compatible update, empty condition types", name: "compatible update, empty condition types",
oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{}}, Conditions: []capi.CertificateSigningRequestCondition{{}},
@@ -457,8 +451,7 @@ func Test_getValidationOptions(t *testing.T) {
want: certificateValidationOptions{ want: certificateValidationOptions{
allowEmptyConditionType: true, allowEmptyConditionType: true,
}, },
}, }, {
{
name: "compatible update, no diff to certificate", name: "compatible update, no diff to certificate",
newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
Certificate: validCertificate, Certificate: validCertificate,
@@ -469,8 +462,7 @@ func Test_getValidationOptions(t *testing.T) {
want: certificateValidationOptions{ want: certificateValidationOptions{
allowArbitraryCertificate: true, allowArbitraryCertificate: true,
}, },
}, }, {
{
name: "compatible update, existing invalid certificate", name: "compatible update, existing invalid certificate",
newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{Status: capi.CertificateSigningRequestStatus{
Certificate: []byte(`new - no PEM blocks`), Certificate: []byte(`new - no PEM blocks`),
@@ -481,22 +473,19 @@ func Test_getValidationOptions(t *testing.T) {
want: certificateValidationOptions{ want: certificateValidationOptions{
allowArbitraryCertificate: true, allowArbitraryCertificate: true,
}, },
}, }, {
{
name: "compatible update, existing unknown usages", name: "compatible update, existing unknown usages",
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"unknown"}}}, oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"unknown"}}},
want: certificateValidationOptions{ want: certificateValidationOptions{
allowUnknownUsages: true, allowUnknownUsages: true,
}, },
}, }, {
{
name: "compatible update, existing duplicate usages", name: "compatible update, existing duplicate usages",
oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"any", "any"}}}, oldCSR: &capi.CertificateSigningRequest{Spec: capi.CertificateSigningRequestSpec{Usages: []capi.KeyUsage{"any", "any"}}},
want: certificateValidationOptions{ want: certificateValidationOptions{
allowDuplicateUsages: true, allowDuplicateUsages: true,
}, },
}, }}
}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
if got := getValidationOptions(tt.newCSR, tt.oldCSR); !reflect.DeepEqual(got, tt.want) { if got := getValidationOptions(tt.newCSR, tt.oldCSR); !reflect.DeepEqual(got, tt.want) {
@@ -524,18 +513,15 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
newCSR *capi.CertificateSigningRequest newCSR *capi.CertificateSigningRequest
oldCSR *capi.CertificateSigningRequest oldCSR *capi.CertificateSigningRequest
errs []string errs []string
}{ }{{
{
name: "no-op", name: "no-op",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
}, }, {
{
name: "finalizer change with invalid status", name: "finalizer change with invalid status",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
}, }, {
{
name: "add Approved condition", name: "add Approved condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
@@ -544,8 +530,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not add a condition of type "Approved"`, `status.conditions: Forbidden: updates may not add a condition of type "Approved"`,
}, },
}, }, {
{
name: "remove Approved condition", name: "remove Approved condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -554,8 +539,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`, `status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
}, },
}, }, {
{
name: "add Denied condition", name: "add Denied condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
@@ -564,8 +548,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not add a condition of type "Denied"`, `status.conditions: Forbidden: updates may not add a condition of type "Denied"`,
}, },
}, }, {
{
name: "remove Denied condition", name: "remove Denied condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -574,16 +557,14 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`, `status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
}, },
}, }, {
{
name: "add Failed condition", name: "add Failed condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
}}, }},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
errs: []string{}, errs: []string{},
}, }, {
{
name: "remove Failed condition", name: "remove Failed condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -592,8 +573,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`, `status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
}, },
}, }, {
{
name: "set certificate", name: "set certificate",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Certificate: validCertificate, Certificate: validCertificate,
@@ -602,8 +582,7 @@ func TestValidateCertificateSigningRequestUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.certificate: Forbidden: updates may not set certificate content`, `status.certificate: Forbidden: updates may not set certificate content`,
}, },
}, }}
}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@@ -640,18 +619,15 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
newCSR *capi.CertificateSigningRequest newCSR *capi.CertificateSigningRequest
oldCSR *capi.CertificateSigningRequest oldCSR *capi.CertificateSigningRequest
errs []string errs []string
}{ }{{
{
name: "no-op", name: "no-op",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
}, }, {
{
name: "finalizer change with invalid status", name: "finalizer change with invalid status",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
}, }, {
{
name: "finalizer change with duplicate and unknown usages", name: "finalizer change with duplicate and unknown usages",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: capi.CertificateSigningRequestSpec{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: capi.CertificateSigningRequestSpec{
Usages: []capi.KeyUsage{"unknown", "unknown"}, Usages: []capi.KeyUsage{"unknown", "unknown"},
@@ -663,8 +639,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
Request: newCSRPEM(t), Request: newCSRPEM(t),
SignerName: validSignerName, SignerName: validSignerName,
}}, }},
}, }, {
{
name: "add Approved condition", name: "add Approved condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
@@ -673,8 +648,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not add a condition of type "Approved"`, `status.conditions: Forbidden: updates may not add a condition of type "Approved"`,
}, },
}, }, {
{
name: "remove Approved condition", name: "remove Approved condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -683,8 +657,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`, `status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
}, },
}, }, {
{
name: "add Denied condition", name: "add Denied condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
@@ -693,8 +666,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not add a condition of type "Denied"`, `status.conditions: Forbidden: updates may not add a condition of type "Denied"`,
}, },
}, }, {
{
name: "remove Denied condition", name: "remove Denied condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -703,16 +675,14 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`, `status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
}, },
}, }, {
{
name: "add Failed condition", name: "add Failed condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
}}, }},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
errs: []string{}, errs: []string{},
}, }, {
{
name: "remove Failed condition", name: "remove Failed condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -721,16 +691,14 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`, `status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
}, },
}, }, {
{
name: "set valid certificate", name: "set valid certificate",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Certificate: validCertificate, Certificate: validCertificate,
}}, }},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
errs: []string{}, errs: []string{},
}, }, {
{
name: "set invalid certificate", name: "set invalid certificate",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Certificate: invalidCertificateNoPEM, Certificate: invalidCertificateNoPEM,
@@ -739,8 +707,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`, `status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`,
}, },
}, }, {
{
name: "reset certificate", name: "reset certificate",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Certificate: invalidCertificateNonCertificatePEM, Certificate: invalidCertificateNonCertificatePEM,
@@ -751,8 +718,7 @@ func TestValidateCertificateSigningRequestStatusUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.certificate: Forbidden: updates may not modify existing certificate content`, `status.certificate: Forbidden: updates may not modify existing certificate content`,
}, },
}, }}
}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@@ -789,25 +755,21 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
newCSR *capi.CertificateSigningRequest newCSR *capi.CertificateSigningRequest
oldCSR *capi.CertificateSigningRequest oldCSR *capi.CertificateSigningRequest
errs []string errs []string
}{ }{{
{
name: "no-op", name: "no-op",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
}, }, {
{
name: "finalizer change with invalid certificate", name: "finalizer change with invalid certificate",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{Certificate: invalidCertificateNoPEM}},
}, }, {
{
name: "add Approved condition", name: "add Approved condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
}}, }},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
}, }, {
{
name: "remove Approved condition", name: "remove Approved condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -816,15 +778,13 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Approved"`, `status.conditions: Forbidden: updates may not remove a condition of type "Approved"`,
}, },
}, }, {
{
name: "add Denied condition", name: "add Denied condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
}}, }},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
}, }, {
{
name: "remove Denied condition", name: "remove Denied condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -833,16 +793,14 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Denied"`, `status.conditions: Forbidden: updates may not remove a condition of type "Denied"`,
}, },
}, }, {
{
name: "add Failed condition", name: "add Failed condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
}}, }},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec}, oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec},
errs: []string{}, errs: []string{},
}, }, {
{
name: "remove Failed condition", name: "remove Failed condition",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec}, newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec},
oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ oldCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMetaWithFinalizers, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
@@ -851,8 +809,7 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.conditions: Forbidden: updates may not remove a condition of type "Failed"`, `status.conditions: Forbidden: updates may not remove a condition of type "Failed"`,
}, },
}, }, {
{
name: "set certificate", name: "set certificate",
newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{ newCSR: &capi.CertificateSigningRequest{ObjectMeta: validUpdateMeta, Spec: validSpec, Status: capi.CertificateSigningRequestStatus{
Certificate: validCertificate, Certificate: validCertificate,
@@ -861,8 +818,7 @@ func TestValidateCertificateSigningRequestApprovalUpdate(t *testing.T) {
errs: []string{ errs: []string{
`status.certificate: Forbidden: updates may not set certificate content`, `status.certificate: Forbidden: updates may not set certificate content`,
}, },
}, }}
}
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@@ -909,32 +865,28 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
{ {
name: "no status", name: "no status",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec}, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec},
}, }, {
{
name: "approved condition", name: "approved condition",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateApproved, Status: core.ConditionTrue}},
}, },
}, },
}, }, {
{
name: "denied condition", name: "denied condition",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateDenied, Status: core.ConditionTrue}},
}, },
}, },
}, }, {
{
name: "failed condition", name: "failed condition",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}}, Conditions: []capi.CertificateSigningRequestCondition{{Type: capi.CertificateFailed, Status: core.ConditionTrue}},
}, },
}, },
}, }, {
{
name: "approved+issued", name: "approved+issued",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -969,8 +921,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
}, },
lenientOpts: certificateValidationOptions{allowEmptyConditionType: true}, lenientOpts: certificateValidationOptions{allowEmptyConditionType: true},
strictErrs: []string{`status.conditions[0].type: Required value`}, strictErrs: []string{`status.conditions[0].type: Required value`},
}, }, {
{
name: "approved and denied", name: "approved and denied",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -979,8 +930,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
}, },
lenientOpts: certificateValidationOptions{allowBothApprovedAndDenied: true}, lenientOpts: certificateValidationOptions{allowBothApprovedAndDenied: true},
strictErrs: []string{`status.conditions[1].type: Invalid value: "Denied": Approved and Denied conditions are mutually exclusive`}, strictErrs: []string{`status.conditions[1].type: Invalid value: "Denied": Approved and Denied conditions are mutually exclusive`},
}, }, {
{
name: "duplicate condition", name: "duplicate condition",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -1002,8 +952,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
}, },
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true}, lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`}, strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`},
}, }, {
{
name: "status.certificate, non-CERTIFICATE PEM", name: "status.certificate, non-CERTIFICATE PEM",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -1013,8 +962,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
}, },
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true}, lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": only CERTIFICATE PEM blocks are allowed, found "CERTIFICATE1"`}, strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": only CERTIFICATE PEM blocks are allowed, found "CERTIFICATE1"`},
}, }, {
{
name: "status.certificate, PEM headers", name: "status.certificate, PEM headers",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -1024,8 +972,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
}, },
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true}, lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": no PEM block headers are permitted`}, strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": no PEM block headers are permitted`},
}, }, {
{
name: "status.certificate, non-base64 PEM", name: "status.certificate, non-base64 PEM",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -1035,8 +982,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
}, },
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true}, lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`}, strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": must contain at least one CERTIFICATE PEM block`},
}, }, {
{
name: "status.certificate, empty PEM block", name: "status.certificate, empty PEM block",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -1046,8 +992,7 @@ func Test_validateCertificateSigningRequestOptions(t *testing.T) {
}, },
lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true}, lenientOpts: certificateValidationOptions{allowArbitraryCertificate: true},
strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": found CERTIFICATE PEM block containing 0 certificates`}, strictErrs: []string{`status.certificate: Invalid value: "<certificate data>": found CERTIFICATE PEM block containing 0 certificates`},
}, }, {
{
name: "status.certificate, non-ASN1 data", name: "status.certificate, non-ASN1 data",
csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec, csr: &capi.CertificateSigningRequest{ObjectMeta: validObjectMeta, Spec: validSpec,
Status: capi.CertificateSigningRequestStatus{ Status: capi.CertificateSigningRequestStatus{
@@ -1164,8 +1109,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
bundle *capi.ClusterTrustBundle bundle *capi.ClusterTrustBundle
opts ValidateClusterTrustBundleOptions opts ValidateClusterTrustBundleOptions
wantErrors field.ErrorList wantErrors field.ErrorList
}{ }{{
{
description: "valid, no signer name", description: "valid, no signer name",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1175,8 +1119,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
TrustBundle: goodCert1Block, TrustBundle: goodCert1Block,
}, },
}, },
}, }, {
{
description: "invalid, no signer name, invalid name", description: "invalid, no signer name, invalid name",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1189,8 +1132,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:bar:foo", "ClusterTrustBundle without signer name must not have \":\" in its name"), field.Invalid(field.NewPath("metadata", "name"), "k8s.io:bar:foo", "ClusterTrustBundle without signer name must not have \":\" in its name"),
}, },
}, }, {
{
description: "valid, with signer name", description: "valid, with signer name",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1201,8 +1143,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
TrustBundle: goodCert1Block, TrustBundle: goodCert1Block,
}, },
}, },
}, }, {
{
description: "invalid, with signer name, missing name prefix", description: "invalid, with signer name, missing name prefix",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1216,8 +1157,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("metadata", "name"), "look-ma-no-prefix", "ClusterTrustBundle for signerName k8s.io/foo must be named with prefix k8s.io:foo:"), field.Invalid(field.NewPath("metadata", "name"), "look-ma-no-prefix", "ClusterTrustBundle for signerName k8s.io/foo must be named with prefix k8s.io:foo:"),
}, },
}, }, {
{
description: "invalid, with signer name, empty name suffix", description: "invalid, with signer name, empty name suffix",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1231,8 +1171,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`), field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`),
}, },
}, }, {
{
description: "invalid, with signer name, bad name suffix", description: "invalid, with signer name, bad name suffix",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1246,8 +1185,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:123notvalidDNSSubdomain", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`), field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:123notvalidDNSSubdomain", `a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')`),
}, },
}, }, {
{
description: "valid, with signer name, with inter-block garbage", description: "valid, with signer name, with inter-block garbage",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1258,8 +1196,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
TrustBundle: "garbage\n" + goodCert1Block + "\ngarbage\n" + goodCert2Block, TrustBundle: "garbage\n" + goodCert1Block + "\ngarbage\n" + goodCert2Block,
}, },
}, },
}, }, {
{
description: "invalid, no signer name, no trust anchors", description: "invalid, no signer name, no trust anchors",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1270,8 +1207,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
}, },
}, }, {
{
description: "invalid, no trust anchors", description: "invalid, no trust anchors",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1284,8 +1220,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
}, },
}, }, {
{
description: "invalid, bad signer name", description: "invalid, bad signer name",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1299,8 +1234,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "signerName"), "invalid", "must be a fully qualified domain and path of the form 'example.com/signer-name'"), field.Invalid(field.NewPath("spec", "signerName"), "invalid", "must be a fully qualified domain and path of the form 'example.com/signer-name'"),
}, },
}, }, {
{
description: "invalid, no blocks", description: "invalid, no blocks",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1313,8 +1247,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
}, },
}, }, {
{
description: "invalid, bad block type", description: "invalid, bad block type",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1327,8 +1260,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has bad block type: NOTACERTIFICATE"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has bad block type: NOTACERTIFICATE"),
}, },
}, }, {
{
description: "invalid, block with headers", description: "invalid, block with headers",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1341,8 +1273,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has PEM block headers"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 has PEM block headers"),
}, },
}, }, {
{
description: "invalid, cert is not a CA cert", description: "invalid, cert is not a CA cert",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1355,8 +1286,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 0 does not have the CA bit set"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 0 does not have the CA bit set"),
}, },
}, }, {
{
description: "invalid, duplicated blocks", description: "invalid, duplicated blocks",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1369,8 +1299,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "duplicate trust anchor (indices [0 1])"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "duplicate trust anchor (indices [0 1])"),
}, },
}, }, {
{
description: "invalid, non-certificate entry", description: "invalid, non-certificate entry",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1383,8 +1312,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 does not parse as X.509"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "entry 1 does not parse as X.509"),
}, },
}, }, {
{
description: "allow any old garbage in the PEM field if we suppress parsing", description: "allow any old garbage in the PEM field if we suppress parsing",
bundle: &capi.ClusterTrustBundle{ bundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1397,8 +1325,7 @@ func TestValidateClusterTrustBundle(t *testing.T) {
opts: ValidateClusterTrustBundleOptions{ opts: ValidateClusterTrustBundleOptions{
SuppressBundleParsing: true, SuppressBundleParsing: true,
}, },
}, }}
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
gotErrors := ValidateClusterTrustBundle(tc.bundle, tc.opts) gotErrors := ValidateClusterTrustBundle(tc.bundle, tc.opts)
@@ -1454,8 +1381,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
description string description string
oldBundle, newBundle *capi.ClusterTrustBundle oldBundle, newBundle *capi.ClusterTrustBundle
wantErrors field.ErrorList wantErrors field.ErrorList
}{ }{{
{
description: "changing signer name disallowed", description: "changing signer name disallowed",
oldBundle: &capi.ClusterTrustBundle{ oldBundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1479,8 +1405,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:bar", "ClusterTrustBundle for signerName k8s.io/bar must be named with prefix k8s.io:bar:"), field.Invalid(field.NewPath("metadata", "name"), "k8s.io:foo:bar", "ClusterTrustBundle for signerName k8s.io/bar must be named with prefix k8s.io:bar:"),
field.Invalid(field.NewPath("spec", "signerName"), "k8s.io/bar", "field is immutable"), field.Invalid(field.NewPath("spec", "signerName"), "k8s.io/bar", "field is immutable"),
}, },
}, }, {
{
description: "adding certificate allowed", description: "adding certificate allowed",
oldBundle: &capi.ClusterTrustBundle{ oldBundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1500,8 +1425,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
TrustBundle: goodCert1Block + "\n" + goodCert2Block, TrustBundle: goodCert1Block + "\n" + goodCert2Block,
}, },
}, },
}, }, {
{
description: "emptying trustBundle disallowed", description: "emptying trustBundle disallowed",
oldBundle: &capi.ClusterTrustBundle{ oldBundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1524,8 +1448,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
}, },
}, }, {
{
description: "emptying trustBundle (replace with non-block garbage) disallowed", description: "emptying trustBundle (replace with non-block garbage) disallowed",
oldBundle: &capi.ClusterTrustBundle{ oldBundle: &capi.ClusterTrustBundle{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@@ -1548,8 +1471,7 @@ func TestValidateClusterTrustBundleUpdate(t *testing.T) {
wantErrors: field.ErrorList{ wantErrors: field.ErrorList{
field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"), field.Invalid(field.NewPath("spec", "trustBundle"), "<value omitted>", "at least one trust anchor must be provided"),
}, },
}, }}
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {

View File

@@ -31,8 +31,7 @@ func TestValidateResourceRequirements(t *testing.T) {
successCase := []struct { successCase := []struct {
name string name string
requirements v1.ResourceRequirements requirements v1.ResourceRequirements
}{ }{{
{
name: "Resources with Requests equal to Limits", name: "Resources with Requests equal to Limits",
requirements: v1.ResourceRequirements{ requirements: v1.ResourceRequirements{
Requests: v1.ResourceList{ Requests: v1.ResourceList{
@@ -44,8 +43,7 @@ func TestValidateResourceRequirements(t *testing.T) {
v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"), v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"),
}, },
}, },
}, }, {
{
name: "Resources with only Limits", name: "Resources with only Limits",
requirements: v1.ResourceRequirements{ requirements: v1.ResourceRequirements{
Limits: v1.ResourceList{ Limits: v1.ResourceList{
@@ -54,8 +52,7 @@ func TestValidateResourceRequirements(t *testing.T) {
v1.ResourceName("my.org/resource"): resource.MustParse("10"), v1.ResourceName("my.org/resource"): resource.MustParse("10"),
}, },
}, },
}, }, {
{
name: "Resources with only Requests", name: "Resources with only Requests",
requirements: v1.ResourceRequirements{ requirements: v1.ResourceRequirements{
Requests: v1.ResourceList{ Requests: v1.ResourceList{
@@ -64,8 +61,7 @@ func TestValidateResourceRequirements(t *testing.T) {
v1.ResourceName("my.org/resource"): resource.MustParse("10"), v1.ResourceName("my.org/resource"): resource.MustParse("10"),
}, },
}, },
}, }, {
{
name: "Resources with Requests Less Than Limits", name: "Resources with Requests Less Than Limits",
requirements: v1.ResourceRequirements{ requirements: v1.ResourceRequirements{
Requests: v1.ResourceList{ Requests: v1.ResourceList{
@@ -79,8 +75,7 @@ func TestValidateResourceRequirements(t *testing.T) {
v1.ResourceName("my.org/resource"): resource.MustParse("9"), v1.ResourceName("my.org/resource"): resource.MustParse("9"),
}, },
}, },
}, }}
}
for _, tc := range successCase { for _, tc := range successCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources")); len(errs) != 0 { if errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources")); len(errs) != 0 {
@@ -94,8 +89,7 @@ func TestValidateResourceRequirements(t *testing.T) {
requirements v1.ResourceRequirements requirements v1.ResourceRequirements
skipLimitValueCheck bool skipLimitValueCheck bool
skipRequestValueCheck bool skipRequestValueCheck bool
}{ }{{
{
name: "Resources with Requests Larger Than Limits", name: "Resources with Requests Larger Than Limits",
requirements: v1.ResourceRequirements{ requirements: v1.ResourceRequirements{
Requests: v1.ResourceList{ Requests: v1.ResourceList{
@@ -109,8 +103,7 @@ func TestValidateResourceRequirements(t *testing.T) {
v1.ResourceName("my.org/resource"): resource.MustParse("9m"), v1.ResourceName("my.org/resource"): resource.MustParse("9m"),
}, },
}, },
}, }, {
{
name: "Invalid Resources with Requests", name: "Invalid Resources with Requests",
requirements: v1.ResourceRequirements{ requirements: v1.ResourceRequirements{
Requests: v1.ResourceList{ Requests: v1.ResourceList{
@@ -118,8 +111,7 @@ func TestValidateResourceRequirements(t *testing.T) {
}, },
}, },
skipRequestValueCheck: true, skipRequestValueCheck: true,
}, }, {
{
name: "Invalid Resources with Limits", name: "Invalid Resources with Limits",
requirements: v1.ResourceRequirements{ requirements: v1.ResourceRequirements{
Limits: v1.ResourceList{ Limits: v1.ResourceList{
@@ -127,8 +119,7 @@ func TestValidateResourceRequirements(t *testing.T) {
}, },
}, },
skipLimitValueCheck: true, skipLimitValueCheck: true,
}, }}
}
for _, tc := range errorCase { for _, tc := range errorCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources")) errs := ValidateResourceRequirements(&tc.requirements, field.NewPath("resources"))
@@ -168,28 +159,22 @@ func TestValidateContainerResourceName(t *testing.T) {
successCase := []struct { successCase := []struct {
name string name string
ResourceName string ResourceName string
}{ }{{
{
name: "CPU resource", name: "CPU resource",
ResourceName: "cpu", ResourceName: "cpu",
}, }, {
{
name: "Memory resource", name: "Memory resource",
ResourceName: "memory", ResourceName: "memory",
}, }, {
{
name: "Hugepages resource", name: "Hugepages resource",
ResourceName: "hugepages-2Mi", ResourceName: "hugepages-2Mi",
}, }, {
{
name: "Namespaced resource", name: "Namespaced resource",
ResourceName: "kubernetes.io/resource-foo", ResourceName: "kubernetes.io/resource-foo",
}, }, {
{
name: "Extended Resource", name: "Extended Resource",
ResourceName: "my.org/resource-bar", ResourceName: "my.org/resource-bar",
}, }}
}
for _, tc := range successCase { for _, tc := range successCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) != 0 { if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) != 0 {
@@ -201,20 +186,16 @@ func TestValidateContainerResourceName(t *testing.T) {
errorCase := []struct { errorCase := []struct {
name string name string
ResourceName string ResourceName string
}{ }{{
{
name: "Invalid standard resource", name: "Invalid standard resource",
ResourceName: "cpu-core", ResourceName: "cpu-core",
}, }, {
{
name: "Invalid namespaced resource", name: "Invalid namespaced resource",
ResourceName: "kubernetes.io/", ResourceName: "kubernetes.io/",
}, }, {
{
name: "Invalid extended resource", name: "Invalid extended resource",
ResourceName: "my.org-foo-resource", ResourceName: "my.org-foo-resource",
}, }}
}
for _, tc := range errorCase { for _, tc := range errorCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) == 0 { if errs := ValidateContainerResourceName(tc.ResourceName, field.NewPath(tc.ResourceName)); len(errs) == 0 {
@@ -239,45 +220,38 @@ func TestValidatePodLogOptions(t *testing.T) {
successCase := []struct { successCase := []struct {
name string name string
podLogOptions v1.PodLogOptions podLogOptions v1.PodLogOptions
}{ }{{
{
name: "Empty PodLogOptions", name: "Empty PodLogOptions",
podLogOptions: v1.PodLogOptions{}, podLogOptions: v1.PodLogOptions{},
}, }, {
{
name: "PodLogOptions with TailLines", name: "PodLogOptions with TailLines",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
TailLines: &positiveLine, TailLines: &positiveLine,
}, },
}, }, {
{
name: "PodLogOptions with LimitBytes", name: "PodLogOptions with LimitBytes",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
LimitBytes: &limitBytesGreaterThan1, LimitBytes: &limitBytesGreaterThan1,
}, },
}, }, {
{
name: "PodLogOptions with only sinceSeconds", name: "PodLogOptions with only sinceSeconds",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
SinceSeconds: &sinceSecondsGreaterThan1, SinceSeconds: &sinceSecondsGreaterThan1,
}, },
}, }, {
{
name: "PodLogOptions with LimitBytes with TailLines", name: "PodLogOptions with LimitBytes with TailLines",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
LimitBytes: &limitBytesGreaterThan1, LimitBytes: &limitBytesGreaterThan1,
TailLines: &positiveLine, TailLines: &positiveLine,
}, },
}, }, {
{
name: "PodLogOptions with LimitBytes with TailLines with SinceSeconds", name: "PodLogOptions with LimitBytes with TailLines with SinceSeconds",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
LimitBytes: &limitBytesGreaterThan1, LimitBytes: &limitBytesGreaterThan1,
TailLines: &positiveLine, TailLines: &positiveLine,
SinceSeconds: &sinceSecondsGreaterThan1, SinceSeconds: &sinceSecondsGreaterThan1,
}, },
}, }}
}
for _, tc := range successCase { for _, tc := range successCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) != 0 { if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) != 0 {
@@ -289,24 +263,21 @@ func TestValidatePodLogOptions(t *testing.T) {
errorCase := []struct { errorCase := []struct {
name string name string
podLogOptions v1.PodLogOptions podLogOptions v1.PodLogOptions
}{ }{{
{
name: "Invalid podLogOptions with Negative TailLines", name: "Invalid podLogOptions with Negative TailLines",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
TailLines: &negativeLine, TailLines: &negativeLine,
LimitBytes: &limitBytesGreaterThan1, LimitBytes: &limitBytesGreaterThan1,
SinceSeconds: &sinceSecondsGreaterThan1, SinceSeconds: &sinceSecondsGreaterThan1,
}, },
}, }, {
{
name: "Invalid podLogOptions with zero or negative LimitBytes", name: "Invalid podLogOptions with zero or negative LimitBytes",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
TailLines: &positiveLine, TailLines: &positiveLine,
LimitBytes: &limitBytesLessThan1, LimitBytes: &limitBytesLessThan1,
SinceSeconds: &sinceSecondsGreaterThan1, SinceSeconds: &sinceSecondsGreaterThan1,
}, },
}, }, {
{
name: "Invalid podLogOptions with zero or negative SinceSeconds", name: "Invalid podLogOptions with zero or negative SinceSeconds",
podLogOptions: v1.PodLogOptions{ podLogOptions: v1.PodLogOptions{
TailLines: &negativeLine, TailLines: &negativeLine,
@@ -321,8 +292,7 @@ func TestValidatePodLogOptions(t *testing.T) {
SinceSeconds: &sinceSecondsGreaterThan1, SinceSeconds: &sinceSecondsGreaterThan1,
SinceTime: &timestamp, SinceTime: &timestamp,
}, },
}, }}
}
for _, tc := range errorCase { for _, tc := range errorCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) == 0 { if errs := ValidatePodLogOptions(&tc.podLogOptions); len(errs) == 0 {
@@ -338,54 +308,37 @@ func TestAccumulateUniqueHostPorts(t *testing.T) {
containers []v1.Container containers []v1.Container
accumulator *sets.String accumulator *sets.String
fldPath *field.Path fldPath *field.Path
}{ }{{
{
name: "HostPort is not allocated while containers use the same port with different protocol", name: "HostPort is not allocated while containers use the same port with different protocol",
containers: []v1.Container{ containers: []v1.Container{{
{ Ports: []v1.ContainerPort{{
Ports: []v1.ContainerPort{
{
HostPort: 8080, HostPort: 8080,
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolUDP,
}, }},
}, }, {
}, Ports: []v1.ContainerPort{{
{
Ports: []v1.ContainerPort{
{
HostPort: 8080, HostPort: 8080,
Protocol: v1.ProtocolTCP, Protocol: v1.ProtocolTCP,
}, }},
}, }},
},
},
accumulator: &sets.String{}, accumulator: &sets.String{},
fldPath: field.NewPath("spec", "containers"), fldPath: field.NewPath("spec", "containers"),
}, }, {
{
name: "HostPort is not allocated while containers use different ports", name: "HostPort is not allocated while containers use different ports",
containers: []v1.Container{ containers: []v1.Container{{
{ Ports: []v1.ContainerPort{{
Ports: []v1.ContainerPort{
{
HostPort: 8080, HostPort: 8080,
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolUDP,
}, }},
}, }, {
}, Ports: []v1.ContainerPort{{
{
Ports: []v1.ContainerPort{
{
HostPort: 8081, HostPort: 8081,
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolUDP,
}, }},
}, }},
},
},
accumulator: &sets.String{}, accumulator: &sets.String{},
fldPath: field.NewPath("spec", "containers"), fldPath: field.NewPath("spec", "containers"),
}, }}
}
for _, tc := range successCase { for _, tc := range successCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) != 0 { if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) != 0 {
@@ -398,54 +351,37 @@ func TestAccumulateUniqueHostPorts(t *testing.T) {
containers []v1.Container containers []v1.Container
accumulator *sets.String accumulator *sets.String
fldPath *field.Path fldPath *field.Path
}{ }{{
{
name: "HostPort is already allocated while containers use the same port with UDP", name: "HostPort is already allocated while containers use the same port with UDP",
containers: []v1.Container{ containers: []v1.Container{{
{ Ports: []v1.ContainerPort{{
Ports: []v1.ContainerPort{
{
HostPort: 8080, HostPort: 8080,
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolUDP,
}, }},
}, }, {
}, Ports: []v1.ContainerPort{{
{
Ports: []v1.ContainerPort{
{
HostPort: 8080, HostPort: 8080,
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolUDP,
}, }},
}, }},
},
},
accumulator: &sets.String{}, accumulator: &sets.String{},
fldPath: field.NewPath("spec", "containers"), fldPath: field.NewPath("spec", "containers"),
}, }, {
{
name: "HostPort is already allocated", name: "HostPort is already allocated",
containers: []v1.Container{ containers: []v1.Container{{
{ Ports: []v1.ContainerPort{{
Ports: []v1.ContainerPort{
{
HostPort: 8080, HostPort: 8080,
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolUDP,
}, }},
}, }, {
}, Ports: []v1.ContainerPort{{
{
Ports: []v1.ContainerPort{
{
HostPort: 8081, HostPort: 8081,
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolUDP,
}, }},
}, }},
},
},
accumulator: &sets.String{"8080/UDP": sets.Empty{}}, accumulator: &sets.String{"8080/UDP": sets.Empty{}},
fldPath: field.NewPath("spec", "containers"), fldPath: field.NewPath("spec", "containers"),
}, }}
}
for _, tc := range errorCase { for _, tc := range errorCase {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) == 0 { if errs := AccumulateUniqueHostPorts(tc.containers, tc.accumulator, tc.fldPath); len(errs) == 0 {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -477,22 +477,18 @@ func TestValidateIngress(t *testing.T) {
}, },
Spec: networking.IngressSpec{ Spec: networking.IngressSpec{
DefaultBackend: &defaultBackend, DefaultBackend: &defaultBackend,
Rules: []networking.IngressRule{ Rules: []networking.IngressRule{{
{
Host: "foo.bar.com", Host: "foo.bar.com",
IngressRuleValue: networking.IngressRuleValue{ IngressRuleValue: networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{ HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{ Paths: []networking.HTTPIngressPath{{
{
Path: "/foo", Path: "/foo",
PathType: &pathTypeImplementationSpecific, PathType: &pathTypeImplementationSpecific,
Backend: defaultBackend, Backend: defaultBackend,
}},
}, },
}, },
}, }},
},
},
},
}, },
Status: networking.IngressStatus{ Status: networking.IngressStatus{
LoadBalancer: networking.IngressLoadBalancerStatus{ LoadBalancer: networking.IngressLoadBalancerStatus{
@@ -595,8 +591,7 @@ func TestValidateIngress(t *testing.T) {
tweakIngress: func(ing *networking.Ingress) { tweakIngress: func(ing *networking.Ingress) {
ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{ ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{ HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{ Paths: []networking.HTTPIngressPath{{
{
Path: "/foo", Path: "/foo",
PathType: &pathTypeImplementationSpecific, PathType: &pathTypeImplementationSpecific,
Backend: networking.IngressBackend{ Backend: networking.IngressBackend{
@@ -607,8 +602,7 @@ func TestValidateIngress(t *testing.T) {
Name: "bar", Name: "bar",
}, },
}, },
}, }},
},
}, },
} }
}, },
@@ -620,8 +614,7 @@ func TestValidateIngress(t *testing.T) {
tweakIngress: func(ing *networking.Ingress) { tweakIngress: func(ing *networking.Ingress) {
ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{ ing.Spec.Rules[0].IngressRuleValue = networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{ HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{ Paths: []networking.HTTPIngressPath{{
{
Path: "/foo", Path: "/foo",
PathType: &pathTypeImplementationSpecific, PathType: &pathTypeImplementationSpecific,
Backend: networking.IngressBackend{ Backend: networking.IngressBackend{
@@ -632,8 +625,7 @@ func TestValidateIngress(t *testing.T) {
Name: "bar", Name: "bar",
}, },
}, },
}, }},
},
}, },
} }
}, },
@@ -790,15 +782,13 @@ func TestValidateIngressRuleValue(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
irv := &networking.IngressRuleValue{ irv := &networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{ HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{ Paths: []networking.HTTPIngressPath{{
{
Path: testCase.path, Path: testCase.path,
PathType: &testCase.pathType, PathType: &testCase.pathType,
Backend: networking.IngressBackend{ Backend: networking.IngressBackend{
Service: &serviceBackend, Service: &serviceBackend,
}, },
}, }},
},
}, },
} }
errs := validateIngressRuleValue(irv, field.NewPath("testing"), IngressValidationOptions{}) errs := validateIngressRuleValue(irv, field.NewPath("testing"), IngressValidationOptions{})
@@ -1638,22 +1628,18 @@ func TestValidateIngressTLS(t *testing.T) {
}, },
Spec: networking.IngressSpec{ Spec: networking.IngressSpec{
DefaultBackend: &defaultBackend, DefaultBackend: &defaultBackend,
Rules: []networking.IngressRule{ Rules: []networking.IngressRule{{
{
Host: "foo.bar.com", Host: "foo.bar.com",
IngressRuleValue: networking.IngressRuleValue{ IngressRuleValue: networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{ HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{ Paths: []networking.HTTPIngressPath{{
{
Path: "/foo", Path: "/foo",
PathType: &pathTypeImplementationSpecific, PathType: &pathTypeImplementationSpecific,
Backend: defaultBackend, Backend: defaultBackend,
}},
}, },
}, },
}, }},
},
},
},
}, },
Status: networking.IngressStatus{ Status: networking.IngressStatus{
LoadBalancer: networking.IngressLoadBalancerStatus{ LoadBalancer: networking.IngressLoadBalancerStatus{
@@ -1670,11 +1656,9 @@ func TestValidateIngressTLS(t *testing.T) {
wildcardHost := "foo.*.bar.com" wildcardHost := "foo.*.bar.com"
badWildcardTLS := newValid() badWildcardTLS := newValid()
badWildcardTLS.Spec.Rules[0].Host = "*.foo.bar.com" badWildcardTLS.Spec.Rules[0].Host = "*.foo.bar.com"
badWildcardTLS.Spec.TLS = []networking.IngressTLS{ badWildcardTLS.Spec.TLS = []networking.IngressTLS{{
{
Hosts: []string{wildcardHost}, Hosts: []string{wildcardHost},
}, }}
}
badWildcardTLSErr := fmt.Sprintf("spec.tls[0].hosts[0]: Invalid value: '%v'", wildcardHost) badWildcardTLSErr := fmt.Sprintf("spec.tls[0].hosts[0]: Invalid value: '%v'", wildcardHost)
errorCases[badWildcardTLSErr] = badWildcardTLS errorCases[badWildcardTLSErr] = badWildcardTLS
@@ -1696,11 +1680,9 @@ func TestValidateIngressTLS(t *testing.T) {
wildHost := "*.bar.com" wildHost := "*.bar.com"
goodWildcardTLS := newValid() goodWildcardTLS := newValid()
goodWildcardTLS.Spec.Rules[0].Host = "*.bar.com" goodWildcardTLS.Spec.Rules[0].Host = "*.bar.com"
goodWildcardTLS.Spec.TLS = []networking.IngressTLS{ goodWildcardTLS.Spec.TLS = []networking.IngressTLS{{
{
Hosts: []string{wildHost}, Hosts: []string{wildHost},
}, }}
}
validCases[fmt.Sprintf("spec.tls[0].hosts: Valid value: '%v'", wildHost)] = goodWildcardTLS validCases[fmt.Sprintf("spec.tls[0].hosts: Valid value: '%v'", wildHost)] = goodWildcardTLS
for k, v := range validCases { for k, v := range validCases {
errs := validateIngress(&v, IngressValidationOptions{}) errs := validateIngress(&v, IngressValidationOptions{})
@@ -1731,21 +1713,17 @@ func TestValidateEmptyIngressTLS(t *testing.T) {
Namespace: metav1.NamespaceDefault, Namespace: metav1.NamespaceDefault,
}, },
Spec: networking.IngressSpec{ Spec: networking.IngressSpec{
Rules: []networking.IngressRule{ Rules: []networking.IngressRule{{
{
Host: "foo.bar.com", Host: "foo.bar.com",
IngressRuleValue: networking.IngressRuleValue{ IngressRuleValue: networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{ HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{ Paths: []networking.HTTPIngressPath{{
{
PathType: &pathTypeImplementationSpecific, PathType: &pathTypeImplementationSpecific,
Backend: defaultBackend, Backend: defaultBackend,
}},
}, },
}, },
}, }},
},
},
},
}, },
} }
} }
@@ -1757,11 +1735,9 @@ func TestValidateEmptyIngressTLS(t *testing.T) {
} }
validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyTLS.Spec.TLS[0])] = goodEmptyTLS validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyTLS.Spec.TLS[0])] = goodEmptyTLS
goodEmptyHosts := newValid() goodEmptyHosts := newValid()
goodEmptyHosts.Spec.TLS = []networking.IngressTLS{ goodEmptyHosts.Spec.TLS = []networking.IngressTLS{{
{
Hosts: []string{}, Hosts: []string{},
}, }}
}
validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyHosts.Spec.TLS[0])] = goodEmptyHosts validCases[fmt.Sprintf("spec.tls[0]: Valid value: %v", goodEmptyHosts.Spec.TLS[0])] = goodEmptyHosts
for k, v := range validCases { for k, v := range validCases {
errs := validateIngress(&v, IngressValidationOptions{}) errs := validateIngress(&v, IngressValidationOptions{})
@@ -1791,21 +1767,17 @@ func TestValidateIngressStatusUpdate(t *testing.T) {
}, },
Spec: networking.IngressSpec{ Spec: networking.IngressSpec{
DefaultBackend: &defaultBackend, DefaultBackend: &defaultBackend,
Rules: []networking.IngressRule{ Rules: []networking.IngressRule{{
{
Host: "foo.bar.com", Host: "foo.bar.com",
IngressRuleValue: networking.IngressRuleValue{ IngressRuleValue: networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{ HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{ Paths: []networking.HTTPIngressPath{{
{
Path: "/foo", Path: "/foo",
Backend: defaultBackend, Backend: defaultBackend,
}},
}, },
}, },
}, }},
},
},
},
}, },
Status: networking.IngressStatus{ Status: networking.IngressStatus{
LoadBalancer: networking.IngressLoadBalancerStatus{ LoadBalancer: networking.IngressLoadBalancerStatus{
@@ -1867,17 +1839,13 @@ func TestValidateIngressStatusUpdate(t *testing.T) {
func makeNodeSelector(key string, op api.NodeSelectorOperator, values []string) *api.NodeSelector { func makeNodeSelector(key string, op api.NodeSelectorOperator, values []string) *api.NodeSelector {
return &api.NodeSelector{ return &api.NodeSelector{
NodeSelectorTerms: []api.NodeSelectorTerm{ NodeSelectorTerms: []api.NodeSelectorTerm{{
{ MatchExpressions: []api.NodeSelectorRequirement{{
MatchExpressions: []api.NodeSelectorRequirement{
{
Key: key, Key: key,
Operator: op, Operator: op,
Values: values, Values: values,
}, }},
}, }},
},
},
} }
} }
@@ -1901,48 +1869,39 @@ func TestValidateClusterCIDR(t *testing.T) {
name string name string
cc *networking.ClusterCIDR cc *networking.ClusterCIDR
expectErr bool expectErr bool
}{ }{{
{
name: "valid SingleStack IPv4 ClusterCIDR", name: "valid SingleStack IPv4 ClusterCIDR",
cc: makeClusterCIDR(8, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits = maxPerNodeHostBits", name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits = maxPerNodeHostBits",
cc: makeClusterCIDR(16, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(16, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits > minPerNodeHostBits", name: "valid SingleStack IPv4 ClusterCIDR, perNodeHostBits > minPerNodeHostBits",
cc: makeClusterCIDR(4, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(4, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid SingleStack IPv6 ClusterCIDR", name: "valid SingleStack IPv6 ClusterCIDR",
cc: makeClusterCIDR(8, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits = maxPerNodeHostBit", name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits = maxPerNodeHostBit",
cc: makeClusterCIDR(64, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(64, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits > minPerNodeHostBit", name: "valid SingleStack IPv6 ClusterCIDR, perNodeHostBits > minPerNodeHostBit",
cc: makeClusterCIDR(4, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(4, "", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid SingleStack IPv6 ClusterCIDR perNodeHostBits=100", name: "valid SingleStack IPv6 ClusterCIDR perNodeHostBits=100",
cc: makeClusterCIDR(100, "", "fd00:1:1::/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(100, "", "fd00:1:1::/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid DualStack ClusterCIDR", name: "valid DualStack ClusterCIDR",
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "valid DualStack ClusterCIDR, no NodeSelector", name: "valid DualStack ClusterCIDR, no NodeSelector",
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", nil), cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", nil),
expectErr: false, expectErr: false,
@@ -1952,8 +1911,7 @@ func TestValidateClusterCIDR(t *testing.T) {
name: "invalid ClusterCIDR, no IPv4 or IPv6 CIDR", name: "invalid ClusterCIDR, no IPv4 or IPv6 CIDR",
cc: makeClusterCIDR(8, "", "", nil), cc: makeClusterCIDR(8, "", "", nil),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid ClusterCIDR, invalid nodeSelector", name: "invalid ClusterCIDR, invalid nodeSelector",
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("NoUppercaseOrSpecialCharsLike=Equals", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("NoUppercaseOrSpecialCharsLike=Equals", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
@@ -1963,13 +1921,11 @@ func TestValidateClusterCIDR(t *testing.T) {
name: "invalid SingleStack IPv4 ClusterCIDR, invalid spec.IPv4", name: "invalid SingleStack IPv4 ClusterCIDR, invalid spec.IPv4",
cc: makeClusterCIDR(8, "test", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "test", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid Singlestack IPv4 ClusterCIDR, perNodeHostBits > maxPerNodeHostBits", name: "invalid Singlestack IPv4 ClusterCIDR, perNodeHostBits > maxPerNodeHostBits",
cc: makeClusterCIDR(100, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(100, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid SingleStack IPv4 ClusterCIDR, perNodeHostBits < minPerNodeHostBits", name: "invalid SingleStack IPv4 ClusterCIDR, perNodeHostBits < minPerNodeHostBits",
cc: makeClusterCIDR(2, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(2, "10.1.0.0/16", "", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
@@ -1979,18 +1935,15 @@ func TestValidateClusterCIDR(t *testing.T) {
name: "invalid SingleStack IPv6 ClusterCIDR, invalid spec.IPv6", name: "invalid SingleStack IPv6 ClusterCIDR, invalid spec.IPv6",
cc: makeClusterCIDR(8, "", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid SingleStack IPv6 ClusterCIDR, valid IPv4 CIDR in spec.IPv6", name: "invalid SingleStack IPv6 ClusterCIDR, valid IPv4 CIDR in spec.IPv6",
cc: makeClusterCIDR(8, "", "10.2.0.0/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "", "10.2.0.0/16", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits", name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits",
cc: makeClusterCIDR(12, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(12, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits < minPerNodeHostBits", name: "invalid SingleStack IPv6 ClusterCIDR, invalid perNodeHostBits < minPerNodeHostBits",
cc: makeClusterCIDR(3, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(3, "", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
@@ -2000,18 +1953,15 @@ func TestValidateClusterCIDR(t *testing.T) {
name: "invalid DualStack ClusterCIDR, valid spec.IPv4, invalid spec.IPv6", name: "invalid DualStack ClusterCIDR, valid spec.IPv4, invalid spec.IPv6",
cc: makeClusterCIDR(8, "10.1.0.0/16", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "10.1.0.0/16", "testv6", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid DualStack ClusterCIDR, valid spec.IPv6, invalid spec.IPv4", name: "invalid DualStack ClusterCIDR, valid spec.IPv6, invalid spec.IPv4",
cc: makeClusterCIDR(8, "testv4", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "testv4", "fd00::/120", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid DualStack ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits", name: "invalid DualStack ClusterCIDR, invalid perNodeHostBits > maxPerNodeHostBits",
cc: makeClusterCIDR(24, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(24, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid DualStack ClusterCIDR, valid IPv6 CIDR in spec.IPv4", name: "invalid DualStack ClusterCIDR, valid IPv6 CIDR in spec.IPv4",
cc: makeClusterCIDR(8, "fd00::/120", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "fd00::/120", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
@@ -2038,33 +1988,27 @@ func TestValidateClusterConfigUpdate(t *testing.T) {
name string name string
cc *networking.ClusterCIDR cc *networking.ClusterCIDR
expectErr bool expectErr bool
}{ }{{
{
name: "Successful update, no changes to ClusterCIDR.Spec", name: "Successful update, no changes to ClusterCIDR.Spec",
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: false, expectErr: false,
}, }, {
{
name: "Failed update, update spec.PerNodeHostBits", name: "Failed update, update spec.PerNodeHostBits",
cc: makeClusterCIDR(12, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(12, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "Failed update, update spec.IPv4", name: "Failed update, update spec.IPv4",
cc: makeClusterCIDR(8, "10.2.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "10.2.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "Failed update, update spec.IPv6", name: "Failed update, update spec.IPv6",
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:2:/112", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})), cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:2:/112", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar"})),
expectErr: true, expectErr: true,
}, }, {
{
name: "Failed update, update spec.NodeSelector", name: "Failed update, update spec.NodeSelector",
cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar2"})), cc: makeClusterCIDR(8, "10.1.0.0/16", "fd00:1:1::/64", makeNodeSelector("foo", api.NodeSelectorOpIn, []string{"bar2"})),
expectErr: true, expectErr: true,
}, }}
}
for _, testCase := range testCases { for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) { t.Run(testCase.name, func(t *testing.T) {
err := ValidateClusterCIDRUpdate(testCase.cc, oldCCC) err := ValidateClusterCIDRUpdate(testCase.cc, oldCCC)
@@ -2244,8 +2188,7 @@ func TestValidateIPAddressUpdate(t *testing.T) {
name string name string
new func(svc *networking.IPAddress) *networking.IPAddress new func(svc *networking.IPAddress) *networking.IPAddress
expectErr bool expectErr bool
}{ }{{
{
name: "Successful update, no changes", name: "Successful update, no changes",
new: func(old *networking.IPAddress) *networking.IPAddress { new: func(old *networking.IPAddress) *networking.IPAddress {
out := old.DeepCopy() out := old.DeepCopy()
@@ -2267,8 +2210,7 @@ func TestValidateIPAddressUpdate(t *testing.T) {
return out return out
}, expectErr: true, }, expectErr: true,
}, }, {
{
name: "Failed update, delete spec.ParentRef", name: "Failed update, delete spec.ParentRef",
new: func(svc *networking.IPAddress) *networking.IPAddress { new: func(svc *networking.IPAddress) *networking.IPAddress {
out := svc.DeepCopy() out := svc.DeepCopy()

View File

@@ -134,8 +134,7 @@ func TestValidateOverhead(t *testing.T) {
successCase := []struct { successCase := []struct {
Name string Name string
overhead *node.Overhead overhead *node.Overhead
}{ }{{
{
Name: "Overhead with valid cpu and memory resources", Name: "Overhead with valid cpu and memory resources",
overhead: &node.Overhead{ overhead: &node.Overhead{
PodFixed: core.ResourceList{ PodFixed: core.ResourceList{
@@ -143,8 +142,7 @@ func TestValidateOverhead(t *testing.T) {
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"), core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
}, },
}, },
}, }}
}
for _, tc := range successCase { for _, tc := range successCase {
rc := &node.RuntimeClass{ rc := &node.RuntimeClass{
@@ -160,16 +158,14 @@ func TestValidateOverhead(t *testing.T) {
errorCase := []struct { errorCase := []struct {
Name string Name string
overhead *node.Overhead overhead *node.Overhead
}{ }{{
{
Name: "Invalid Resources", Name: "Invalid Resources",
overhead: &node.Overhead{ overhead: &node.Overhead{
PodFixed: core.ResourceList{ PodFixed: core.ResourceList{
core.ResourceName("my.org"): resource.MustParse("10m"), core.ResourceName("my.org"): resource.MustParse("10m"),
}, },
}, },
}, }}
}
for _, tc := range errorCase { for _, tc := range errorCase {
rc := &node.RuntimeClass{ rc := &node.RuntimeClass{
ObjectMeta: metav1.ObjectMeta{Name: "foo"}, ObjectMeta: metav1.ObjectMeta{Name: "foo"},

View File

@@ -107,40 +107,35 @@ func TestValidateUnhealthyPodEvictionPolicyDisruptionBudgetSpec(t *testing.T) {
name string name string
pdbSpec policy.PodDisruptionBudgetSpec pdbSpec policy.PodDisruptionBudgetSpec
expectErr bool expectErr bool
}{ }{{
{
name: "valid nil UnhealthyPodEvictionPolicy", name: "valid nil UnhealthyPodEvictionPolicy",
pdbSpec: policy.PodDisruptionBudgetSpec{ pdbSpec: policy.PodDisruptionBudgetSpec{
MinAvailable: &c1, MinAvailable: &c1,
UnhealthyPodEvictionPolicy: nil, UnhealthyPodEvictionPolicy: nil,
}, },
expectErr: false, expectErr: false,
}, }, {
{
name: "valid UnhealthyPodEvictionPolicy", name: "valid UnhealthyPodEvictionPolicy",
pdbSpec: policy.PodDisruptionBudgetSpec{ pdbSpec: policy.PodDisruptionBudgetSpec{
MinAvailable: &c1, MinAvailable: &c1,
UnhealthyPodEvictionPolicy: &alwaysAllowPolicy, UnhealthyPodEvictionPolicy: &alwaysAllowPolicy,
}, },
expectErr: false, expectErr: false,
}, }, {
{
name: "empty UnhealthyPodEvictionPolicy", name: "empty UnhealthyPodEvictionPolicy",
pdbSpec: policy.PodDisruptionBudgetSpec{ pdbSpec: policy.PodDisruptionBudgetSpec{
MinAvailable: &c1, MinAvailable: &c1,
UnhealthyPodEvictionPolicy: new(policy.UnhealthyPodEvictionPolicyType), UnhealthyPodEvictionPolicy: new(policy.UnhealthyPodEvictionPolicyType),
}, },
expectErr: true, expectErr: true,
}, }, {
{
name: "invalid UnhealthyPodEvictionPolicy", name: "invalid UnhealthyPodEvictionPolicy",
pdbSpec: policy.PodDisruptionBudgetSpec{ pdbSpec: policy.PodDisruptionBudgetSpec{
MinAvailable: &c1, MinAvailable: &c1,
UnhealthyPodEvictionPolicy: &invalidPolicy, UnhealthyPodEvictionPolicy: &invalidPolicy,
}, },
expectErr: true, expectErr: true,
}, }}
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
@@ -162,8 +157,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
name string name string
pdbStatus policy.PodDisruptionBudgetStatus pdbStatus policy.PodDisruptionBudgetStatus
expectErrForVersion map[schema.GroupVersion]bool expectErrForVersion map[schema.GroupVersion]bool
}{ }{{
{
name: "DisruptionsAllowed: 10", name: "DisruptionsAllowed: 10",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
DisruptionsAllowed: 10, DisruptionsAllowed: 10,
@@ -172,8 +166,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectNoErrors, policy.SchemeGroupVersion: expectNoErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "CurrentHealthy: 5", name: "CurrentHealthy: 5",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
CurrentHealthy: 5, CurrentHealthy: 5,
@@ -182,8 +175,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectNoErrors, policy.SchemeGroupVersion: expectNoErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "DesiredHealthy: 3", name: "DesiredHealthy: 3",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
DesiredHealthy: 3, DesiredHealthy: 3,
@@ -192,8 +184,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectNoErrors, policy.SchemeGroupVersion: expectNoErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "ExpectedPods: 2", name: "ExpectedPods: 2",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
ExpectedPods: 2, ExpectedPods: 2,
@@ -202,8 +193,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectNoErrors, policy.SchemeGroupVersion: expectNoErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "DisruptionsAllowed: -10", name: "DisruptionsAllowed: -10",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
DisruptionsAllowed: -10, DisruptionsAllowed: -10,
@@ -212,8 +202,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectErrors, policy.SchemeGroupVersion: expectErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "CurrentHealthy: -5", name: "CurrentHealthy: -5",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
CurrentHealthy: -5, CurrentHealthy: -5,
@@ -222,8 +211,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectErrors, policy.SchemeGroupVersion: expectErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "DesiredHealthy: -3", name: "DesiredHealthy: -3",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
DesiredHealthy: -3, DesiredHealthy: -3,
@@ -232,8 +220,7 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectErrors, policy.SchemeGroupVersion: expectErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "ExpectedPods: -2", name: "ExpectedPods: -2",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
ExpectedPods: -2, ExpectedPods: -2,
@@ -242,12 +229,10 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
policy.SchemeGroupVersion: expectErrors, policy.SchemeGroupVersion: expectErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "Conditions valid", name: "Conditions valid",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
Conditions: []metav1.Condition{ Conditions: []metav1.Condition{{
{
Type: policyv1beta1.DisruptionAllowedCondition, Type: policyv1beta1.DisruptionAllowedCondition,
Status: metav1.ConditionTrue, Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Time{ LastTransitionTime: metav1.Time{
@@ -256,34 +241,28 @@ func TestValidatePodDisruptionBudgetStatus(t *testing.T) {
Reason: policyv1beta1.SufficientPodsReason, Reason: policyv1beta1.SufficientPodsReason,
Message: "message", Message: "message",
ObservedGeneration: 3, ObservedGeneration: 3,
}, }},
},
}, },
expectErrForVersion: map[schema.GroupVersion]bool{ expectErrForVersion: map[schema.GroupVersion]bool{
policy.SchemeGroupVersion: expectNoErrors, policy.SchemeGroupVersion: expectNoErrors,
policyv1beta1.SchemeGroupVersion: expectNoErrors, policyv1beta1.SchemeGroupVersion: expectNoErrors,
}, },
}, }, {
{
name: "Conditions not valid", name: "Conditions not valid",
pdbStatus: policy.PodDisruptionBudgetStatus{ pdbStatus: policy.PodDisruptionBudgetStatus{
Conditions: []metav1.Condition{ Conditions: []metav1.Condition{{
{
Type: policyv1beta1.DisruptionAllowedCondition, Type: policyv1beta1.DisruptionAllowedCondition,
Status: metav1.ConditionTrue, Status: metav1.ConditionTrue,
}, }, {
{
Type: policyv1beta1.DisruptionAllowedCondition, Type: policyv1beta1.DisruptionAllowedCondition,
Status: metav1.ConditionFalse, Status: metav1.ConditionFalse,
}, }},
},
}, },
expectErrForVersion: map[schema.GroupVersion]bool{ expectErrForVersion: map[schema.GroupVersion]bool{
policy.SchemeGroupVersion: expectErrors, policy.SchemeGroupVersion: expectErrors,
policyv1beta1.SchemeGroupVersion: expectErrors, policyv1beta1.SchemeGroupVersion: expectErrors,
}, },
}, }}
}
for _, tc := range testCases { for _, tc := range testCases {
for apiVersion, expectErrors := range tc.expectErrForVersion { for apiVersion, expectErrors := range tc.expectErrForVersion {
@@ -1165,23 +1144,19 @@ func TestAllowEphemeralVolumeType(t *testing.T) {
description string description string
hasGenericVolume bool hasGenericVolume bool
psp func() *policy.PodSecurityPolicy psp func() *policy.PodSecurityPolicy
}{ }{{
{
description: "PodSecurityPolicySpec Without GenericVolume", description: "PodSecurityPolicySpec Without GenericVolume",
hasGenericVolume: false, hasGenericVolume: false,
psp: pspWithoutGenericVolume, psp: pspWithoutGenericVolume,
}, }, {
{
description: "PodSecurityPolicySpec With GenericVolume", description: "PodSecurityPolicySpec With GenericVolume",
hasGenericVolume: true, hasGenericVolume: true,
psp: pspWithGenericVolume, psp: pspWithGenericVolume,
}, }, {
{
description: "is nil", description: "is nil",
hasGenericVolume: false, hasGenericVolume: false,
psp: pspNil, psp: pspNil,
}, }}
}
for _, oldPSPInfo := range pspInfo { for _, oldPSPInfo := range pspInfo {
for _, newPSPInfo := range pspInfo { for _, newPSPInfo := range pspInfo {

View File

@@ -402,12 +402,10 @@ func TestValidateRoleNonResourceURL(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "default", Name: "default",
}, },
Rules: []rbac.PolicyRule{ Rules: []rbac.PolicyRule{{
{
Verbs: []string{"get"}, Verbs: []string{"get"},
NonResourceURLs: []string{"/*"}, NonResourceURLs: []string{"/*"},
}, }},
},
}, },
wantErr: false, wantErr: false,
}.test(t) }.test(t)
@@ -420,13 +418,11 @@ func TestValidateRoleNamespacedNonResourceURL(t *testing.T) {
Namespace: "default", Namespace: "default",
Name: "default", Name: "default",
}, },
Rules: []rbac.PolicyRule{ Rules: []rbac.PolicyRule{{
{
// non-resource URLs are invalid for namespaced rules // non-resource URLs are invalid for namespaced rules
Verbs: []string{"get"}, Verbs: []string{"get"},
NonResourceURLs: []string{"/*"}, NonResourceURLs: []string{"/*"},
}, }},
},
}, },
wantErr: true, wantErr: true,
errType: field.ErrorTypeInvalid, errType: field.ErrorTypeInvalid,
@@ -440,12 +436,10 @@ func TestValidateRoleNonResourceURLNoVerbs(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "default", Name: "default",
}, },
Rules: []rbac.PolicyRule{ Rules: []rbac.PolicyRule{{
{
Verbs: []string{}, Verbs: []string{},
NonResourceURLs: []string{"/*"}, NonResourceURLs: []string{"/*"},
}, }},
},
}, },
wantErr: true, wantErr: true,
errType: field.ErrorTypeRequired, errType: field.ErrorTypeRequired,
@@ -460,14 +454,12 @@ func TestValidateRoleMixedNonResourceAndResource(t *testing.T) {
Name: "default", Name: "default",
Namespace: "default", Namespace: "default",
}, },
Rules: []rbac.PolicyRule{ Rules: []rbac.PolicyRule{{
{
Verbs: []string{"get"}, Verbs: []string{"get"},
NonResourceURLs: []string{"/*"}, NonResourceURLs: []string{"/*"},
APIGroups: []string{"v1"}, APIGroups: []string{"v1"},
Resources: []string{"pods"}, Resources: []string{"pods"},
}, }},
},
}, },
wantErr: true, wantErr: true,
errType: field.ErrorTypeInvalid, errType: field.ErrorTypeInvalid,
@@ -482,13 +474,11 @@ func TestValidateRoleValidResource(t *testing.T) {
Name: "default", Name: "default",
Namespace: "default", Namespace: "default",
}, },
Rules: []rbac.PolicyRule{ Rules: []rbac.PolicyRule{{
{
Verbs: []string{"get"}, Verbs: []string{"get"},
APIGroups: []string{"v1"}, APIGroups: []string{"v1"},
Resources: []string{"pods"}, Resources: []string{"pods"},
}, }},
},
}, },
wantErr: false, wantErr: false,
}.test(t) }.test(t)
@@ -501,12 +491,10 @@ func TestValidateRoleNoAPIGroup(t *testing.T) {
Name: "default", Name: "default",
Namespace: "default", Namespace: "default",
}, },
Rules: []rbac.PolicyRule{ Rules: []rbac.PolicyRule{{
{
Verbs: []string{"get"}, Verbs: []string{"get"},
Resources: []string{"pods"}, Resources: []string{"pods"},
}, }},
},
}, },
wantErr: true, wantErr: true,
errType: field.ErrorTypeRequired, errType: field.ErrorTypeRequired,
@@ -521,12 +509,10 @@ func TestValidateRoleNoResources(t *testing.T) {
Name: "default", Name: "default",
Namespace: "default", Namespace: "default",
}, },
Rules: []rbac.PolicyRule{ Rules: []rbac.PolicyRule{{
{
Verbs: []string{"get"}, Verbs: []string{"get"},
APIGroups: []string{"v1"}, APIGroups: []string{"v1"},
}, }},
},
}, },
wantErr: true, wantErr: true,
errType: field.ErrorTypeRequired, errType: field.ErrorTypeRequired,

File diff suppressed because it is too large Load Diff

View File

@@ -86,22 +86,19 @@ func TestValidateKubeletConfiguration(t *testing.T) {
name string name string
configure func(config *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration configure func(config *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration
errMsg string errMsg string
}{ }{{
{
name: "Success", name: "Success",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
return conf return conf
}, },
}, }, {
{
name: "invalid NodeLeaseDurationSeconds", name: "invalid NodeLeaseDurationSeconds",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.NodeLeaseDurationSeconds = 0 conf.NodeLeaseDurationSeconds = 0
return conf return conf
}, },
errMsg: "invalid configuration: nodeLeaseDurationSeconds must be greater than 0", errMsg: "invalid configuration: nodeLeaseDurationSeconds must be greater than 0",
}, }, {
{
name: "specify EnforceNodeAllocatable without enabling CgroupsPerQOS", name: "specify EnforceNodeAllocatable without enabling CgroupsPerQOS",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.CgroupsPerQOS = false conf.CgroupsPerQOS = false
@@ -109,8 +106,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) is not supported unless cgroupsPerQOS (--cgroups-per-qos) is set to true", errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) is not supported unless cgroupsPerQOS (--cgroups-per-qos) is set to true",
}, }, {
{
name: "specify SystemCgroups without CgroupRoot", name: "specify SystemCgroups without CgroupRoot",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.SystemCgroups = "/" conf.SystemCgroups = "/"
@@ -118,32 +114,28 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: systemCgroups (--system-cgroups) was specified and cgroupRoot (--cgroup-root) was not specified", errMsg: "invalid configuration: systemCgroups (--system-cgroups) was specified and cgroupRoot (--cgroup-root) was not specified",
}, }, {
{
name: "invalid EventBurst", name: "invalid EventBurst",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.EventBurst = -1 conf.EventBurst = -1
return conf return conf
}, },
errMsg: "invalid configuration: eventBurst (--event-burst) -1 must not be a negative number", errMsg: "invalid configuration: eventBurst (--event-burst) -1 must not be a negative number",
}, }, {
{
name: "invalid EventRecordQPS", name: "invalid EventRecordQPS",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.EventRecordQPS = -1 conf.EventRecordQPS = -1
return conf return conf
}, },
errMsg: "invalid configuration: eventRecordQPS (--event-qps) -1 must not be a negative number", errMsg: "invalid configuration: eventRecordQPS (--event-qps) -1 must not be a negative number",
}, }, {
{
name: "invalid HealthzPort", name: "invalid HealthzPort",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.HealthzPort = 65536 conf.HealthzPort = 65536
return conf return conf
}, },
errMsg: "invalid configuration: healthzPort (--healthz-port) 65536 must be between 1 and 65535, inclusive", errMsg: "invalid configuration: healthzPort (--healthz-port) 65536 must be between 1 and 65535, inclusive",
}, }, {
{
name: "specify CPUCFSQuotaPeriod without enabling CPUCFSQuotaPeriod", name: "specify CPUCFSQuotaPeriod without enabling CPUCFSQuotaPeriod",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": false} conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": false}
@@ -151,8 +143,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {200ms} requires feature gate CustomCPUCFSQuotaPeriod", errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {200ms} requires feature gate CustomCPUCFSQuotaPeriod",
}, }, {
{
name: "invalid CPUCFSQuotaPeriod", name: "invalid CPUCFSQuotaPeriod",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": true} conf.FeatureGates = map[string]bool{"CustomCPUCFSQuotaPeriod": true}
@@ -160,24 +151,21 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {2s} must be between 1ms and 1sec, inclusive", errMsg: "invalid configuration: cpuCFSQuotaPeriod (--cpu-cfs-quota-period) {2s} must be between 1ms and 1sec, inclusive",
}, }, {
{
name: "invalid ImageGCHighThresholdPercent", name: "invalid ImageGCHighThresholdPercent",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ImageGCHighThresholdPercent = 101 conf.ImageGCHighThresholdPercent = 101
return conf return conf
}, },
errMsg: "invalid configuration: imageGCHighThresholdPercent (--image-gc-high-threshold) 101 must be between 0 and 100, inclusive", errMsg: "invalid configuration: imageGCHighThresholdPercent (--image-gc-high-threshold) 101 must be between 0 and 100, inclusive",
}, }, {
{
name: "invalid ImageGCLowThresholdPercent", name: "invalid ImageGCLowThresholdPercent",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ImageGCLowThresholdPercent = -1 conf.ImageGCLowThresholdPercent = -1
return conf return conf
}, },
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) -1 must be between 0 and 100, inclusive", errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) -1 must be between 0 and 100, inclusive",
}, }, {
{
name: "ImageGCLowThresholdPercent is equal to ImageGCHighThresholdPercent", name: "ImageGCLowThresholdPercent is equal to ImageGCHighThresholdPercent",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ImageGCHighThresholdPercent = 0 conf.ImageGCHighThresholdPercent = 0
@@ -185,8 +173,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 0 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0", errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 0 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0",
}, }, {
{
name: "ImageGCLowThresholdPercent is greater than ImageGCHighThresholdPercent", name: "ImageGCLowThresholdPercent is greater than ImageGCHighThresholdPercent",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ImageGCHighThresholdPercent = 0 conf.ImageGCHighThresholdPercent = 0
@@ -194,120 +181,105 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 1 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0", errMsg: "invalid configuration: imageGCLowThresholdPercent (--image-gc-low-threshold) 1 must be less than imageGCHighThresholdPercent (--image-gc-high-threshold) 0",
}, }, {
{
name: "invalid IPTablesDropBit", name: "invalid IPTablesDropBit",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.IPTablesDropBit = 32 conf.IPTablesDropBit = 32
return conf return conf
}, },
errMsg: "invalid configuration: iptablesDropBit (--iptables-drop-bit) 32 must be between 0 and 31, inclusive", errMsg: "invalid configuration: iptablesDropBit (--iptables-drop-bit) 32 must be between 0 and 31, inclusive",
}, }, {
{
name: "invalid IPTablesMasqueradeBit", name: "invalid IPTablesMasqueradeBit",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.IPTablesMasqueradeBit = 32 conf.IPTablesMasqueradeBit = 32
return conf return conf
}, },
errMsg: "invalid configuration: iptablesMasqueradeBit (--iptables-masquerade-bit) 32 must be between 0 and 31, inclusive", errMsg: "invalid configuration: iptablesMasqueradeBit (--iptables-masquerade-bit) 32 must be between 0 and 31, inclusive",
}, }, {
{
name: "invalid KubeAPIBurst", name: "invalid KubeAPIBurst",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.KubeAPIBurst = -1 conf.KubeAPIBurst = -1
return conf return conf
}, },
errMsg: "invalid configuration: kubeAPIBurst (--kube-api-burst) -1 must not be a negative number", errMsg: "invalid configuration: kubeAPIBurst (--kube-api-burst) -1 must not be a negative number",
}, }, {
{
name: "invalid KubeAPIQPS", name: "invalid KubeAPIQPS",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.KubeAPIQPS = -1 conf.KubeAPIQPS = -1
return conf return conf
}, },
errMsg: "invalid configuration: kubeAPIQPS (--kube-api-qps) -1 must not be a negative number", errMsg: "invalid configuration: kubeAPIQPS (--kube-api-qps) -1 must not be a negative number",
}, }, {
{
name: "invalid NodeStatusMaxImages", name: "invalid NodeStatusMaxImages",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.NodeStatusMaxImages = -2 conf.NodeStatusMaxImages = -2
return conf return conf
}, },
errMsg: "invalid configuration: nodeStatusMaxImages (--node-status-max-images) -2 must be -1 or greater", errMsg: "invalid configuration: nodeStatusMaxImages (--node-status-max-images) -2 must be -1 or greater",
}, }, {
{
name: "invalid MaxOpenFiles", name: "invalid MaxOpenFiles",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.MaxOpenFiles = -1 conf.MaxOpenFiles = -1
return conf return conf
}, },
errMsg: "invalid configuration: maxOpenFiles (--max-open-files) -1 must not be a negative number", errMsg: "invalid configuration: maxOpenFiles (--max-open-files) -1 must not be a negative number",
}, }, {
{
name: "invalid MaxPods", name: "invalid MaxPods",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.MaxPods = -1 conf.MaxPods = -1
return conf return conf
}, },
errMsg: "invalid configuration: maxPods (--max-pods) -1 must not be a negative number", errMsg: "invalid configuration: maxPods (--max-pods) -1 must not be a negative number",
}, }, {
{
name: "invalid OOMScoreAdj", name: "invalid OOMScoreAdj",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.OOMScoreAdj = 1001 conf.OOMScoreAdj = 1001
return conf return conf
}, },
errMsg: "invalid configuration: oomScoreAdj (--oom-score-adj) 1001 must be between -1000 and 1000, inclusive", errMsg: "invalid configuration: oomScoreAdj (--oom-score-adj) 1001 must be between -1000 and 1000, inclusive",
}, }, {
{
name: "invalid PodsPerCore", name: "invalid PodsPerCore",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.PodsPerCore = -1 conf.PodsPerCore = -1
return conf return conf
}, },
errMsg: "invalid configuration: podsPerCore (--pods-per-core) -1 must not be a negative number", errMsg: "invalid configuration: podsPerCore (--pods-per-core) -1 must not be a negative number",
}, }, {
{
name: "invalid Port", name: "invalid Port",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.Port = 65536 conf.Port = 65536
return conf return conf
}, },
errMsg: "invalid configuration: port (--port) 65536 must be between 1 and 65535, inclusive", errMsg: "invalid configuration: port (--port) 65536 must be between 1 and 65535, inclusive",
}, }, {
{
name: "invalid ReadOnlyPort", name: "invalid ReadOnlyPort",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ReadOnlyPort = 65536 conf.ReadOnlyPort = 65536
return conf return conf
}, },
errMsg: "invalid configuration: readOnlyPort (--read-only-port) 65536 must be between 0 and 65535, inclusive", errMsg: "invalid configuration: readOnlyPort (--read-only-port) 65536 must be between 0 and 65535, inclusive",
}, }, {
{
name: "invalid RegistryBurst", name: "invalid RegistryBurst",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.RegistryBurst = -1 conf.RegistryBurst = -1
return conf return conf
}, },
errMsg: "invalid configuration: registryBurst (--registry-burst) -1 must not be a negative number", errMsg: "invalid configuration: registryBurst (--registry-burst) -1 must not be a negative number",
}, }, {
{
name: "invalid RegistryPullQPS", name: "invalid RegistryPullQPS",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.RegistryPullQPS = -1 conf.RegistryPullQPS = -1
return conf return conf
}, },
errMsg: "invalid configuration: registryPullQPS (--registry-qps) -1 must not be a negative number", errMsg: "invalid configuration: registryPullQPS (--registry-qps) -1 must not be a negative number",
}, }, {
{
name: "invalid MaxParallelImagePulls", name: "invalid MaxParallelImagePulls",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.MaxParallelImagePulls = utilpointer.Int32(0) conf.MaxParallelImagePulls = utilpointer.Int32(0)
return conf return conf
}, },
errMsg: "invalid configuration: maxParallelImagePulls 0 must be a positive number", errMsg: "invalid configuration: maxParallelImagePulls 0 must be a positive number",
}, }, {
{
name: "invalid MaxParallelImagePulls and SerializeImagePulls combination", name: "invalid MaxParallelImagePulls and SerializeImagePulls combination",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.MaxParallelImagePulls = utilpointer.Int32(3) conf.MaxParallelImagePulls = utilpointer.Int32(3)
@@ -315,16 +287,14 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: maxParallelImagePulls cannot be larger than 1 unless SerializeImagePulls (--serialize-image-pulls) is set to false", errMsg: "invalid configuration: maxParallelImagePulls cannot be larger than 1 unless SerializeImagePulls (--serialize-image-pulls) is set to false",
}, }, {
{
name: "valid MaxParallelImagePulls and SerializeImagePulls combination", name: "valid MaxParallelImagePulls and SerializeImagePulls combination",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.MaxParallelImagePulls = utilpointer.Int32(1) conf.MaxParallelImagePulls = utilpointer.Int32(1)
conf.SerializeImagePulls = true conf.SerializeImagePulls = true
return conf return conf
}, },
}, }, {
{
name: "specify ServerTLSBootstrap without enabling RotateKubeletServerCertificate", name: "specify ServerTLSBootstrap without enabling RotateKubeletServerCertificate",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"RotateKubeletServerCertificate": false} conf.FeatureGates = map[string]bool{"RotateKubeletServerCertificate": false}
@@ -332,24 +302,21 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: serverTLSBootstrap true requires feature gate RotateKubeletServerCertificate", errMsg: "invalid configuration: serverTLSBootstrap true requires feature gate RotateKubeletServerCertificate",
}, }, {
{
name: "invalid TopologyManagerPolicy", name: "invalid TopologyManagerPolicy",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.TopologyManagerPolicy = "invalid-policy" conf.TopologyManagerPolicy = "invalid-policy"
return conf return conf
}, },
errMsg: "invalid configuration: topologyManagerPolicy (--topology-manager-policy) \"invalid-policy\" must be one of: [\"none\" \"best-effort\" \"restricted\" \"single-numa-node\"]", errMsg: "invalid configuration: topologyManagerPolicy (--topology-manager-policy) \"invalid-policy\" must be one of: [\"none\" \"best-effort\" \"restricted\" \"single-numa-node\"]",
}, }, {
{
name: "invalid TopologyManagerScope", name: "invalid TopologyManagerScope",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.TopologyManagerScope = "invalid-scope" conf.TopologyManagerScope = "invalid-scope"
return conf return conf
}, },
errMsg: "invalid configuration: topologyManagerScope (--topology-manager-scope) \"invalid-scope\" must be one of: \"container\", or \"pod\"", errMsg: "invalid configuration: topologyManagerScope (--topology-manager-scope) \"invalid-scope\" must be one of: \"container\", or \"pod\"",
}, }, {
{
name: "ShutdownGracePeriodCriticalPods is greater than ShutdownGracePeriod", name: "ShutdownGracePeriodCriticalPods is greater than ShutdownGracePeriod",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true} conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
@@ -358,8 +325,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {2s} must be <= shutdownGracePeriod {1s}", errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {2s} must be <= shutdownGracePeriod {1s}",
}, }, {
{
name: "ShutdownGracePeriod is less than 1 sec", name: "ShutdownGracePeriod is less than 1 sec",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true} conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
@@ -367,8 +333,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: shutdownGracePeriod {1ms} must be either zero or otherwise >= 1 sec", errMsg: "invalid configuration: shutdownGracePeriod {1ms} must be either zero or otherwise >= 1 sec",
}, }, {
{
name: "ShutdownGracePeriodCriticalPods is less than 1 sec", name: "ShutdownGracePeriodCriticalPods is less than 1 sec",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true} conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": true}
@@ -376,8 +341,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {1ms} must be either zero or otherwise >= 1 sec", errMsg: "invalid configuration: shutdownGracePeriodCriticalPods {1ms} must be either zero or otherwise >= 1 sec",
}, }, {
{
name: "specify ShutdownGracePeriod without enabling GracefulNodeShutdown", name: "specify ShutdownGracePeriod without enabling GracefulNodeShutdown",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false} conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false}
@@ -385,8 +349,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown", errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown",
}, }, {
{
name: "specify ShutdownGracePeriodCriticalPods without enabling GracefulNodeShutdown", name: "specify ShutdownGracePeriodCriticalPods without enabling GracefulNodeShutdown",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false} conf.FeatureGates = map[string]bool{"GracefulNodeShutdown": false}
@@ -394,8 +357,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown", errMsg: "invalid configuration: specifying shutdownGracePeriod or shutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown",
}, }, {
{
name: "invalid MemorySwap.SwapBehavior", name: "invalid MemorySwap.SwapBehavior",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"NodeSwap": true} conf.FeatureGates = map[string]bool{"NodeSwap": true}
@@ -403,8 +365,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: memorySwap.swapBehavior \"invalid-behavior\" must be one of: \"\", \"LimitedSwap\", or \"UnlimitedSwap\"", errMsg: "invalid configuration: memorySwap.swapBehavior \"invalid-behavior\" must be one of: \"\", \"LimitedSwap\", or \"UnlimitedSwap\"",
}, }, {
{
name: "specify MemorySwap.SwapBehavior without enabling NodeSwap", name: "specify MemorySwap.SwapBehavior without enabling NodeSwap",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"NodeSwap": false} conf.FeatureGates = map[string]bool{"NodeSwap": false}
@@ -412,8 +373,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: memorySwap.swapBehavior cannot be set when NodeSwap feature flag is disabled", errMsg: "invalid configuration: memorySwap.swapBehavior cannot be set when NodeSwap feature flag is disabled",
}, }, {
{
name: "specify SystemReservedEnforcementKey without specifying SystemReservedCgroup", name: "specify SystemReservedEnforcementKey without specifying SystemReservedCgroup",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.EnforceNodeAllocatable = []string{kubetypes.SystemReservedEnforcementKey} conf.EnforceNodeAllocatable = []string{kubetypes.SystemReservedEnforcementKey}
@@ -421,8 +381,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: systemReservedCgroup (--system-reserved-cgroup) must be specified when \"system-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)", errMsg: "invalid configuration: systemReservedCgroup (--system-reserved-cgroup) must be specified when \"system-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)",
}, }, {
{
name: "specify KubeReservedEnforcementKey without specifying KubeReservedCgroup", name: "specify KubeReservedEnforcementKey without specifying KubeReservedCgroup",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.EnforceNodeAllocatable = []string{kubetypes.KubeReservedEnforcementKey} conf.EnforceNodeAllocatable = []string{kubetypes.KubeReservedEnforcementKey}
@@ -430,32 +389,28 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: kubeReservedCgroup (--kube-reserved-cgroup) must be specified when \"kube-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)", errMsg: "invalid configuration: kubeReservedCgroup (--kube-reserved-cgroup) must be specified when \"kube-reserved\" contained in enforceNodeAllocatable (--enforce-node-allocatable)",
}, }, {
{
name: "specify NodeAllocatableNoneKey with additional enforcements", name: "specify NodeAllocatableNoneKey with additional enforcements",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.EnforceNodeAllocatable = []string{kubetypes.NodeAllocatableNoneKey, kubetypes.KubeReservedEnforcementKey} conf.EnforceNodeAllocatable = []string{kubetypes.NodeAllocatableNoneKey, kubetypes.KubeReservedEnforcementKey}
return conf return conf
}, },
errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) may not contain additional enforcements when \"none\" is specified", errMsg: "invalid configuration: enforceNodeAllocatable (--enforce-node-allocatable) may not contain additional enforcements when \"none\" is specified",
}, }, {
{
name: "invalid EnforceNodeAllocatable", name: "invalid EnforceNodeAllocatable",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.EnforceNodeAllocatable = []string{"invalid-enforce-node-allocatable"} conf.EnforceNodeAllocatable = []string{"invalid-enforce-node-allocatable"}
return conf return conf
}, },
errMsg: "invalid configuration: option \"invalid-enforce-node-allocatable\" specified for enforceNodeAllocatable (--enforce-node-allocatable). Valid options are \"pods\", \"system-reserved\", \"kube-reserved\", or \"none\"", errMsg: "invalid configuration: option \"invalid-enforce-node-allocatable\" specified for enforceNodeAllocatable (--enforce-node-allocatable). Valid options are \"pods\", \"system-reserved\", \"kube-reserved\", or \"none\"",
}, }, {
{
name: "invalid HairpinMode", name: "invalid HairpinMode",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.HairpinMode = "invalid-hair-pin-mode" conf.HairpinMode = "invalid-hair-pin-mode"
return conf return conf
}, },
errMsg: "invalid configuration: option \"invalid-hair-pin-mode\" specified for hairpinMode (--hairpin-mode). Valid options are \"none\", \"hairpin-veth\" or \"promiscuous-bridge\"", errMsg: "invalid configuration: option \"invalid-hair-pin-mode\" specified for hairpinMode (--hairpin-mode). Valid options are \"none\", \"hairpin-veth\" or \"promiscuous-bridge\"",
}, }, {
{
name: "specify ReservedSystemCPUs with SystemReservedCgroup", name: "specify ReservedSystemCPUs with SystemReservedCgroup",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ReservedSystemCPUs = "0-3" conf.ReservedSystemCPUs = "0-3"
@@ -463,8 +418,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)", errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)",
}, }, {
{
name: "specify ReservedSystemCPUs with KubeReservedCgroup", name: "specify ReservedSystemCPUs with KubeReservedCgroup",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ReservedSystemCPUs = "0-3" conf.ReservedSystemCPUs = "0-3"
@@ -472,16 +426,14 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)", errMsg: "invalid configuration: can't use reservedSystemCPUs (--reserved-cpus) with systemReservedCgroup (--system-reserved-cgroup) or kubeReservedCgroup (--kube-reserved-cgroup)",
}, }, {
{
name: "invalid ReservedSystemCPUs", name: "invalid ReservedSystemCPUs",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.ReservedSystemCPUs = "invalid-reserved-system-cpus" conf.ReservedSystemCPUs = "invalid-reserved-system-cpus"
return conf return conf
}, },
errMsg: "invalid configuration: unable to parse reservedSystemCPUs (--reserved-cpus) invalid-reserved-system-cpus, error:", errMsg: "invalid configuration: unable to parse reservedSystemCPUs (--reserved-cpus) invalid-reserved-system-cpus, error:",
}, }, {
{
name: "enable MemoryQoS without specifying MemoryThrottlingFactor", name: "enable MemoryQoS without specifying MemoryThrottlingFactor",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"MemoryQoS": true} conf.FeatureGates = map[string]bool{"MemoryQoS": true}
@@ -489,16 +441,14 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: memoryThrottlingFactor is required when MemoryQoS feature flag is enabled", errMsg: "invalid configuration: memoryThrottlingFactor is required when MemoryQoS feature flag is enabled",
}, }, {
{
name: "invalid MemoryThrottlingFactor", name: "invalid MemoryThrottlingFactor",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.MemoryThrottlingFactor = utilpointer.Float64(1.1) conf.MemoryThrottlingFactor = utilpointer.Float64(1.1)
return conf return conf
}, },
errMsg: "invalid configuration: memoryThrottlingFactor 1.1 must be greater than 0 and less than or equal to 1.0", errMsg: "invalid configuration: memoryThrottlingFactor 1.1 must be greater than 0 and less than or equal to 1.0",
}, }, {
{
name: "invalid Taint.TimeAdded", name: "invalid Taint.TimeAdded",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
now := metav1.Now() now := metav1.Now()
@@ -506,8 +456,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: taint.TimeAdded is not nil", errMsg: "invalid configuration: taint.TimeAdded is not nil",
}, }, {
{
name: "specify tracing with KubeletTracing disabled", name: "specify tracing with KubeletTracing disabled",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
samplingRate := int32(99999) samplingRate := int32(99999)
@@ -516,8 +465,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: tracing should not be configured if KubeletTracing feature flag is disabled.", errMsg: "invalid configuration: tracing should not be configured if KubeletTracing feature flag is disabled.",
}, }, {
{
name: "specify tracing invalid sampling rate", name: "specify tracing invalid sampling rate",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
samplingRate := int32(-1) samplingRate := int32(-1)
@@ -526,8 +474,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "tracing.samplingRatePerMillion: Invalid value: -1: sampling rate must be positive", errMsg: "tracing.samplingRatePerMillion: Invalid value: -1: sampling rate must be positive",
}, }, {
{
name: "specify tracing invalid endpoint", name: "specify tracing invalid endpoint",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
ep := "dn%2s://localhost:4317" ep := "dn%2s://localhost:4317"
@@ -536,42 +483,36 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "tracing.endpoint: Invalid value: \"dn%2s://localhost:4317\": parse \"dn%2s://localhost:4317\": first path segment in URL cannot contain colon", errMsg: "tracing.endpoint: Invalid value: \"dn%2s://localhost:4317\": parse \"dn%2s://localhost:4317\": first path segment in URL cannot contain colon",
}, }, {
{
name: "invalid GracefulNodeShutdownBasedOnPodPriority", name: "invalid GracefulNodeShutdownBasedOnPodPriority",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": true} conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": true}
conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{ conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{{
{
Priority: 0, Priority: 0,
ShutdownGracePeriodSeconds: 0, ShutdownGracePeriodSeconds: 0,
}} }}
return conf return conf
}, },
errMsg: "invalid configuration: Cannot specify both shutdownGracePeriodByPodPriority and shutdownGracePeriod at the same time", errMsg: "invalid configuration: Cannot specify both shutdownGracePeriodByPodPriority and shutdownGracePeriod at the same time",
}, }, {
{
name: "Specifying shutdownGracePeriodByPodPriority without enable GracefulNodeShutdownBasedOnPodPriority", name: "Specifying shutdownGracePeriodByPodPriority without enable GracefulNodeShutdownBasedOnPodPriority",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": false} conf.FeatureGates = map[string]bool{"GracefulNodeShutdownBasedOnPodPriority": false}
conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{ conf.ShutdownGracePeriodByPodPriority = []kubeletconfig.ShutdownGracePeriodByPodPriority{{
{
Priority: 0, Priority: 0,
ShutdownGracePeriodSeconds: 0, ShutdownGracePeriodSeconds: 0,
}} }}
return conf return conf
}, },
errMsg: "invalid configuration: Specifying shutdownGracePeriodByPodPriority requires feature gate GracefulNodeShutdownBasedOnPodPriority", errMsg: "invalid configuration: Specifying shutdownGracePeriodByPodPriority requires feature gate GracefulNodeShutdownBasedOnPodPriority",
}, }, {
{
name: "enableSystemLogQuery is enabled without NodeLogQuery feature gate", name: "enableSystemLogQuery is enabled without NodeLogQuery feature gate",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.EnableSystemLogQuery = true conf.EnableSystemLogQuery = true
return conf return conf
}, },
errMsg: "invalid configuration: NodeLogQuery feature gate is required for enableSystemLogHandler", errMsg: "invalid configuration: NodeLogQuery feature gate is required for enableSystemLogHandler",
}, }, {
{
name: "enableSystemLogQuery is enabled without enableSystemLogHandler", name: "enableSystemLogQuery is enabled without enableSystemLogHandler",
configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration { configure: func(conf *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration {
conf.FeatureGates = map[string]bool{"NodeLogQuery": true} conf.FeatureGates = map[string]bool{"NodeLogQuery": true}
@@ -580,8 +521,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
return conf return conf
}, },
errMsg: "invalid configuration: enableSystemLogHandler is required for enableSystemLogQuery", errMsg: "invalid configuration: enableSystemLogHandler is required for enableSystemLogQuery",
}, }}
}
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {

View File

@@ -36,8 +36,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
} else { } else {
proxyMode = kubeproxyconfig.ProxyModeIPVS proxyMode = kubeproxyconfig.ProxyModeIPVS
} }
successCases := []kubeproxyconfig.KubeProxyConfiguration{ successCases := []kubeproxyconfig.KubeProxyConfiguration{{
{
BindAddress: "192.168.59.103", BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256", HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -59,8 +58,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
}, },
}, }, {
{
BindAddress: "192.168.59.103", BindAddress: "192.168.59.103",
HealthzBindAddress: "0.0.0.0:10256", HealthzBindAddress: "0.0.0.0:10256",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -77,8 +75,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
}, },
}, }, {
{
BindAddress: "192.168.59.103", BindAddress: "192.168.59.103",
HealthzBindAddress: "", HealthzBindAddress: "",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -95,8 +92,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
}, },
}, }, {
{
BindAddress: "fd00:192:168:59::103", BindAddress: "fd00:192:168:59::103",
HealthzBindAddress: "", HealthzBindAddress: "",
MetricsBindAddress: "[::1]:10249", MetricsBindAddress: "[::1]:10249",
@@ -113,8 +109,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
}, },
}, }, {
{
BindAddress: "10.10.12.11", BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345", HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -131,8 +126,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
}, },
}, }, {
{
BindAddress: "10.10.12.11", BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345", HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -149,8 +143,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
}, },
}, }, {
{
BindAddress: "10.10.12.11", BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345", HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -167,8 +160,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second}, TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
}, },
}, }, {
{
BindAddress: "10.10.12.11", BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345", HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -189,8 +181,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{ DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
InterfaceNamePrefix: "vethabcde", InterfaceNamePrefix: "vethabcde",
}, },
}, }, {
{
BindAddress: "10.10.12.11", BindAddress: "10.10.12.11",
HealthzBindAddress: "0.0.0.0:12345", HealthzBindAddress: "0.0.0.0:12345",
MetricsBindAddress: "127.0.0.1:10249", MetricsBindAddress: "127.0.0.1:10249",
@@ -211,8 +202,7 @@ func TestValidateKubeProxyConfiguration(t *testing.T) {
DetectLocal: kubeproxyconfig.DetectLocalConfiguration{ DetectLocal: kubeproxyconfig.DetectLocalConfiguration{
BridgeInterface: "avz", BridgeInterface: "avz",
}, },
}, }}
}
for _, successCase := range successCases { for _, successCase := range successCases {
if errs := Validate(&successCase); len(errs) != 0 { if errs := Validate(&successCase); len(errs) != 0 {

View File

@@ -57,8 +57,7 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
PodInitialBackoffSeconds: podInitialBackoffSeconds, PodInitialBackoffSeconds: podInitialBackoffSeconds,
PodMaxBackoffSeconds: podMaxBackoffSeconds, PodMaxBackoffSeconds: podMaxBackoffSeconds,
PercentageOfNodesToScore: pointer.Int32(35), PercentageOfNodesToScore: pointer.Int32(35),
Profiles: []config.KubeSchedulerProfile{ Profiles: []config.KubeSchedulerProfile{{
{
SchedulerName: "me", SchedulerName: "me",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
@@ -68,14 +67,11 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
Disabled: []config.Plugin{{Name: "*"}}, Disabled: []config.Plugin{{Name: "*"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100}, Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
}, }},
}, }, {
},
{
SchedulerName: "other", SchedulerName: "other",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
@@ -85,14 +81,11 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
Enabled: []config.Plugin{{Name: "CustomBind"}}, Enabled: []config.Plugin{{Name: "CustomBind"}},
}, },
}, },
}, }},
}, Extenders: []config.Extender{{
Extenders: []config.Extender{
{
PrioritizeVerb: "prioritize", PrioritizeVerb: "prioritize",
Weight: 1, Weight: 1,
}, }},
},
} }
invalidParallelismValue := validConfig.DeepCopy() invalidParallelismValue := validConfig.DeepCopy()
@@ -145,60 +138,46 @@ func TestValidateKubeSchedulerConfigurationV1beta2(t *testing.T) {
extenderNegativeWeight.Extenders[0].Weight = -1 extenderNegativeWeight.Extenders[0].Weight = -1
invalidNodePercentage := validConfig.DeepCopy() invalidNodePercentage := validConfig.DeepCopy()
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{ invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100}, Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
}, }}
}
invalidPluginArgs := validConfig.DeepCopy() invalidPluginArgs := validConfig.DeepCopy()
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{ invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.InterPodAffinityArgs{}, Args: &config.InterPodAffinityArgs{},
}, }}
}
duplicatedPluginConfig := validConfig.DeepCopy() duplicatedPluginConfig := validConfig.DeepCopy()
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{ duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "config", Name: "config",
}, }, {
{
Name: "config", Name: "config",
}, }}
}
mismatchQueueSort := validConfig.DeepCopy() mismatchQueueSort := validConfig.DeepCopy()
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{ mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{{
{
SchedulerName: "me", SchedulerName: "me",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
Enabled: []config.Plugin{{Name: "PrioritySort"}}, Enabled: []config.Plugin{{Name: "PrioritySort"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "PrioritySort", Name: "PrioritySort",
}, }},
}, }, {
},
{
SchedulerName: "other", SchedulerName: "other",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
Enabled: []config.Plugin{{Name: "CustomSort"}}, Enabled: []config.Plugin{{Name: "CustomSort"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "CustomSort", Name: "CustomSort",
}, }},
}, }}
},
}
extenderDuplicateManagedResource := validConfig.DeepCopy() extenderDuplicateManagedResource := validConfig.DeepCopy()
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{ extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
@@ -455,8 +434,7 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
PodInitialBackoffSeconds: podInitialBackoffSeconds, PodInitialBackoffSeconds: podInitialBackoffSeconds,
PodMaxBackoffSeconds: podMaxBackoffSeconds, PodMaxBackoffSeconds: podMaxBackoffSeconds,
PercentageOfNodesToScore: pointer.Int32(35), PercentageOfNodesToScore: pointer.Int32(35),
Profiles: []config.KubeSchedulerProfile{ Profiles: []config.KubeSchedulerProfile{{
{
SchedulerName: "me", SchedulerName: "me",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
@@ -466,14 +444,11 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
Disabled: []config.Plugin{{Name: "*"}}, Disabled: []config.Plugin{{Name: "*"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100}, Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
}, }},
}, }, {
},
{
SchedulerName: "other", SchedulerName: "other",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
@@ -483,14 +458,11 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
Enabled: []config.Plugin{{Name: "CustomBind"}}, Enabled: []config.Plugin{{Name: "CustomBind"}},
}, },
}, },
}, }},
}, Extenders: []config.Extender{{
Extenders: []config.Extender{
{
PrioritizeVerb: "prioritize", PrioritizeVerb: "prioritize",
Weight: 1, Weight: 1,
}, }},
},
} }
invalidParallelismValue := validConfig.DeepCopy() invalidParallelismValue := validConfig.DeepCopy()
@@ -543,20 +515,16 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
extenderNegativeWeight.Extenders[0].Weight = -1 extenderNegativeWeight.Extenders[0].Weight = -1
invalidNodePercentage := validConfig.DeepCopy() invalidNodePercentage := validConfig.DeepCopy()
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{ invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100}, Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
}, }}
}
invalidPluginArgs := validConfig.DeepCopy() invalidPluginArgs := validConfig.DeepCopy()
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{ invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.InterPodAffinityArgs{}, Args: &config.InterPodAffinityArgs{},
}, }}
}
duplicatedPlugins := validConfig.DeepCopy() duplicatedPlugins := validConfig.DeepCopy()
duplicatedPlugins.Profiles[0].Plugins.PreEnqueue.Enabled = []config.Plugin{ duplicatedPlugins.Profiles[0].Plugins.PreEnqueue.Enabled = []config.Plugin{
@@ -565,44 +533,34 @@ func TestValidateKubeSchedulerConfigurationV1beta3(t *testing.T) {
} }
duplicatedPluginConfig := validConfig.DeepCopy() duplicatedPluginConfig := validConfig.DeepCopy()
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{ duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "config", Name: "config",
}, }, {
{
Name: "config", Name: "config",
}, }}
}
mismatchQueueSort := validConfig.DeepCopy() mismatchQueueSort := validConfig.DeepCopy()
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{ mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{{
{
SchedulerName: "me", SchedulerName: "me",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
Enabled: []config.Plugin{{Name: "PrioritySort"}}, Enabled: []config.Plugin{{Name: "PrioritySort"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "PrioritySort", Name: "PrioritySort",
}, }},
}, }, {
},
{
SchedulerName: "other", SchedulerName: "other",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
Enabled: []config.Plugin{{Name: "CustomSort"}}, Enabled: []config.Plugin{{Name: "CustomSort"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "CustomSort", Name: "CustomSort",
}, }},
}, }}
},
}
extenderDuplicateManagedResource := validConfig.DeepCopy() extenderDuplicateManagedResource := validConfig.DeepCopy()
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{ extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{
@@ -858,8 +816,7 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
}, },
PodInitialBackoffSeconds: podInitialBackoffSeconds, PodInitialBackoffSeconds: podInitialBackoffSeconds,
PodMaxBackoffSeconds: podMaxBackoffSeconds, PodMaxBackoffSeconds: podMaxBackoffSeconds,
Profiles: []config.KubeSchedulerProfile{ Profiles: []config.KubeSchedulerProfile{{
{
SchedulerName: "me", SchedulerName: "me",
PercentageOfNodesToScore: pointer.Int32(35), PercentageOfNodesToScore: pointer.Int32(35),
Plugins: &config.Plugins{ Plugins: &config.Plugins{
@@ -870,14 +827,11 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
Disabled: []config.Plugin{{Name: "*"}}, Disabled: []config.Plugin{{Name: "*"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100}, Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
}, }},
}, }, {
},
{
SchedulerName: "other", SchedulerName: "other",
PercentageOfNodesToScore: pointer.Int32(35), PercentageOfNodesToScore: pointer.Int32(35),
Plugins: &config.Plugins{ Plugins: &config.Plugins{
@@ -888,14 +842,11 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
Enabled: []config.Plugin{{Name: "CustomBind"}}, Enabled: []config.Plugin{{Name: "CustomBind"}},
}, },
}, },
}, }},
}, Extenders: []config.Extender{{
Extenders: []config.Extender{
{
PrioritizeVerb: "prioritize", PrioritizeVerb: "prioritize",
Weight: 1, Weight: 1,
}, }},
},
} }
invalidParallelismValue := validConfig.DeepCopy() invalidParallelismValue := validConfig.DeepCopy()
@@ -948,60 +899,46 @@ func TestValidateKubeSchedulerConfigurationV1(t *testing.T) {
extenderNegativeWeight.Extenders[0].Weight = -1 extenderNegativeWeight.Extenders[0].Weight = -1
invalidNodePercentage := validConfig.DeepCopy() invalidNodePercentage := validConfig.DeepCopy()
invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{ invalidNodePercentage.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100}, Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 200, MinCandidateNodesAbsolute: 100},
}, }}
}
invalidPluginArgs := validConfig.DeepCopy() invalidPluginArgs := validConfig.DeepCopy()
invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{ invalidPluginArgs.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "DefaultPreemption", Name: "DefaultPreemption",
Args: &config.InterPodAffinityArgs{}, Args: &config.InterPodAffinityArgs{},
}, }}
}
duplicatedPluginConfig := validConfig.DeepCopy() duplicatedPluginConfig := validConfig.DeepCopy()
duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{ duplicatedPluginConfig.Profiles[0].PluginConfig = []config.PluginConfig{{
{
Name: "config", Name: "config",
}, }, {
{
Name: "config", Name: "config",
}, }}
}
mismatchQueueSort := validConfig.DeepCopy() mismatchQueueSort := validConfig.DeepCopy()
mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{ mismatchQueueSort.Profiles = []config.KubeSchedulerProfile{{
{
SchedulerName: "me", SchedulerName: "me",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
Enabled: []config.Plugin{{Name: "PrioritySort"}}, Enabled: []config.Plugin{{Name: "PrioritySort"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "PrioritySort", Name: "PrioritySort",
}, }},
}, }, {
},
{
SchedulerName: "other", SchedulerName: "other",
Plugins: &config.Plugins{ Plugins: &config.Plugins{
QueueSort: config.PluginSet{ QueueSort: config.PluginSet{
Enabled: []config.Plugin{{Name: "CustomSort"}}, Enabled: []config.Plugin{{Name: "CustomSort"}},
}, },
}, },
PluginConfig: []config.PluginConfig{ PluginConfig: []config.PluginConfig{{
{
Name: "CustomSort", Name: "CustomSort",
}, }},
}, }}
},
}
extenderDuplicateManagedResource := validConfig.DeepCopy() extenderDuplicateManagedResource := validConfig.DeepCopy()
extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{ extenderDuplicateManagedResource.Extenders[0].ManagedResources = []config.ExtenderManagedResource{

View File

@@ -27,158 +27,124 @@ func TestValidateConfiguration(t *testing.T) {
name string name string
config eventratelimitapi.Configuration config eventratelimitapi.Configuration
expectedResult bool expectedResult bool
}{ }{{
{
name: "valid server", name: "valid server",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "Server", Type: "Server",
Burst: 5, Burst: 5,
QPS: 1, QPS: 1,
}, }},
},
}, },
expectedResult: true, expectedResult: true,
}, }, {
{
name: "valid namespace", name: "valid namespace",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "Namespace", Type: "Namespace",
Burst: 10, Burst: 10,
QPS: 2, QPS: 2,
CacheSize: 100, CacheSize: 100,
}, }},
},
}, },
expectedResult: true, expectedResult: true,
}, }, {
{
name: "valid user", name: "valid user",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "User", Type: "User",
Burst: 10, Burst: 10,
QPS: 2, QPS: 2,
CacheSize: 100, CacheSize: 100,
}, }},
},
}, },
expectedResult: true, expectedResult: true,
}, }, {
{
name: "valid source+object", name: "valid source+object",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "SourceAndObject", Type: "SourceAndObject",
Burst: 5, Burst: 5,
QPS: 1, QPS: 1,
CacheSize: 1000, CacheSize: 1000,
}, }},
},
}, },
expectedResult: true, expectedResult: true,
}, }, {
{
name: "valid multiple", name: "valid multiple",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "Server", Type: "Server",
Burst: 5, Burst: 5,
QPS: 1, QPS: 1,
}, }, {
{
Type: "Namespace", Type: "Namespace",
Burst: 10, Burst: 10,
QPS: 2, QPS: 2,
CacheSize: 100, CacheSize: 100,
}, }, {
{
Type: "SourceAndObject", Type: "SourceAndObject",
Burst: 25, Burst: 25,
QPS: 10, QPS: 10,
CacheSize: 1000, CacheSize: 1000,
}, }},
},
}, },
expectedResult: true, expectedResult: true,
}, }, {
{
name: "missing limits", name: "missing limits",
config: eventratelimitapi.Configuration{}, config: eventratelimitapi.Configuration{},
expectedResult: false, expectedResult: false,
}, }, {
{
name: "missing type", name: "missing type",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Burst: 25, Burst: 25,
QPS: 10, QPS: 10,
CacheSize: 1000, CacheSize: 1000,
}, }},
},
}, },
expectedResult: false, expectedResult: false,
}, }, {
{
name: "invalid type", name: "invalid type",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "unknown-type", Type: "unknown-type",
Burst: 25, Burst: 25,
QPS: 10, QPS: 10,
CacheSize: 1000, CacheSize: 1000,
}, }},
},
}, },
expectedResult: false, expectedResult: false,
}, }, {
{
name: "missing burst", name: "missing burst",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "Server", Type: "Server",
QPS: 1, QPS: 1,
}, }},
},
}, },
expectedResult: false, expectedResult: false,
}, }, {
{
name: "missing qps", name: "missing qps",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "Server", Type: "Server",
Burst: 5, Burst: 5,
}, }},
},
}, },
expectedResult: false, expectedResult: false,
}, }, {
{
name: "negative cache size", name: "negative cache size",
config: eventratelimitapi.Configuration{ config: eventratelimitapi.Configuration{
Limits: []eventratelimitapi.Limit{ Limits: []eventratelimitapi.Limit{{
{
Type: "Namespace", Type: "Namespace",
Burst: 10, Burst: 10,
QPS: 2, QPS: 2,
CacheSize: -1, CacheSize: -1,
}, }},
},
}, },
expectedResult: false, expectedResult: false,
}, }}
}
for _, tc := range cases { for _, tc := range cases {
errs := ValidateConfiguration(&tc.config) errs := ValidateConfiguration(&tc.config)
if e, a := tc.expectedResult, len(errs) == 0; e != a { if e, a := tc.expectedResult, len(errs) == 0; e != a {

View File

@@ -17,9 +17,10 @@ limitations under the License.
package validation package validation
import ( import (
"testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
internalapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction" internalapi "k8s.io/kubernetes/plugin/pkg/admission/podtolerationrestriction/apis/podtolerationrestriction"
"testing"
) )
func TestValidateConfiguration(t *testing.T) { func TestValidateConfiguration(t *testing.T) {
@@ -28,8 +29,7 @@ func TestValidateConfiguration(t *testing.T) {
config internalapi.Configuration config internalapi.Configuration
testName string testName string
testStatus bool testStatus bool
}{ }{{
{
config: internalapi.Configuration{ config: internalapi.Configuration{
Default: []api.Toleration{ Default: []api.Toleration{
{Key: "foo", Operator: "Exists", Value: "", Effect: "NoExecute", TolerationSeconds: &[]int64{60}[0]}, {Key: "foo", Operator: "Exists", Value: "", Effect: "NoExecute", TolerationSeconds: &[]int64{60}[0]},
@@ -44,22 +44,19 @@ func TestValidateConfiguration(t *testing.T) {
}, },
testName: "Valid cases", testName: "Valid cases",
testStatus: true, testStatus: true,
}, }, {
{
config: internalapi.Configuration{ config: internalapi.Configuration{
Whitelist: []api.Toleration{{Key: "foo", Operator: "Exists", Value: "bar", Effect: "NoSchedule"}}, Whitelist: []api.Toleration{{Key: "foo", Operator: "Exists", Value: "bar", Effect: "NoSchedule"}},
}, },
testName: "Invalid case", testName: "Invalid case",
testStatus: false, testStatus: false,
}, }, {
{
config: internalapi.Configuration{ config: internalapi.Configuration{
Default: []api.Toleration{{Operator: "Equal", Value: "bar", Effect: "NoSchedule"}}, Default: []api.Toleration{{Operator: "Equal", Value: "bar", Effect: "NoSchedule"}},
}, },
testName: "Invalid case", testName: "Invalid case",
testStatus: false, testStatus: false,
}, }}
}
for i := range tests { for i := range tests {
errs := ValidateConfiguration(&tests[i].config) errs := ValidateConfiguration(&tests[i].config)

View File

@@ -17,9 +17,10 @@ limitations under the License.
package validation package validation
import ( import (
"testing"
"k8s.io/apimachinery/pkg/apis/meta/internalversion" "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"testing"
) )
func TestValidateListOptions(t *testing.T) { func TestValidateListOptions(t *testing.T) {
@@ -32,55 +33,47 @@ func TestValidateListOptions(t *testing.T) {
opts internalversion.ListOptions opts internalversion.ListOptions
watchListFeatureEnabled bool watchListFeatureEnabled bool
expectErrors []string expectErrors []string
}{ }{{
{
name: "valid-default", name: "valid-default",
opts: internalversion.ListOptions{}, opts: internalversion.ListOptions{},
}, }, {
{
name: "valid-resourceversionmatch-exact", name: "valid-resourceversionmatch-exact",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
ResourceVersion: "1", ResourceVersion: "1",
ResourceVersionMatch: metav1.ResourceVersionMatchExact, ResourceVersionMatch: metav1.ResourceVersionMatchExact,
}, },
}, }, {
{
name: "invalid-resourceversionmatch-exact", name: "invalid-resourceversionmatch-exact",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
ResourceVersion: "0", ResourceVersion: "0",
ResourceVersionMatch: metav1.ResourceVersionMatchExact, ResourceVersionMatch: metav1.ResourceVersionMatchExact,
}, },
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch \"exact\" is forbidden for resourceVersion \"0\""}, expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch \"exact\" is forbidden for resourceVersion \"0\""},
}, }, {
{
name: "valid-resourceversionmatch-notolderthan", name: "valid-resourceversionmatch-notolderthan",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
ResourceVersion: "0", ResourceVersion: "0",
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
}, },
}, }, {
{
name: "invalid-resourceversionmatch", name: "invalid-resourceversionmatch",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
ResourceVersion: "0", ResourceVersion: "0",
ResourceVersionMatch: "foo", ResourceVersionMatch: "foo",
}, },
expectErrors: []string{"resourceVersionMatch: Unsupported value: \"foo\": supported values: \"Exact\", \"NotOlderThan\", \"\""}, expectErrors: []string{"resourceVersionMatch: Unsupported value: \"foo\": supported values: \"Exact\", \"NotOlderThan\", \"\""},
}, }, {
{
name: "list-sendInitialEvents-forbidden", name: "list-sendInitialEvents-forbidden",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
SendInitialEvents: boolPtrFn(true), SendInitialEvents: boolPtrFn(true),
}, },
expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for list"}, expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for list"},
}, }, {
{
name: "valid-watch-default", name: "valid-watch-default",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
}, },
}, }, {
{
name: "valid-watch-sendInitialEvents-on", name: "valid-watch-sendInitialEvents-on",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -89,8 +82,7 @@ func TestValidateListOptions(t *testing.T) {
AllowWatchBookmarks: true, AllowWatchBookmarks: true,
}, },
watchListFeatureEnabled: true, watchListFeatureEnabled: true,
}, }, {
{
name: "valid-watch-sendInitialEvents-off", name: "valid-watch-sendInitialEvents-off",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -99,24 +91,21 @@ func TestValidateListOptions(t *testing.T) {
AllowWatchBookmarks: true, AllowWatchBookmarks: true,
}, },
watchListFeatureEnabled: true, watchListFeatureEnabled: true,
}, }, {
{
name: "watch-resourceversionmatch-without-sendInitialEvents-forbidden", name: "watch-resourceversionmatch-without-sendInitialEvents-forbidden",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
}, },
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden for watch unless sendInitialEvents is provided"}, expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden for watch unless sendInitialEvents is provided"},
}, }, {
{
name: "watch-sendInitialEvents-without-resourceversionmatch-forbidden", name: "watch-sendInitialEvents-without-resourceversionmatch-forbidden",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
SendInitialEvents: boolPtrFn(true), SendInitialEvents: boolPtrFn(true),
}, },
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"}, expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
}, }, {
{
name: "watch-sendInitialEvents-with-exact-resourceversionmatch-forbidden", name: "watch-sendInitialEvents-with-exact-resourceversionmatch-forbidden",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -126,8 +115,7 @@ func TestValidateListOptions(t *testing.T) {
}, },
watchListFeatureEnabled: true, watchListFeatureEnabled: true,
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"Exact\": supported values: \"NotOlderThan\""}, expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"Exact\": supported values: \"NotOlderThan\""},
}, }, {
{
name: "watch-sendInitialEvents-on-with-empty-resourceversionmatch-forbidden", name: "watch-sendInitialEvents-on-with-empty-resourceversionmatch-forbidden",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -135,8 +123,7 @@ func TestValidateListOptions(t *testing.T) {
ResourceVersionMatch: "", ResourceVersionMatch: "",
}, },
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"}, expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
}, }, {
{
name: "watch-sendInitialEvents-off-with-empty-resourceversionmatch-forbidden", name: "watch-sendInitialEvents-off-with-empty-resourceversionmatch-forbidden",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -144,8 +131,7 @@ func TestValidateListOptions(t *testing.T) {
ResourceVersionMatch: "", ResourceVersionMatch: "",
}, },
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"}, expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
}, }, {
{
name: "watch-sendInitialEvents-with-incorrect-resourceversionmatch-forbidden", name: "watch-sendInitialEvents-with-incorrect-resourceversionmatch-forbidden",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -155,8 +141,7 @@ func TestValidateListOptions(t *testing.T) {
}, },
watchListFeatureEnabled: true, watchListFeatureEnabled: true,
expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"incorrect\": supported values: \"NotOlderThan\""}, expectErrors: []string{"resourceVersionMatch: Forbidden: sendInitialEvents requires setting resourceVersionMatch to NotOlderThan", "resourceVersionMatch: Unsupported value: \"incorrect\": supported values: \"NotOlderThan\""},
}, }, {
{
// note that validating allowWatchBookmarks would break backward compatibility // note that validating allowWatchBookmarks would break backward compatibility
// because it was possible to request initial events via resourceVersion=0 before this change // because it was possible to request initial events via resourceVersion=0 before this change
name: "watch-sendInitialEvents-no-allowWatchBookmark", name: "watch-sendInitialEvents-no-allowWatchBookmark",
@@ -166,8 +151,7 @@ func TestValidateListOptions(t *testing.T) {
ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan, ResourceVersionMatch: metav1.ResourceVersionMatchNotOlderThan,
}, },
watchListFeatureEnabled: true, watchListFeatureEnabled: true,
}, }, {
{
name: "watch-sendInitialEvents-no-watchlist-fg-disabled", name: "watch-sendInitialEvents-no-watchlist-fg-disabled",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -176,8 +160,7 @@ func TestValidateListOptions(t *testing.T) {
AllowWatchBookmarks: true, AllowWatchBookmarks: true,
}, },
expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"}, expectErrors: []string{"sendInitialEvents: Forbidden: sendInitialEvents is forbidden for watch unless the WatchList feature gate is enabled"},
}, }, {
{
name: "watch-sendInitialEvents-no-watchlist-fg-disabled", name: "watch-sendInitialEvents-no-watchlist-fg-disabled",
opts: internalversion.ListOptions{ opts: internalversion.ListOptions{
Watch: true, Watch: true,
@@ -188,8 +171,7 @@ func TestValidateListOptions(t *testing.T) {
}, },
watchListFeatureEnabled: true, watchListFeatureEnabled: true,
expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden when continue is provided"}, expectErrors: []string{"resourceVersionMatch: Forbidden: resourceVersionMatch is forbidden when continue is provided"},
}, }}
}
for _, tc := range cases { for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {

View File

@@ -136,31 +136,26 @@ func TestValidPatchOptions(t *testing.T) {
tests := []struct { tests := []struct {
opts metav1.PatchOptions opts metav1.PatchOptions
patchType types.PatchType patchType types.PatchType
}{ }{{
{
opts: metav1.PatchOptions{ opts: metav1.PatchOptions{
Force: boolPtr(true), Force: boolPtr(true),
FieldManager: "kubectl", FieldManager: "kubectl",
}, },
patchType: types.ApplyPatchType, patchType: types.ApplyPatchType,
}, }, {
{
opts: metav1.PatchOptions{ opts: metav1.PatchOptions{
FieldManager: "kubectl", FieldManager: "kubectl",
}, },
patchType: types.ApplyPatchType, patchType: types.ApplyPatchType,
}, }, {
{
opts: metav1.PatchOptions{}, opts: metav1.PatchOptions{},
patchType: types.MergePatchType, patchType: types.MergePatchType,
}, }, {
{
opts: metav1.PatchOptions{ opts: metav1.PatchOptions{
FieldManager: "patcher", FieldManager: "patcher",
}, },
patchType: types.MergePatchType, patchType: types.MergePatchType,
}, }}
}
for _, test := range tests { for _, test := range tests {
t.Run(fmt.Sprintf("%v", test.opts), func(t *testing.T) { t.Run(fmt.Sprintf("%v", test.opts), func(t *testing.T) {
@@ -243,36 +238,30 @@ func TestValidateFieldManagerInvalid(t *testing.T) {
} }
func TestValidateManagedFieldsInvalid(t *testing.T) { func TestValidateManagedFieldsInvalid(t *testing.T) {
tests := []metav1.ManagedFieldsEntry{ tests := []metav1.ManagedFieldsEntry{{
{
Operation: metav1.ManagedFieldsOperationUpdate, Operation: metav1.ManagedFieldsOperationUpdate,
FieldsType: "RandomVersion", FieldsType: "RandomVersion",
APIVersion: "v1", APIVersion: "v1",
}, }, {
{
Operation: "RandomOperation", Operation: "RandomOperation",
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
APIVersion: "v1", APIVersion: "v1",
}, }, {
{
// Operation is missing // Operation is missing
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
APIVersion: "v1", APIVersion: "v1",
}, }, {
{
Operation: metav1.ManagedFieldsOperationUpdate, Operation: metav1.ManagedFieldsOperationUpdate,
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
// Invalid fieldManager // Invalid fieldManager
Manager: "field\nmanager", Manager: "field\nmanager",
APIVersion: "v1", APIVersion: "v1",
}, }, {
{
Operation: metav1.ManagedFieldsOperationApply, Operation: metav1.ManagedFieldsOperationApply,
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
APIVersion: "v1", APIVersion: "v1",
Subresource: "TooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLong", Subresource: "TooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLongTooLong",
}, }}
}
for _, test := range tests { for _, test := range tests {
t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) { t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) {
@@ -285,30 +274,25 @@ func TestValidateManagedFieldsInvalid(t *testing.T) {
} }
func TestValidateMangedFieldsValid(t *testing.T) { func TestValidateMangedFieldsValid(t *testing.T) {
tests := []metav1.ManagedFieldsEntry{ tests := []metav1.ManagedFieldsEntry{{
{
Operation: metav1.ManagedFieldsOperationUpdate, Operation: metav1.ManagedFieldsOperationUpdate,
APIVersion: "v1", APIVersion: "v1",
// FieldsType is missing // FieldsType is missing
}, }, {
{
Operation: metav1.ManagedFieldsOperationUpdate, Operation: metav1.ManagedFieldsOperationUpdate,
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
APIVersion: "v1", APIVersion: "v1",
}, }, {
{
Operation: metav1.ManagedFieldsOperationApply, Operation: metav1.ManagedFieldsOperationApply,
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
APIVersion: "v1", APIVersion: "v1",
Subresource: "scale", Subresource: "scale",
}, }, {
{
Operation: metav1.ManagedFieldsOperationApply, Operation: metav1.ManagedFieldsOperationApply,
FieldsType: "FieldsV1", FieldsType: "FieldsV1",
APIVersion: "v1", APIVersion: "v1",
Manager: "🍔", Manager: "🍔",
}, }}
}
for _, test := range tests { for _, test := range tests {
t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) { t.Run(fmt.Sprintf("%#v", test), func(t *testing.T) {
@@ -325,8 +309,7 @@ func TestValidateConditions(t *testing.T) {
name string name string
conditions []metav1.Condition conditions []metav1.Condition
validateErrs func(t *testing.T, errs field.ErrorList) validateErrs func(t *testing.T, errs field.ErrorList)
}{ }{{
{
name: "bunch-of-invalid-fields", name: "bunch-of-invalid-fields",
conditions: []metav1.Condition{{ conditions: []metav1.Condition{{
Type: ":invalid", Type: ":invalid",
@@ -358,27 +341,22 @@ func TestValidateConditions(t *testing.T) {
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs)) t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
} }
}, },
}, }, {
{
name: "duplicates", name: "duplicates",
conditions: []metav1.Condition{{ conditions: []metav1.Condition{{
Type: "First", Type: "First",
}, }, {
{
Type: "Second", Type: "Second",
}, }, {
{
Type: "First", Type: "First",
}, }},
},
validateErrs: func(t *testing.T, errs field.ErrorList) { validateErrs: func(t *testing.T, errs field.ErrorList) {
needle := `status.conditions[2].type: Duplicate value: "First"` needle := `status.conditions[2].type: Duplicate value: "First"`
if !hasError(errs, needle) { if !hasError(errs, needle) {
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs)) t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
} }
}, },
}, }, {
{
name: "colon-allowed-in-reason", name: "colon-allowed-in-reason",
conditions: []metav1.Condition{{ conditions: []metav1.Condition{{
Type: "First", Type: "First",
@@ -390,8 +368,7 @@ func TestValidateConditions(t *testing.T) {
t.Errorf("has %q in\n%v", needle, errorsAsString(errs)) t.Errorf("has %q in\n%v", needle, errorsAsString(errs))
} }
}, },
}, }, {
{
name: "comma-allowed-in-reason", name: "comma-allowed-in-reason",
conditions: []metav1.Condition{{ conditions: []metav1.Condition{{
Type: "First", Type: "First",
@@ -403,8 +380,7 @@ func TestValidateConditions(t *testing.T) {
t.Errorf("has %q in\n%v", needle, errorsAsString(errs)) t.Errorf("has %q in\n%v", needle, errorsAsString(errs))
} }
}, },
}, }, {
{
name: "reason-does-not-end-in-delimiter", name: "reason-does-not-end-in-delimiter",
conditions: []metav1.Condition{{ conditions: []metav1.Condition{{
Type: "First", Type: "First",
@@ -416,8 +392,7 @@ func TestValidateConditions(t *testing.T) {
t.Errorf("missing %q in\n%v", needle, errorsAsString(errs)) t.Errorf("missing %q in\n%v", needle, errorsAsString(errs))
} }
}, },
}, }}
}
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
@@ -433,31 +408,25 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
labelSelector *metav1.LabelSelector labelSelector *metav1.LabelSelector
wantErrorNumber int wantErrorNumber int
validateErrs func(t *testing.T, errs field.ErrorList) validateErrs func(t *testing.T, errs field.ErrorList)
}{ }{{
{
name: "Valid LabelSelector", name: "Valid LabelSelector",
labelSelector: &metav1.LabelSelector{ labelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{ MatchExpressions: []metav1.LabelSelectorRequirement{{
{
Key: "key", Key: "key",
Operator: metav1.LabelSelectorOpIn, Operator: metav1.LabelSelectorOpIn,
Values: []string{"value"}, Values: []string{"value"},
}, }},
},
}, },
wantErrorNumber: 0, wantErrorNumber: 0,
validateErrs: nil, validateErrs: nil,
}, }, {
{
name: "MatchExpression's key name isn't valid", name: "MatchExpression's key name isn't valid",
labelSelector: &metav1.LabelSelector{ labelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{ MatchExpressions: []metav1.LabelSelectorRequirement{{
{
Key: "-key", Key: "-key",
Operator: metav1.LabelSelectorOpIn, Operator: metav1.LabelSelectorOpIn,
Values: []string{"value"}, Values: []string{"value"},
}, }},
},
}, },
wantErrorNumber: 1, wantErrorNumber: 1,
validateErrs: func(t *testing.T, errs field.ErrorList) { validateErrs: func(t *testing.T, errs field.ErrorList) {
@@ -466,17 +435,14 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs)) t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
} }
}, },
}, }, {
{
name: "MatchExpression's operator isn't valid", name: "MatchExpression's operator isn't valid",
labelSelector: &metav1.LabelSelector{ labelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{ MatchExpressions: []metav1.LabelSelectorRequirement{{
{
Key: "key", Key: "key",
Operator: "abc", Operator: "abc",
Values: []string{"value"}, Values: []string{"value"},
}, }},
},
}, },
wantErrorNumber: 1, wantErrorNumber: 1,
validateErrs: func(t *testing.T, errs field.ErrorList) { validateErrs: func(t *testing.T, errs field.ErrorList) {
@@ -485,17 +451,14 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs)) t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
} }
}, },
}, }, {
{
name: "MatchExpression's value name isn't valid", name: "MatchExpression's value name isn't valid",
labelSelector: &metav1.LabelSelector{ labelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{ MatchExpressions: []metav1.LabelSelectorRequirement{{
{
Key: "key", Key: "key",
Operator: metav1.LabelSelectorOpIn, Operator: metav1.LabelSelectorOpIn,
Values: []string{"-value"}, Values: []string{"-value"},
}, }},
},
}, },
wantErrorNumber: 1, wantErrorNumber: 1,
validateErrs: func(t *testing.T, errs field.ErrorList) { validateErrs: func(t *testing.T, errs field.ErrorList) {
@@ -504,8 +467,7 @@ func TestLabelSelectorMatchExpression(t *testing.T) {
t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs)) t.Errorf("missing %q in\n%v", errMessage, errorsAsString(errs))
} }
}, },
}, }}
}
for index, testCase := range testCases { for index, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) { t.Run(testCase.name, func(t *testing.T) {
allErrs := ValidateLabelSelector(testCase.labelSelector, LabelSelectorValidationOptions{false}, field.NewPath("labelSelector")) allErrs := ValidateLabelSelector(testCase.labelSelector, LabelSelectorValidationOptions{false}, field.NewPath("labelSelector"))

View File

@@ -630,33 +630,27 @@ func TestIsFullyQualifiedName(t *testing.T) {
name string name string
targetName string targetName string
err string err string
}{ }{{
{
name: "name needs to be fully qualified, i.e., contains at least 2 dots", name: "name needs to be fully qualified, i.e., contains at least 2 dots",
targetName: "k8s.io", targetName: "k8s.io",
err: "should be a domain with at least three segments separated by dots", err: "should be a domain with at least three segments separated by dots",
}, }, {
{
name: "name should not include scheme", name: "name should not include scheme",
targetName: "http://foo.k8s.io", targetName: "http://foo.k8s.io",
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters", err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
}, }, {
{
name: "email should be invalid", name: "email should be invalid",
targetName: "example@foo.k8s.io", targetName: "example@foo.k8s.io",
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters", err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
}, }, {
{
name: "name cannot be empty", name: "name cannot be empty",
targetName: "", targetName: "",
err: "Required value", err: "Required value",
}, }, {
{
name: "name must conform to RFC 1123", name: "name must conform to RFC 1123",
targetName: "A.B.C", targetName: "A.B.C",
err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters", err: "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters",
}, }}
}
for _, tc := range messageTests { for _, tc := range messageTests {
err := IsFullyQualifiedName(field.NewPath(""), tc.targetName).ToAggregate() err := IsFullyQualifiedName(field.NewPath(""), tc.targetName).ToAggregate()
switch { switch {

View File

@@ -23,22 +23,16 @@ import (
) )
func TestValidateConfiguration(t *testing.T) { func TestValidateConfiguration(t *testing.T) {
successCases := []resourcequotaapi.Configuration{ successCases := []resourcequotaapi.Configuration{{
{ LimitedResources: []resourcequotaapi.LimitedResource{{
LimitedResources: []resourcequotaapi.LimitedResource{
{
Resource: "pods", Resource: "pods",
MatchContains: []string{"requests.cpu"}, MatchContains: []string{"requests.cpu"},
}, }},
}, }, {
}, LimitedResources: []resourcequotaapi.LimitedResource{{
{
LimitedResources: []resourcequotaapi.LimitedResource{
{
Resource: "persistentvolumeclaims", Resource: "persistentvolumeclaims",
MatchContains: []string{"requests.storage"}, MatchContains: []string{"requests.storage"},
}, }},
},
}, },
} }
for i := range successCases { for i := range successCases {

View File

@@ -134,11 +134,9 @@ func TestValidatePolicy(t *testing.T) {
policy := audit.Policy{OmitStages: []audit.Stage{ policy := audit.Policy{OmitStages: []audit.Stage{
audit.Stage("foo"), audit.Stage("foo"),
}, },
Rules: []audit.PolicyRule{ Rules: []audit.PolicyRule{{
{
Level: audit.LevelMetadata, Level: audit.LevelMetadata,
}, }},
},
} }
errorCases = append(errorCases, policy) errorCases = append(errorCases, policy)

View File

@@ -748,37 +748,31 @@ func TestErrConfigurationInvalidWithErrorsIs(t *testing.T) {
err error err error
matchAgainst error matchAgainst error
expectMatch bool expectMatch bool
}{ }{{
{
name: "no match", name: "no match",
err: errConfigurationInvalid{errors.New("my-error"), errors.New("my-other-error")}, err: errConfigurationInvalid{errors.New("my-error"), errors.New("my-other-error")},
matchAgainst: fmt.Errorf("no entry %s", "here"), matchAgainst: fmt.Errorf("no entry %s", "here"),
}, }, {
{
name: "match via .Is()", name: "match via .Is()",
err: errConfigurationInvalid{errors.New("forbidden"), alwaysMatchingError{}}, err: errConfigurationInvalid{errors.New("forbidden"), alwaysMatchingError{}},
matchAgainst: errors.New("unauthorized"), matchAgainst: errors.New("unauthorized"),
expectMatch: true, expectMatch: true,
}, }, {
{
name: "match via equality", name: "match via equality",
err: errConfigurationInvalid{errors.New("err"), someError{}}, err: errConfigurationInvalid{errors.New("err"), someError{}},
matchAgainst: someError{}, matchAgainst: someError{},
expectMatch: true, expectMatch: true,
}, }, {
{
name: "match via nested aggregate", name: "match via nested aggregate",
err: errConfigurationInvalid{errors.New("closed today"), errConfigurationInvalid{errConfigurationInvalid{someError{}}}}, err: errConfigurationInvalid{errors.New("closed today"), errConfigurationInvalid{errConfigurationInvalid{someError{}}}},
matchAgainst: someError{}, matchAgainst: someError{},
expectMatch: true, expectMatch: true,
}, }, {
{
name: "match via wrapped aggregate", name: "match via wrapped aggregate",
err: fmt.Errorf("wrap: %w", errConfigurationInvalid{errors.New("err"), someError{}}), err: fmt.Errorf("wrap: %w", errConfigurationInvalid{errors.New("err"), someError{}}),
matchAgainst: someError{}, matchAgainst: someError{},
expectMatch: true, expectMatch: true,
}, }}
}
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {