Change floats to ints recursively on env encoding

Fixes #6246
Docker-DCO-1.1-Signed-off-by: Alexandr Morozov <lk4d4math@gmail.com> (github: LK4D4)
This commit is contained in:
LK4D4 2014-06-07 14:05:23 +04:00 committed by Victor Vieux
parent e899700254
commit 1d3d1c5d2b
2 changed files with 58 additions and 4 deletions

View File

@ -199,6 +199,22 @@ func (env *Env) SetAuto(k string, v interface{}) {
}
}
func changeFloats(v interface{}) interface{} {
switch v := v.(type) {
case float64:
return int(v)
case map[string]interface{}:
for key, val := range v {
v[key] = changeFloats(val)
}
case []interface{}:
for idx, val := range v {
v[idx] = changeFloats(val)
}
}
return v
}
func (env *Env) Encode(dst io.Writer) error {
m := make(map[string]interface{})
for k, v := range env.Map() {
@ -207,10 +223,7 @@ func (env *Env) Encode(dst io.Writer) error {
// FIXME: we fix-convert float values to int, because
// encoding/json decodes integers to float64, but cannot encode them back.
// (See http://golang.org/src/pkg/encoding/json/decode.go#L46)
if fval, isFloat := val.(float64); isFloat {
val = int(fval)
}
m[k] = val
m[k] = changeFloats(val)
} else {
m[k] = v
}

View File

@ -2,6 +2,7 @@ package engine
import (
"bytes"
"encoding/json"
"testing"
"github.com/dotcloud/docker/pkg/testutils"
@ -269,3 +270,43 @@ func BenchmarkDecode(b *testing.B) {
reader.Seek(0, 0)
}
}
func TestLongNumbers(t *testing.T) {
type T struct {
TestNum int64
}
v := T{67108864}
var buf bytes.Buffer
e := &Env{}
e.SetJson("Test", v)
if err := e.Encode(&buf); err != nil {
t.Fatal(err)
}
res := make(map[string]T)
if err := json.Unmarshal(buf.Bytes(), &res); err != nil {
t.Fatal(err)
}
if res["Test"].TestNum != v.TestNum {
t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum)
}
}
func TestLongNumbersArray(t *testing.T) {
type T struct {
TestNum []int64
}
v := T{[]int64{67108864}}
var buf bytes.Buffer
e := &Env{}
e.SetJson("Test", v)
if err := e.Encode(&buf); err != nil {
t.Fatal(err)
}
res := make(map[string]T)
if err := json.Unmarshal(buf.Bytes(), &res); err != nil {
t.Fatal(err)
}
if res["Test"].TestNum[0] != v.TestNum[0] {
t.Fatalf("TestNum %d, expected %d", res["Test"].TestNum, v.TestNum)
}
}