Skip to content

Commit

Permalink
Unit tests for space (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
outofforest authored Oct 4, 2024
1 parent aa891f1 commit 881266b
Show file tree
Hide file tree
Showing 5 changed files with 576 additions and 236 deletions.
2 changes: 1 addition & 1 deletion alloc/allocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (a *Allocator) Node(nodeAddress types.NodeAddress) []byte {
// Allocate allocates node and copies data into it.
func (a *Allocator) Allocate(copyFrom []byte) (types.NodeAddress, []byte, error) {
a.lastAllocatedNode++
if a.lastAllocatedNode >= types.NodeAddress(len(a.data)) {
if uint64(a.lastAllocatedNode+1)*a.config.NodeSize > uint64(len(a.data)) {
return 0, nil, errors.New("out of space")
}
node := a.Node(a.lastAllocatedNode)
Expand Down
77 changes: 77 additions & 0 deletions alloc/test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package alloc

import (
"sort"

"github.com/outofforest/quantum/types"
)

// NewTestAllocator creates memory allocator used in tests.
func NewTestAllocator(parentAllocator types.Allocator) *TestAllocator {
return &TestAllocator{
parentAllocator: parentAllocator,
nodesAccessed: map[types.NodeAddress]struct{}{},
nodesAllocated: map[types.NodeAddress]struct{}{},
nodesDeallocated: map[types.NodeAddress]struct{}{},
}
}

// TestAllocator is the allocator implementation used in tests.
type TestAllocator struct {
parentAllocator types.Allocator

nodesAccessed map[types.NodeAddress]struct{}
nodesAllocated map[types.NodeAddress]struct{}
nodesDeallocated map[types.NodeAddress]struct{}
}

// Node returns node bytes.
func (a *TestAllocator) Node(nodeAddress types.NodeAddress) []byte {
a.nodesAccessed[nodeAddress] = struct{}{}
return a.parentAllocator.Node(nodeAddress)
}

// Allocate allocates node and copies data into it.
func (a *TestAllocator) Allocate(copyFrom []byte) (types.NodeAddress, []byte, error) {
nodeAddress, node, err := a.parentAllocator.Allocate(copyFrom)
if err != nil {
return 0, nil, err
}
a.nodesAllocated[nodeAddress] = struct{}{}
return nodeAddress, node, nil
}

// Deallocate deallocates node.
func (a *TestAllocator) Deallocate(nodeAddress types.NodeAddress) {
a.nodesDeallocated[nodeAddress] = struct{}{}
a.parentAllocator.Deallocate(nodeAddress)
}

// NodeSize returns size of node.
func (a *TestAllocator) NodeSize() uint64 {
return a.parentAllocator.NodeSize()
}

// Nodes returns touched nodes.
func (a *TestAllocator) Nodes() (
accessed []types.NodeAddress,
allocated []types.NodeAddress,
deallocated []types.NodeAddress,
) {
return mapToSlice(a.nodesAccessed), mapToSlice(a.nodesAllocated), mapToSlice(a.nodesDeallocated)
}

func mapToSlice(m map[types.NodeAddress]struct{}) []types.NodeAddress {
s := make([]types.NodeAddress, 0, len(m))
for k := range m {
s = append(s, k)
}

clear(m)

sort.Slice(s, func(i, j int) bool {
return s[i] < s[j]
})

return s
}
201 changes: 0 additions & 201 deletions db_test.go

This file was deleted.

57 changes: 57 additions & 0 deletions space/collission_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package space

import (
"fmt"
"math"
"sort"
"testing"

"github.com/stretchr/testify/assert"

"github.com/outofforest/quantum/types"
)

var collisions = [][]int{
{15691551, 62234586, 76498628, 79645586},
{6417226, 8828927, 78061179, 87384387},
{9379853, 15271236, 26924827, 39742852},
{71180670, 73568605, 96077640, 100118418},
{11317952, 69053141, 82160848, 112455075},
{33680651, 34881710, 52672514, 56033413},
{635351, 7564491, 43998577, 77923294},
{15069177, 60348274, 84185567, 116299206},
{43622549, 93531002, 108158183, 115087013},
{32134280, 33645087, 37005304, 83416269},
}

// go test -run=TestFindCollisions -v -tags=testing .

func TestFindCollisions(t *testing.T) {
// Remove SkipNow and use command
// go test -run=TestFindCollisions -v -tags=testing .
// to generate integers with colliding hashes.
t.SkipNow()

fmt.Println("started")

m := map[types.Hash][]int{}
for i := range math.MaxInt {
h := hashKey(i, 0)
if h2 := m[h]; len(h2) == 4 {
sort.Ints(h2)
fmt.Printf("%#v\n", h2)
} else {
m[h] = append(m[h], i)
}
}
}

func TestCollisions(t *testing.T) {
for _, set := range collisions {
m := map[types.Hash]struct{}{}
for _, i := range set {
m[hashKey(i, 0)] = struct{}{}
}
assert.Len(t, m, 1)
}
}
Loading

0 comments on commit 881266b

Please sign in to comment.