package util
import (
"reflect"
"testing"
kapi "k8s.io/kubernetes/pkg/api"
kmeta "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/runtime"
deployapi "github.com/openshift/origin/pkg/deploy/api"
)
type FakeLabelsResource struct {
unversioned.TypeMeta `json:",inline"`
kapi.ObjectMeta `json:"metadata,omitempty"`
}
func (obj *FakeLabelsResource) GetObjectKind() unversioned.ObjectKind { return &obj.TypeMeta }
func TestAddConfigLabels(t *testing.T) {
var nilLabels map[string]string
testCases := []struct {
obj runtime.Object
addLabels map[string]string
err bool
expectedLabels map[string]string
}{
{ // [0] Test nil + nil => nil
obj: &kapi.Pod{},
addLabels: nilLabels,
err: false,
expectedLabels: nilLabels,
},
{ // [1] Test nil + empty labels => empty labels
obj: &kapi.Pod{},
addLabels: map[string]string{},
err: false,
expectedLabels: map[string]string{},
},
{ // [2] Test obj.Labels + nil => obj.Labels
obj: &kapi.Pod{
ObjectMeta: kapi.ObjectMeta{Labels: map[string]string{"foo": "bar"}},
},
addLabels: nilLabels,
err: false,
expectedLabels: map[string]string{"foo": "bar"},
},
{ // [3] Test obj.Labels + empty labels => obj.Labels
obj: &kapi.Pod{
ObjectMeta: kapi.ObjectMeta{Labels: map[string]string{"foo": "bar"}},
},
addLabels: map[string]string{},
err: false,
expectedLabels: map[string]string{"foo": "bar"},
},
{ // [4] Test nil + addLabels => addLabels
obj: &kapi.Pod{},
addLabels: map[string]string{"foo": "bar"},
err: false,
expectedLabels: map[string]string{"foo": "bar"},
},
{ // [5] Test obj.labels + addLabels => expectedLabels
obj: &kapi.Service{
ObjectMeta: kapi.ObjectMeta{Labels: map[string]string{"baz": ""}},
},
addLabels: map[string]string{"foo": "bar"},
err: false,
expectedLabels: map[string]string{"foo": "bar", "baz": ""},
},
{ // [6] Test conflicting keys with the same value
obj: &kapi.Service{
ObjectMeta: kapi.ObjectMeta{Labels: map[string]string{"foo": "same value"}},
},
addLabels: map[string]string{"foo": "same value"},
err: false,
expectedLabels: map[string]string{"foo": "same value"},
},
{ // [7] Test conflicting keys with a different value
obj: &kapi.Service{
ObjectMeta: kapi.ObjectMeta{Labels: map[string]string{"foo": "first value"}},
},
addLabels: map[string]string{"foo": "second value"},
err: false,
expectedLabels: map[string]string{"foo": "second value"},
},
{ // [8] Test conflicting keys with the same value in ReplicationController nested labels
obj: &kapi.ReplicationController{
ObjectMeta: kapi.ObjectMeta{
Labels: map[string]string{"foo": "same value"},
},
Spec: kapi.ReplicationControllerSpec{
Template: &kapi.PodTemplateSpec{
ObjectMeta: kapi.ObjectMeta{
Labels: map[string]string{},
},
},
},
},
addLabels: map[string]string{"foo": "same value"},
err: false,
expectedLabels: map[string]string{"foo": "same value"},
},
{ // [9] Test adding labels to a DeploymentConfig object
obj: &deployapi.DeploymentConfig{
ObjectMeta: kapi.ObjectMeta{
Labels: map[string]string{"foo": "first value"},
},
Spec: deployapi.DeploymentConfigSpec{
Template: &kapi.PodTemplateSpec{
ObjectMeta: kapi.ObjectMeta{
Labels: map[string]string{"foo": "first value"},
},
},
},
},
addLabels: map[string]string{"bar": "second value"},
err: false,
expectedLabels: map[string]string{"foo": "first value", "bar": "second value"},
},
{ // [10] Test unknown Generic Object with Labels field
obj: &FakeLabelsResource{
ObjectMeta: kapi.ObjectMeta{Labels: map[string]string{"baz": ""}},
},
addLabels: map[string]string{"foo": "bar"},
err: false,
expectedLabels: map[string]string{"foo": "bar", "baz": ""},
},
}
for i, test := range testCases {
err := AddObjectLabels(test.obj, test.addLabels)
if err != nil && !test.err {
t.Errorf("Unexpected error while setting labels on testCase[%v]: %v.", i, err)
} else if err == nil && test.err {
t.Errorf("Unexpected non-error while setting labels on testCase[%v].", i)
}
accessor, err := kmeta.Accessor(test.obj)
if err != nil {
t.Error(err)
}
metaLabels := accessor.GetLabels()
if e, a := test.expectedLabels, metaLabels; !reflect.DeepEqual(e, a) {
t.Errorf("Unexpected labels on testCase[%v]. Expected: %#v, got: %#v.", i, e, a)
}
// must not add any new nested labels
switch objType := test.obj.(type) {
case *kapi.ReplicationController:
if e, a := map[string]string{}, objType.Spec.Template.Labels; !reflect.DeepEqual(e, a) {
t.Errorf("Unexpected labels on testCase[%v]. Expected: %#v, got: %#v.", i, e, a)
}
case *deployapi.DeploymentConfig:
if e, a := test.expectedLabels, objType.Spec.Template.Labels; !reflect.DeepEqual(e, a) {
t.Errorf("Unexpected labels on testCase[%v]. Expected: %#v, got: %#v.", i, e, a)
}
}
}
}
func TestMergeInto(t *testing.T) {
var nilMap map[int]int
testCases := []struct {
dst interface{}
src interface{}
flags int
err bool
expected interface{}
}{
{ // [0] Can't merge into nil
dst: nil,
src: map[int]int{},
flags: 0,
err: true,
expected: nil,
},
{ // [1] Can't merge untyped nil into an empty map
dst: map[int]int{},
src: nil,
flags: 0,
err: true,
expected: map[int]int{},
},
{ // [2] Merge nil map into an empty map
dst: map[int]int{},
src: nilMap,
flags: 0,
err: false,
expected: map[int]int{},
},
{ // [3] Can't merge into nil map
dst: nilMap,
src: map[int]int{},
flags: 0,
err: true,
expected: nilMap,
},
{ // [4] Can't merge into pointer
dst: &nilMap,
src: map[int]int{},
flags: 0,
err: true,
expected: &nilMap,
},
{ // [5] Test empty maps
dst: map[int]int{},
src: map[int]int{},
flags: 0,
err: false,
expected: map[int]int{},
},
{ // [6] Test dst + src => expected
dst: map[int]byte{0: 0, 1: 1},
src: map[int]byte{2: 2, 3: 3},
flags: 0,
err: false,
expected: map[int]byte{0: 0, 1: 1, 2: 2, 3: 3},
},
{ // [7] Test dst + src => expected, do not overwrite dst
dst: map[string]string{"foo": "bar"},
src: map[string]string{"foo": ""},
flags: 0,
err: false,
expected: map[string]string{"foo": "bar"},
},
{ // [8] Test dst + src => expected, overwrite dst
dst: map[string]string{"foo": "bar"},
src: map[string]string{"foo": ""},
flags: OverwriteExistingDstKey,
err: false,
expected: map[string]string{"foo": ""},
},
{ // [9] Test dst + src => expected, error on existing key value
dst: map[string]string{"foo": "bar"},
src: map[string]string{"foo": "bar"},
flags: ErrorOnExistingDstKey | OverwriteExistingDstKey,
err: true,
expected: map[string]string{"foo": "bar"},
},
{ // [10] Test dst + src => expected, do not error on same key value
dst: map[string]string{"foo": "bar"},
src: map[string]string{"foo": "bar"},
flags: ErrorOnDifferentDstKeyValue | OverwriteExistingDstKey,
err: false,
expected: map[string]string{"foo": "bar"},
},
{ // [11] Test dst + src => expected, error on different key value
dst: map[string]string{"foo": "bar"},
src: map[string]string{"foo": ""},
flags: ErrorOnDifferentDstKeyValue | OverwriteExistingDstKey,
err: true,
expected: map[string]string{"foo": "bar"},
},
}
for i, test := range testCases {
err := MergeInto(test.dst, test.src, test.flags)
if err != nil && !test.err {
t.Errorf("Unexpected error while merging maps on testCase[%v]: %v.", i, err)
} else if err == nil && test.err {
t.Errorf("Unexpected non-error while merging maps on testCase[%v].", i)
}
if !reflect.DeepEqual(test.dst, test.expected) {
t.Errorf("Unexpected map on testCase[%v]. Expected: %#v, got: %#v.", i, test.expected, test.dst)
}
}
}