This commit contains test cases to verify the changes and to
solidify the library.
Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
| ... | ... |
@@ -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 |
} |