Browse code

Rename config.mergeMaps() as util.MergeInto()

Vojtech Vitek (V-Teq) authored on 2014/12/02 06:41:14
Showing 5 changed files
... ...
@@ -2,7 +2,6 @@ package config
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"reflect"
6 5
 
7 6
 	kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
8 7
 	errs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
... ...
@@ -10,8 +9,10 @@ import (
10 10
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
11 11
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
12 12
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
13
+
13 14
 	"github.com/openshift/origin/pkg/config/api"
14 15
 	deployapi "github.com/openshift/origin/pkg/deploy/api"
16
+	"github.com/openshift/origin/pkg/util"
15 17
 )
16 18
 
17 19
 // ApplyResult holds the response from the REST server and potential errors
... ...
@@ -103,40 +104,40 @@ func addLabelError(kind string, err error) error {
103 103
 func AddConfigLabel(obj runtime.Object, labels labels.Set) error {
104 104
 	switch t := obj.(type) {
105 105
 	case *kapi.Pod:
106
-		if err := mergeMaps(&t.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
106
+		if err := util.MergeInto(&t.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
107 107
 			return addLabelError("Pod", err)
108 108
 		}
109 109
 	case *kapi.Service:
110
-		if err := mergeMaps(&t.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
110
+		if err := util.MergeInto(&t.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
111 111
 			return addLabelError("Service", err)
112 112
 		}
113 113
 	case *kapi.ReplicationController:
114
-		if err := mergeMaps(&t.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
114
+		if err := util.MergeInto(&t.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
115 115
 			return addLabelError("ReplicationController", err)
116 116
 		}
117
-		if err := mergeMaps(&t.DesiredState.PodTemplate.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
117
+		if err := util.MergeInto(&t.DesiredState.PodTemplate.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
118 118
 			return addLabelError("ReplicationController.PodTemplate", err)
119 119
 		}
120
-		if err := mergeMaps(&t.DesiredState.PodTemplate.Labels, t.DesiredState.ReplicaSelector, ErrorOnDifferentDstKeyValue); err != nil {
120
+		if err := util.MergeInto(&t.DesiredState.PodTemplate.Labels, t.DesiredState.ReplicaSelector, util.ErrorOnDifferentDstKeyValue); err != nil {
121 121
 			return addLabelError("ReplicationController.ReplicaSelector", err)
122 122
 		}
123 123
 		// The ReplicaSelector and DesiredState.PodTemplate.Labels need to make
124 124
 		// create succeed
125
-		if err := mergeMaps(&t.DesiredState.ReplicaSelector, t.DesiredState.PodTemplate.Labels, ErrorOnDifferentDstKeyValue); err != nil {
125
+		if err := util.MergeInto(&t.DesiredState.ReplicaSelector, t.DesiredState.PodTemplate.Labels, util.ErrorOnDifferentDstKeyValue); err != nil {
126 126
 			return addLabelError("ReplicationController.PodTemplate", err)
127 127
 		}
128 128
 	case *deployapi.Deployment:
129
-		if err := mergeMaps(&t.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
129
+		if err := util.MergeInto(&t.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
130 130
 			return addLabelError("Deployment", err)
131 131
 		}
132
-		if err := mergeMaps(&t.ControllerTemplate.PodTemplate.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
132
+		if err := util.MergeInto(&t.ControllerTemplate.PodTemplate.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
133 133
 			return addLabelError("Deployment.ControllerTemplate.PodTemplate", err)
134 134
 		}
135 135
 	case *deployapi.DeploymentConfig:
136
-		if err := mergeMaps(&t.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
136
+		if err := util.MergeInto(&t.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
137 137
 			return addLabelError("DeploymentConfig", err)
138 138
 		}
139
-		if err := mergeMaps(&t.Template.ControllerTemplate.PodTemplate.Labels, labels, ErrorOnDifferentDstKeyValue); err != nil {
139
+		if err := util.MergeInto(&t.Template.ControllerTemplate.PodTemplate.Labels, labels, util.ErrorOnDifferentDstKeyValue); err != nil {
140 140
 			return addLabelError("DeploymentConfig.ControllerTemplate.PodTemplate", err)
141 141
 		}
142 142
 	default:
... ...
@@ -168,72 +169,3 @@ func AddConfigLabels(c *api.Config, labels labels.Set) errs.ValidationErrorList
168 168
 	}
169 169
 	return itemErrors.Prefix("Config")
170 170
 }
171
-
172
-// mergeMaps flags
173
-const (
174
-	OverwriteExistingDstKey     = 1 << iota
175
-	ErrorOnExistingDstKey       = 1 << iota
176
-	ErrorOnDifferentDstKeyValue = 1 << iota
177
-)
178
-
179
-// mergeMaps merges items from a src map into a dst map.
180
-// Returns an error when the maps are not of the same type.
181
-// Flags:
182
-// - ErrorOnExistingDstKey
183
-//     When set: Return an error if any of the dst keys is already set.
184
-// - ErrorOnDifferentDstKeyValue
185
-//     When set: Return an error if any of the dst keys is already set
186
-//               to a different value than src key.
187
-// - OverwriteDstKey
188
-//     When set: Overwrite existing dst key value with src key value.
189
-func mergeMaps(dst, src interface{}, flags int) error {
190
-	dstVal := reflect.ValueOf(dst)
191
-	srcVal := reflect.ValueOf(src)
192
-
193
-	if dstVal.Kind() == reflect.Interface || dstVal.Kind() == reflect.Ptr {
194
-		dstVal = dstVal.Elem()
195
-	}
196
-	if srcVal.Kind() == reflect.Interface || srcVal.Kind() == reflect.Ptr {
197
-		srcVal = srcVal.Elem()
198
-	}
199
-
200
-	if !dstVal.IsValid() {
201
-		return fmt.Errorf("Dst is not a valid value")
202
-	}
203
-	if dstVal.Kind() != reflect.Map {
204
-		return fmt.Errorf("Dst is not a map")
205
-	}
206
-
207
-	dstTyp := dstVal.Type()
208
-	srcTyp := srcVal.Type()
209
-	if !dstTyp.AssignableTo(srcTyp) {
210
-		return fmt.Errorf("Type mismatch, can't assign '%v' to '%v'", srcTyp, dstTyp)
211
-	}
212
-
213
-	if dstVal.IsNil() {
214
-		if !dstVal.CanSet() {
215
-			return fmt.Errorf("Dst value is (not addressable) nil, pass a pointer instead")
216
-		}
217
-		dstVal.Set(reflect.MakeMap(dstTyp))
218
-	}
219
-
220
-	for _, k := range srcVal.MapKeys() {
221
-		if dstVal.MapIndex(k).IsValid() {
222
-			if flags&ErrorOnExistingDstKey != 0 {
223
-				return fmt.Errorf("ErrorOnExistingDstKey flag: Dst key already set to a different value, '%v'='%v'", k, dstVal.MapIndex(k))
224
-			}
225
-			if dstVal.MapIndex(k).String() != srcVal.MapIndex(k).String() {
226
-				if flags&ErrorOnDifferentDstKeyValue != 0 {
227
-					return fmt.Errorf("ErrorOnDifferentDstKeyValue flag: Dst key already set to a different value, '%v'='%v'", k, dstVal.MapIndex(k))
228
-				}
229
-				if flags&OverwriteExistingDstKey != 0 {
230
-					dstVal.SetMapIndex(k, srcVal.MapIndex(k))
231
-				}
232
-			}
233
-		} else {
234
-			dstVal.SetMapIndex(k, srcVal.MapIndex(k))
235
-		}
236
-	}
237
-
238
-	return nil
239
-}
... ...
@@ -294,76 +294,3 @@ func TestAddConfigLabels(t *testing.T) {
294 294
 		}
295 295
 	}
296 296
 }
297
-
298
-func TestMergeMaps(t *testing.T) {
299
-	testCases := []struct {
300
-		dst        interface{}
301
-		src        interface{}
302
-		flags      int
303
-		shouldPass bool
304
-		expected   interface{}
305
-	}{
306
-		{ // Test empty maps
307
-			map[int]int{},
308
-			map[int]int{},
309
-			0,
310
-			true,
311
-			map[int]int{},
312
-		},
313
-		{ // Test dst + src => expected
314
-			map[int]string{1: "foo"},
315
-			map[int]string{2: "bar"},
316
-			0,
317
-			true,
318
-			map[int]string{1: "foo", 2: "bar"},
319
-		},
320
-		{ // Test dst + src => expected, do not overwrite dst
321
-			map[string]string{"foo": "bar"},
322
-			map[string]string{"foo": ""},
323
-			0,
324
-			true,
325
-			map[string]string{"foo": "bar"},
326
-		},
327
-		{ // Test dst + src => expected, overwrite dst
328
-			map[string]string{"foo": "bar"},
329
-			map[string]string{"foo": ""},
330
-			OverwriteExistingDstKey,
331
-			true,
332
-			map[string]string{"foo": ""},
333
-		},
334
-		{ // Test dst + src => expected, error on existing key value
335
-			map[string]string{"foo": "bar"},
336
-			map[string]string{"foo": "bar"},
337
-			ErrorOnExistingDstKey | OverwriteExistingDstKey,
338
-			false,
339
-			map[string]string{"foo": "bar"},
340
-		},
341
-		{ // Test dst + src => expected, do not error on same key value
342
-			map[string]string{"foo": "bar"},
343
-			map[string]string{"foo": "bar"},
344
-			ErrorOnDifferentDstKeyValue | OverwriteExistingDstKey,
345
-			true,
346
-			map[string]string{"foo": "bar"},
347
-		},
348
-		{ // Test dst + src => expected, error on different key value
349
-			map[string]string{"foo": "bar"},
350
-			map[string]string{"foo": ""},
351
-			ErrorOnDifferentDstKeyValue | OverwriteExistingDstKey,
352
-			false,
353
-			map[string]string{"foo": "bar"},
354
-		},
355
-	}
356
-
357
-	for i, test := range testCases {
358
-		err := mergeMaps(test.dst, test.src, test.flags)
359
-		if err != nil && test.shouldPass {
360
-			t.Errorf("Unexpected error while merging maps on testCase[%v].", i)
361
-		}
362
-		if err == nil && !test.shouldPass {
363
-			t.Errorf("Unexpected non-error while merging maps on testCase[%v].", i)
364
-		}
365
-		if !reflect.DeepEqual(test.dst, test.expected) {
366
-			t.Errorf("Unexpected map on testCase[%v]. Expected: %v, got: %v.", i, test.expected, test.dst)
367
-		}
368
-	}
369
-}
370 297
new file mode 100644
... ...
@@ -0,0 +1,4 @@
0
+// Package util implements various utility functions used in both testing and
1
+// implementation of OpenShift. Package util may not depend on any other
2
+// package in the OpenShift package tree.
3
+package util
0 4
new file mode 100644
... ...
@@ -0,0 +1,75 @@
0
+package util
1
+
2
+import (
3
+	"fmt"
4
+	"reflect"
5
+)
6
+
7
+// MergeInto flags
8
+const (
9
+	OverwriteExistingDstKey     = 1 << iota
10
+	ErrorOnExistingDstKey       = 1 << iota
11
+	ErrorOnDifferentDstKeyValue = 1 << iota
12
+)
13
+
14
+// MergeInto merges items from a src map into a dst map.
15
+// Returns an error when the maps are not of the same type.
16
+// Flags:
17
+// - ErrorOnExistingDstKey
18
+//     When set: Return an error if any of the dst keys is already set.
19
+// - ErrorOnDifferentDstKeyValue
20
+//     When set: Return an error if any of the dst keys is already set
21
+//               to a different value than src key.
22
+// - OverwriteDstKey
23
+//     When set: Overwrite existing dst key value with src key value.
24
+func MergeInto(dst, src interface{}, flags int) error {
25
+	dstVal := reflect.ValueOf(dst)
26
+	srcVal := reflect.ValueOf(src)
27
+
28
+	if dstVal.Kind() == reflect.Interface || dstVal.Kind() == reflect.Ptr {
29
+		dstVal = dstVal.Elem()
30
+	}
31
+	if srcVal.Kind() == reflect.Interface || srcVal.Kind() == reflect.Ptr {
32
+		srcVal = srcVal.Elem()
33
+	}
34
+
35
+	if !dstVal.IsValid() {
36
+		return fmt.Errorf("Dst is not a valid value")
37
+	}
38
+	if dstVal.Kind() != reflect.Map {
39
+		return fmt.Errorf("Dst is not a map")
40
+	}
41
+
42
+	dstTyp := dstVal.Type()
43
+	srcTyp := srcVal.Type()
44
+	if !dstTyp.AssignableTo(srcTyp) {
45
+		return fmt.Errorf("Type mismatch, can't assign '%v' to '%v'", srcTyp, dstTyp)
46
+	}
47
+
48
+	if dstVal.IsNil() {
49
+		if !dstVal.CanSet() {
50
+			return fmt.Errorf("Dst value is (not addressable) nil, pass a pointer instead")
51
+		}
52
+		dstVal.Set(reflect.MakeMap(dstTyp))
53
+	}
54
+
55
+	for _, k := range srcVal.MapKeys() {
56
+		if dstVal.MapIndex(k).IsValid() {
57
+			if flags&ErrorOnExistingDstKey != 0 {
58
+				return fmt.Errorf("ErrorOnExistingDstKey flag: Dst key already set to a different value, '%v'='%v'", k, dstVal.MapIndex(k))
59
+			}
60
+			if dstVal.MapIndex(k).String() != srcVal.MapIndex(k).String() {
61
+				if flags&ErrorOnDifferentDstKeyValue != 0 {
62
+					return fmt.Errorf("ErrorOnDifferentDstKeyValue flag: Dst key already set to a different value, '%v'='%v'", k, dstVal.MapIndex(k))
63
+				}
64
+				if flags&OverwriteExistingDstKey != 0 {
65
+					dstVal.SetMapIndex(k, srcVal.MapIndex(k))
66
+				}
67
+			}
68
+		} else {
69
+			dstVal.SetMapIndex(k, srcVal.MapIndex(k))
70
+		}
71
+	}
72
+
73
+	return nil
74
+}
0 75
new file mode 100644
... ...
@@ -0,0 +1,79 @@
0
+package util
1
+
2
+import (
3
+	"reflect"
4
+	"testing"
5
+)
6
+
7
+func TestMergeMaps(t *testing.T) {
8
+	testCases := []struct {
9
+		dst        interface{}
10
+		src        interface{}
11
+		flags      int
12
+		shouldPass bool
13
+		expected   interface{}
14
+	}{
15
+		{ // Test empty maps
16
+			map[int]int{},
17
+			map[int]int{},
18
+			0,
19
+			true,
20
+			map[int]int{},
21
+		},
22
+		{ // Test dst + src => expected
23
+			map[int]string{1: "foo"},
24
+			map[int]string{2: "bar"},
25
+			0,
26
+			true,
27
+			map[int]string{1: "foo", 2: "bar"},
28
+		},
29
+		{ // Test dst + src => expected, do not overwrite dst
30
+			map[string]string{"foo": "bar"},
31
+			map[string]string{"foo": ""},
32
+			0,
33
+			true,
34
+			map[string]string{"foo": "bar"},
35
+		},
36
+		{ // Test dst + src => expected, overwrite dst
37
+			map[string]string{"foo": "bar"},
38
+			map[string]string{"foo": ""},
39
+			OverwriteExistingDstKey,
40
+			true,
41
+			map[string]string{"foo": ""},
42
+		},
43
+		{ // Test dst + src => expected, error on existing key value
44
+			map[string]string{"foo": "bar"},
45
+			map[string]string{"foo": "bar"},
46
+			ErrorOnExistingDstKey | OverwriteExistingDstKey,
47
+			false,
48
+			map[string]string{"foo": "bar"},
49
+		},
50
+		{ // Test dst + src => expected, do not error on same key value
51
+			map[string]string{"foo": "bar"},
52
+			map[string]string{"foo": "bar"},
53
+			ErrorOnDifferentDstKeyValue | OverwriteExistingDstKey,
54
+			true,
55
+			map[string]string{"foo": "bar"},
56
+		},
57
+		{ // Test dst + src => expected, error on different key value
58
+			map[string]string{"foo": "bar"},
59
+			map[string]string{"foo": ""},
60
+			ErrorOnDifferentDstKeyValue | OverwriteExistingDstKey,
61
+			false,
62
+			map[string]string{"foo": "bar"},
63
+		},
64
+	}
65
+
66
+	for i, test := range testCases {
67
+		err := MergeInto(test.dst, test.src, test.flags)
68
+		if err != nil && test.shouldPass {
69
+			t.Errorf("Unexpected error while merging maps on testCase[%v].", i)
70
+		}
71
+		if err == nil && !test.shouldPass {
72
+			t.Errorf("Unexpected non-error while merging maps on testCase[%v].", i)
73
+		}
74
+		if !reflect.DeepEqual(test.dst, test.expected) {
75
+			t.Errorf("Unexpected map on testCase[%v]. Expected: %v, got: %v.", i, test.expected, test.dst)
76
+		}
77
+	}
78
+}