ha_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
ha_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
ha_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
+ha_unittests_LDADD += $(top_builddir)/src/lib/testutils/libkea-testutils.la
ha_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
ha_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
ha_unittests_LDADD += $(LOG4CPLUS_LIBS)
#include <dhcp/dhcp6.h>
#include <exceptions/exceptions.h>
#include <http/date_time.h>
+#include <testutils/gtest_utils.h>
+#include <testutils/test_to_element.h>
#include <util/multi_threading_mgr.h>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace isc::ha;
using namespace isc::ha::test;
using namespace isc::http;
+using namespace isc::test;
using namespace isc::util;
using namespace boost::posix_time;
ASSERT_NO_THROW(state_.analyzeMessage(createMessage4(DHCPDISCOVER, 1, 0, 15)));
// Get the report.
- auto report = state_.getReport();
+ ElementPtr report;
+ ASSERT_NO_THROW_LOG(report = state_.getReport());
ASSERT_TRUE(report);
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ checkThatTimeIsParsable(report);
+
// Compare with the expected output.
std::string expected = "{"
" \"age\": 100,"
" \"connecting-clients\": 2,"
" \"unacked-clients\": 1,"
" \"unacked-clients-left\": 10,"
- " \"analyzed-packets\": 2"
+ " \"analyzed-packets\": 2,"
+ " \"clock-skew\": 0"
"}";
- EXPECT_TRUE(isEquivalent(Element::fromJSON(expected), report));
+ expectEqWithDiff(Element::fromJSON(expected), report);
}
// Tests unusual values used to create the report.
void
CommunicationStateTest::getReportDefaultValuesTest() {
- auto report = state_.getReport();
+ ElementPtr report;
+ ASSERT_NO_THROW_LOG(report = state_.getReport());
ASSERT_TRUE(report);
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ checkThatTimeIsParsable(report);
+
// Compare with the expected output.
std::string expected = "{"
" \"age\": 0,"
" \"connecting-clients\": 0,"
" \"unacked-clients\": 0,"
" \"unacked-clients-left\": 0,"
- " \"analyzed-packets\": 0"
+ " \"analyzed-packets\": 0,"
+ " \"clock-skew\": 0"
"}";
- EXPECT_TRUE(isEquivalent(Element::fromJSON(expected), report));
+ expectEqWithDiff(Element::fromJSON(expected), report);
}
void
#include <hooks/hooks_manager.h>
#include <stats/stats_mgr.h>
#include <testutils/gtest_utils.h>
+#include <testutils/test_to_element.h>
+
#include <boost/pointer_cast.hpp>
+
#include <gtest/gtest.h>
+
#include <string>
using namespace isc::asiolink;
using namespace isc::ha::test;
using namespace isc::hooks;
using namespace isc::stats;
+using namespace isc::test;
namespace {
callout_handle->getArgument("response", got);
ASSERT_TRUE(got);
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ ConstElementPtr ha_servers(
+ got->get("arguments")->get("high-availability")->get(0)->get("ha-servers"));
+ EXPECT_TRUE(ha_servers);
+ ElementPtr local(boost::const_pointer_cast<Element>(ha_servers->get("local")));
+ ElementPtr remote(boost::const_pointer_cast<Element>(ha_servers->get("remote")));
+ checkThatTimeIsParsable(local);
+ checkThatTimeIsParsable(remote);
+
std::string expected =
"{"
" \"arguments\": {"
" \"connecting-clients\": 0,"
" \"unacked-clients\": 0,"
" \"unacked-clients-left\": 0,"
- " \"analyzed-packets\": 0"
+ " \"analyzed-packets\": 0,"
+ " \"clock-skew\": 0"
" }"
" }"
" }"
" },"
" \"result\": 0"
"}";
- EXPECT_TRUE(isEquivalent(got, Element::fromJSON(expected)));
+ expectEqWithDiff(Element::fromJSON(expected), got);
}
// Tests status-get command processed handler for backup server.
callout_handle->getArgument("response", got);
ASSERT_TRUE(got);
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ ConstElementPtr ha_servers(
+ got->get("arguments")->get("high-availability")->get(0)->get("ha-servers"));
+ EXPECT_TRUE(ha_servers);
+ ElementPtr local(boost::const_pointer_cast<Element>(ha_servers->get("local")));
+ checkThatTimeIsParsable(local);
+
std::string expected =
"{"
" \"arguments\": {"
" },"
" \"result\": 0"
"}";
- EXPECT_TRUE(isEquivalent(got, Element::fromJSON(expected)));
+ expectEqWithDiff(Element::fromJSON(expected), got);
}
// Tests status-get command processed handler for primary server being in the
callout_handle->getArgument("response", got);
ASSERT_TRUE(got);
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ ConstElementPtr ha_servers(
+ got->get("arguments")->get("high-availability")->get(0)->get("ha-servers"));
+ EXPECT_TRUE(ha_servers);
+ ElementPtr local(boost::const_pointer_cast<Element>(ha_servers->get("local")));
+ checkThatTimeIsParsable(local);
+
std::string expected =
"{"
" \"arguments\": {"
" },"
" \"result\": 0"
"}";
- EXPECT_TRUE(isEquivalent(got, Element::fromJSON(expected)));
+ expectEqWithDiff(Element::fromJSON(expected), got);
}
// Tests status-get command processed handler for standby server in the
callout_handle->getArgument("response", got);
ASSERT_TRUE(got);
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ for (int i = 0; i < 2; ++i) {
+ ConstElementPtr ha_servers(
+ got->get("arguments")->get("high-availability")->get(i)->get("ha-servers"));
+ EXPECT_TRUE(ha_servers);
+ ElementPtr local(boost::const_pointer_cast<Element>(ha_servers->get("local")));
+ ElementPtr remote(boost::const_pointer_cast<Element>(ha_servers->get("remote")));
+ checkThatTimeIsParsable(local);
+ checkThatTimeIsParsable(remote);
+ }
+
std::string expected =
"{"
" \"arguments\": {"
" \"remote\": {"
" \"age\": 0,"
" \"analyzed-packets\": 0,"
+ " \"clock-skew\": 0,"
" \"communication-interrupted\": false,"
" \"connecting-clients\": 0,"
" \"in-touch\": false,"
" \"remote\": {"
" \"age\": 0,"
" \"analyzed-packets\": 0,"
+ " \"clock-skew\": 0,"
" \"communication-interrupted\": false,"
" \"connecting-clients\": 0,"
" \"in-touch\": false,"
" },"
" \"result\": 0"
"}";
- EXPECT_TRUE(isEquivalent(got, Element::fromJSON(expected)));
+ expectEqWithDiff(Element::fromJSON(expected), got);
}
// Test ha-maintenance-notify command handler with server name.
#include <http/response_json.h>
#include <util/multi_threading_mgr.h>
#include <testutils/gtest_utils.h>
+#include <testutils/test_to_element.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/pointer_cast.hpp>
using namespace isc::ha::test;
using namespace isc::hooks;
using namespace isc::http;
+using namespace isc::test;
using namespace isc::util;
/// @file The tests herein were created prior to HA+MT but are very valuable
// Check the reported info about servers.
ConstElementPtr ha_servers = service.processStatusGet();
ASSERT_TRUE(ha_servers);
+
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ ElementPtr local(boost::const_pointer_cast<Element>(ha_servers->get("local")));
+ ElementPtr remote(boost::const_pointer_cast<Element>(ha_servers->get("remote")));
+ checkThatTimeIsParsable(local);
+ checkThatTimeIsParsable(remote);
+
std::string expected = "{"
" \"local\": {"
" \"role\": \"primary\","
" \"connecting-clients\": 0,"
" \"unacked-clients\": 0,"
" \"unacked-clients-left\": 0,"
- " \"analyzed-packets\": 0"
+ " \"analyzed-packets\": 0,"
+ " \"clock-skew\": 0"
" }"
"}";
- EXPECT_TRUE(isEquivalent(Element::fromJSON(expected), ha_servers));
+ expectEqWithDiff(Element::fromJSON(expected), ha_servers);
// Set the test size - 65535 queries.
const unsigned queries_num = 65535;
ConstElementPtr ha_servers = service.processStatusGet();
ASSERT_TRUE(ha_servers);
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ ElementPtr local(boost::const_pointer_cast<Element>(ha_servers->get("local")));
+ ElementPtr remote(boost::const_pointer_cast<Element>(ha_servers->get("remote")));
+ checkThatTimeIsParsable(local);
+ checkThatTimeIsParsable(remote);
+
std::string expected = "{"
" \"local\": {"
" \"role\": \"standby\","
" \"connecting-clients\": 0,"
" \"unacked-clients\": 0,"
" \"unacked-clients-left\": 0,"
- " \"analyzed-packets\": 0"
+ " \"analyzed-packets\": 0,"
+ " \"clock-skew\": 0"
" }"
"}";
- EXPECT_TRUE(isEquivalent(Element::fromJSON(expected), ha_servers));
+ expectEqWithDiff(Element::fromJSON(expected), ha_servers);
// Set the test size - 65535 queries.
const unsigned queries_num = 65535;
std::ostringstream s;
s << age_value;
+ // Check that system-time exists and that format is parsable by ptime.
+ // Do not check exact value because it can be time-sensitive.
+ ElementPtr mutable_local(boost::const_pointer_cast<Element>(ha_servers->get("local")));
+ ElementPtr mutable_remote(boost::const_pointer_cast<Element>(ha_servers->get("remote")));
+ checkThatTimeIsParsable(mutable_local);
+ checkThatTimeIsParsable(mutable_remote);
+
std::string expected = "{"
" \"local\": {"
" \"role\": \"primary\","
" \"connecting-clients\": 0,"
" \"unacked-clients\": 0,"
" \"unacked-clients-left\": 0,"
- " \"analyzed-packets\": 0"
+ " \"analyzed-packets\": 0,"
+ " \"clock-skew\": 0"
" }"
"}";
- EXPECT_TRUE(isEquivalent(Element::fromJSON(expected), ha_servers));
+ expectEqWithDiff(Element::fromJSON(expected), ha_servers);
// Crash the partner and see whether our server can return to the partner
// down state.
#include <hooks/hooks_manager.h>
#include <util/range_utilities.h>
#include <functional>
-#include <utility>
#include <vector>
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::hooks;
+using namespace std;
+
namespace {
/// @brief Structure that holds registered hook indexes.
condvar.notify_one();
}
+
+void
+HATest::checkThatTimeIsParsable(ElementPtr node) {
+ ConstElementPtr system_time(node->get("system-time"));
+ EXPECT_TRUE(system_time);
+
+ // Is freed automatically by std::locale. See [localization.locales.locale#6] and
+ // [localization.locales.locale.facet#2] in the C++ standard.
+ boost::posix_time::time_input_facet* facet(
+ new boost::posix_time::time_input_facet("%Y-%m-%d %H:%M:%S"));
+
+ stringstream ss;
+ ss.imbue(std::locale(std::locale(), facet));
+ EXPECT_EQ(system_time->getType(), Element::string);
+ ss << system_time->stringValue();
+ boost::posix_time::ptime t;
+ ss >> t;
+
+ // Reset stringstream.
+ ss = stringstream();
+
+ ss << t;
+ EXPECT_NE(ss.str(), "not-a-date-time");
+
+ node->remove("system-time");
+}
+
void
HATest::stopIOServiceHandler(bool& stop_flag) {
stop_flag = true;
void signalServiceRunning(bool& running, std::mutex& mutex,
std::condition_variable& condvar);
+ /// @brief Check that a map element pointer representing the reported status
+ /// of an HA node contains string element pointer indexed by the
+ /// "system-time" key that can be parsed in a ptime object.
+ ///
+ /// Also removes the "system-time" element for the purpose of holistically
+ /// comparing the node without worrying about time-sensitive information.
+ ///
+ /// @brief param the node element pointer
+ void checkThatTimeIsParsable(isc::data::ElementPtr node);
+
public:
/// @brief Handler for timeout during runIOService invocation.