io_service_->poll();
}
+ /// @brief Verifies that the partner state is set and retrieved correctly.
+ void partnerStateTest();
+
+ /// @brief Verifies that the partner's scopes are set and retrieved correctly.
+ void partnerScopesTest();
+
+ /// @brief Verifies that the object is poked right after construction.
+ void initialDurationTest();
+
+ /// @brief Verifies that poking the state updates the returned duration.
+ void pokeTest();
+
+ /// @brief Test that heartbeat function is triggered.
+ void heartbeatTest();
+
+ /// @brief Test that invalid values provided to startHeartbeat are rejected.
+ void startHeartbeatInvalidValuesTest();
+
+ /// @brief Test that failure detection works properly for DHCPv4 case.
+ void detectFailureV4Test();
+
+ /// @brief This test verifies that it is possible to disable analysis of the DHCPv4
+ /// packets in which case the partner's failure is assumed when there is
+ /// no connection over the control channel.
+ void failureDetectionDisabled4Test();
+
+ /// @brief Test that failure detection works properly for DHCPv6 case.
+ void detectFailureV6Test();
+
+ /// @brief This test verifies that it is possible to disable analysis of the DHCPv6
+ /// packets in which case the partner's failure is assumed when there is
+ /// no connection over the control channel.
+ void failureDetectionDisabled6Test();
+
+ /// @brief This test verifies that the clock skew is checked properly by the
+ /// clockSkewShouldWarn and clockSkewShouldTerminate functions.
+ void clockSkewTest();
+
+ /// @brief This test verifies that the clock skew value is formatted correctly
+ /// for logging.
+ void logFormatClockSkewTest();
+
+ /// @brief Tests that the communication state report is correct.
+ void getReportTest();
+
+ /// @brief Tests unusual values used to create the report.
+ void getReportDefaultValuesTest();
+
/// @brief Returns test heartbeat implementation.
///
/// @return Pointer to heartbeat implementation function under test.
};
// Verifies that the partner state is set and retrieved correctly.
-TEST_F(CommunicationStateTest, partnerState) {
+void
+CommunicationStateTest::partnerStateTest() {
// Initially the state is unknown.
EXPECT_LT(state_.getPartnerState(), 0);
}
// Verifies that the partner's scopes are set and retrieved correctly.
-TEST_F(CommunicationStateTest, partnerScopes) {
+void
+CommunicationStateTest::partnerScopesTest() {
// Initially, the scopes should be empty.
ASSERT_TRUE(state_.getPartnerScopes().empty());
}
// Verifies that the object is poked right after construction.
-TEST_F(CommunicationStateTest, initialDuration) {
+void
+CommunicationStateTest::initialDurationTest() {
EXPECT_TRUE(state_.isPoked());
}
// Verifies that poking the state updates the returned duration.
-TEST_F(CommunicationStateTest, poke) {
- state_.modifyPokeTime(-30);
- ASSERT_GE(state_.getDurationInMillisecs(), 30000);
- ASSERT_TRUE(state_.isCommunicationInterrupted());
- ASSERT_NO_THROW(state_.poke());
- EXPECT_TRUE(state_.isPoked());
- EXPECT_FALSE(state_.isCommunicationInterrupted());
-}
-
-// Verifies that poking the state updates the returned duration.
-TEST_F(CommunicationStateTest, pokeMultiThreading) {
- MultiThreadingMgr::instance().setMode(true);
+void
+CommunicationStateTest::pokeTest() {
state_.modifyPokeTime(-30);
ASSERT_GE(state_.getDurationInMillisecs(), 30000);
ASSERT_TRUE(state_.isCommunicationInterrupted());
}
// Test that heartbeat function is triggered.
-TEST_F(CommunicationStateTest, heartbeat) {
+void
+CommunicationStateTest::heartbeatTest() {
// Set poke time to the past and expect that the object is considered
// not poked.
state_.modifyPokeTime(-30);
}
// Test that invalid values provided to startHeartbeat are rejected.
-TEST_F(CommunicationStateTest, startHeartbeatInvalidValues) {
+void
+CommunicationStateTest::startHeartbeatInvalidValuesTest() {
EXPECT_THROW(state_.startHeartbeat(-1, getHeartbeatImpl()), BadValue);
EXPECT_THROW(state_.startHeartbeat(0, getHeartbeatImpl()), BadValue);
EXPECT_THROW(state_.startHeartbeat(1, 0), BadValue);
}
// Test that failure detection works properly for DHCPv4 case.
-TEST_F(CommunicationStateTest, detectFailureV4) {
- // Initially, there should be no unacked clients recorded.
- ASSERT_FALSE(state_.failureDetected());
- EXPECT_EQ(0, state_.getUnackedClientsCount());
- EXPECT_EQ(0, state_.getConnectingClientsCount());
- EXPECT_EQ(0, state_.getAnalyzedMessagesCount());
-
- // The maximum number of unacked clients is 10. Let's provide 10
- // DHCPDISCOVER messages with the "secs" value of 15 which exceeds
- // the threshold of 10. All these clients should be recorded as
- // unacked.
- for (uint8_t i = 0; i < 10; ++i) {
- // Some of the requests have no client identifier to test that
- // we don't fall over if the client identifier is null.
- const uint8_t client_id_seed = (i < 5 ? i : 0);
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, i,
- client_id_seed,
- 15)));
- // We don't exceed the maximum of number of unacked clients so the
- // partner failure shouldn't be reported.
- ASSERT_FALSE(state_.failureDetected())
- << "failure detected for the request number "
- << static_cast<int>(i);
- }
- EXPECT_EQ(10, state_.getUnackedClientsCount());
- EXPECT_EQ(10, state_.getConnectingClientsCount());
- EXPECT_EQ(10, state_.getAnalyzedMessagesCount());
-
- // Let's provide similar set of requests but this time the "secs" field is
- // below the threshold. They should not be counted as failures. Also,
- // all of these requests have client identifier.
- for (uint8_t i = 0; i < 10; ++i) {
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, i, i,
- 9)));
- ASSERT_FALSE(state_.failureDetected())
- << "failure detected for the request number "
- << static_cast<int>(i);
- }
- EXPECT_EQ(10, state_.getUnackedClientsCount());
- EXPECT_EQ(15, state_.getConnectingClientsCount());
- EXPECT_EQ(20, state_.getAnalyzedMessagesCount());
-
- // Let's create a message from a new (not recorded yet) client with the
- // "secs" field value below the threshold. It should not be counted as failure.
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, 10, 10, 6)));
-
- // Still no failure.
- ASSERT_FALSE(state_.failureDetected());
- EXPECT_EQ(10, state_.getUnackedClientsCount());
- EXPECT_EQ(16, state_.getConnectingClientsCount());
- EXPECT_EQ(21, state_.getAnalyzedMessagesCount());
-
- // Let's repeat one of the requests which already have been recorded as
- // unacked but with a greater value of "secs" field. This should not
- // be counted because only new clients count.
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, 3, 3, 20)));
- ASSERT_FALSE(state_.failureDetected());
- EXPECT_EQ(10, state_.getUnackedClientsCount());
- EXPECT_EQ(16, state_.getConnectingClientsCount());
- EXPECT_EQ(22, state_.getAnalyzedMessagesCount());
-
- // This time let's simulate a client with a MAC address already recorded but
- // with a client identifier. This should be counted as a new unacked request.
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, 7, 7, 15)));
- ASSERT_TRUE(state_.failureDetected());
- EXPECT_EQ(11, state_.getUnackedClientsCount());
- EXPECT_EQ(16, state_.getConnectingClientsCount());
- EXPECT_EQ(23, state_.getAnalyzedMessagesCount());
-
- // Poking should cause all counters to reset as it is an indication that the
- // control connection has been re-established.
- ASSERT_NO_THROW(state_.poke());
-
- // We're back to no failure state.
- EXPECT_FALSE(state_.failureDetected());
- EXPECT_EQ(0, state_.getUnackedClientsCount());
- EXPECT_EQ(0, state_.getConnectingClientsCount());
- EXPECT_EQ(0, state_.getAnalyzedMessagesCount());
-
- // Send 11 DHCPDISCOVER messages with the "secs" field bytes swapped. Swapping
- // bytes was reported for some misbehaving Windows clients. The server should
- // detect bytes swapping when second byte is 0 and the first byte is non-zero.
- // However, the first byte is equal to 5 which is below our threshold so none
- // of the requests below should count as unacked.
- for (uint8_t i = 0; i < 11; ++i) {
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, i, i,
- 0x0500)));
- ASSERT_FALSE(state_.failureDetected())
- << "failure detected for the request number "
- << static_cast<int>(i)
- << " when testing swapped secs field bytes";
- }
- EXPECT_EQ(0, state_.getUnackedClientsCount());
- EXPECT_EQ(11, state_.getConnectingClientsCount());
- EXPECT_EQ(11, state_.getAnalyzedMessagesCount());
-
- // Repeat the same test, but this time either the first byte exceeds the
- // secs threshold or the second byte is non-zero. All should be counted
- // as unacked.
- for (uint8_t i = 0; i < 10; ++i) {
- uint16_t secs = (i % 2 == 0 ? 0x0F00 : 0x0501);
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, i, i,
- secs)));
- ASSERT_FALSE(state_.failureDetected())
- << "failure detected for the request number "
- << static_cast<int>(i)
- << " when testing swapped secs field bytes";
- }
-
- // This last message should cause the failure state.
- ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, 11, 11,
- 0x30)));
- EXPECT_TRUE(state_.failureDetected());
- EXPECT_EQ(11, state_.getUnackedClientsCount());
- EXPECT_EQ(12, state_.getConnectingClientsCount());
- EXPECT_EQ(22, state_.getAnalyzedMessagesCount());
-}
-
-// Test that failure detection works properly for DHCPv4 case.
-TEST_F(CommunicationStateTest, detectFailureV4MultiThreading) {
- MultiThreadingMgr::instance().setMode(true);
+void
+CommunicationStateTest::detectFailureV4Test() {
// Initially, there should be no unacked clients recorded.
ASSERT_FALSE(state_.failureDetected());
EXPECT_EQ(0, state_.getUnackedClientsCount());
// This test verifies that it is possible to disable analysis of the DHCPv4
// packets in which case the partner's failure is assumed when there is
// no connection over the control channel.
-TEST_F(CommunicationStateTest, failureDetectionDisabled4) {
+void
+CommunicationStateTest::failureDetectionDisabled4Test() {
state_.config_->setMaxUnackedClients(0);
EXPECT_TRUE(state_.failureDetected());
}
-// This test verifies that it is possible to disable analysis of the DHCPv4
-// packets in which case the partner's failure is assumed when there is
-// no connection over the control channel.
-TEST_F(CommunicationStateTest, failureDetectionDisabled4MultiThreading) {
- MultiThreadingMgr::instance().setMode(true);
- state_.config_->setMaxUnackedClients(0);
- EXPECT_TRUE(state_.failureDetected());
-}
-
-// Test that failure detection works properly for DHCPv6 case.
-TEST_F(CommunicationStateTest, detectFailureV6) {
- // Initially, there should be no unacked clients recorded.
- ASSERT_FALSE(state6_.failureDetected());
- EXPECT_EQ(0, state6_.getUnackedClientsCount());
- EXPECT_EQ(0, state6_.getConnectingClientsCount());
- EXPECT_EQ(0, state6_.getAnalyzedMessagesCount());
-
- // The maximum number of unacked clients is 10. Let's provide 10
- // Solicit messages with the "elapsed time" value of 1500 which exceeds
- // the threshold of 10000ms. Note that the elapsed time value is provided
- // in 1/100s of 1 second. All these clients should be recorded as
- // unacked.
- for (uint8_t i = 0; i < 10; ++i) {
- ASSERT_NO_THROW(state6_.analyzeMessage(createMessage6(DHCPV6_SOLICIT, i,
- 1500)));
- // We don't exceed the maximum number of unacked clients so the
- // partner failure shouldn't be reported.
- ASSERT_FALSE(state6_.failureDetected())
- << "failure detected for the request number "
- << static_cast<int>(i);
- }
- EXPECT_EQ(10, state6_.getUnackedClientsCount());
- EXPECT_EQ(10, state6_.getConnectingClientsCount());
- EXPECT_EQ(10, state6_.getAnalyzedMessagesCount());
-
- // Let's provide similar set of requests but this time the "elapsed time" is
- // below the threshold. This should not reduce the number of unacked or new
- // clients.
- for (uint8_t i = 0; i < 10; ++i) {
- ASSERT_NO_THROW(state6_.analyzeMessage(createMessage6(DHCPV6_SOLICIT, i,
- 900)));
- ASSERT_FALSE(state6_.failureDetected())
- << "failure detected for the request number "
- << static_cast<int>(i);
- }
- EXPECT_EQ(10, state6_.getUnackedClientsCount());
- EXPECT_EQ(10, state6_.getConnectingClientsCount());
- EXPECT_EQ(20, state6_.getAnalyzedMessagesCount());
-
- // Let's create a message from a new (not recorded yet) client with the
- // "elapsed time" value below the threshold. It should not count as failure.
- ASSERT_NO_THROW(state6_.analyzeMessage(createMessage6(DHCPV6_SOLICIT, 10, 600)));
-
- // Still no failure.
- ASSERT_FALSE(state6_.failureDetected());
- EXPECT_EQ(10, state6_.getUnackedClientsCount());
- EXPECT_EQ(11, state6_.getConnectingClientsCount());
- EXPECT_EQ(21, state6_.getAnalyzedMessagesCount());
-
- // Let's repeat one of the requests which already have been recorded as
- // unacked but with a greater value of "elapsed time". This should not
- // be counted because only new clients count.
- ASSERT_NO_THROW(state6_.analyzeMessage(createMessage6(DHCPV6_SOLICIT, 3, 2000)));
- ASSERT_FALSE(state6_.failureDetected());
- EXPECT_EQ(10, state6_.getUnackedClientsCount());
- EXPECT_EQ(11, state6_.getConnectingClientsCount());
- EXPECT_EQ(22, state6_.getAnalyzedMessagesCount());
-
- // New unacked client should cause failure to be detected.
- ASSERT_NO_THROW(state6_.analyzeMessage(createMessage6(DHCPV6_SOLICIT, 11, 1500)));
- ASSERT_TRUE(state6_.failureDetected());
- EXPECT_EQ(11, state6_.getUnackedClientsCount());
- EXPECT_EQ(12, state6_.getConnectingClientsCount());
- EXPECT_EQ(23, state6_.getAnalyzedMessagesCount());
-
- // Poking should cause all counters to reset as it is an indication that the
- // control connection has been re-established.
- ASSERT_NO_THROW(state6_.poke());
-
- // We're back to no failure state.
- EXPECT_FALSE(state6_.failureDetected());
- EXPECT_EQ(0, state6_.getUnackedClientsCount());
- EXPECT_EQ(0, state6_.getConnectingClientsCount());
- EXPECT_EQ(0, state6_.getAnalyzedMessagesCount());
-}
-
// Test that failure detection works properly for DHCPv6 case.
-TEST_F(CommunicationStateTest, detectFailureV6MultiThreading) {
- MultiThreadingMgr::instance().setMode(true);
+void
+CommunicationStateTest::detectFailureV6Test() {
// Initially, there should be no unacked clients recorded.
ASSERT_FALSE(state6_.failureDetected());
EXPECT_EQ(0, state6_.getUnackedClientsCount());
// This test verifies that it is possible to disable analysis of the DHCPv6
// packets in which case the partner's failure is assumed when there is
// no connection over the control channel.
-TEST_F(CommunicationStateTest, failureDetectionDisabled6) {
- state6_.config_->setMaxUnackedClients(0);
- EXPECT_TRUE(state6_.failureDetected());
-}
-
-// This test verifies that it is possible to disable analysis of the DHCPv6
-// packets in which case the partner's failure is assumed when there is
-// no connection over the control channel.
-TEST_F(CommunicationStateTest, failureDetectionDisabled6MultiThreading) {
- MultiThreadingMgr::instance().setMode(true);
+void
+CommunicationStateTest::failureDetectionDisabled6Test() {
state6_.config_->setMaxUnackedClients(0);
EXPECT_TRUE(state6_.failureDetected());
}
// This test verifies that the clock skew is checked properly by the
// clockSkewShouldWarn and clockSkewShouldTerminate functions.
-TEST_F(CommunicationStateTest, clockSkew) {
+void
+CommunicationStateTest::clockSkewTest() {
// Default clock skew is 0.
EXPECT_FALSE(state_.clockSkewShouldWarn());
EXPECT_FALSE(state_.clockSkewShouldTerminate());
// This test verifies that the clock skew value is formatted correctly
// for logging.
-TEST_F(CommunicationStateTest, logFormatClockSkew) {
+void
+CommunicationStateTest::logFormatClockSkewTest() {
// Make sure logFormatClockSkew() does not throw if called prior
// the first call to setPartnerTime().
std::string log;
}
// Tests that the communication state report is correct.
-TEST_F(CommunicationStateTest, getReport) {
+void
+CommunicationStateTest::getReportTest() {
state_.setPartnerState("waiting");
auto scopes = Element::createList();
}
// Tests unusual values used to create the report.
-TEST_F(CommunicationStateTest, getReportDefaultValues) {
+void
+CommunicationStateTest::getReportDefaultValuesTest() {
auto report = state_.getReport();
ASSERT_TRUE(report);
EXPECT_TRUE(isEquivalent(Element::fromJSON(expected), report));
}
+TEST_F(CommunicationStateTest, partnerStateTest) {
+ partnerStateTest();
+}
+
+TEST_F(CommunicationStateTest, partnerStateTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ partnerStateTest();
+}
+
+TEST_F(CommunicationStateTest, partnerScopesTest) {
+ partnerScopesTest();
+}
+
+TEST_F(CommunicationStateTest, partnerScopesTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ partnerScopesTest();
+}
+
+TEST_F(CommunicationStateTest, initialDurationTest) {
+ initialDurationTest();
+}
+
+TEST_F(CommunicationStateTest, initialDurationTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ initialDurationTest();
+}
+
+TEST_F(CommunicationStateTest, pokeTest) {
+ pokeTest();
+}
+
+TEST_F(CommunicationStateTest, pokeTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ pokeTest();
+}
+
+TEST_F(CommunicationStateTest, heartbeatTest) {
+ heartbeatTest();
+}
+
+TEST_F(CommunicationStateTest, heartbeatTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ heartbeatTest();
+}
+
+TEST_F(CommunicationStateTest, startHeartbeatInvalidValuesTest) {
+ startHeartbeatInvalidValuesTest();
+}
+
+TEST_F(CommunicationStateTest, startHeartbeatInvalidValuesTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ startHeartbeatInvalidValuesTest();
+}
+
+TEST_F(CommunicationStateTest, detectFailureV4Test) {
+ detectFailureV4Test();
+}
+
+TEST_F(CommunicationStateTest, detectFailureV4TestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ detectFailureV4Test();
+}
+
+TEST_F(CommunicationStateTest, failureDetectionDisabled4Test) {
+ failureDetectionDisabled4Test();
+}
+
+TEST_F(CommunicationStateTest, failureDetectionDisabled4TestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ failureDetectionDisabled4Test();
+}
+
+TEST_F(CommunicationStateTest, detectFailureV6Test) {
+ detectFailureV6Test();
+}
+
+TEST_F(CommunicationStateTest, detectFailureV6TestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ detectFailureV6Test();
+}
+
+TEST_F(CommunicationStateTest, failureDetectionDisabled6Test) {
+ failureDetectionDisabled6Test();
+}
+
+TEST_F(CommunicationStateTest, failureDetectionDisabled6TestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ failureDetectionDisabled6Test();
+}
+
+TEST_F(CommunicationStateTest, clockSkewTest) {
+ clockSkewTest();
+}
+
+TEST_F(CommunicationStateTest, clockSkewTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ clockSkewTest();
+}
+
+TEST_F(CommunicationStateTest, logFormatClockSkewTest) {
+ logFormatClockSkewTest();
+}
+
+TEST_F(CommunicationStateTest, logFormatClockSkewTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ logFormatClockSkewTest();
+}
+
+TEST_F(CommunicationStateTest, getReportTest) {
+ getReportTest();
+}
+
+TEST_F(CommunicationStateTest, getReportTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ getReportTest();
+}
+
+TEST_F(CommunicationStateTest, getReportDefaultValuesTest) {
+ getReportDefaultValuesTest();
+}
+
+TEST_F(CommunicationStateTest, getReportDefaultValuesTestMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ getReportDefaultValuesTest();
+}
+
}