Browse code

IPAM and Bitseq test cases

This commit contains test cases to verify the changes and to
solidify the library.

Signed-off-by: Abhinandan Prativadi <abhi@docker.com>

Abhinandan Prativadi authored on 2018/03/09 03:39:30
Showing 2 changed files
... ...
@@ -192,6 +192,11 @@ func TestGetFirstAvailable(t *testing.T) {
192 192
 		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffffffe, count: 1, next: &sequence{block: 0xffffffff, count: 6}}}, 7, 7, 0},
193 193
 
194 194
 		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0x0, count: 6}}, 8, 0, 0},
195
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 4, 0, 16},
196
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 7, 15},
197
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0x0, count: 6}}, 1, 6, 10},
198
+		{&sequence{block: 0xfffcfffe, count: 1, next: &sequence{block: 0x0, count: 6}}, 3, 7, 31},
199
+		{&sequence{block: 0xfffcffff, count: 1, next: &sequence{block: 0xffffffff, count: 6}}, invalidPos, invalidPos, 31},
195 200
 	}
196 201
 
197 202
 	for n, i := range input {
... ...
@@ -1238,7 +1243,7 @@ func TestIsCorrupted(t *testing.T) {
1238 1238
 	}
1239 1239
 }
1240 1240
 
1241
-func TestSetRollover(t *testing.T) {
1241
+func testSetRollover(t *testing.T, serial bool) {
1242 1242
 	ds, err := randomLocalStore()
1243 1243
 	if err != nil {
1244 1244
 		t.Fatal(err)
... ...
@@ -1253,7 +1258,7 @@ func TestSetRollover(t *testing.T) {
1253 1253
 
1254 1254
 	// Allocate first half of the bits
1255 1255
 	for i := 0; i < numBits/2; i++ {
1256
-		_, err := hnd.SetAny(true)
1256
+		_, err := hnd.SetAny(serial)
1257 1257
 		if err != nil {
1258 1258
 			t.Fatalf("Unexpected failure on allocation %d: %v\n%s", i, err, hnd)
1259 1259
 		}
... ...
@@ -1276,12 +1281,12 @@ func TestSetRollover(t *testing.T) {
1276 1276
 		}
1277 1277
 	}
1278 1278
 	if hnd.Unselected() != uint64(3*numBits/4) {
1279
-		t.Fatalf("Expected full sequence. Instead found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
1279
+		t.Fatalf("Unexpected free bits: found %d free bits.\nSeed: %d.\n%s", hnd.unselected, seed, hnd)
1280 1280
 	}
1281 1281
 
1282 1282
 	//request to allocate for remaining half of the bits
1283 1283
 	for i := 0; i < numBits/2; i++ {
1284
-		_, err := hnd.SetAny(true)
1284
+		_, err := hnd.SetAny(serial)
1285 1285
 		if err != nil {
1286 1286
 			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
1287 1287
 		}
... ...
@@ -1294,7 +1299,7 @@ func TestSetRollover(t *testing.T) {
1294 1294
 	}
1295 1295
 
1296 1296
 	for i := 0; i < numBits/4; i++ {
1297
-		_, err := hnd.SetAny(true)
1297
+		_, err := hnd.SetAny(serial)
1298 1298
 		if err != nil {
1299 1299
 			t.Fatalf("Unexpected failure on allocation %d: %v\nSeed: %d\n%s", i, err, seed, hnd)
1300 1300
 		}
... ...
@@ -1302,7 +1307,7 @@ func TestSetRollover(t *testing.T) {
1302 1302
 	//Now requesting to allocate the unallocated random bits (qurter of the number of bits) should
1303 1303
 	//leave no more bits that can be allocated.
1304 1304
 	if hnd.Unselected() != 0 {
1305
-		t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), numBits/4)
1305
+		t.Fatalf("Unexpected number of unselected bits %d, Expected %d", hnd.Unselected(), 0)
1306 1306
 	}
1307 1307
 
1308 1308
 	err = hnd.Destroy()
... ...
@@ -1310,3 +1315,47 @@ func TestSetRollover(t *testing.T) {
1310 1310
 		t.Fatal(err)
1311 1311
 	}
1312 1312
 }
1313
+
1314
+func TestSetRollover(t *testing.T) {
1315
+	testSetRollover(t, false)
1316
+}
1317
+
1318
+func TestSetRolloverSerial(t *testing.T) {
1319
+	testSetRollover(t, true)
1320
+}
1321
+
1322
+func TestGetFirstAvailableFromCurrent(t *testing.T) {
1323
+	input := []struct {
1324
+		mask    *sequence
1325
+		bytePos uint64
1326
+		bitPos  uint64
1327
+		start   uint64
1328
+		curr    uint64
1329
+		end     uint64
1330
+	}{
1331
+		{&sequence{block: 0xffffffff, count: 2048}, invalidPos, invalidPos, 0, 0, 65536},
1332
+		{&sequence{block: 0x0, count: 8}, 0, 0, 0, 0, 256},
1333
+		{&sequence{block: 0x80000000, count: 8}, 1, 0, 0, 8, 256},
1334
+		{&sequence{block: 0xC0000000, count: 8}, 0, 2, 0, 2, 256},
1335
+		{&sequence{block: 0xE0000000, count: 8}, 0, 3, 0, 0, 256},
1336
+		{&sequence{block: 0xFFFB1FFF, count: 8}, 2, 0, 14, 0, 256},
1337
+		{&sequence{block: 0xFFFFFFFE, count: 8}, 3, 7, 0, 0, 256},
1338
+
1339
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0x00000000, count: 1, next: &sequence{block: 0xffffffff, count: 14}}}, 4, 0, 0, 32, 512},
1340
+		{&sequence{block: 0xfffeffff, count: 1, next: &sequence{block: 0xffffffff, count: 15}}, 1, 7, 0, 16, 512},
1341
+		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 5, 7, 0, 16, 512},
1342
+		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0xffffffff, count: 1}}, 9, 7, 0, 48, 512},
1343
+		{&sequence{block: 0xffffffff, count: 2, next: &sequence{block: 0xffffffef, count: 14}}, 19, 3, 0, 124, 512},
1344
+		{&sequence{block: 0xfffeffff, count: 15, next: &sequence{block: 0x0fffffff, count: 1}}, 60, 0, 0, 480, 512},
1345
+		{&sequence{block: 0xffffffff, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 17, 7, 0, 124, 512},
1346
+		{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xffffffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 3, 5, 0, 124, 512},
1347
+		{&sequence{block: 0xfffffffb, count: 1, next: &sequence{block: 0xfffeffff, count: 14, next: &sequence{block: 0xffffffff, count: 1}}}, 13, 7, 0, 80, 512},
1348
+	}
1349
+
1350
+	for n, i := range input {
1351
+		bytePos, bitPos, _ := getAvailableFromCurrent(i.mask, i.start, i.curr, i.end)
1352
+		if bytePos != i.bytePos || bitPos != i.bitPos {
1353
+			t.Fatalf("Error in (%d) getFirstAvailable(). Expected (%d, %d). Got (%d, %d)", n, i.bytePos, i.bitPos, bytePos, bitPos)
1354
+		}
1355
+	}
1356
+}
... ...
@@ -8,6 +8,7 @@ import (
8 8
 	"math/rand"
9 9
 	"net"
10 10
 	"strconv"
11
+	"sync"
11 12
 	"testing"
12 13
 	"time"
13 14
 
... ...
@@ -30,7 +31,10 @@ func init() {
30 30
 }
31 31
 
32 32
 // OptionBoltdbWithRandomDBFile function returns a random dir for local store backend
33
-func randomLocalStore() (datastore.DataStore, error) {
33
+func randomLocalStore(needStore bool) (datastore.DataStore, error) {
34
+	if !needStore {
35
+		return nil, nil
36
+	}
34 37
 	tmp, err := ioutil.TempFile("", "libnetwork-")
35 38
 	if err != nil {
36 39
 		return nil, fmt.Errorf("Error creating temp file: %v", err)
... ...
@@ -50,17 +54,13 @@ func randomLocalStore() (datastore.DataStore, error) {
50 50
 	})
51 51
 }
52 52
 
53
-func getAllocator() (*Allocator, error) {
53
+func getAllocator(store bool) (*Allocator, error) {
54 54
 	ipamutils.InitNetworks(nil)
55
-	ds, err := randomLocalStore()
56
-	if err != nil {
57
-		return nil, err
58
-	}
59
-	a, err := NewAllocator(ds, nil)
55
+	ds, err := randomLocalStore(store)
60 56
 	if err != nil {
61 57
 		return nil, err
62 58
 	}
63
-	return a, nil
59
+	return NewAllocator(ds, nil)
64 60
 }
65 61
 
66 62
 func TestInt2IP2IntConversion(t *testing.T) {
... ...
@@ -170,7 +170,7 @@ func TestPoolDataMarshal(t *testing.T) {
170 170
 }
171 171
 
172 172
 func TestSubnetsMarshal(t *testing.T) {
173
-	a, err := getAllocator()
173
+	a, err := getAllocator(true)
174 174
 	if err != nil {
175 175
 		t.Fatal(err)
176 176
 	}
... ...
@@ -217,7 +217,7 @@ func TestSubnetsMarshal(t *testing.T) {
217 217
 }
218 218
 
219 219
 func TestAddSubnets(t *testing.T) {
220
-	a, err := getAllocator()
220
+	a, err := getAllocator(true)
221 221
 	if err != nil {
222 222
 		t.Fatal(err)
223 223
 	}
... ...
@@ -286,7 +286,7 @@ func TestAddSubnets(t *testing.T) {
286 286
 func TestAddReleasePoolID(t *testing.T) {
287 287
 	var k0, k1, k2 SubnetKey
288 288
 
289
-	a, err := getAllocator()
289
+	a, err := getAllocator(true)
290 290
 	if err != nil {
291 291
 		t.Fatal(err)
292 292
 	}
... ...
@@ -448,7 +448,7 @@ func TestAddReleasePoolID(t *testing.T) {
448 448
 }
449 449
 
450 450
 func TestPredefinedPool(t *testing.T) {
451
-	a, err := getAllocator()
451
+	a, err := getAllocator(true)
452 452
 	if err != nil {
453 453
 		t.Fatal(err)
454 454
 	}
... ...
@@ -476,7 +476,7 @@ func TestPredefinedPool(t *testing.T) {
476 476
 }
477 477
 
478 478
 func TestRemoveSubnet(t *testing.T) {
479
-	a, err := getAllocator()
479
+	a, err := getAllocator(true)
480 480
 	if err != nil {
481 481
 		t.Fatal(err)
482 482
 	}
... ...
@@ -519,7 +519,7 @@ func TestRemoveSubnet(t *testing.T) {
519 519
 }
520 520
 
521 521
 func TestGetSameAddress(t *testing.T) {
522
-	a, err := getAllocator()
522
+	a, err := getAllocator(true)
523 523
 	if err != nil {
524 524
 		t.Fatal(err)
525 525
 	}
... ...
@@ -549,7 +549,7 @@ func TestGetSameAddress(t *testing.T) {
549 549
 }
550 550
 
551 551
 func TestGetAddressSubPoolEqualPool(t *testing.T) {
552
-	a, err := getAllocator()
552
+	a, err := getAllocator(true)
553 553
 	if err != nil {
554 554
 		t.Fatal(err)
555 555
 	}
... ...
@@ -566,7 +566,7 @@ func TestGetAddressSubPoolEqualPool(t *testing.T) {
566 566
 }
567 567
 
568 568
 func TestRequestReleaseAddressFromSubPool(t *testing.T) {
569
-	a, err := getAllocator()
569
+	a, err := getAllocator(true)
570 570
 	if err != nil {
571 571
 		t.Fatal(err)
572 572
 	}
... ...
@@ -697,8 +697,9 @@ func TestRequestReleaseAddressFromSubPool(t *testing.T) {
697 697
 
698 698
 func TestSerializeRequestReleaseAddressFromSubPool(t *testing.T) {
699 699
 	opts := map[string]string{
700
-		ipamapi.AllocSerialPrefix: "true"}
701
-	a, err := getAllocator()
700
+		ipamapi.AllocSerialPrefix: "true",
701
+	}
702
+	a, err := getAllocator(false)
702 703
 	if err != nil {
703 704
 		t.Fatal(err)
704 705
 	}
... ...
@@ -848,7 +849,7 @@ func TestRequestSyntaxCheck(t *testing.T) {
848 848
 		err     error
849 849
 	)
850 850
 
851
-	a, err := getAllocator()
851
+	a, err := getAllocator(true)
852 852
 	if err != nil {
853 853
 		t.Fatal(err)
854 854
 	}
... ...
@@ -950,7 +951,7 @@ func TestRelease(t *testing.T) {
950 950
 		subnet = "192.168.0.0/23"
951 951
 	)
952 952
 
953
-	a, err := getAllocator()
953
+	a, err := getAllocator(true)
954 954
 	if err != nil {
955 955
 		t.Fatal(err)
956 956
 	}
... ...
@@ -1057,7 +1058,7 @@ func assertNRequests(t *testing.T, subnet string, numReq int, lastExpectedIP str
1057 1057
 	)
1058 1058
 
1059 1059
 	lastIP := net.ParseIP(lastExpectedIP)
1060
-	a, err := getAllocator()
1060
+	a, err := getAllocator(true)
1061 1061
 	if err != nil {
1062 1062
 		t.Fatal(err)
1063 1063
 	}
... ...
@@ -1088,24 +1089,24 @@ func benchmarkRequest(b *testing.B, a *Allocator, subnet string) {
1088 1088
 }
1089 1089
 
1090 1090
 func benchMarkRequest(subnet string, b *testing.B) {
1091
-	a, _ := getAllocator()
1091
+	a, _ := getAllocator(true)
1092 1092
 	for n := 0; n < b.N; n++ {
1093 1093
 		benchmarkRequest(b, a, subnet)
1094 1094
 	}
1095 1095
 }
1096 1096
 
1097 1097
 func BenchmarkRequest_24(b *testing.B) {
1098
-	a, _ := getAllocator()
1098
+	a, _ := getAllocator(true)
1099 1099
 	benchmarkRequest(b, a, "10.0.0.0/24")
1100 1100
 }
1101 1101
 
1102 1102
 func BenchmarkRequest_16(b *testing.B) {
1103
-	a, _ := getAllocator()
1103
+	a, _ := getAllocator(true)
1104 1104
 	benchmarkRequest(b, a, "10.0.0.0/16")
1105 1105
 }
1106 1106
 
1107 1107
 func BenchmarkRequest_8(b *testing.B) {
1108
-	a, _ := getAllocator()
1108
+	a, _ := getAllocator(true)
1109 1109
 	benchmarkRequest(b, a, "10.0.0.0/8")
1110 1110
 }
1111 1111
 
... ...
@@ -1115,7 +1116,7 @@ func TestAllocateRandomDeallocate(t *testing.T) {
1115 1115
 }
1116 1116
 
1117 1117
 func testAllocateRandomDeallocate(t *testing.T, pool, subPool string, num int) {
1118
-	ds, err := randomLocalStore()
1118
+	ds, err := randomLocalStore(true)
1119 1119
 	if err != nil {
1120 1120
 		t.Fatal(err)
1121 1121
 	}
... ...
@@ -1184,7 +1185,7 @@ func testAllocateRandomDeallocate(t *testing.T, pool, subPool string, num int) {
1184 1184
 
1185 1185
 func TestRetrieveFromStore(t *testing.T) {
1186 1186
 	num := 200
1187
-	ds, err := randomLocalStore()
1187
+	ds, err := randomLocalStore(true)
1188 1188
 	if err != nil {
1189 1189
 		t.Fatal(err)
1190 1190
 	}
... ...
@@ -1319,7 +1320,7 @@ func runParallelTests(t *testing.T, instance int) {
1319 1319
 	// The first instance creates the allocator, gives the start
1320 1320
 	// and finally checks the pools each instance was assigned
1321 1321
 	if instance == first {
1322
-		allocator, err = getAllocator()
1322
+		allocator, err = getAllocator(true)
1323 1323
 		if err != nil {
1324 1324
 			t.Fatal(err)
1325 1325
 		}
... ...
@@ -1362,6 +1363,71 @@ func runParallelTests(t *testing.T, instance int) {
1362 1362
 	}
1363 1363
 }
1364 1364
 
1365
+func TestRequestReleaseAddressDuplicate(t *testing.T) {
1366
+	a, err := getAllocator(false)
1367
+	if err != nil {
1368
+		t.Fatal(err)
1369
+	}
1370
+	type IP struct {
1371
+		ip  *net.IPNet
1372
+		ref int
1373
+	}
1374
+	ips := []IP{}
1375
+	allocatedIPs := []*net.IPNet{}
1376
+	a.addrSpaces["rosso"] = &addrSpace{
1377
+		id:      dsConfigKey + "/" + "rosso",
1378
+		ds:      a.addrSpaces[localAddressSpace].ds,
1379
+		alloc:   a.addrSpaces[localAddressSpace].alloc,
1380
+		scope:   a.addrSpaces[localAddressSpace].scope,
1381
+		subnets: map[SubnetKey]*PoolData{},
1382
+	}
1383
+	var wg sync.WaitGroup
1384
+	opts := map[string]string{
1385
+		ipamapi.AllocSerialPrefix: "true",
1386
+	}
1387
+	var l sync.Mutex
1388
+
1389
+	poolID, _, _, err := a.RequestPool("rosso", "198.168.0.0/23", "", nil, false)
1390
+	if err != nil {
1391
+		t.Fatal(err)
1392
+	}
1393
+
1394
+	for err == nil {
1395
+		var c *net.IPNet
1396
+		if c, _, err = a.RequestAddress(poolID, nil, opts); err == nil {
1397
+			l.Lock()
1398
+			ips = append(ips, IP{c, 1})
1399
+			l.Unlock()
1400
+			allocatedIPs = append(allocatedIPs, c)
1401
+			if len(allocatedIPs) > 500 {
1402
+				i := rand.Intn(len(allocatedIPs) - 1)
1403
+				wg.Add(1)
1404
+				go func(ip *net.IPNet) {
1405
+					if err = a.ReleaseAddress(poolID, ip.IP); err != nil {
1406
+						t.Fatal(err)
1407
+					}
1408
+					l.Lock()
1409
+					ips = append(ips, IP{ip, -1})
1410
+					l.Unlock()
1411
+					wg.Done()
1412
+				}(allocatedIPs[i])
1413
+				allocatedIPs = append(allocatedIPs[:i], allocatedIPs[i+1:]...)
1414
+			}
1415
+		}
1416
+	}
1417
+	wg.Wait()
1418
+	refMap := make(map[string]int)
1419
+	for _, ip := range ips {
1420
+		refMap[ip.ip.String()] = refMap[ip.ip.String()] + ip.ref
1421
+		if refMap[ip.ip.String()] < 0 {
1422
+			t.Fatalf("IP %s was previously released", ip.ip.String())
1423
+		}
1424
+		if refMap[ip.ip.String()] > 1 {
1425
+			t.Fatalf("IP %s was previously allocated", ip.ip.String())
1426
+		}
1427
+	}
1428
+}
1429
+
1365 1430
 func TestParallelPredefinedRequest1(t *testing.T) {
1366 1431
 	runParallelTests(t, 0)
1367 1432
 }