From 14e93a112ba49d7df1ad5c1dff48dae7d148718b Mon Sep 17 00:00:00 2001 From: rsokolowski Date: Thu, 19 Feb 2015 16:40:35 +0100 Subject: [PATCH] Make DeepHashObject function deterministic. --- pkg/util/hash.go | 3 ++- pkg/util/hash_test.go | 43 +++++++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/pkg/util/hash.go b/pkg/util/hash.go index fc5bd3bb6b1..b372ceaa8f6 100644 --- a/pkg/util/hash.go +++ b/pkg/util/hash.go @@ -26,5 +26,6 @@ import ( // which follows pointers and prints actual values of the nested objects // ensuring the hash does not change when a pointer changes. func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) { - spew.Fprintf(hasher, "%#v", objectToWrite) + printer := spew.ConfigState{Indent: " ", SortKeys: true} + printer.Fprintf(hasher, "%#v", objectToWrite) } diff --git a/pkg/util/hash_test.go b/pkg/util/hash_test.go index c4218b60eb5..553e720bcbe 100644 --- a/pkg/util/hash_test.go +++ b/pkg/util/hash_test.go @@ -28,6 +28,7 @@ type wheel struct { type unicycle struct { primaryWheel *wheel licencePlateID string + tags map[string]string } func TestDeepObjectPointer(t *testing.T) { @@ -36,28 +37,30 @@ func TestDeepObjectPointer(t *testing.T) { wheel2 := wheel{radius: 22} wheel3 := wheel{radius: 17} - myUni1 := unicycle{licencePlateID: "blah", primaryWheel: &wheel1} - myUni2 := unicycle{licencePlateID: "blah", primaryWheel: &wheel2} - myUni3 := unicycle{licencePlateID: "blah", primaryWheel: &wheel3} + myUni1 := unicycle{licencePlateID: "blah", primaryWheel: &wheel1, tags: map[string]string{"color": "blue", "name": "john"}} + myUni2 := unicycle{licencePlateID: "blah", primaryWheel: &wheel2, tags: map[string]string{"color": "blue", "name": "john"}} + myUni3 := unicycle{licencePlateID: "blah", primaryWheel: &wheel3, tags: map[string]string{"color": "blue", "name": "john"}} - hasher1 := adler32.New() - hasher2 := adler32.New() - hasher3 := adler32.New() + // Run it more than once to verify determinism of hasher. + for i := 0; i < 100; i++ { + hasher1 := adler32.New() + hasher2 := adler32.New() + hasher3 := adler32.New() + // Act + DeepHashObject(hasher1, myUni1) + hash1 := hasher1.Sum32() + DeepHashObject(hasher2, myUni2) + hash2 := hasher2.Sum32() + DeepHashObject(hasher3, myUni3) + hash3 := hasher3.Sum32() - // Act - DeepHashObject(hasher1, myUni1) - hash1 := hasher1.Sum32() - DeepHashObject(hasher2, myUni2) - hash2 := hasher2.Sum32() - DeepHashObject(hasher3, myUni3) - hash3 := hasher3.Sum32() + // Assert + if hash1 == hash2 { + t.Errorf("hash1 (%d) and hash2(%d) must be different because they have different values for wheel size", hash1, hash2) + } - // Assert - if hash1 == hash2 { - t.Errorf("hash1 (%d) and hash2(%d) must be different because they have different values for wheel size", hash1, hash2) - } - - if hash1 != hash3 { - t.Errorf("hash1 (%d) and hash3(%d) must be the same because although they point to different objects, they have the same values for wheel size", hash1, hash3) + if hash1 != hash3 { + t.Errorf("hash1 (%d) and hash3(%d) must be the same because although they point to different objects, they have the same values for wheel size", hash1, hash3) + } } }