Browse code

Change floats to ints recursively on env encoding

Fixes #6246
Docker-DCO-1.1-Signed-off-by: Alexandr Morozov <lk4d4math@gmail.com> (github: LK4D4)

LK4D4 authored on 2014/06/07 19:05:23
Showing 2 changed files
... ...
@@ -199,6 +199,22 @@ func (env *Env) SetAuto(k string, v interface{}) {
199 199
 	}
200 200
 }
201 201
 
202
+func changeFloats(v interface{}) interface{} {
203
+	switch v := v.(type) {
204
+	case float64:
205
+		return int(v)
206
+	case map[string]interface{}:
207
+		for key, val := range v {
208
+			v[key] = changeFloats(val)
209
+		}
210
+	case []interface{}:
211
+		for idx, val := range v {
212
+			v[idx] = changeFloats(val)
213
+		}
214
+	}
215
+	return v
216
+}
217
+
202 218
 func (env *Env) Encode(dst io.Writer) error {
203 219
 	m := make(map[string]interface{})
204 220
 	for k, v := range env.Map() {
... ...
@@ -207,10 +223,7 @@ func (env *Env) Encode(dst io.Writer) error {
207 207
 			// FIXME: we fix-convert float values to int, because
208 208
 			// encoding/json decodes integers to float64, but cannot encode them back.
209 209
 			// (See http://golang.org/src/pkg/encoding/json/decode.go#L46)
210
-			if fval, isFloat := val.(float64); isFloat {
211
-				val = int(fval)
212
-			}
213
-			m[k] = val
210
+			m[k] = changeFloats(val)
214 211
 		} else {
215 212
 			m[k] = v
216 213
 		}
... ...
@@ -2,6 +2,7 @@ package engine
2 2
 
3 3
 import (
4 4
 	"bytes"
5
+	"encoding/json"
5 6
 	"testing"
6 7
 
7 8
 	"github.com/dotcloud/docker/pkg/testutils"
... ...
@@ -269,3 +270,43 @@ func BenchmarkDecode(b *testing.B) {
269 269
 		reader.Seek(0, 0)
270 270
 	}
271 271
 }
272
+
273
+func TestLongNumbers(t *testing.T) {
274
+	type T struct {
275
+		TestNum int64
276
+	}
277
+	v := T{67108864}
278
+	var buf bytes.Buffer
279
+	e := &Env{}
280
+	e.SetJson("Test", v)
281
+	if err := e.Encode(&buf); err != nil {
282
+		t.Fatal(err)
283
+	}
284
+	res := make(map[string]T)
285
+	if err := json.Unmarshal(buf.Bytes(), &res); err != nil {
286
+		t.Fatal(err)
287
+	}
288
+	if res["Test"].TestNum != v.TestNum {
289
+		t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum)
290
+	}
291
+}
292
+
293
+func TestLongNumbersArray(t *testing.T) {
294
+	type T struct {
295
+		TestNum []int64
296
+	}
297
+	v := T{[]int64{67108864}}
298
+	var buf bytes.Buffer
299
+	e := &Env{}
300
+	e.SetJson("Test", v)
301
+	if err := e.Encode(&buf); err != nil {
302
+		t.Fatal(err)
303
+	}
304
+	res := make(map[string]T)
305
+	if err := json.Unmarshal(buf.Bytes(), &res); err != nil {
306
+		t.Fatal(err)
307
+	}
308
+	if res["Test"].TestNum[0] != v.TestNum[0] {
309
+		t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum)
310
+	}
311
+}