From d57d5ee664aa2ce338e8e41890e653232aead5c9 Mon Sep 17 00:00:00 2001 From: Mengqi Yu Date: Wed, 11 Apr 2018 15:20:49 -0700 Subject: [PATCH] update hash util --- hash/hash.go | 14 +++++++++----- hash/hash_test.go | 22 +++++++++++++++++++--- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/hash/hash.go b/hash/hash.go index e5685280b0..de0036245d 100644 --- a/hash/hash.go +++ b/hash/hash.go @@ -25,7 +25,7 @@ import ( ) // ConfigMapHash returns a hash of the ConfigMap. -// The data, Kind, and Name are taken into account. +// The Data, Kind, and Name are taken into account. func ConfigMapHash(cm *v1.ConfigMap) (string, error) { encoded, err := encodeConfigMap(cm) if err != nil { @@ -39,7 +39,7 @@ func ConfigMapHash(cm *v1.ConfigMap) (string, error) { } // SecretHash returns a hash of the Secret. -// The data, Kind, Name, and Type are taken into account. +// The Data, Kind, Name, and Type are taken into account. func SecretHash(sec *v1.Secret) (string, error) { encoded, err := encodeSecret(sec) if err != nil { @@ -53,10 +53,14 @@ func SecretHash(sec *v1.Secret) (string, error) { } // encodeConfigMap encodes a ConfigMap. -// data, Kind, and Name are taken into account. +// Data, Kind, and Name are taken into account. func encodeConfigMap(cm *v1.ConfigMap) (string, error) { // json.Marshal sorts the keys in a stable order in the encoding - data, err := json.Marshal(map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, "data": cm.Data}) + m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, "data": cm.Data} + if len(cm.BinaryData) > 0 { + m["binaryData"] = cm.BinaryData + } + data, err := json.Marshal(m) if err != nil { return "", err } @@ -64,7 +68,7 @@ func encodeConfigMap(cm *v1.ConfigMap) (string, error) { } // encodeSecret encodes a Secret. -// data, Kind, Name, and Type are taken into account. +// Data, Kind, Name, and Type are taken into account. func encodeSecret(sec *v1.Secret) (string, error) { // json.Marshal sorts the keys in a stable order in the encoding data, err := json.Marshal(map[string]interface{}{"kind": "Secret", "type": sec.Type, "name": sec.Name, "data": sec.Data}) diff --git a/hash/hash_test.go b/hash/hash_test.go index aa2d085c21..f527a98a20 100644 --- a/hash/hash_test.go +++ b/hash/hash_test.go @@ -32,11 +32,19 @@ func TestConfigMapHash(t *testing.T) { err string }{ // empty map - {"empty data", &v1.ConfigMap{Data: map[string]string{}}, "42745tchd9", ""}, + {"empty data", &v1.ConfigMap{Data: map[string]string{}, BinaryData: map[string][]byte{}}, "42745tchd9", ""}, // one key {"one key", &v1.ConfigMap{Data: map[string]string{"one": ""}}, "9g67k2htb6", ""}, // three keys (tests sorting order) {"three keys", &v1.ConfigMap{Data: map[string]string{"two": "2", "one": "", "three": "3"}}, "f5h7t85m9b", ""}, + // empty binary data map + {"empty binary data", &v1.ConfigMap{BinaryData: map[string][]byte{}}, "dk855m5d49", ""}, + // one key with binary data + {"one key with binary data", &v1.ConfigMap{BinaryData: map[string][]byte{"one": []byte("")}}, "mk79584b8c", ""}, + // three keys with binary data (tests sorting order) + {"three keys with binary data", &v1.ConfigMap{BinaryData: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "t458mc6db2", ""}, + // two keys, one with string and another with binary data + {"two keys with one each", &v1.ConfigMap{Data: map[string]string{"one": ""}, BinaryData: map[string][]byte{"two": []byte("")}}, "698h7c7t9m", ""}, } for _, c := range cases { @@ -89,6 +97,14 @@ func TestEncodeConfigMap(t *testing.T) { {"one key", &v1.ConfigMap{Data: map[string]string{"one": ""}}, `{"data":{"one":""},"kind":"ConfigMap","name":""}`, ""}, // three keys (tests sorting order) {"three keys", &v1.ConfigMap{Data: map[string]string{"two": "2", "one": "", "three": "3"}}, `{"data":{"one":"","three":"3","two":"2"},"kind":"ConfigMap","name":""}`, ""}, + // empty binary map + {"empty data", &v1.ConfigMap{BinaryData: map[string][]byte{}}, `{"data":null,"kind":"ConfigMap","name":""}`, ""}, + // one key with binary data + {"one key", &v1.ConfigMap{BinaryData: map[string][]byte{"one": []byte("")}}, `{"binaryData":{"one":""},"data":null,"kind":"ConfigMap","name":""}`, ""}, + // three keys with binary data (tests sorting order) + {"three keys", &v1.ConfigMap{BinaryData: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, `{"binaryData":{"one":"","three":"Mw==","two":"Mg=="},"data":null,"kind":"ConfigMap","name":""}`, ""}, + // two keys, one string and one binary values + {"two keys with one each", &v1.ConfigMap{Data: map[string]string{"one": ""}, BinaryData: map[string][]byte{"two": []byte("")}}, `{"binaryData":{"two":""},"data":{"one":""},"kind":"ConfigMap","name":""}`, ""}, } for _, c := range cases { s, err := encodeConfigMap(c.cm) @@ -141,14 +157,14 @@ func TestTypeStability(t *testing.T) { errfmt := `case %q, expected %d fields but got %d Depending on the field(s) you added, you may need to modify the hash function for this type. To guide you: the hash function targets fields that comprise the contents of objects, -not their metadata (e.g. the data of a ConfigMap, but nothing in ObjectMeta). +not their metadata (e.g. the Data of a ConfigMap, but nothing in ObjectMeta). ` cases := []struct { typeName string obj interface{} expect int }{ - {"ConfigMap", v1.ConfigMap{}, 3}, + {"ConfigMap", v1.ConfigMap{}, 4}, {"Secret", v1.Secret{}, 5}, } for _, c := range cases {