// Copyright 2016 by Sascha L. Teichmann // Use of this source code is governed by the MIT license // that can be found in the LICENSE file. package common import ( "math/rand" "testing" ) func randomBaseTileHash(updates int) *BaseTileHash { bth := NewBaseTileHash(256) h1 := []byte{1} h2 := []byte{2} for i := 0; i < updates; i++ { x, y := rand.Intn(100), rand.Intn(100) var h []byte if i%2 == 0 { h = h1 } else { h = h2 } bth.Update(x, y, h) } return bth } func TestBaseTileHashLenList(t *testing.T) { for _, updates := range []int{53, 111, 1345, 11261} { bth := randomBaseTileHash(updates) countNext := 0 for cur := bth.root.next; cur != &bth.root; cur = cur.next { countNext++ } countPrev := 0 for cur := bth.root.prev; cur != &bth.root; cur = cur.prev { countPrev++ } if countPrev != countNext { t.Errorf("count prev != count next: %d %d", countPrev, countNext) } if countPrev != len(bth.hashes) { t.Errorf("count prev != len(hash): %d %d", countPrev, len(bth.hashes)) } } } func TestBaseTileHashIntegrity(t *testing.T) { for _, updates := range []int{10, 100, 1000, 10000} { bth := randomBaseTileHash(updates) entries := map[*btHashEntry]bool{} for cur := bth.root.next; cur != &bth.root; cur = cur.next { if entries[cur] { t.Errorf("hash element found more than once: %d", updates) } entries[cur] = true } if len(entries) != len(bth.hashes) { t.Errorf("List has differnt length than hashes: %d : %d", len(entries), len(bth.hashes)) } var already1 bool var already2 bool for k, v := range bth.hashes { if !entries[v] { if !already1 { already1 = true t.Errorf("Hash contains pointer to element not being in list: %d", updates) } } if k != v.btKey { if !already2 { already2 = true t.Errorf("Key in entry does not match hash key: %d", updates) } } delete(entries, v) } if len(entries) > 0 { t.Error("There are more entries than indexed by hash") } } } func TestBaseTileHashOverwrite(t *testing.T) { bth := NewBaseTileHash(256) h1 := []byte{1} h2 := []byte{2} if updated := bth.Update(0, 0, h1); !updated { t.Error("First insert does not trigger update") } if updated := bth.Update(0, 0, h2); !updated { t.Error("Second insert does not trigger update") } if updated := bth.Update(0, 0, h2); updated { t.Error("Third insert does trigger update") } } func TestBaseTileHashSeparate(t *testing.T) { bth := NewBaseTileHash(256) h1 := []byte{1} if updated := bth.Update(0, 0, h1); !updated { t.Error("First insert does not trigger update") } if updated := bth.Update(0, 1, h1); !updated { t.Error("Second insert does not trigger update") } if updated := bth.Update(1, 0, h1); !updated { t.Error("Third insert does trigger update") } if len(bth.hashes) != 3 { t.Errorf("Expected size to be 3. Current size: %d", len(bth.hashes)) } } func TestBaseTileHashLRU(t *testing.T) { bth := NewBaseTileHash(2) h1 := []byte{1} if updated := bth.Update(0, 0, h1); !updated { t.Error("First insert does not trigger update") } if updated := bth.Update(0, 1, h1); !updated { t.Error("Second insert does not trigger update") } if updated := bth.Update(1, 0, h1); !updated { t.Error("Third insert does trigger update") } if len(bth.hashes) != 2 { t.Errorf("Expected size to be 2. Current size: %d", len(bth.hashes)) } }