fgerlits commented on a change in pull request #958:
URL: https://github.com/apache/nifi-minifi-cpp/pull/958#discussion_r542401133
##########
File path: libminifi/test/unit/NetworkPrioritizerServiceTests.cpp
##########
@@ -41,129 +47,105 @@ TEST_CASE("TestPrioritizerOneInterface", "[test1]") {
}
TEST_CASE("TestPrioritizerOneInterfaceMaxPayload", "[test2]") {
- auto controller =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService");
- std::shared_ptr<minifi::Configure> configuration =
std::make_shared<minifi::Configure>();
+ auto controller = createNetworkPrioritizerService("TestService");
controller->initialize();
controller->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth0,eth1");
controller->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
-
controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"1 B");
-
controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxPayload,
"1 B");
+
controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"1 kB");
+
controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxPayload,
"10 B");
controller->onEnable();
- // can't because we've triggered the max payload
- REQUIRE("" == controller->getInterface(5).getInterface());
+
+ REQUIRE("eth0" == controller->getInterface(5).getInterface());
+ REQUIRE("" == controller->getInterface(20).getInterface()); // larger than
max payload
+ REQUIRE("eth0" == controller->getInterface(5).getInterface());
}
TEST_CASE("TestPrioritizerOneInterfaceMaxThroughput", "[test3]") {
- auto controller =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService");
- std::shared_ptr<minifi::Configure> configuration =
std::make_shared<minifi::Configure>();
+ auto clock = std::make_shared<utils::ManualClock>();
+ auto controller = createNetworkPrioritizerService("TestService", clock);
controller->initialize();
controller->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth0,eth1");
controller->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
controller->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"10 B");
controller->onEnable();
- // can't because we've triggered the max payload
REQUIRE("eth0" == controller->getInterface(5).getInterface());
REQUIRE("eth0" == controller->getInterface(5).getInterface());
- REQUIRE("" == controller->getInterface(5).getInterface());
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- REQUIRE("eth0" == controller->getInterface(5).getInterface());
+ REQUIRE("" == controller->getInterface(5).getInterface()); // max
throughput reached
+ clock->advance(std::chrono::milliseconds{10}); // wait for more tokens to
be generated
+ REQUIRE("eth0" == controller->getInterface(5).getInterface()); // now we
can send again
}
TEST_CASE("TestPriorotizerMultipleInterfaces", "[test4]") {
-
LogTestController::getInstance().setTrace<minifi::controllers::NetworkPrioritizerService>();
-
- auto controller =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService");
- auto controller2 =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService2");
- auto controller3 =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService3");
+ auto clock = std::make_shared<utils::ManualClock>();
+ auto parent_controller = createNetworkPrioritizerService("TestService",
clock);
std::shared_ptr<minifi::Configure> configuration =
std::make_shared<minifi::Configure>();
- controller->initialize();
-
controller->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
+ parent_controller->initialize();
+
parent_controller->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
- controller3->initialize();
-
controller3->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth0");
-
controller3->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
-
controller3->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"10 B");
- controller3->onEnable();
-
- controller2->initialize();
-
controller2->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth1");
-
controller2->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
-
controller2->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"10 B");
- controller2->onEnable();
- std::vector<std::shared_ptr<core::controller::ControllerService> > services;
- services.push_back(controller2);
- services.push_back(controller3);
- controller->setLinkedControllerServices(services);
- controller->onEnable();
- // can't because we've triggered the max payload
- REQUIRE("eth1" == controller->getInterface(5).getInterface());
- REQUIRE("eth1" == controller->getInterface(5).getInterface());
- REQUIRE("eth0" == controller->getInterface(5).getInterface());
- REQUIRE("eth0" == controller->getInterface(5).getInterface());
-}
+ auto controller0 = createNetworkPrioritizerService("TestService_eth0",
clock);
+ controller0->initialize();
+
controller0->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth0");
+
controller0->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
+
controller0->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"10 B");
+ controller0->onEnable();
-TEST_CASE("TestPriorotizerMultipleInterfacesNeverSwitch", "[test5]") {
- auto controller =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService");
- auto controller2 =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService2");
- auto controller3 =
std::make_shared<minifi::controllers::NetworkPrioritizerService>("TestService3");
- std::shared_ptr<minifi::Configure> configuration =
std::make_shared<minifi::Configure>();
- controller->initialize();
-
controller->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
+ auto controller1 = createNetworkPrioritizerService("TestService_eth1",
clock);
+ controller1->initialize();
+
controller1->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth1");
+
controller1->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
+
controller1->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"10 B");
+ controller1->onEnable();
- controller3->initialize();
-
controller3->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth0");
-
controller3->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
-
controller3->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"1 kB");
- controller3->onEnable();
-
- controller2->initialize();
-
controller2->setProperty(minifi::controllers::NetworkPrioritizerService::NetworkControllers,
"eth1");
-
controller2->setProperty(minifi::controllers::NetworkPrioritizerService::VerifyInterfaces,
"false");
-
controller2->setProperty(minifi::controllers::NetworkPrioritizerService::MaxThroughput,
"10 B");
- controller2->onEnable();
std::vector<std::shared_ptr<core::controller::ControllerService> > services;
- services.push_back(controller3);
- services.push_back(controller2);
- controller->setLinkedControllerServices(services);
- controller->onEnable();
- // can't because we've triggered the max payload
- for (int i = 0; i < 50; i++) {
- REQUIRE("eth0" == controller->getInterface(5).getInterface());
- REQUIRE("eth0" == controller->getInterface(5).getInterface());
- REQUIRE("eth0" == controller->getInterface(5).getInterface());
- REQUIRE("eth0" == controller->getInterface(5).getInterface());
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
+ services.push_back(controller0);
+ services.push_back(controller1);
+ parent_controller->setLinkedControllerServices(services);
+ parent_controller->onEnable();
+
+ SECTION("Switch to second interface when the first is saturated") {
+ REQUIRE("eth0" == parent_controller->getInterface(5).getInterface());
+ REQUIRE("eth0" == parent_controller->getInterface(5).getInterface());
+ // triggered the max throughput on eth0, switching to eth1
+ REQUIRE("eth1" == parent_controller->getInterface(5).getInterface());
+ REQUIRE("eth1" == parent_controller->getInterface(5).getInterface());
}
-}
+ SECTION("Can keep sending on eth0 if we wait between packets") {
+ for (int i = 0; i < 100; i++) {
+ REQUIRE("eth0" == parent_controller->getInterface(10).getInterface());
Review comment:
> `getInterface(size)` returns a network interface that we should use to
send the next size number of bytes?
Yes.
> what controls how long we should wait (5ms in this case) until the same
interface is available?
It is a (version of the) [token bucket
algorithm](https://en.wikipedia.org/wiki/Token_bucket): conceptually, the
bucket starts out with `b` tokens and `t` tokens are added to the bucket each
millisecond, and each send operation removes `s` times `size` tokens from the
bucket, if there are enough tokens available, otherwise it fails (and does not
remove any tokens).
[In practice, the bucket is filled in `getInterface()` according to the
number of elapsed milliseconds since the last call to `getInterface()`, and the
way the `b`, `t` and `s` parameters are set is a bit strange (`t` is always 2,
`b` and `s` depend on `MaxThroughput`, but differently depending on whether
`MaxThroughput` is less or more than 1 kB).]
Since I don't think anybody actually uses this class at the moment, I did
not clean it up; I only fixed the unit test so that it is no longer dependent
on timing, and fixed a few obvious bugs in the service code.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]