mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			543 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			543 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2014 The Kubernetes Authors All rights reserved.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package validation
 | 
						|
 | 
						|
import (
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"k8s.io/kubernetes/pkg/api"
 | 
						|
	"k8s.io/kubernetes/pkg/api/resource"
 | 
						|
	"k8s.io/kubernetes/pkg/expapi"
 | 
						|
	errors "k8s.io/kubernetes/pkg/util/fielderrors"
 | 
						|
)
 | 
						|
 | 
						|
func TestValidateHorizontalPodAutoscaler(t *testing.T) {
 | 
						|
	successCases := []expapi.HorizontalPodAutoscaler{
 | 
						|
		{
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleRef: &expapi.SubresourceReference{
 | 
						|
					Subresource: "scale",
 | 
						|
				},
 | 
						|
				MinCount: 1,
 | 
						|
				MaxCount: 5,
 | 
						|
				Target:   expapi.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, successCase := range successCases {
 | 
						|
		if errs := ValidateHorizontalPodAutoscaler(&successCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	errorCases := map[string]expapi.HorizontalPodAutoscaler{
 | 
						|
		"must be non-negative": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleRef: &expapi.SubresourceReference{
 | 
						|
					Subresource: "scale",
 | 
						|
				},
 | 
						|
				MinCount: -1,
 | 
						|
				MaxCount: 5,
 | 
						|
				Target:   expapi.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"must be bigger or equal to minCount": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleRef: &expapi.SubresourceReference{
 | 
						|
					Subresource: "scale",
 | 
						|
				},
 | 
						|
				MinCount: 7,
 | 
						|
				MaxCount: 5,
 | 
						|
				Target:   expapi.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid value": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleRef: &expapi.SubresourceReference{
 | 
						|
					Subresource: "scale",
 | 
						|
				},
 | 
						|
				MinCount: 1,
 | 
						|
				MaxCount: 5,
 | 
						|
				Target:   expapi.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("-0.8")},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"resource not supported": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.HorizontalPodAutoscalerSpec{
 | 
						|
				ScaleRef: &expapi.SubresourceReference{
 | 
						|
					Subresource: "scale",
 | 
						|
				},
 | 
						|
				MinCount: 1,
 | 
						|
				MaxCount: 5,
 | 
						|
				Target:   expapi.ResourceConsumption{Resource: api.ResourceName("NotSupportedResource"), Quantity: resource.MustParse("0.8")},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"required value": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "myautoscaler",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.HorizontalPodAutoscalerSpec{
 | 
						|
				MinCount: 1,
 | 
						|
				MaxCount: 5,
 | 
						|
				Target:   expapi.ResourceConsumption{Resource: api.ResourceCPU, Quantity: resource.MustParse("0.8")},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for k, v := range errorCases {
 | 
						|
		errs := ValidateHorizontalPodAutoscaler(&v)
 | 
						|
		if len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure for %s", k)
 | 
						|
		} else if !strings.Contains(errs[0].Error(), k) {
 | 
						|
			t.Errorf("unexpected error: %v, expected: %s", errs[0], k)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateDaemonUpdate(t *testing.T) {
 | 
						|
	validSelector := map[string]string{"a": "b"}
 | 
						|
	validSelector2 := map[string]string{"c": "d"}
 | 
						|
	invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
 | 
						|
 | 
						|
	validPodSpecAbc := api.PodSpec{
 | 
						|
		RestartPolicy: api.RestartPolicyAlways,
 | 
						|
		DNSPolicy:     api.DNSClusterFirst,
 | 
						|
		Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
 | 
						|
	}
 | 
						|
	validPodSpecDef := api.PodSpec{
 | 
						|
		RestartPolicy: api.RestartPolicyAlways,
 | 
						|
		DNSPolicy:     api.DNSClusterFirst,
 | 
						|
		Containers:    []api.Container{{Name: "def", Image: "image", ImagePullPolicy: "IfNotPresent"}},
 | 
						|
	}
 | 
						|
	validPodSpecNodeSelector := api.PodSpec{
 | 
						|
		NodeSelector:  validSelector,
 | 
						|
		NodeName:      "xyz",
 | 
						|
		RestartPolicy: api.RestartPolicyAlways,
 | 
						|
		DNSPolicy:     api.DNSClusterFirst,
 | 
						|
		Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
 | 
						|
	}
 | 
						|
	validPodSpecVolume := api.PodSpec{
 | 
						|
		Volumes:       []api.Volume{{Name: "gcepd", VolumeSource: api.VolumeSource{GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{PDName: "my-PD", FSType: "ext4", Partition: 1, ReadOnly: false}}}},
 | 
						|
		RestartPolicy: api.RestartPolicyAlways,
 | 
						|
		DNSPolicy:     api.DNSClusterFirst,
 | 
						|
		Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
 | 
						|
	}
 | 
						|
 | 
						|
	validPodTemplateAbc := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: validSelector,
 | 
						|
			},
 | 
						|
			Spec: validPodSpecAbc,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	validPodTemplateNodeSelector := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: validSelector,
 | 
						|
			},
 | 
						|
			Spec: validPodSpecNodeSelector,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	validPodTemplateAbc2 := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: validSelector2,
 | 
						|
			},
 | 
						|
			Spec: validPodSpecAbc,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	validPodTemplateDef := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: validSelector2,
 | 
						|
			},
 | 
						|
			Spec: validPodSpecDef,
 | 
						|
		},
 | 
						|
	}
 | 
						|
	invalidPodTemplate := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			Spec: api.PodSpec{
 | 
						|
				RestartPolicy: api.RestartPolicyAlways,
 | 
						|
				DNSPolicy:     api.DNSClusterFirst,
 | 
						|
			},
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: invalidSelector,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	readWriteVolumePodTemplate := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: validSelector,
 | 
						|
			},
 | 
						|
			Spec: validPodSpecVolume,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	type dcUpdateTest struct {
 | 
						|
		old    expapi.Daemon
 | 
						|
		update expapi.Daemon
 | 
						|
	}
 | 
						|
	successCases := []dcUpdateTest{
 | 
						|
		{
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector2,
 | 
						|
					Template: &validPodTemplateAbc2.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateNodeSelector.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, successCase := range successCases {
 | 
						|
		successCase.old.ObjectMeta.ResourceVersion = "1"
 | 
						|
		successCase.update.ObjectMeta.ResourceVersion = "1"
 | 
						|
		if errs := ValidateDaemonUpdate(&successCase.old, &successCase.update); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	errorCases := map[string]dcUpdateTest{
 | 
						|
		"change daemon name": {
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid selector": {
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: invalidSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid pod": {
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &invalidPodTemplate.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"change container image": {
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateDef.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"read-write volume": {
 | 
						|
			old: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &validPodTemplateAbc.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			update: expapi.Daemon{
 | 
						|
				ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
				Spec: expapi.DaemonSpec{
 | 
						|
					Selector: validSelector,
 | 
						|
					Template: &readWriteVolumePodTemplate.Template,
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for testName, errorCase := range errorCases {
 | 
						|
		if errs := ValidateDaemonUpdate(&errorCase.old, &errorCase.update); len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure: %s", testName)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestValidateDaemon(t *testing.T) {
 | 
						|
	validSelector := map[string]string{"a": "b"}
 | 
						|
	validPodTemplate := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: validSelector,
 | 
						|
			},
 | 
						|
			Spec: api.PodSpec{
 | 
						|
				RestartPolicy: api.RestartPolicyAlways,
 | 
						|
				DNSPolicy:     api.DNSClusterFirst,
 | 
						|
				Containers:    []api.Container{{Name: "abc", Image: "image", ImagePullPolicy: "IfNotPresent"}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	invalidSelector := map[string]string{"NoUppercaseOrSpecialCharsLike=Equals": "b"}
 | 
						|
	invalidPodTemplate := api.PodTemplate{
 | 
						|
		Template: api.PodTemplateSpec{
 | 
						|
			Spec: api.PodSpec{
 | 
						|
				RestartPolicy: api.RestartPolicyAlways,
 | 
						|
				DNSPolicy:     api.DNSClusterFirst,
 | 
						|
			},
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Labels: invalidSelector,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	successCases := []expapi.Daemon{
 | 
						|
		{
 | 
						|
			ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			ObjectMeta: api.ObjectMeta{Name: "abc-123", Namespace: api.NamespaceDefault},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for _, successCase := range successCases {
 | 
						|
		if errs := ValidateDaemon(&successCase); len(errs) != 0 {
 | 
						|
			t.Errorf("expected success: %v", errs)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	errorCases := map[string]expapi.Daemon{
 | 
						|
		"zero-length ID": {
 | 
						|
			ObjectMeta: api.ObjectMeta{Name: "", Namespace: api.NamespaceDefault},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"missing-namespace": {
 | 
						|
			ObjectMeta: api.ObjectMeta{Name: "abc-123"},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"empty selector": {
 | 
						|
			ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"selector_doesnt_match": {
 | 
						|
			ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: map[string]string{"foo": "bar"},
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid manifest": {
 | 
						|
			ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: api.NamespaceDefault},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid_label": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "abc-123",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
				Labels: map[string]string{
 | 
						|
					"NoUppercaseOrSpecialCharsLike=Equals": "bar",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid_label 2": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "abc-123",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
				Labels: map[string]string{
 | 
						|
					"NoUppercaseOrSpecialCharsLike=Equals": "bar",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Template: &invalidPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid_annotation": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "abc-123",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
				Annotations: map[string]string{
 | 
						|
					"NoUppercaseOrSpecialCharsLike=Equals": "bar",
 | 
						|
				},
 | 
						|
			},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &validPodTemplate.Template,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid restart policy 1": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "abc-123",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &api.PodTemplateSpec{
 | 
						|
					Spec: api.PodSpec{
 | 
						|
						RestartPolicy: api.RestartPolicyOnFailure,
 | 
						|
						DNSPolicy:     api.DNSClusterFirst,
 | 
						|
						Containers:    []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
 | 
						|
					},
 | 
						|
					ObjectMeta: api.ObjectMeta{
 | 
						|
						Labels: validSelector,
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalid restart policy 2": {
 | 
						|
			ObjectMeta: api.ObjectMeta{
 | 
						|
				Name:      "abc-123",
 | 
						|
				Namespace: api.NamespaceDefault,
 | 
						|
			},
 | 
						|
			Spec: expapi.DaemonSpec{
 | 
						|
				Selector: validSelector,
 | 
						|
				Template: &api.PodTemplateSpec{
 | 
						|
					Spec: api.PodSpec{
 | 
						|
						RestartPolicy: api.RestartPolicyNever,
 | 
						|
						DNSPolicy:     api.DNSClusterFirst,
 | 
						|
						Containers:    []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
 | 
						|
					},
 | 
						|
					ObjectMeta: api.ObjectMeta{
 | 
						|
						Labels: validSelector,
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	for k, v := range errorCases {
 | 
						|
		errs := ValidateDaemon(&v)
 | 
						|
		if len(errs) == 0 {
 | 
						|
			t.Errorf("expected failure for %s", k)
 | 
						|
		}
 | 
						|
		for i := range errs {
 | 
						|
			field := errs[i].(*errors.ValidationError).Field
 | 
						|
			if !strings.HasPrefix(field, "spec.template.") &&
 | 
						|
				field != "metadata.name" &&
 | 
						|
				field != "metadata.namespace" &&
 | 
						|
				field != "spec.selector" &&
 | 
						|
				field != "spec.template" &&
 | 
						|
				field != "GCEPersistentDisk.ReadOnly" &&
 | 
						|
				field != "spec.template.labels" &&
 | 
						|
				field != "metadata.annotations" &&
 | 
						|
				field != "metadata.labels" {
 | 
						|
				t.Errorf("%s: missing prefix for: %v", k, errs[i])
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |