diff options
author | Kari Oikarinen <kari.oikarinen@qt.io> | 2017-03-15 16:40:19 +0200 |
---|---|---|
committer | Kari Oikarinen <kari.oikarinen@qt.io> | 2017-05-02 13:21:24 +0000 |
commit | 842e0c9a9e95c7e8b0b02791f620fd859477d2e1 (patch) | |
tree | 7f38a232301583027724508615f079a7363eb2d7 /tests | |
parent | cac1d51ed38a3aa2db7d61fee3ab3245ab99f588 (diff) |
Keep track of used subnets
If we don't keep track of them, inserting two devices at the same time
can lead to both picking the same candidate. This happens if the host
does not get an IP in time and thus the network is still free from host
perspective as the second call looks for the subnet to use.
The tracking is done by UsbDevice and DeviceInformation keeping a
SubnetReservation. The SubnetReservation is gotten from
findUnusedSubnet(), which uses a SubnetPool singleton to keep track of
them. When the SubnetReservations are destructed, they call SubnetPool
to free the subnet the reserved.
Task-number: QTBUG-59449
Change-Id: I4b28ade4fa7a5660bd699882398facafafc9d795
Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/tst_subnet.cpp | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/tests/tst_subnet.cpp b/tests/tst_subnet.cpp index 5aa36cf..90733f0 100644 --- a/tests/tst_subnet.cpp +++ b/tests/tst_subnet.cpp @@ -25,12 +25,6 @@ using Subnets = std::vector<Subnet>; -bool operator==(const Subnet &lhs, const Subnet &rhs) -{ - return lhs.address == rhs.address - && lhs.prefixLength == rhs.prefixLength; -} - class tst_Subnet : public QObject { Q_OBJECT @@ -40,6 +34,9 @@ private slots: void freeSubnets_data(); void usedSubnets(); void usedSubnets_data(); + void reserveOne(); + void reserveOne_data(); + void reserveSome(); }; void tst_Subnet::freeSubnets() @@ -95,6 +92,66 @@ void tst_Subnet::usedSubnets_data() QTest::newRow("3") << candidates << subnets; } +void tst_Subnet::reserveOne() +{ + QFETCH(Subnet, subnet); + + SubnetPool *pool = SubnetPool::instance(); + const auto amountOfCandidates = pool->candidates().size(); + QVERIFY(amountOfCandidates >= 1); + { + const auto reservation = pool->reserve(subnet); + const auto candidates = pool->candidates(); + QCOMPARE(candidates.size(), amountOfCandidates - 1); + QVERIFY(std::none_of(candidates.begin(), candidates.end(), + [&](const Subnet &other) { + return subnet == other; + })); + } + const auto candidates = pool->candidates(); + QCOMPARE(candidates.size(), amountOfCandidates); + QVERIFY(std::find(candidates.begin(), candidates.end(), subnet) != candidates.end()); +} + +void tst_Subnet::reserveOne_data() +{ + QTest::addColumn<Subnet>("subnet"); + QTest::newRow("first") << Subnet{QHostAddress{"172.16.58.1"}, 30}; + QTest::newRow("middle") << Subnet{QHostAddress{"172.25.58.1"}, 30}; + QTest::newRow("last") << Subnet{QHostAddress{"10.17.20.1"}, 30}; +} + +void tst_Subnet::reserveSome() +{ + SubnetPool *pool = SubnetPool::instance(); + const Subnets subnetsToReserve {{QHostAddress{"172.18.58.1"}, 30}, + {QHostAddress{"172.19.58.1"}, 30}, + {QHostAddress{"172.20.58.1"}, 30}}; + const auto amountOfCandidates = pool->candidates().size(); + + std::vector<SubnetReservation> reservations; + for (const Subnet &subnet : subnetsToReserve) + { + reservations.push_back(pool->reserve(subnet)); + const auto candidates = pool->candidates(); + QCOMPARE(candidates.size(), amountOfCandidates - reservations.size()); + QVERIFY(std::find(candidates.begin(), candidates.end(), subnet) == candidates.end()); + } + const auto candidates = pool->candidates(); + QCOMPARE(candidates.size(), amountOfCandidates - reservations.size()); + QVERIFY(std::none_of(candidates.begin(), candidates.end(), + [&](const Subnet &subnet) { + return std::find(subnetsToReserve.begin(), + subnetsToReserve.end(), + subnet) + != subnetsToReserve.end(); + })); + + reservations.clear(); + + QCOMPARE(pool->candidates().size(), amountOfCandidates); +} + QTEST_APPLESS_MAIN(tst_Subnet) #include "tst_subnet.moc" |