Merge pull request #4595 from rsokolowski/deterministic-hash

Make DeepHashObject function deterministic.
This commit is contained in:
Yu-Ju Hong 2015-02-19 10:10:08 -08:00
commit 1b5d14423c
2 changed files with 25 additions and 21 deletions

View File

@ -26,5 +26,6 @@ import (
// which follows pointers and prints actual values of the nested objects // which follows pointers and prints actual values of the nested objects
// ensuring the hash does not change when a pointer changes. // ensuring the hash does not change when a pointer changes.
func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) { func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) {
spew.Fprintf(hasher, "%#v", objectToWrite) printer := spew.ConfigState{Indent: " ", SortKeys: true}
printer.Fprintf(hasher, "%#v", objectToWrite)
} }

View File

@ -28,6 +28,7 @@ type wheel struct {
type unicycle struct { type unicycle struct {
primaryWheel *wheel primaryWheel *wheel
licencePlateID string licencePlateID string
tags map[string]string
} }
func TestDeepObjectPointer(t *testing.T) { func TestDeepObjectPointer(t *testing.T) {
@ -36,28 +37,30 @@ func TestDeepObjectPointer(t *testing.T) {
wheel2 := wheel{radius: 22} wheel2 := wheel{radius: 22}
wheel3 := wheel{radius: 17} wheel3 := wheel{radius: 17}
myUni1 := unicycle{licencePlateID: "blah", primaryWheel: &wheel1} myUni1 := unicycle{licencePlateID: "blah", primaryWheel: &wheel1, tags: map[string]string{"color": "blue", "name": "john"}}
myUni2 := unicycle{licencePlateID: "blah", primaryWheel: &wheel2} myUni2 := unicycle{licencePlateID: "blah", primaryWheel: &wheel2, tags: map[string]string{"color": "blue", "name": "john"}}
myUni3 := unicycle{licencePlateID: "blah", primaryWheel: &wheel3} myUni3 := unicycle{licencePlateID: "blah", primaryWheel: &wheel3, tags: map[string]string{"color": "blue", "name": "john"}}
hasher1 := adler32.New() // Run it more than once to verify determinism of hasher.
hasher2 := adler32.New() for i := 0; i < 100; i++ {
hasher3 := adler32.New() 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 // Assert
DeepHashObject(hasher1, myUni1) if hash1 == hash2 {
hash1 := hasher1.Sum32() t.Errorf("hash1 (%d) and hash2(%d) must be different because they have different values for wheel size", hash1, hash2)
DeepHashObject(hasher2, myUni2) }
hash2 := hasher2.Sum32()
DeepHashObject(hasher3, myUni3)
hash3 := hasher3.Sum32()
// Assert if hash1 != hash3 {
if hash1 == hash2 { 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)
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)
} }
} }