Make validation work when not in the api package.

This commit is contained in:
Daniel Smith
2014-08-29 18:20:27 -07:00
parent eb5ca80946
commit 7615c00a9a
3 changed files with 120 additions and 99 deletions

19
pkg/api/validation/doc.go Normal file
View 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

View File

@@ -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))

View File

@@ -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,
}, },