Make validation work when not in the api package.
This commit is contained in:
19
pkg/api/validation/doc.go
Normal file
19
pkg/api/validation/doc.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 Google Inc. 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 has functions for validating the correctness of api
|
||||||
|
// objects and explaining what is wrong with them when they aren't valid.
|
||||||
|
package validation
|
@@ -19,12 +19,13 @@ package validation
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
errs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
errs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateVolumes(volumes []Volume) (util.StringSet, errs.ErrorList) {
|
func validateVolumes(volumes []api.Volume) (util.StringSet, errs.ErrorList) {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
|
|
||||||
allNames := util.StringSet{}
|
allNames := util.StringSet{}
|
||||||
@@ -51,7 +52,7 @@ func validateVolumes(volumes []Volume) (util.StringSet, errs.ErrorList) {
|
|||||||
return allNames, allErrs
|
return allNames, allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateSource(source *VolumeSource) errs.ErrorList {
|
func validateSource(source *api.VolumeSource) errs.ErrorList {
|
||||||
numVolumes := 0
|
numVolumes := 0
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
if source.HostDirectory != nil {
|
if source.HostDirectory != nil {
|
||||||
@@ -68,7 +69,7 @@ func validateSource(source *VolumeSource) errs.ErrorList {
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateHostDir(hostDir *HostDirectory) errs.ErrorList {
|
func validateHostDir(hostDir *api.HostDirectory) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
if hostDir.Path == "" {
|
if hostDir.Path == "" {
|
||||||
allErrs = append(allErrs, errs.NewNotFound("path", hostDir.Path))
|
allErrs = append(allErrs, errs.NewNotFound("path", hostDir.Path))
|
||||||
@@ -78,7 +79,7 @@ func validateHostDir(hostDir *HostDirectory) errs.ErrorList {
|
|||||||
|
|
||||||
var supportedPortProtocols = util.NewStringSet("TCP", "UDP")
|
var supportedPortProtocols = util.NewStringSet("TCP", "UDP")
|
||||||
|
|
||||||
func validatePorts(ports []Port) errs.ErrorList {
|
func validatePorts(ports []api.Port) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
|
|
||||||
allNames := util.StringSet{}
|
allNames := util.StringSet{}
|
||||||
@@ -112,7 +113,7 @@ func validatePorts(ports []Port) errs.ErrorList {
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateEnv(vars []EnvVar) errs.ErrorList {
|
func validateEnv(vars []api.EnvVar) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
|
|
||||||
for i := range vars {
|
for i := range vars {
|
||||||
@@ -129,7 +130,7 @@ func validateEnv(vars []EnvVar) errs.ErrorList {
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateVolumeMounts(mounts []VolumeMount, volumes util.StringSet) errs.ErrorList {
|
func validateVolumeMounts(mounts []api.VolumeMount, volumes util.StringSet) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
|
|
||||||
for i := range mounts {
|
for i := range mounts {
|
||||||
@@ -150,7 +151,7 @@ func validateVolumeMounts(mounts []VolumeMount, volumes util.StringSet) errs.Err
|
|||||||
|
|
||||||
// AccumulateUniquePorts runs an extraction function on each Port of each Container,
|
// AccumulateUniquePorts runs an extraction function on each Port of each Container,
|
||||||
// accumulating the results and returning an error if any ports conflict.
|
// accumulating the results and returning an error if any ports conflict.
|
||||||
func AccumulateUniquePorts(containers []Container, accumulator map[int]bool, extract func(*Port) int) errs.ErrorList {
|
func AccumulateUniquePorts(containers []api.Container, accumulator map[int]bool, extract func(*api.Port) int) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
|
|
||||||
for ci := range containers {
|
for ci := range containers {
|
||||||
@@ -174,12 +175,12 @@ func AccumulateUniquePorts(containers []Container, accumulator map[int]bool, ext
|
|||||||
|
|
||||||
// checkHostPortConflicts checks for colliding Port.HostPort values across
|
// checkHostPortConflicts checks for colliding Port.HostPort values across
|
||||||
// a slice of containers.
|
// a slice of containers.
|
||||||
func checkHostPortConflicts(containers []Container) errs.ErrorList {
|
func checkHostPortConflicts(containers []api.Container) errs.ErrorList {
|
||||||
allPorts := map[int]bool{}
|
allPorts := map[int]bool{}
|
||||||
return AccumulateUniquePorts(containers, allPorts, func(p *Port) int { return p.HostPort })
|
return AccumulateUniquePorts(containers, allPorts, func(p *api.Port) int { return p.HostPort })
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateContainers(containers []Container, volumes util.StringSet) errs.ErrorList {
|
func validateContainers(containers []api.Container, volumes util.StringSet) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
|
|
||||||
allNames := util.StringSet{}
|
allNames := util.StringSet{}
|
||||||
@@ -219,7 +220,7 @@ var supportedManifestVersions = util.NewStringSet("v1beta1", "v1beta2")
|
|||||||
// This includes checking formatting and uniqueness. It also canonicalizes the
|
// This includes checking formatting and uniqueness. It also canonicalizes the
|
||||||
// structure by setting default values and implementing any backwards-compatibility
|
// structure by setting default values and implementing any backwards-compatibility
|
||||||
// tricks.
|
// tricks.
|
||||||
func ValidateManifest(manifest *ContainerManifest) errs.ErrorList {
|
func ValidateManifest(manifest *api.ContainerManifest) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
|
|
||||||
if len(manifest.Version) == 0 {
|
if len(manifest.Version) == 0 {
|
||||||
@@ -233,13 +234,13 @@ func ValidateManifest(manifest *ContainerManifest) errs.ErrorList {
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidatePodState(podState *PodState) errs.ErrorList {
|
func ValidatePodState(podState *api.PodState) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList(ValidateManifest(&podState.Manifest)).Prefix("manifest")
|
allErrs := errs.ErrorList(ValidateManifest(&podState.Manifest)).Prefix("manifest")
|
||||||
if podState.RestartPolicy.Type == "" {
|
if podState.RestartPolicy.Type == "" {
|
||||||
podState.RestartPolicy.Type = RestartAlways
|
podState.RestartPolicy.Type = api.RestartAlways
|
||||||
} else if podState.RestartPolicy.Type != RestartAlways &&
|
} else if podState.RestartPolicy.Type != api.RestartAlways &&
|
||||||
podState.RestartPolicy.Type != RestartOnFailure &&
|
podState.RestartPolicy.Type != api.RestartOnFailure &&
|
||||||
podState.RestartPolicy.Type != RestartNever {
|
podState.RestartPolicy.Type != api.RestartNever {
|
||||||
allErrs = append(allErrs, errs.NewNotSupported("restartPolicy.type", podState.RestartPolicy.Type))
|
allErrs = append(allErrs, errs.NewNotSupported("restartPolicy.type", podState.RestartPolicy.Type))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +248,7 @@ func ValidatePodState(podState *PodState) errs.ErrorList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidatePod tests if required fields in the pod are set.
|
// ValidatePod tests if required fields in the pod are set.
|
||||||
func ValidatePod(pod *Pod) errs.ErrorList {
|
func ValidatePod(pod *api.Pod) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
if len(pod.ID) == 0 {
|
if len(pod.ID) == 0 {
|
||||||
allErrs = append(allErrs, errs.NewRequired("id", pod.ID))
|
allErrs = append(allErrs, errs.NewRequired("id", pod.ID))
|
||||||
@@ -257,7 +258,7 @@ func ValidatePod(pod *Pod) errs.ErrorList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateService tests if required fields in the service are set.
|
// ValidateService tests if required fields in the service are set.
|
||||||
func ValidateService(service *Service) errs.ErrorList {
|
func ValidateService(service *api.Service) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
if len(service.ID) == 0 {
|
if len(service.ID) == 0 {
|
||||||
allErrs = append(allErrs, errs.NewRequired("id", service.ID))
|
allErrs = append(allErrs, errs.NewRequired("id", service.ID))
|
||||||
@@ -274,7 +275,7 @@ func ValidateService(service *Service) errs.ErrorList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateReplicationController tests if required fields in the replication controller are set.
|
// ValidateReplicationController tests if required fields in the replication controller are set.
|
||||||
func ValidateReplicationController(controller *ReplicationController) errs.ErrorList {
|
func ValidateReplicationController(controller *api.ReplicationController) errs.ErrorList {
|
||||||
allErrs := errs.ErrorList{}
|
allErrs := errs.ErrorList{}
|
||||||
if len(controller.ID) == 0 {
|
if len(controller.ID) == 0 {
|
||||||
allErrs = append(allErrs, errs.NewRequired("id", controller.ID))
|
allErrs = append(allErrs, errs.NewRequired("id", controller.ID))
|
||||||
|
@@ -20,6 +20,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
@@ -33,11 +34,11 @@ func expectPrefix(t *testing.T, prefix string, errs errors.ErrorList) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateVolumes(t *testing.T) {
|
func TestValidateVolumes(t *testing.T) {
|
||||||
successCase := []Volume{
|
successCase := []api.Volume{
|
||||||
{Name: "abc"},
|
{Name: "abc"},
|
||||||
{Name: "123", Source: &VolumeSource{HostDirectory: &HostDirectory{"/mnt/path2"}}},
|
{Name: "123", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/path2"}}},
|
||||||
{Name: "abc-123", Source: &VolumeSource{HostDirectory: &HostDirectory{"/mnt/path3"}}},
|
{Name: "abc-123", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/path3"}}},
|
||||||
{Name: "empty", Source: &VolumeSource{EmptyDirectory: &EmptyDirectory{}}},
|
{Name: "empty", Source: &api.VolumeSource{EmptyDirectory: &api.EmptyDirectory{}}},
|
||||||
}
|
}
|
||||||
names, errs := validateVolumes(successCase)
|
names, errs := validateVolumes(successCase)
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
@@ -48,14 +49,14 @@ func TestValidateVolumes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorCases := map[string]struct {
|
errorCases := map[string]struct {
|
||||||
V []Volume
|
V []api.Volume
|
||||||
T errors.ValidationErrorType
|
T errors.ValidationErrorType
|
||||||
F string
|
F string
|
||||||
}{
|
}{
|
||||||
"zero-length name": {[]Volume{{Name: ""}}, errors.ValidationErrorTypeRequired, "[0].name"},
|
"zero-length name": {[]api.Volume{{Name: ""}}, errors.ValidationErrorTypeRequired, "[0].name"},
|
||||||
"name > 63 characters": {[]Volume{{Name: strings.Repeat("a", 64)}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
"name > 63 characters": {[]api.Volume{{Name: strings.Repeat("a", 64)}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
||||||
"name not a DNS label": {[]Volume{{Name: "a.b.c"}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
"name not a DNS label": {[]api.Volume{{Name: "a.b.c"}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
||||||
"name not unique": {[]Volume{{Name: "abc"}, {Name: "abc"}}, errors.ValidationErrorTypeDuplicate, "[1].name"},
|
"name not unique": {[]api.Volume{{Name: "abc"}, {Name: "abc"}}, errors.ValidationErrorTypeDuplicate, "[1].name"},
|
||||||
}
|
}
|
||||||
for k, v := range errorCases {
|
for k, v := range errorCases {
|
||||||
_, errs := validateVolumes(v.V)
|
_, errs := validateVolumes(v.V)
|
||||||
@@ -75,7 +76,7 @@ func TestValidateVolumes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidatePorts(t *testing.T) {
|
func TestValidatePorts(t *testing.T) {
|
||||||
successCase := []Port{
|
successCase := []api.Port{
|
||||||
{Name: "abc", ContainerPort: 80, HostPort: 80, Protocol: "TCP"},
|
{Name: "abc", ContainerPort: 80, HostPort: 80, Protocol: "TCP"},
|
||||||
{Name: "123", ContainerPort: 81, HostPort: 81},
|
{Name: "123", ContainerPort: 81, HostPort: 81},
|
||||||
{Name: "easy", ContainerPort: 82, Protocol: "TCP"},
|
{Name: "easy", ContainerPort: 82, Protocol: "TCP"},
|
||||||
@@ -88,7 +89,7 @@ func TestValidatePorts(t *testing.T) {
|
|||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
nonCanonicalCase := []Port{
|
nonCanonicalCase := []api.Port{
|
||||||
{ContainerPort: 80},
|
{ContainerPort: 80},
|
||||||
}
|
}
|
||||||
if errs := validatePorts(nonCanonicalCase); len(errs) != 0 {
|
if errs := validatePorts(nonCanonicalCase); len(errs) != 0 {
|
||||||
@@ -99,20 +100,20 @@ func TestValidatePorts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorCases := map[string]struct {
|
errorCases := map[string]struct {
|
||||||
P []Port
|
P []api.Port
|
||||||
T errors.ValidationErrorType
|
T errors.ValidationErrorType
|
||||||
F string
|
F string
|
||||||
}{
|
}{
|
||||||
"name > 63 characters": {[]Port{{Name: strings.Repeat("a", 64), ContainerPort: 80}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
"name > 63 characters": {[]api.Port{{Name: strings.Repeat("a", 64), ContainerPort: 80}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
||||||
"name not a DNS label": {[]Port{{Name: "a.b.c", ContainerPort: 80}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
"name not a DNS label": {[]api.Port{{Name: "a.b.c", ContainerPort: 80}}, errors.ValidationErrorTypeInvalid, "[0].name"},
|
||||||
"name not unique": {[]Port{
|
"name not unique": {[]api.Port{
|
||||||
{Name: "abc", ContainerPort: 80},
|
{Name: "abc", ContainerPort: 80},
|
||||||
{Name: "abc", ContainerPort: 81},
|
{Name: "abc", ContainerPort: 81},
|
||||||
}, errors.ValidationErrorTypeDuplicate, "[1].name"},
|
}, errors.ValidationErrorTypeDuplicate, "[1].name"},
|
||||||
"zero container port": {[]Port{{ContainerPort: 0}}, errors.ValidationErrorTypeRequired, "[0].containerPort"},
|
"zero container port": {[]api.Port{{ContainerPort: 0}}, errors.ValidationErrorTypeRequired, "[0].containerPort"},
|
||||||
"invalid container port": {[]Port{{ContainerPort: 65536}}, errors.ValidationErrorTypeInvalid, "[0].containerPort"},
|
"invalid container port": {[]api.Port{{ContainerPort: 65536}}, errors.ValidationErrorTypeInvalid, "[0].containerPort"},
|
||||||
"invalid host port": {[]Port{{ContainerPort: 80, HostPort: 65536}}, errors.ValidationErrorTypeInvalid, "[0].hostPort"},
|
"invalid host port": {[]api.Port{{ContainerPort: 80, HostPort: 65536}}, errors.ValidationErrorTypeInvalid, "[0].hostPort"},
|
||||||
"invalid protocol": {[]Port{{ContainerPort: 80, Protocol: "ICMP"}}, errors.ValidationErrorTypeNotSupported, "[0].protocol"},
|
"invalid protocol": {[]api.Port{{ContainerPort: 80, Protocol: "ICMP"}}, errors.ValidationErrorTypeNotSupported, "[0].protocol"},
|
||||||
}
|
}
|
||||||
for k, v := range errorCases {
|
for k, v := range errorCases {
|
||||||
errs := validatePorts(v.P)
|
errs := validatePorts(v.P)
|
||||||
@@ -131,7 +132,7 @@ func TestValidatePorts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateEnv(t *testing.T) {
|
func TestValidateEnv(t *testing.T) {
|
||||||
successCase := []EnvVar{
|
successCase := []api.EnvVar{
|
||||||
{Name: "abc", Value: "value"},
|
{Name: "abc", Value: "value"},
|
||||||
{Name: "ABC", Value: "value"},
|
{Name: "ABC", Value: "value"},
|
||||||
{Name: "AbC_123", Value: "value"},
|
{Name: "AbC_123", Value: "value"},
|
||||||
@@ -141,7 +142,7 @@ func TestValidateEnv(t *testing.T) {
|
|||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCases := map[string][]EnvVar{
|
errorCases := map[string][]api.EnvVar{
|
||||||
"zero-length name": {{Name: ""}},
|
"zero-length name": {{Name: ""}},
|
||||||
"name not a C identifier": {{Name: "a.b.c"}},
|
"name not a C identifier": {{Name: "a.b.c"}},
|
||||||
}
|
}
|
||||||
@@ -155,7 +156,7 @@ func TestValidateEnv(t *testing.T) {
|
|||||||
func TestValidateVolumeMounts(t *testing.T) {
|
func TestValidateVolumeMounts(t *testing.T) {
|
||||||
volumes := util.NewStringSet("abc", "123", "abc-123")
|
volumes := util.NewStringSet("abc", "123", "abc-123")
|
||||||
|
|
||||||
successCase := []VolumeMount{
|
successCase := []api.VolumeMount{
|
||||||
{Name: "abc", MountPath: "/foo"},
|
{Name: "abc", MountPath: "/foo"},
|
||||||
{Name: "123", MountPath: "/foo"},
|
{Name: "123", MountPath: "/foo"},
|
||||||
{Name: "abc-123", MountPath: "/bar"},
|
{Name: "abc-123", MountPath: "/bar"},
|
||||||
@@ -164,7 +165,7 @@ func TestValidateVolumeMounts(t *testing.T) {
|
|||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCases := map[string][]VolumeMount{
|
errorCases := map[string][]api.VolumeMount{
|
||||||
"empty name": {{Name: "", MountPath: "/foo"}},
|
"empty name": {{Name: "", MountPath: "/foo"}},
|
||||||
"name not found": {{Name: "", MountPath: "/foo"}},
|
"name not found": {{Name: "", MountPath: "/foo"}},
|
||||||
"empty mountpath": {{Name: "abc", MountPath: ""}},
|
"empty mountpath": {{Name: "abc", MountPath: ""}},
|
||||||
@@ -179,7 +180,7 @@ func TestValidateVolumeMounts(t *testing.T) {
|
|||||||
func TestValidateContainers(t *testing.T) {
|
func TestValidateContainers(t *testing.T) {
|
||||||
volumes := util.StringSet{}
|
volumes := util.StringSet{}
|
||||||
|
|
||||||
successCase := []Container{
|
successCase := []api.Container{
|
||||||
{Name: "abc", Image: "image"},
|
{Name: "abc", Image: "image"},
|
||||||
{Name: "123", Image: "image"},
|
{Name: "123", Image: "image"},
|
||||||
{Name: "abc-123", Image: "image"},
|
{Name: "abc-123", Image: "image"},
|
||||||
@@ -188,7 +189,7 @@ func TestValidateContainers(t *testing.T) {
|
|||||||
t.Errorf("expected success: %v", errs)
|
t.Errorf("expected success: %v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCases := map[string][]Container{
|
errorCases := map[string][]api.Container{
|
||||||
"zero-length name": {{Name: "", Image: "image"}},
|
"zero-length name": {{Name: "", Image: "image"}},
|
||||||
"name > 63 characters": {{Name: strings.Repeat("a", 64), Image: "image"}},
|
"name > 63 characters": {{Name: strings.Repeat("a", 64), Image: "image"}},
|
||||||
"name not a DNS label": {{Name: "a.b.c", Image: "image"}},
|
"name not a DNS label": {{Name: "a.b.c", Image: "image"}},
|
||||||
@@ -198,14 +199,14 @@ func TestValidateContainers(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"zero-length image": {{Name: "abc", Image: ""}},
|
"zero-length image": {{Name: "abc", Image: ""}},
|
||||||
"host port not unique": {
|
"host port not unique": {
|
||||||
{Name: "abc", Image: "image", Ports: []Port{{ContainerPort: 80, HostPort: 80}}},
|
{Name: "abc", Image: "image", Ports: []api.Port{{ContainerPort: 80, HostPort: 80}}},
|
||||||
{Name: "def", Image: "image", Ports: []Port{{ContainerPort: 81, HostPort: 80}}},
|
{Name: "def", Image: "image", Ports: []api.Port{{ContainerPort: 81, HostPort: 80}}},
|
||||||
},
|
},
|
||||||
"invalid env var name": {
|
"invalid env var name": {
|
||||||
{Name: "abc", Image: "image", Env: []EnvVar{{Name: "ev.1"}}},
|
{Name: "abc", Image: "image", Env: []api.EnvVar{{Name: "ev.1"}}},
|
||||||
},
|
},
|
||||||
"unknown volume name": {
|
"unknown volume name": {
|
||||||
{Name: "abc", Image: "image", VolumeMounts: []VolumeMount{{Name: "anything", MountPath: "/foo"}}},
|
{Name: "abc", Image: "image", VolumeMounts: []api.VolumeMount{{Name: "anything", MountPath: "/foo"}}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for k, v := range errorCases {
|
for k, v := range errorCases {
|
||||||
@@ -216,16 +217,16 @@ func TestValidateContainers(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateManifest(t *testing.T) {
|
func TestValidateManifest(t *testing.T) {
|
||||||
successCases := []ContainerManifest{
|
successCases := []api.ContainerManifest{
|
||||||
{Version: "v1beta1", ID: "abc"},
|
{Version: "v1beta1", ID: "abc"},
|
||||||
{Version: "v1beta2", ID: "123"},
|
{Version: "v1beta2", ID: "123"},
|
||||||
{Version: "V1BETA1", ID: "abc.123.do-re-mi"},
|
{Version: "V1BETA1", ID: "abc.123.do-re-mi"},
|
||||||
{
|
{
|
||||||
Version: "v1beta1",
|
Version: "v1beta1",
|
||||||
ID: "abc",
|
ID: "abc",
|
||||||
Volumes: []Volume{{Name: "vol1", Source: &VolumeSource{HostDirectory: &HostDirectory{"/mnt/vol1"}}},
|
Volumes: []api.Volume{{Name: "vol1", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/vol1"}}},
|
||||||
{Name: "vol2", Source: &VolumeSource{HostDirectory: &HostDirectory{"/mnt/vol2"}}}},
|
{Name: "vol2", Source: &api.VolumeSource{HostDirectory: &api.HostDirectory{"/mnt/vol2"}}}},
|
||||||
Containers: []Container{
|
Containers: []api.Container{
|
||||||
{
|
{
|
||||||
Name: "abc",
|
Name: "abc",
|
||||||
Image: "image",
|
Image: "image",
|
||||||
@@ -233,17 +234,17 @@ func TestValidateManifest(t *testing.T) {
|
|||||||
WorkingDir: "/tmp",
|
WorkingDir: "/tmp",
|
||||||
Memory: 1,
|
Memory: 1,
|
||||||
CPU: 1,
|
CPU: 1,
|
||||||
Ports: []Port{
|
Ports: []api.Port{
|
||||||
{Name: "p1", ContainerPort: 80, HostPort: 8080},
|
{Name: "p1", ContainerPort: 80, HostPort: 8080},
|
||||||
{Name: "p2", ContainerPort: 81},
|
{Name: "p2", ContainerPort: 81},
|
||||||
{ContainerPort: 82},
|
{ContainerPort: 82},
|
||||||
},
|
},
|
||||||
Env: []EnvVar{
|
Env: []api.EnvVar{
|
||||||
{Name: "ev1", Value: "val1"},
|
{Name: "ev1", Value: "val1"},
|
||||||
{Name: "ev2", Value: "val2"},
|
{Name: "ev2", Value: "val2"},
|
||||||
{Name: "EV3", Value: "val3"},
|
{Name: "EV3", Value: "val3"},
|
||||||
},
|
},
|
||||||
VolumeMounts: []VolumeMount{
|
VolumeMounts: []api.VolumeMount{
|
||||||
{Name: "vol1", MountPath: "/foo"},
|
{Name: "vol1", MountPath: "/foo"},
|
||||||
{Name: "vol1", MountPath: "/bar"},
|
{Name: "vol1", MountPath: "/bar"},
|
||||||
},
|
},
|
||||||
@@ -257,18 +258,18 @@ func TestValidateManifest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCases := map[string]ContainerManifest{
|
errorCases := map[string]api.ContainerManifest{
|
||||||
"empty version": {Version: "", ID: "abc"},
|
"empty version": {Version: "", ID: "abc"},
|
||||||
"invalid version": {Version: "bogus", ID: "abc"},
|
"invalid version": {Version: "bogus", ID: "abc"},
|
||||||
"invalid volume name": {
|
"invalid volume name": {
|
||||||
Version: "v1beta1",
|
Version: "v1beta1",
|
||||||
ID: "abc",
|
ID: "abc",
|
||||||
Volumes: []Volume{{Name: "vol.1"}},
|
Volumes: []api.Volume{{Name: "vol.1"}},
|
||||||
},
|
},
|
||||||
"invalid container name": {
|
"invalid container name": {
|
||||||
Version: "v1beta1",
|
Version: "v1beta1",
|
||||||
ID: "abc",
|
ID: "abc",
|
||||||
Containers: []Container{{Name: "ctr.1", Image: "image"}},
|
Containers: []api.Container{{Name: "ctr.1", Image: "image"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for k, v := range errorCases {
|
for k, v := range errorCases {
|
||||||
@@ -279,40 +280,40 @@ func TestValidateManifest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestValidatePod(t *testing.T) {
|
func TestValidatePod(t *testing.T) {
|
||||||
errs := ValidatePod(&Pod{
|
errs := ValidatePod(&api.Pod{
|
||||||
JSONBase: JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
DesiredState: PodState{
|
DesiredState: api.PodState{
|
||||||
Manifest: ContainerManifest{Version: "v1beta1", ID: "abc"},
|
Manifest: api.ContainerManifest{Version: "v1beta1", ID: "abc"},
|
||||||
RestartPolicy: RestartPolicy{Type: "RestartAlways"},
|
RestartPolicy: api.RestartPolicy{Type: "RestartAlways"},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
t.Errorf("Unexpected non-zero error list: %#v", errs)
|
t.Errorf("Unexpected non-zero error list: %#v", errs)
|
||||||
}
|
}
|
||||||
errs = ValidatePod(&Pod{
|
errs = ValidatePod(&api.Pod{
|
||||||
JSONBase: JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
DesiredState: PodState{
|
DesiredState: api.PodState{
|
||||||
Manifest: ContainerManifest{Version: "v1beta1", ID: "abc"},
|
Manifest: api.ContainerManifest{Version: "v1beta1", ID: "abc"},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if len(errs) != 0 {
|
if len(errs) != 0 {
|
||||||
t.Errorf("Unexpected non-zero error list: %#v", errs)
|
t.Errorf("Unexpected non-zero error list: %#v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errs = ValidatePod(&Pod{
|
errs = ValidatePod(&api.Pod{
|
||||||
JSONBase: JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
DesiredState: PodState{
|
DesiredState: api.PodState{
|
||||||
Manifest: ContainerManifest{Version: "v1beta1", ID: "abc"},
|
Manifest: api.ContainerManifest{Version: "v1beta1", ID: "abc"},
|
||||||
RestartPolicy: RestartPolicy{Type: "WhatEver"},
|
RestartPolicy: api.RestartPolicy{Type: "WhatEver"},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if len(errs) != 1 {
|
if len(errs) != 1 {
|
||||||
@@ -323,8 +324,8 @@ func TestValidatePod(t *testing.T) {
|
|||||||
func TestValidateService(t *testing.T) {
|
func TestValidateService(t *testing.T) {
|
||||||
// This test should fail because the port number is invalid i.e.
|
// This test should fail because the port number is invalid i.e.
|
||||||
// the Port field has a default value of 0.
|
// the Port field has a default value of 0.
|
||||||
errs := ValidateService(&Service{
|
errs := ValidateService(&api.Service{
|
||||||
JSONBase: JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{
|
Selector: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
@@ -333,9 +334,9 @@ func TestValidateService(t *testing.T) {
|
|||||||
t.Errorf("Unexpected error list: %#v", errs)
|
t.Errorf("Unexpected error list: %#v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errs = ValidateService(&Service{
|
errs = ValidateService(&api.Service{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
JSONBase: JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
Selector: map[string]string{
|
Selector: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
@@ -344,7 +345,7 @@ func TestValidateService(t *testing.T) {
|
|||||||
t.Errorf("Unexpected non-zero error list: %#v", errs)
|
t.Errorf("Unexpected non-zero error list: %#v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errs = ValidateService(&Service{
|
errs = ValidateService(&api.Service{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
Selector: map[string]string{
|
Selector: map[string]string{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
@@ -354,15 +355,15 @@ func TestValidateService(t *testing.T) {
|
|||||||
t.Errorf("Unexpected error list: %#v", errs)
|
t.Errorf("Unexpected error list: %#v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errs = ValidateService(&Service{
|
errs = ValidateService(&api.Service{
|
||||||
Port: 6502,
|
Port: 6502,
|
||||||
JSONBase: JSONBase{ID: "foo"},
|
JSONBase: api.JSONBase{ID: "foo"},
|
||||||
})
|
})
|
||||||
if len(errs) != 1 {
|
if len(errs) != 1 {
|
||||||
t.Errorf("Unexpected error list: %#v", errs)
|
t.Errorf("Unexpected error list: %#v", errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
errs = ValidateService(&Service{})
|
errs = ValidateService(&api.Service{})
|
||||||
if len(errs) != 3 {
|
if len(errs) != 3 {
|
||||||
t.Errorf("Unexpected error list: %#v", errs)
|
t.Errorf("Unexpected error list: %#v", errs)
|
||||||
}
|
}
|
||||||
@@ -370,26 +371,26 @@ func TestValidateService(t *testing.T) {
|
|||||||
|
|
||||||
func TestValidateReplicationController(t *testing.T) {
|
func TestValidateReplicationController(t *testing.T) {
|
||||||
validSelector := map[string]string{"a": "b"}
|
validSelector := map[string]string{"a": "b"}
|
||||||
validPodTemplate := PodTemplate{
|
validPodTemplate := api.PodTemplate{
|
||||||
DesiredState: PodState{
|
DesiredState: api.PodState{
|
||||||
Manifest: ContainerManifest{
|
Manifest: api.ContainerManifest{
|
||||||
Version: "v1beta1",
|
Version: "v1beta1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Labels: validSelector,
|
Labels: validSelector,
|
||||||
}
|
}
|
||||||
|
|
||||||
successCases := []ReplicationController{
|
successCases := []api.ReplicationController{
|
||||||
{
|
{
|
||||||
JSONBase: JSONBase{ID: "abc"},
|
JSONBase: api.JSONBase{ID: "abc"},
|
||||||
DesiredState: ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
ReplicaSelector: validSelector,
|
ReplicaSelector: validSelector,
|
||||||
PodTemplate: validPodTemplate,
|
PodTemplate: validPodTemplate,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
JSONBase: JSONBase{ID: "abc-123"},
|
JSONBase: api.JSONBase{ID: "abc-123"},
|
||||||
DesiredState: ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
ReplicaSelector: validSelector,
|
ReplicaSelector: validSelector,
|
||||||
PodTemplate: validPodTemplate,
|
PodTemplate: validPodTemplate,
|
||||||
},
|
},
|
||||||
@@ -401,36 +402,36 @@ func TestValidateReplicationController(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errorCases := map[string]ReplicationController{
|
errorCases := map[string]api.ReplicationController{
|
||||||
"zero-length ID": {
|
"zero-length ID": {
|
||||||
JSONBase: JSONBase{ID: ""},
|
JSONBase: api.JSONBase{ID: ""},
|
||||||
DesiredState: ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
ReplicaSelector: validSelector,
|
ReplicaSelector: validSelector,
|
||||||
PodTemplate: validPodTemplate,
|
PodTemplate: validPodTemplate,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"empty selector": {
|
"empty selector": {
|
||||||
JSONBase: JSONBase{ID: "abc"},
|
JSONBase: api.JSONBase{ID: "abc"},
|
||||||
DesiredState: ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
PodTemplate: validPodTemplate,
|
PodTemplate: validPodTemplate,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"selector_doesnt_match": {
|
"selector_doesnt_match": {
|
||||||
JSONBase: JSONBase{ID: "abc"},
|
JSONBase: api.JSONBase{ID: "abc"},
|
||||||
DesiredState: ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
ReplicaSelector: map[string]string{"foo": "bar"},
|
ReplicaSelector: map[string]string{"foo": "bar"},
|
||||||
PodTemplate: validPodTemplate,
|
PodTemplate: validPodTemplate,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"invalid manifest": {
|
"invalid manifest": {
|
||||||
JSONBase: JSONBase{ID: "abc"},
|
JSONBase: api.JSONBase{ID: "abc"},
|
||||||
DesiredState: ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
ReplicaSelector: validSelector,
|
ReplicaSelector: validSelector,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"negative_replicas": {
|
"negative_replicas": {
|
||||||
JSONBase: JSONBase{ID: "abc"},
|
JSONBase: api.JSONBase{ID: "abc"},
|
||||||
DesiredState: ReplicationControllerState{
|
DesiredState: api.ReplicationControllerState{
|
||||||
Replicas: -1,
|
Replicas: -1,
|
||||||
ReplicaSelector: validSelector,
|
ReplicaSelector: validSelector,
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user