Skip to content

Commit

Permalink
Make DeepHashObject function deterministic.
Browse files Browse the repository at this point in the history
  • Loading branch information
rsokolowski committed Feb 19, 2015
1 parent 413e1db commit 14e93a1
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 23 deletions.
3 changes: 2 additions & 1 deletion pkg/util/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
47 changes: 25 additions & 22 deletions pkg/util/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type wheel struct {
type unicycle struct {
primaryWheel *wheel
licencePlateID string
tags map[string]string
}

func TestDeepObjectPointer(t *testing.T) {
Expand All @@ -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}

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()

// Assert
if hash1 == hash2 {
t.Errorf("hash1 (%d) and hash2(%d) must be different because they have different values for wheel size", hash1, hash2)
}
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"}}

// 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()

// 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)
}
}
}

0 comments on commit 14e93a1

Please sign in to comment.