github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/bitseq/sequence_test.go (about)

     1  package bitseq
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"math/rand"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/docker/libkv/store"
    11  	"github.com/docker/libkv/store/boltdb"
    12  	"github.com/docker/libnetwork/datastore"
    13  	_ "github.com/docker/libnetwork/testutils"
    14  )
    15  
    16  const (
    17  	defaultPrefix = "/tmp/libnetwork/test/bitseq"
    18  )
    19  
    20  func init() {
    21  	boltdb.Register()
    22  }
    23  
    24  func randomLocalStore() (datastore.DataStore, error) {
    25  	tmp, err := ioutil.TempFile("", "libnetwork-")
    26  	if err != nil {
    27  		return nil, fmt.Errorf("Error creating temp file: %v", err)
    28  	}
    29  	if err := tmp.Close(); err != nil {
    30  		return nil, fmt.Errorf("Error closing temp file: %v", err)
    31  	}
    32  	return datastore.NewDataStore(datastore.LocalScope, &datastore.ScopeCfg{
    33  		Client: datastore.ScopeClientCfg{
    34  			Provider: "boltdb",
    35  			Address:  defaultPrefix + tmp.Name(),
    36  			Config: &store.Config{
    37  				Bucket:            "libnetwork",
    38  				ConnectionTimeout: 3 * time.Second,
    39  			},
    40  		},
    41  	})
    42  }
    43  
    44  func TestSequenceGetAvailableBit(t *testing.T) {
    45  	input := []struct {
    46  		head    *sequence
    47  		from    uint64
    48  		bytePos uint64
    49  		bitPos  uint64
    50  	}{
    51  		{&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
    52  		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
    53  		{&sequence{block: 0x0, count: 100}, 0, 0, 0},
    54  
    55  		{&sequence{block: 0x80000000, count: 0}, 0, invalidPos, invalidPos},
    56  		{&sequence{block: 0x80000000, count: 1}, 0, 0, 1},
    57  		{&sequence{block: 0x80000000, count: 100}, 0, 0, 1},
    58  
    59  		{&sequence{block: 0xFF000000, count: 0}, 0, invalidPos, invalidPos},
    60  		{&sequence{block: 0xFF000000, count: 1}, 0, 1, 0},
    61  		{&sequence{block: 0xFF000000, count: 100}, 0, 1, 0},
    62  
    63  		{&sequence{block: 0xFF800000, count: 0}, 0, invalidPos, invalidPos},
    64  		{&sequence{block: 0xFF800000, count: 1}, 0, 1, 1},
    65  		{&sequence{block: 0xFF800000, count: 100}, 0, 1, 1},
    66  
    67  		{&sequence{block: 0xFFC0FF00, count: 0}, 0, invalidPos, invalidPos},
    68  		{&sequence{block: 0xFFC0FF00, count: 1}, 0, 1, 2},
    69  		{&sequence{block: 0xFFC0FF00, count: 100}, 0, 1, 2},
    70  
    71  		{&sequence{block: 0xFFE0FF00, count: 0}, 0, invalidPos, invalidPos},
    72  		{&sequence{block: 0xFFE0FF00, count: 1}, 0, 1, 3},
    73  		{&sequence{block: 0xFFE0FF00, count: 100}, 0, 1, 3},
    74  
    75  		{&sequence{block: 0xFFFEFF00, count: 0}, 0, invalidPos, invalidPos},
    76  		{&sequence{block: 0xFFFEFF00, count: 1}, 0, 1, 7},
    77  		{&sequence{block: 0xFFFEFF00, count: 100}, 0, 1, 7},
    78  
    79  		{&sequence{block: 0xFFFFC0FF, count: 0}, 0, invalidPos, invalidPos},
    80  		{&sequence{block: 0xFFFFC0FF, count: 1}, 0, 2, 2},
    81  		{&sequence{block: 0xFFFFC0FF, count: 100}, 0, 2, 2},
    82  
    83  		{&sequence{block: 0xFFFFFF00, count: 0}, 0, invalidPos, invalidPos},
    84  		{&sequence{block: 0xFFFFFF00, count: 1}, 0, 3, 0},
    85  		{&sequence{block: 0xFFFFFF00, count: 100}, 0, 3, 0},
    86  
    87  		{&sequence{block: 0xFFFFFFFE, count: 0}, 0, invalidPos, invalidPos},
    88  		{&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
    89  		{&sequence{block: 0xFFFFFFFE, count: 100}, 0, 3, 7},
    90  
    91  		{&sequence{block: 0xFFFFFFFF, count: 0}, 0, invalidPos, invalidPos},
    92  		{&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
    93  		{&sequence{block: 0xFFFFFFFF, count: 100}, 0, invalidPos, invalidPos},
    94  
    95  		// now test with offset
    96  		{&sequence{block: 0x0, count: 0}, 0, invalidPos, invalidPos},
    97  		{&sequence{block: 0x0, count: 0}, 31, invalidPos, invalidPos},
    98  		{&sequence{block: 0x0, count: 0}, 32, invalidPos, invalidPos},
    99  		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
   100  		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
   101  		{&sequence{block: 0x0, count: 1}, 31, 3, 7},
   102  		{&sequence{block: 0xF0FF0000, count: 1}, 0, 0, 4},
   103  		{&sequence{block: 0xF0FF0000, count: 1}, 8, 2, 0},
   104  		{&sequence{block: 0xFFFFFFFF, count: 1}, 0, invalidPos, invalidPos},
   105  		{&sequence{block: 0xFFFFFFFF, count: 1}, 16, invalidPos, invalidPos},
   106  		{&sequence{block: 0xFFFFFFFF, count: 1}, 31, invalidPos, invalidPos},
   107  		{&sequence{block: 0xFFFFFFFE, count: 1}, 0, 3, 7},
   108  		{&sequence{block: 0xFFFFFFFF, count: 2}, 0, invalidPos, invalidPos},
   109  		{&sequence{block: 0xFFFFFFFF, count: 2}, 32, invalidPos, invalidPos},
   110  	}
   111  
   112  	for n, i := range input {
   113  		b, bb, err := i.head.getAvailableBit(i.from)
   114  		if b != i.bytePos || bb != i.bitPos {
   115  			t.Fatalf("Error in sequence.getAvailableBit(%d) (%d).\nExp: (%d, %d)\nGot: (%d, %d), err: %v", i.from, n, i.bytePos, i.bitPos, b, bb, err)
   116  		}
   117  	}
   118  }
   119  
   120  func TestSequenceEqual(t *testing.T) {
   121  	input := []struct {
   122  		first    *sequence
   123  		second   *sequence
   124  		areEqual bool
   125  	}{
   126  		{&sequence{block: 0x0, count: 8, next: nil}, &sequence{block: 0x0, count: 8}, true},
   127  		{&sequence{block: 0x0, count: 0, next: nil}, &sequence{block: 0x0, count: 0}, true},
   128  		{&sequence{block: 0x0, count: 2, next: nil}, &sequence{block: 0x0, count: 1, next: &sequence{block: 0x0, count: 1}}, false},
   129  		{&sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}, &sequence{block: 0x0, count: 2}, false},
   130  
   131  		{&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 8}, true},
   132  		{&sequence{block: 0x12345678, count: 8, next: nil}, &sequence{block: 0x12345678, count: 9}, false},
   133  		{&sequence{block: 0x12345678, count: 1, next: &sequence{block: 0XFFFFFFFF, count: 1}}, &sequence{block: 0x12345678, count: 1}, false},
   134  		{&sequence{block: 0x12345678, count: 1}, &sequence{block: 0x12345678, count: 1, next: &sequence{block: 0XFFFFFFFF, count: 1}}, false},
   135  	}
   136  
   137  	for n, i := range input {
   138  		if i.areEqual != i.first.equal(i.second) {
   139  			t.Fatalf("Error in sequence.equal() (%d).\nExp: %t\nGot: %t,", n, i.areEqual, !i.areEqual)
   140  		}
   141  	}
   142  }
   143  
   144  func TestSequenceCopy(t *testing.T) {
   145  	s := getTestSequence()
   146  	n := s.getCopy()
   147  	if !s.equal(n) {
   148  		t.Fatalf("copy of s failed")
   149  	}
   150  	if n == s {
   151  		t.Fatalf("not true copy of s")
   152  	}
   153  }
   154  
   155  func TestGetFirstAvailable(t *testing.T) {
   156  	input := []struct {
   157  		mask    *sequence
   158  		bytePos uint64
   159  		bitPos  uint64
   160  	}{
   161  		{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos},
   162  		{&sequence{block: 0x0, count: 8}, 0, 0},
   163  		{&sequence{block: 0x80000000, count: 8}, 0, 1},
   164  		{&sequence{block: 0xC0000000, count: 8}, 0, 2},
   165  		{&sequence{block: 0xE0000000, count: 8}, 0, 3},
   166  		{&sequence{block: 0xF0000000, count: 8}, 0, 4},
   167  		{&sequence{block: 0xF8000000, count: 8}, 0, 5},
   168  		{&sequence{block: 0xFC000000, count: 8}, 0, 6},
   169  		{&sequence{block: 0xFE000000, count: 8}, 0, 7},
   170  
   171  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 0},
   172  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1},
   173  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2},
   174  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3},
   175  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4},
   176  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5},
   177  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6},
   178  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7},
   179  
   180  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0},
   181  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1},
   182  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2},
   183  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3},
   184  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4},
   185  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5},
   186  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6},
   187  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7},
   188  
   189  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 7, 7},
   190  
   191  		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0},
   192  	}
   193  
   194  	for n, i := range input {
   195  		bytePos, bitPos, _ := getFirstAvailable(i.mask, 0)
   196  		if bytePos != i.bytePos || bitPos != i.bitPos {
   197  			t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
   198  		}
   199  	}
   200  }
   201  
   202  func TestFindSequence(t *testing.T) {
   203  	input := []struct {
   204  		head           *sequence
   205  		bytePos        uint64
   206  		precBlocks     uint64
   207  		inBlockBytePos uint64
   208  	}{
   209  		{&sequence{block: 0xffffffff, count: 0}, 0, 0, invalidPos},
   210  		{&sequence{block: 0xffffffff, count: 0}, 31, 0, invalidPos},
   211  		{&sequence{block: 0xffffffff, count: 0}, 100, 0, invalidPos},
   212  
   213  		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
   214  		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
   215  		{&sequence{block: 0x0, count: 1}, 31, 0, invalidPos},
   216  		{&sequence{block: 0x0, count: 1}, 60, 0, invalidPos},
   217  
   218  		{&sequence{block: 0xffffffff, count: 10}, 0, 0, 0},
   219  		{&sequence{block: 0xffffffff, count: 10}, 3, 0, 3},
   220  		{&sequence{block: 0xffffffff, count: 10}, 4, 1, 0},
   221  		{&sequence{block: 0xffffffff, count: 10}, 7, 1, 3},
   222  		{&sequence{block: 0xffffffff, count: 10}, 8, 2, 0},
   223  		{&sequence{block: 0xffffffff, count: 10}, 39, 9, 3},
   224  
   225  		{&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 79, 9, 3},
   226  		{&sequence{block: 0xffffffff, count: 10, next: &sequence{block: 0xcc000000, count: 10}}, 80, 0, invalidPos},
   227  	}
   228  
   229  	for n, i := range input {
   230  		_, _, precBlocks, inBlockBytePos := findSequence(i.head, i.bytePos)
   231  		if precBlocks != i.precBlocks || inBlockBytePos != i.inBlockBytePos {
   232  			t.Fatalf("Error in (%d) findSequence(). Expected (%d, %d). Got (%d, %d)", n, i.precBlocks, i.inBlockBytePos, precBlocks, inBlockBytePos)
   233  		}
   234  	}
   235  }
   236  
   237  func TestCheckIfAvailable(t *testing.T) {
   238  	input := []struct {
   239  		head    *sequence
   240  		ordinal uint64
   241  		bytePos uint64
   242  		bitPos  uint64
   243  	}{
   244  		{&sequence{block: 0xffffffff, count: 0}, 0, invalidPos, invalidPos},
   245  		{&sequence{block: 0xffffffff, count: 0}, 31, invalidPos, invalidPos},
   246  		{&sequence{block: 0xffffffff, count: 0}, 100, invalidPos, invalidPos},
   247  
   248  		{&sequence{block: 0x0, count: 1}, 0, 0, 0},
   249  		{&sequence{block: 0x0, count: 1}, 1, 0, 1},
   250  		{&sequence{block: 0x0, count: 1}, 31, 3, 7},
   251  		{&sequence{block: 0x0, count: 1}, 60, invalidPos, invalidPos},
   252  
   253  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 31, invalidPos, invalidPos},
   254  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 32, invalidPos, invalidPos},
   255  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x800000ff, count: 1}}, 33, 4, 1},
   256  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 33, invalidPos, invalidPos},
   257  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1}}, 34, 4, 2},
   258  
   259  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 55, 6, 7},
   260  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 56, invalidPos, invalidPos},
   261  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 63, invalidPos, invalidPos},
   262  
   263  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 64, 8, 0},
   264  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 95, 11, 7},
   265  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC00000ff, count: 1, next: &sequence{block: 0x0, count: 1}}}, 96, invalidPos, invalidPos},
   266  	}
   267  
   268  	for n, i := range input {
   269  		bytePos, bitPos, err := checkIfAvailable(i.head, i.ordinal)
   270  		if bytePos != i.bytePos || bitPos != i.bitPos {
   271  			t.Fatalf("Error in (%d) checkIfAvailable(ord:%d). Expected (%d, %d). Got (%d, %d). err: %v", n, i.ordinal, i.bytePos, i.bitPos, bytePos, bitPos, err)
   272  		}
   273  	}
   274  }
   275  
   276  func TestMergeSequences(t *testing.T) {
   277  	input := []struct {
   278  		original *sequence
   279  		merged   *sequence
   280  	}{
   281  		{&sequence{block: 0xFE000000, count: 8, next: &sequence{block: 0xFE000000, count: 2}}, &sequence{block: 0xFE000000, count: 10}},
   282  		{&sequence{block: 0xFFFFFFFF, count: 8, next: &sequence{block: 0xFFFFFFFF, count: 1}}, &sequence{block: 0xFFFFFFFF, count: 9}},
   283  		{&sequence{block: 0xFFFFFFFF, count: 1, next: &sequence{block: 0xFFFFFFFF, count: 8}}, &sequence{block: 0xFFFFFFFF, count: 9}},
   284  
   285  		{&sequence{block: 0xFFFFFFF0, count: 8, next: &sequence{block: 0xFFFFFFF0, count: 1}}, &sequence{block: 0xFFFFFFF0, count: 9}},
   286  		{&sequence{block: 0xFFFFFFF0, count: 1, next: &sequence{block: 0xFFFFFFF0, count: 8}}, &sequence{block: 0xFFFFFFF0, count: 9}},
   287  
   288  		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5}}}, &sequence{block: 0xFE, count: 14}},
   289  		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFE, count: 1, next: &sequence{block: 0xFE, count: 5, next: &sequence{block: 0xFF, count: 1}}}},
   290  			&sequence{block: 0xFE, count: 14, next: &sequence{block: 0xFF, count: 1}}},
   291  
   292  		// No merge
   293  		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}},
   294  			&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xF8, count: 1, next: &sequence{block: 0xFE, count: 5}}}},
   295  
   296  		// No merge from head: // Merge function tries to merge from passed head. If it can't merge with next, it does not reattempt with next as head
   297  		{&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 1, next: &sequence{block: 0xFF, count: 5}}},
   298  			&sequence{block: 0xFE, count: 8, next: &sequence{block: 0xFF, count: 6}}},
   299  	}
   300  
   301  	for n, i := range input {
   302  		mergeSequences(i.original)
   303  		for !i.merged.equal(i.original) {
   304  			t.Fatalf("Error in (%d) mergeSequences().\nExp: %s\nGot: %s,", n, i.merged.toString(), i.original.toString())
   305  		}
   306  	}
   307  }
   308  
   309  func TestPushReservation(t *testing.T) {
   310  	input := []struct {
   311  		mask    *sequence
   312  		bytePos uint64
   313  		bitPos  uint64
   314  		newMask *sequence
   315  	}{
   316  		// Create first sequence and fill in 8 addresses starting from address 0
   317  		{&sequence{block: 0x0, count: 8, next: nil}, 0, 0, &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
   318  		{&sequence{block: 0x80000000, count: 8}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x80000000, count: 7, next: nil}}},
   319  		{&sequence{block: 0xC0000000, count: 8}, 0, 2, &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xC0000000, count: 7, next: nil}}},
   320  		{&sequence{block: 0xE0000000, count: 8}, 0, 3, &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xE0000000, count: 7, next: nil}}},
   321  		{&sequence{block: 0xF0000000, count: 8}, 0, 4, &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xF0000000, count: 7, next: nil}}},
   322  		{&sequence{block: 0xF8000000, count: 8}, 0, 5, &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xF8000000, count: 7, next: nil}}},
   323  		{&sequence{block: 0xFC000000, count: 8}, 0, 6, &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xFC000000, count: 7, next: nil}}},
   324  		{&sequence{block: 0xFE000000, count: 8}, 0, 7, &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xFE000000, count: 7, next: nil}}},
   325  
   326  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 7}}, 0, 1, &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 7, next: nil}}},
   327  
   328  		// Create second sequence and fill in 8 addresses starting from address 32
   329  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 6, next: nil}}}, 4, 0,
   330  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   331  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 1,
   332  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   333  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 2,
   334  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   335  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xE0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 3,
   336  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   337  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF0000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 4,
   338  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   339  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xF8000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 5,
   340  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   341  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFC000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 6,
   342  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   343  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFE000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 4, 7,
   344  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   345  		// fill in 8 addresses starting from address 40
   346  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF000000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 0,
   347  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   348  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFF800000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 1,
   349  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   350  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFC00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 2,
   351  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   352  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFE00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 3,
   353  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   354  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF00000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 4,
   355  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   356  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFF80000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 5,
   357  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   358  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFC0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 6,
   359  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   360  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFE0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 5, 7,
   361  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xFFFF0000, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}},
   362  
   363  		// Insert new sequence
   364  		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0,
   365  			&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
   366  		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5}}}, 8, 1,
   367  			&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xC0000000, count: 1, next: &sequence{block: 0x0, count: 5}}}},
   368  
   369  		// Merge affected with next
   370  		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 2, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
   371  			&sequence{block: 0xffffffff, count: 8, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
   372  		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffc, count: 1, next: &sequence{block: 0xfffffffe, count: 6}}}, 7, 6,
   373  			&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 7}}},
   374  
   375  		// Merge affected with next and next.next
   376  		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
   377  			&sequence{block: 0xffffffff, count: 9}},
   378  		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1}}, 31, 7,
   379  			&sequence{block: 0xffffffff, count: 8}},
   380  
   381  		// Merge affected with previous and next
   382  		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 31, 7,
   383  			&sequence{block: 0xffffffff, count: 9}},
   384  
   385  		// Redundant push: No change
   386  		{&sequence{block: 0xffff0000, count: 1}, 0, 0, &sequence{block: 0xffff0000, count: 1}},
   387  		{&sequence{block: 0xffff0000, count: 7}, 25, 7, &sequence{block: 0xffff0000, count: 7}},
   388  		{&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}, 7, 7,
   389  			&sequence{block: 0xffffffff, count: 7, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 1}}}},
   390  
   391  		// Set last bit
   392  		{&sequence{block: 0x0, count: 8}, 31, 7, &sequence{block: 0x0, count: 7, next: &sequence{block: 0x1, count: 1}}},
   393  
   394  		// Set bit in a middle sequence in the first block, first bit
   395  		{&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
   396  			&sequence{block: 0x40000000, count: 1, next: &sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5,
   397  				next: &sequence{block: 0x1, count: 1}}}}},
   398  
   399  		// Set bit in a middle sequence in the first block, first bit (merge involved)
   400  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 0,
   401  			&sequence{block: 0x80000000, count: 2, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1}}}},
   402  
   403  		// Set bit in a middle sequence in the first block, last bit
   404  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 31,
   405  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x1, count: 1, next: &sequence{block: 0x0, count: 5,
   406  				next: &sequence{block: 0x1, count: 1}}}}},
   407  
   408  		// Set bit in a middle sequence in the first block, middle bit
   409  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 4, 16,
   410  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x8000, count: 1, next: &sequence{block: 0x0, count: 5,
   411  				next: &sequence{block: 0x1, count: 1}}}}},
   412  
   413  		// Set bit in a middle sequence in a middle block, first bit
   414  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 0,
   415  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x80000000, count: 1,
   416  				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
   417  
   418  		// Set bit in a middle sequence in a middle block, last bit
   419  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 31,
   420  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x1, count: 1,
   421  				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
   422  
   423  		// Set bit in a middle sequence in a middle block, middle bit
   424  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 16, 15,
   425  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 3, next: &sequence{block: 0x10000, count: 1,
   426  				next: &sequence{block: 0x0, count: 2, next: &sequence{block: 0x1, count: 1}}}}}},
   427  
   428  		// Set bit in a middle sequence in the last block, first bit
   429  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 0,
   430  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x80000000, count: 1,
   431  				next: &sequence{block: 0x1, count: 1}}}}},
   432  
   433  		// Set bit in a middle sequence in the last block, last bit
   434  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x4, count: 1}}}, 24, 31,
   435  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 1,
   436  				next: &sequence{block: 0x4, count: 1}}}}},
   437  
   438  		// Set bit in a middle sequence in the last block, last bit (merge involved)
   439  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 31,
   440  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x1, count: 2}}}},
   441  
   442  		// Set bit in a middle sequence in the last block, middle bit
   443  		{&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 6, next: &sequence{block: 0x1, count: 1}}}, 24, 16,
   444  			&sequence{block: 0x80000000, count: 1, next: &sequence{block: 0x0, count: 5, next: &sequence{block: 0x8000, count: 1,
   445  				next: &sequence{block: 0x1, count: 1}}}}},
   446  	}
   447  
   448  	for n, i := range input {
   449  		mask := pushReservation(i.bytePos, i.bitPos, i.mask, false)
   450  		if !mask.equal(i.newMask) {
   451  			t.Fatalf("Error in (%d) pushReservation():\n%s + (%d,%d):\nExp: %s\nGot: %s,",
   452  				n, i.mask.toString(), i.bytePos, i.bitPos, i.newMask.toString(), mask.toString())
   453  		}
   454  	}
   455  }
   456  
   457  func TestSerializeDeserialize(t *testing.T) {
   458  	s := getTestSequence()
   459  
   460  	data, err := s.toByteArray()
   461  	if err != nil {
   462  		t.Fatal(err)
   463  	}
   464  
   465  	r := &sequence{}
   466  	err = r.fromByteArray(data)
   467  	if err != nil {
   468  		t.Fatal(err)
   469  	}
   470  
   471  	if !s.equal(r) {
   472  		t.Fatalf("Sequences are different: \n%v\n%v", s, r)
   473  	}
   474  }
   475  
   476  func getTestSequence() *sequence {
   477  	// Returns a custom sequence of 1024 * 32 bits
   478  	return &sequence{
   479  		block: 0XFFFFFFFF,
   480  		count: 100,
   481  		next: &sequence{
   482  			block: 0xFFFFFFFE,
   483  			count: 1,
   484  			next: &sequence{
   485  				block: 0xFF000000,
   486  				count: 10,
   487  				next: &sequence{
   488  					block: 0XFFFFFFFF,
   489  					count: 50,
   490  					next: &sequence{
   491  						block: 0XFFFFFFFC,
   492  						count: 1,
   493  						next: &sequence{
   494  							block: 0xFF800000,
   495  							count: 1,
   496  							next: &sequence{
   497  								block: 0XFFFFFFFF,
   498  								count: 87,
   499  								next: &sequence{
   500  									block: 0x0,
   501  									count: 150,
   502  									next: &sequence{
   503  										block: 0XFFFFFFFF,
   504  										count: 200,
   505  										next: &sequence{
   506  											block: 0x0000FFFF,
   507  											count: 1,
   508  											next: &sequence{
   509  												block: 0x0,
   510  												count: 399,
   511  												next: &sequence{
   512  													block: 0XFFFFFFFF,
   513  													count: 23,
   514  													next: &sequence{
   515  														block: 0x1,
   516  														count: 1,
   517  													},
   518  												},
   519  											},
   520  										},
   521  									},
   522  								},
   523  							},
   524  						},
   525  					},
   526  				},
   527  			},
   528  		},
   529  	}
   530  }
   531  
   532  func TestSet(t *testing.T) {
   533  	hnd, err := NewHandle("", nil, "", 1024*32)
   534  	if err != nil {
   535  		t.Fatal(err)
   536  	}
   537  	hnd.head = getTestSequence()
   538  
   539  	firstAv := uint64(32*100 + 31)
   540  	last := uint64(1024*32 - 1)
   541  
   542  	if hnd.IsSet(100000) {
   543  		t.Fatal("IsSet() returned wrong result")
   544  	}
   545  
   546  	if !hnd.IsSet(0) {
   547  		t.Fatal("IsSet() returned wrong result")
   548  	}
   549  
   550  	if hnd.IsSet(firstAv) {
   551  		t.Fatal("IsSet() returned wrong result")
   552  	}
   553  
   554  	if !hnd.IsSet(last) {
   555  		t.Fatal("IsSet() returned wrong result")
   556  	}
   557  
   558  	if err := hnd.Set(0); err == nil {
   559  		t.Fatalf("Expected failure, but succeeded")
   560  	}
   561  
   562  	os, err := hnd.SetAny()
   563  	if err != nil {
   564  		t.Fatalf("Unexpected failure: %v", err)
   565  	}
   566  	if os != firstAv {
   567  		t.Fatalf("SetAny returned unexpected ordinal. Expected %d. Got %d.", firstAv, os)
   568  	}
   569  	if !hnd.IsSet(firstAv) {
   570  		t.Fatal("IsSet() returned wrong result")
   571  	}
   572  
   573  	if err := hnd.Unset(firstAv); err != nil {
   574  		t.Fatalf("Unexpected failure: %v", err)
   575  	}
   576  
   577  	if hnd.IsSet(firstAv) {
   578  		t.Fatal("IsSet() returned wrong result")
   579  	}
   580  
   581  	if err := hnd.Set(firstAv); err != nil {
   582  		t.Fatalf("Unexpected failure: %v", err)
   583  	}
   584  
   585  	if err := hnd.Set(last); err == nil {
   586  		t.Fatalf("Expected failure, but succeeded")
   587  	}
   588  }
   589  
   590  func TestSetUnset(t *testing.T) {
   591  	numBits := uint64(32 * blockLen)
   592  	hnd, err := NewHandle("", nil, "", numBits)
   593  	if err != nil {
   594  		t.Fatal(err)
   595  	}
   596  
   597  	if err := hnd.Set(uint64(32 * blockLen)); err == nil {
   598  		t.Fatalf("Expected failure, but succeeded")
   599  	}
   600  	if err := hnd.Unset(uint64(32 * blockLen)); err == nil {
   601  		t.Fatalf("Expected failure, but succeeded")
   602  	}
   603  
   604  	// set and unset all one by one
   605  	for hnd.Unselected() > 0 {
   606  		if _, err := hnd.SetAny(); err != nil {
   607  			t.Fatal(err)
   608  		}
   609  	}
   610  	if _, err := hnd.SetAny(); err != ErrNoBitAvailable {
   611  		t.Fatalf("Expected error. Got success")
   612  	}
   613  	if _, err := hnd.SetAnyInRange(10, 20); err != ErrNoBitAvailable {
   614  		t.Fatalf("Expected error. Got success")
   615  	}
   616  	if err := hnd.Set(50); err != ErrBitAllocated {
   617  		t.Fatalf("Expected error. Got %v: %s", err, hnd)
   618  	}
   619  	i := uint64(0)
   620  	for hnd.Unselected() < numBits {
   621  		if err := hnd.Unset(i); err != nil {
   622  			t.Fatal(err)
   623  		}
   624  		i++
   625  	}
   626  }
   627  
   628  func TestSetInRange(t *testing.T) {
   629  	numBits := uint64(1024 * blockLen)
   630  	hnd, err := NewHandle("", nil, "", numBits)
   631  	if err != nil {
   632  		t.Fatal(err)
   633  	}
   634  	hnd.head = getTestSequence()
   635  
   636  	firstAv := uint64(100*blockLen + blockLen - 1)
   637  
   638  	if o, err := hnd.SetAnyInRange(4, 3); err == nil {
   639  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   640  	}
   641  
   642  	if o, err := hnd.SetAnyInRange(0, numBits); err == nil {
   643  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   644  	}
   645  
   646  	o, err := hnd.SetAnyInRange(100*uint64(blockLen), 101*uint64(blockLen))
   647  	if err != nil {
   648  		t.Fatalf("Unexpected failure: (%d, %v)", o, err)
   649  	}
   650  	if o != firstAv {
   651  		t.Fatalf("Unexpected ordinal: %d", o)
   652  	}
   653  
   654  	if o, err := hnd.SetAnyInRange(0, uint64(blockLen)); err == nil {
   655  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   656  	}
   657  
   658  	if o, err := hnd.SetAnyInRange(0, firstAv-1); err == nil {
   659  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   660  	}
   661  
   662  	if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen)); err == nil {
   663  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   664  	}
   665  
   666  	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
   667  	if err != nil {
   668  		t.Fatal(err)
   669  	}
   670  	if o != 161*uint64(blockLen)+30 {
   671  		t.Fatalf("Unexpected ordinal: %d", o)
   672  	}
   673  
   674  	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
   675  	if err != nil {
   676  		t.Fatal(err)
   677  	}
   678  	if o != 161*uint64(blockLen)+31 {
   679  		t.Fatalf("Unexpected ordinal: %d", o)
   680  	}
   681  
   682  	o, err = hnd.SetAnyInRange(161*uint64(blockLen), 162*uint64(blockLen))
   683  	if err == nil {
   684  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   685  	}
   686  
   687  	if _, err := hnd.SetAnyInRange(0, numBits-1); err != nil {
   688  		t.Fatalf("Unexpected failure: %v", err)
   689  	}
   690  
   691  	// set one bit using the set range with 1 bit size range
   692  	if _, err := hnd.SetAnyInRange(uint64(163*blockLen-1), uint64(163*blockLen-1)); err != nil {
   693  		t.Fatal(err)
   694  	}
   695  
   696  	// create a non multiple of 32 mask
   697  	hnd, err = NewHandle("", nil, "", 30)
   698  	if err != nil {
   699  		t.Fatal(err)
   700  	}
   701  
   702  	// set all bit in the first range
   703  	for hnd.Unselected() > 22 {
   704  		if o, err := hnd.SetAnyInRange(0, 7); err != nil {
   705  			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
   706  		}
   707  	}
   708  	// try one more set, which should fail
   709  	o, err = hnd.SetAnyInRange(0, 7)
   710  	if err == nil {
   711  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   712  	}
   713  	if err != ErrNoBitAvailable {
   714  		t.Fatalf("Unexpected error: %v", err)
   715  	}
   716  
   717  	// set all bit in a second range
   718  	for hnd.Unselected() > 14 {
   719  		if o, err := hnd.SetAnyInRange(8, 15); err != nil {
   720  			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
   721  		}
   722  	}
   723  
   724  	// try one more set, which should fail
   725  	o, err = hnd.SetAnyInRange(0, 15)
   726  	if err == nil {
   727  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   728  	}
   729  	if err != ErrNoBitAvailable {
   730  		t.Fatalf("Unexpected error: %v", err)
   731  	}
   732  
   733  	// set all bit in a range which includes the last bit
   734  	for hnd.Unselected() > 12 {
   735  		if o, err := hnd.SetAnyInRange(28, 29); err != nil {
   736  			t.Fatalf("Unexpected failure: (%d, %v)", o, err)
   737  		}
   738  	}
   739  	o, err = hnd.SetAnyInRange(28, 29)
   740  	if err == nil {
   741  		t.Fatalf("Expected failure. Got success with ordinal:%d", o)
   742  	}
   743  	if err != ErrNoBitAvailable {
   744  		t.Fatalf("Unexpected error: %v", err)
   745  	}
   746  }
   747  
   748  // This one tests an allocation pattern which unveiled an issue in pushReservation
   749  // Specifically a failure in detecting when we are in the (B) case (the bit to set
   750  // belongs to the last block of the current sequence). Because of a bug, code
   751  // was assuming the bit belonged to a block in the middle of the current sequence.
   752  // Which in turn caused an incorrect allocation when requesting a bit which is not
   753  // in the first or last sequence block.
   754  func TestSetAnyInRange(t *testing.T) {
   755  	numBits := uint64(8 * blockLen)
   756  	hnd, err := NewHandle("", nil, "", numBits)
   757  	if err != nil {
   758  		t.Fatal(err)
   759  	}
   760  
   761  	if err := hnd.Set(0); err != nil {
   762  		t.Fatal(err)
   763  	}
   764  
   765  	if err := hnd.Set(255); err != nil {
   766  		t.Fatal(err)
   767  	}
   768  
   769  	o, err := hnd.SetAnyInRange(128, 255)
   770  	if err != nil {
   771  		t.Fatal(err)
   772  	}
   773  	if o != 128 {
   774  		t.Fatalf("Unexpected ordinal: %d", o)
   775  	}
   776  
   777  	o, err = hnd.SetAnyInRange(128, 255)
   778  	if err != nil {
   779  		t.Fatal(err)
   780  	}
   781  
   782  	if o != 129 {
   783  		t.Fatalf("Unexpected ordinal: %d", o)
   784  	}
   785  
   786  	o, err = hnd.SetAnyInRange(246, 255)
   787  	if err != nil {
   788  		t.Fatal(err)
   789  	}
   790  	if o != 246 {
   791  		t.Fatalf("Unexpected ordinal: %d", o)
   792  	}
   793  
   794  	o, err = hnd.SetAnyInRange(246, 255)
   795  	if err != nil {
   796  		t.Fatal(err)
   797  	}
   798  	if o != 247 {
   799  		t.Fatalf("Unexpected ordinal: %d", o)
   800  	}
   801  }
   802  
   803  func TestMethods(t *testing.T) {
   804  	numBits := uint64(256 * blockLen)
   805  	hnd, err := NewHandle("path/to/data", nil, "sequence1", uint64(numBits))
   806  	if err != nil {
   807  		t.Fatal(err)
   808  	}
   809  
   810  	if hnd.Bits() != numBits {
   811  		t.Fatalf("Unexpected bit number: %d", hnd.Bits())
   812  	}
   813  
   814  	if hnd.Unselected() != numBits {
   815  		t.Fatalf("Unexpected bit number: %d", hnd.Unselected())
   816  	}
   817  
   818  	exp := "(0x0, 256)->end"
   819  	if hnd.head.toString() != exp {
   820  		t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
   821  	}
   822  
   823  	for i := 0; i < 192; i++ {
   824  		_, err := hnd.SetAny()
   825  		if err != nil {
   826  			t.Fatal(err)
   827  		}
   828  	}
   829  
   830  	exp = "(0xffffffff, 6)->(0x0, 250)->end"
   831  	if hnd.head.toString() != exp {
   832  		t.Fatalf("Unexpected sequence string: %s", hnd.head.toString())
   833  	}
   834  }
   835  
   836  func TestRandomAllocateDeallocate(t *testing.T) {
   837  	ds, err := randomLocalStore()
   838  	if err != nil {
   839  		t.Fatal(err)
   840  	}
   841  
   842  	numBits := int(16 * blockLen)
   843  	hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
   844  	if err != nil {
   845  		t.Fatal(err)
   846  	}
   847  
   848  	seed := time.Now().Unix()
   849  	rand.Seed(seed)
   850  
   851  	// Allocate all bits using a random pattern
   852  	pattern := rand.Perm(numBits)
   853  	for _, bit := range pattern {
   854  		err := hnd.Set(uint64(bit))
   855  		if err != nil {
   856  			t.Fatalf("Unexpected failure on allocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
   857  		}
   858  	}
   859  	if hnd.Unselected() != 0 {
   860  		t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
   861  	}
   862  	if hnd.head.toString() != "(0xffffffff, 16)->end" {
   863  		t.Fatalf("Unexpected db: %s", hnd.head.toString())
   864  	}
   865  
   866  	// Deallocate all bits using a random pattern
   867  	pattern = rand.Perm(numBits)
   868  	for _, bit := range pattern {
   869  		err := hnd.Unset(uint64(bit))
   870  		if err != nil {
   871  			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
   872  		}
   873  	}
   874  	if hnd.Unselected() != uint64(numBits) {
   875  		t.Fatalf("Expected full sequence. Instead found %d free bits. Seed: %d.\n%s", hnd.unselected, seed, hnd)
   876  	}
   877  	if hnd.head.toString() != "(0x0, 16)->end" {
   878  		t.Fatalf("Unexpected db: %s", hnd.head.toString())
   879  	}
   880  
   881  	err = hnd.Destroy()
   882  	if err != nil {
   883  		t.Fatal(err)
   884  	}
   885  }
   886  
   887  func TestAllocateRandomDeallocate(t *testing.T) {
   888  	ds, err := randomLocalStore()
   889  	if err != nil {
   890  		t.Fatal(err)
   891  	}
   892  
   893  	numBlocks := uint32(8)
   894  	numBits := int(numBlocks * blockLen)
   895  	hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
   896  	if err != nil {
   897  		t.Fatal(err)
   898  	}
   899  
   900  	expected := &sequence{block: 0xffffffff, count: uint64(numBlocks / 2), next: &sequence{block: 0x0, count: uint64(numBlocks / 2)}}
   901  
   902  	// Allocate first half of the bits
   903  	for i := 0; i < numBits/2; i++ {
   904  		_, err := hnd.SetAny()
   905  		if err != nil {
   906  			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
   907  		}
   908  	}
   909  	if hnd.Unselected() != uint64(numBits/2) {
   910  		t.Fatalf("Expected full sequence. Instead found %d free bits. %s", hnd.unselected, hnd)
   911  	}
   912  	if !hnd.head.equal(expected) {
   913  		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
   914  	}
   915  
   916  	seed := time.Now().Unix()
   917  	rand.Seed(seed)
   918  
   919  	// Deallocate half of the allocated bits following a random pattern
   920  	pattern := rand.Perm(numBits / 2)
   921  	for i := 0; i < numBits/4; i++ {
   922  		bit := pattern[i]
   923  		err := hnd.Unset(uint64(bit))
   924  		if err != nil {
   925  			t.Fatalf("Unexpected failure on deallocation of %d: %v.\nSeed: %d.\n%s", bit, err, seed, hnd)
   926  		}
   927  	}
   928  	if hnd.Unselected() != uint64(3*numBits/4) {
   929  		t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
   930  	}
   931  
   932  	// Request a quarter of bits
   933  	for i := 0; i < numBits/4; i++ {
   934  		_, err := hnd.SetAny()
   935  		if err != nil {
   936  			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
   937  		}
   938  	}
   939  	if hnd.Unselected() != uint64(numBits/2) {
   940  		t.Fatalf("Expected half sequence. Instead found %d free bits.\nSeed: %d\n%s", hnd.unselected, seed, hnd)
   941  	}
   942  	if !hnd.head.equal(expected) {
   943  		t.Fatalf("Unexpected sequence. Got:\n%s", hnd)
   944  	}
   945  
   946  	err = hnd.Destroy()
   947  	if err != nil {
   948  		t.Fatal(err)
   949  	}
   950  }
   951  
   952  func TestRetrieveFromStore(t *testing.T) {
   953  	ds, err := randomLocalStore()
   954  	if err != nil {
   955  		t.Fatal(err)
   956  	}
   957  
   958  	numBits := int(8 * blockLen)
   959  	hnd, err := NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
   960  	if err != nil {
   961  		t.Fatal(err)
   962  	}
   963  
   964  	// Allocate first half of the bits
   965  	for i := 0; i < numBits/2; i++ {
   966  		_, err := hnd.SetAny()
   967  		if err != nil {
   968  			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
   969  		}
   970  	}
   971  	hnd0 := hnd.String()
   972  
   973  	// Retrieve same handle
   974  	hnd, err = NewHandle("bitseq-test/data/", ds, "test1", uint64(numBits))
   975  	if err != nil {
   976  		t.Fatal(err)
   977  	}
   978  	hnd1 := hnd.String()
   979  
   980  	if hnd1 != hnd0 {
   981  		t.Fatalf("%v\n%v", hnd0, hnd1)
   982  	}
   983  
   984  	err = hnd.Destroy()
   985  	if err != nil {
   986  		t.Fatal(err)
   987  	}
   988  }
   989  
   990  func TestIsCorrupted(t *testing.T) {
   991  	ds, err := randomLocalStore()
   992  	if err != nil {
   993  		t.Fatal(err)
   994  	}
   995  	// Negative test
   996  	hnd, err := NewHandle("bitseq-test/data/", ds, "test_corrupted", 1024)
   997  	if err != nil {
   998  		t.Fatal(err)
   999  	}
  1000  
  1001  	if hnd.runConsistencyCheck() {
  1002  		t.Fatalf("Unexpected corrupted for %s", hnd)
  1003  	}
  1004  
  1005  	if err := hnd.CheckConsistency(); err != nil {
  1006  		t.Fatal(err)
  1007  	}
  1008  
  1009  	hnd.Set(0)
  1010  	if hnd.runConsistencyCheck() {
  1011  		t.Fatalf("Unexpected corrupted for %s", hnd)
  1012  	}
  1013  
  1014  	hnd.Set(1023)
  1015  	if hnd.runConsistencyCheck() {
  1016  		t.Fatalf("Unexpected corrupted for %s", hnd)
  1017  	}
  1018  
  1019  	if err := hnd.CheckConsistency(); err != nil {
  1020  		t.Fatal(err)
  1021  	}
  1022  
  1023  	// Try real corrupted ipam handles found in the local store files reported by three docker users,
  1024  	// plus a generic ipam handle from docker 1.9.1. This last will fail as well, because of how the
  1025  	// last node in the sequence is expressed (This is true for IPAM handle only, because of the broadcast
  1026  	// address reservation: last bit). This will allow an application using bitseq that runs a consistency
  1027  	// check to detect and replace the 1.9.0/1 old vulnerable handle with the new one.
  1028  	input := []*Handle{
  1029  		{
  1030  			id:         "LocalDefault/172.17.0.0/16",
  1031  			bits:       65536,
  1032  			unselected: 65412,
  1033  			head: &sequence{
  1034  				block: 0xffffffff,
  1035  				count: 3,
  1036  				next: &sequence{
  1037  					block: 0xffffffbf,
  1038  					count: 0,
  1039  					next: &sequence{
  1040  						block: 0xfe98816e,
  1041  						count: 1,
  1042  						next: &sequence{
  1043  							block: 0xffffffff,
  1044  							count: 0,
  1045  							next: &sequence{
  1046  								block: 0xe3bc0000,
  1047  								count: 1,
  1048  								next: &sequence{
  1049  									block: 0x0,
  1050  									count: 2042,
  1051  									next: &sequence{
  1052  										block: 0x1, count: 1,
  1053  										next: &sequence{
  1054  											block: 0x0, count: 0,
  1055  										},
  1056  									},
  1057  								},
  1058  							},
  1059  						},
  1060  					},
  1061  				},
  1062  			},
  1063  		},
  1064  		{
  1065  			id:         "LocalDefault/172.17.0.0/16",
  1066  			bits:       65536,
  1067  			unselected: 65319,
  1068  			head: &sequence{
  1069  				block: 0xffffffff,
  1070  				count: 7,
  1071  				next: &sequence{
  1072  					block: 0xffffff7f,
  1073  					count: 0,
  1074  					next: &sequence{
  1075  						block: 0xffffffff,
  1076  						count: 0,
  1077  						next: &sequence{
  1078  							block: 0x2000000,
  1079  							count: 1,
  1080  							next: &sequence{
  1081  								block: 0x0,
  1082  								count: 2039,
  1083  								next: &sequence{
  1084  									block: 0x1,
  1085  									count: 1,
  1086  									next: &sequence{
  1087  										block: 0x0,
  1088  										count: 0,
  1089  									},
  1090  								},
  1091  							},
  1092  						},
  1093  					},
  1094  				},
  1095  			},
  1096  		},
  1097  		{
  1098  			id:         "LocalDefault/172.17.0.0/16",
  1099  			bits:       65536,
  1100  			unselected: 65456,
  1101  			head: &sequence{
  1102  				block: 0xffffffff, count: 2,
  1103  				next: &sequence{
  1104  					block: 0xfffbffff, count: 0,
  1105  					next: &sequence{
  1106  						block: 0xffd07000, count: 1,
  1107  						next: &sequence{
  1108  							block: 0x0, count: 333,
  1109  							next: &sequence{
  1110  								block: 0x40000000, count: 1,
  1111  								next: &sequence{
  1112  									block: 0x0, count: 1710,
  1113  									next: &sequence{
  1114  										block: 0x1, count: 1,
  1115  										next: &sequence{
  1116  											block: 0x0, count: 0,
  1117  										},
  1118  									},
  1119  								},
  1120  							},
  1121  						},
  1122  					},
  1123  				},
  1124  			},
  1125  		},
  1126  	}
  1127  
  1128  	for idx, hnd := range input {
  1129  		if !hnd.runConsistencyCheck() {
  1130  			t.Fatalf("Expected corrupted for (%d): %s", idx, hnd)
  1131  		}
  1132  		if hnd.runConsistencyCheck() {
  1133  			t.Fatalf("Sequence still marked corrupted (%d): %s", idx, hnd)
  1134  		}
  1135  	}
  1136  }