mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #814 from aboch/bst
Increase test coverage in bitsequence
This commit is contained in:
commit
3881fa3063
1 changed files with 235 additions and 1 deletions
|
@ -1,11 +1,41 @@
|
|||
package bitseq
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libkv/store"
|
||||
"github.com/docker/libnetwork/datastore"
|
||||
_ "github.com/docker/libnetwork/testutils"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultPrefix = "/tmp/libnetwork/test/bitseq"
|
||||
)
|
||||
|
||||
func randomLocalStore() (datastore.DataStore, error) {
|
||||
tmp, err := ioutil.TempFile("", "libnetwork-")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating temp file: %v", err)
|
||||
}
|
||||
if err := tmp.Close(); err != nil {
|
||||
return nil, fmt.Errorf("Error closing temp file: %v", err)
|
||||
}
|
||||
return datastore.NewDataStore(datastore.LocalScope, &datastore.ScopeCfg{
|
||||
Client: datastore.ScopeClientCfg{
|
||||
Provider: "boltdb",
|
||||
Address: defaultPrefix + tmp.Name(),
|
||||
Config: &store.Config{
|
||||
Bucket: "libnetwork",
|
||||
ConnectionTimeout: 3 * time.Second,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestSequenceGetAvailableBit(t *testing.T) {
|
||||
input := []struct {
|
||||
head *sequence
|
||||
|
@ -553,17 +583,34 @@ func TestSet(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSetUnset(t *testing.T) {
|
||||
numBits := uint64(64 * 1024)
|
||||
numBits := uint64(32 * blockLen)
|
||||
hnd, err := NewHandle("", nil, "", numBits)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := hnd.Set(uint64(32 * blockLen)); err == nil {
|
||||
t.Fatalf("Expected failure, but succeeded")
|
||||
}
|
||||
if err := hnd.Unset(uint64(32 * blockLen)); err == nil {
|
||||
t.Fatalf("Expected failure, but succeeded")
|
||||
}
|
||||
|
||||
// set and unset all one by one
|
||||
for hnd.Unselected() > 0 {
|
||||
if _, err := hnd.SetAny(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if _, err := hnd.SetAny(); err != ErrNoBitAvailable {
|
||||
t.Fatalf("Expected error. Got success")
|
||||
}
|
||||
if _, err := hnd.SetAnyInRange(10, 20); err != ErrNoBitAvailable {
|
||||
t.Fatalf("Expected error. Got success")
|
||||
}
|
||||
if err := hnd.Set(50); err != ErrBitAllocated {
|
||||
t.Fatalf("Expected error. Got %v: %s", err, hnd)
|
||||
}
|
||||
i := uint64(0)
|
||||
for hnd.Unselected() < numBits {
|
||||
if err := hnd.Unset(i); err != nil {
|
||||
|
@ -746,3 +793,190 @@ func TestSetAnyInRange(t *testing.T) {
|
|||
t.Fatalf("Unexpected ordinal: %d", o)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethods(t *testing.T) {
|
||||
numBits := uint64(256 * blockLen)
|
||||
hnd, err := NewHandle("path/to/data", nil, "sequence1", uint64(numBits))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if hnd.Bits() != numBits {
|
||||
t.Fatalf("Unexpected bit number: %d", hnd.Bits())
|
||||
}
|
||||
|
||||
if hnd.Unselected() != numBits {
|
||||
t.Fatalf("Unexpected bit number: %d", hnd.Unselected())
|
||||
}
|
||||
|
||||
exp := "(0x0, 256)->end"
|
||||
if hnd.head.toString() != exp {
|
||||
t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
|
||||
}
|
||||
|
||||
for i := 0; i < 192; i++ {
|
||||
_, err := hnd.SetAny()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
exp = "(0xffffffff, 6)->(0x0, 250)->end"
|
||||
if hnd.head.toString() != exp {
|
||||
t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandomAllocateDeallocate(t *testing.T) {
|
||||
ds, err := randomLocalStore()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
numBits := int(16 * blockLen)
|
||||
hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
seed := time.Now().Unix()
|
||||
rand.Seed(seed)
|
||||
|
||||
// Allocate all bits using a random pattern
|
||||
pattern := rand.Perm(numBits)
|
||||
for _, bit := range pattern {
|
||||
err := hnd.Set(uint64(bit))
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
|
||||
}
|
||||
}
|
||||
if hnd.Unselected() != 0 {
|
||||
t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
|
||||
}
|
||||
if hnd.head.toString() != "(0xffffffff, 16)->end" {
|
||||
t.Fatalf("Unexpected db: %s", hnd.head.toString())
|
||||
}
|
||||
|
||||
// Deallocate all bits using a random pattern
|
||||
pattern = rand.Perm(numBits)
|
||||
for _, bit := range pattern {
|
||||
err := hnd.Unset(uint64(bit))
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
|
||||
}
|
||||
}
|
||||
if hnd.Unselected() != uint64(numBits) {
|
||||
t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
|
||||
}
|
||||
if hnd.head.toString() != "(0x0, 16)->end" {
|
||||
t.Fatalf("Unexpected db: %s", hnd.head.toString())
|
||||
}
|
||||
|
||||
err = hnd.Destroy()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllocateRandomDeallocate(t *testing.T) {
|
||||
ds, err := randomLocalStore()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
numBlocks := uint32(8)
|
||||
numBits := int(numBlocks * blockLen)
|
||||
hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
|
||||
|
||||
// Allocate first half of the bits
|
||||
for i := 0; i < numBits/2; i++ {
|
||||
_, err := hnd.SetAny()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
|
||||
}
|
||||
}
|
||||
if hnd.Unselected() != uint64(numBits/2) {
|
||||
t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
|
||||
}
|
||||
if !hnd.head.equal(expected) {
|
||||
t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
|
||||
}
|
||||
|
||||
seed := time.Now().Unix()
|
||||
rand.Seed(seed)
|
||||
|
||||
// Deallocate half of the allocated bits following a random pattern
|
||||
pattern := rand.Perm(numBits / 2)
|
||||
for i := 0; i < numBits/4; i++ {
|
||||
bit := pattern[i]
|
||||
err := hnd.Unset(uint64(bit))
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
|
||||
}
|
||||
}
|
||||
if hnd.Unselected() != uint64(3*numBits/4) {
|
||||
t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
|
||||
}
|
||||
|
||||
// Request a quarter of bits
|
||||
for i := 0; i < numBits/4; i++ {
|
||||
_, err := hnd.SetAny()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
|
||||
}
|
||||
}
|
||||
if hnd.Unselected() != uint64(numBits/2) {
|
||||
t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
|
||||
}
|
||||
if !hnd.head.equal(expected) {
|
||||
t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
|
||||
}
|
||||
|
||||
err = hnd.Destroy()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRetrieveFromStore(t *testing.T) {
|
||||
ds, err := randomLocalStore()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
numBits := int(8 * blockLen)
|
||||
hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Allocate first half of the bits
|
||||
for i := 0; i < numBits/2; i++ {
|
||||
_, err := hnd.SetAny()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
|
||||
}
|
||||
}
|
||||
hnd0 := hnd.String()
|
||||
|
||||
// Retrieve same handle
|
||||
hnd, err = NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hnd1 := hnd.String()
|
||||
|
||||
if hnd1 != hnd0 {
|
||||
t.Fatalf("%v\n%v", hnd0, hnd1)
|
||||
}
|
||||
|
||||
err = hnd.Destroy()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue