gcs/gcs_test: match zero element
This commit is contained in:
parent
3ac1210f4b
commit
6f51807c27
1 changed files with 79 additions and 0 deletions
|
@ -88,6 +88,85 @@ func TestGCSFilterBuild(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestGCSMatchZeroHash ensures that Match and MatchAny properly match an item
|
||||
// if it's hash after the reduction is zero. This is accomplished by brute
|
||||
// forcing a specific target whose hash is zero given a certain (P, M, key,
|
||||
// len(elements)) combination. In this case, P and M are the default, key was
|
||||
// chosen randomly, and len(elements) is 13. The target 4-byte value of 16060032
|
||||
// is the first such 32-bit value, thus we use the number 0-11 as the other
|
||||
// elements in the filter since we know they won't collide. We test both the
|
||||
// positive and negative cases, when the zero hash item is in the filter and
|
||||
// when it is excluded. In the negative case, the 32-bit value of 12 is added to
|
||||
// the filter instead of the target.
|
||||
func TestGCSMatchZeroHash(t *testing.T) {
|
||||
t.Run("include zero", func(t *testing.T) {
|
||||
testGCSMatchZeroHash(t, true)
|
||||
})
|
||||
t.Run("exclude zero", func(t *testing.T) {
|
||||
testGCSMatchZeroHash(t, false)
|
||||
})
|
||||
}
|
||||
|
||||
func testGCSMatchZeroHash(t *testing.T, includeZeroHash bool) {
|
||||
key := [gcs.KeySize]byte{
|
||||
0x25, 0x28, 0x0d, 0x25, 0x26, 0xe1, 0xd3, 0xc7,
|
||||
0xa5, 0x71, 0x85, 0x34, 0x92, 0xa5, 0x7e, 0x68,
|
||||
}
|
||||
|
||||
// Construct the target data to match, whose hash is zero after applying
|
||||
// the reduction with the parameters in the test.
|
||||
target := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(target, 16060032)
|
||||
|
||||
// Construct the set of 13 items including the target, using the 32-bit
|
||||
// values of 0 through 11 as the first 12 items. We known none of these
|
||||
// hash to zero since the brute force ended well beyond them.
|
||||
elements := make([][]byte, 0, 13)
|
||||
for i := 0; i < 12; i++ {
|
||||
data := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(data, uint32(i))
|
||||
elements = append(elements, data)
|
||||
}
|
||||
|
||||
// If the filter should include the zero hash element, add the target
|
||||
// which we know hashes to zero. Otherwise add 32-bit value of 12 which
|
||||
// we know does not hash to zero.
|
||||
if includeZeroHash {
|
||||
elements = append(elements, target)
|
||||
} else {
|
||||
data := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(data, 12)
|
||||
elements = append(elements, data)
|
||||
}
|
||||
|
||||
filter, err := gcs.BuildGCSFilter(P, M, key, elements)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to build filter: %v", err)
|
||||
}
|
||||
|
||||
match, err := filter.Match(key, target)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to match: %v", err)
|
||||
}
|
||||
|
||||
// We should only get a match iff the target was included.
|
||||
if match != includeZeroHash {
|
||||
t.Fatalf("expected match from Match: %t, got %t",
|
||||
includeZeroHash, match)
|
||||
}
|
||||
|
||||
match, err = filter.MatchAny(key, [][]byte{target})
|
||||
if err != nil {
|
||||
t.Fatalf("unable to match any: %v", err)
|
||||
}
|
||||
|
||||
// We should only get a match iff the target was included.
|
||||
if match != includeZeroHash {
|
||||
t.Fatalf("expected match from MatchAny: %t, got %t",
|
||||
includeZeroHash, match)
|
||||
}
|
||||
}
|
||||
|
||||
// TestGCSFilterCopy deserializes and serializes a filter to create a copy.
|
||||
func TestGCSFilterCopy(t *testing.T) {
|
||||
serialized2, err := filter.Bytes()
|
||||
|
|
Loading…
Reference in a new issue