d2_unittests_SOURCES += d2_command_unittest.cc
d2_unittests_SOURCES += simple_add_unittests.cc
d2_unittests_SOURCES += simple_remove_unittests.cc
+d2_unittests_SOURCES += stats_test_utils.cc stats_test_utils.h
d2_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
d2_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS)
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
#include <nc_test_utils.h>
+#include <stats_test_utils.h>
#include <functional>
using namespace std;
using namespace isc::asiolink;
using namespace isc::asiodns;
using namespace isc::d2;
-
-using namespace isc;
+using namespace isc::d2::test;
+using namespace isc::data;
using namespace isc::dns;
+using namespace isc::stats;
using namespace isc::util;
using namespace boost::asio;
using namespace boost::asio::ip;
// properly handled a task may be hanging for a long time. In order to prevent
// it, the asiolink::IntervalTimer is used to break a running test if test
// timeout is hit. This will result in test failure.
-class DNSClientTest : public virtual ::testing::Test, DNSClient::Callback {
+class DNSClientTest : public virtual D2StatTest, DNSClient::Callback {
public:
IOService service_;
D2UpdateMessagePtr response_;
// Verifies that TSIG can be used to sign requests and verify responses.
TEST_F(DNSClientTest, runTSIGTest) {
+ ConstElementPtr stats_all = StatsMgr::instance().getAll();
+ ASSERT_TRUE(stats_all);
+ EXPECT_TRUE(stats_all->empty());
std::string secret ("key number one");
D2TsigKeyPtr key_one;
ASSERT_NO_THROW(key_one.reset(new
D2TsigKey(Name("one.com"),
TSIGKey::HMACMD5_NAME(),
secret.c_str(), secret.size())));
+ StatMap stats_key = {
+ { "update-sent", 0},
+ { "update-success", 0},
+ { "update-timeout", 0},
+ { "update-error", 0}
+ };
+ checkStats("one.com.", stats_key);
secret = "key number two";
D2TsigKeyPtr key_two;
ASSERT_NO_THROW(key_two.reset(new
D2TsigKey(Name("two.com"),
TSIGKey::HMACMD5_NAME(),
secret.c_str(), secret.size())));
+ checkStats("two.com.", stats_key);
D2TsigKeyPtr nokey;
+ StatsMgr::instance().setValue("update-sent", 0LL);
+ StatsMgr::instance().setValue("update-signed", 0LL);
+ StatsMgr::instance().setValue("update-unsigned", 0LL);
+ StatsMgr::instance().setValue("update-success", 0LL);
+ StatsMgr::instance().setValue("update-timeout", 0LL);
+ StatsMgr::instance().setValue("update-error", 0LL);
// Should be able to send and receive with no keys.
// Neither client nor server will attempt to sign or verify.
// Client neither signs nor verifies, server responds with a signed answer
// Since we are "liberal" in what we accept this should be ok.
runTSIGTest(nokey, key_two);
+
+ // Check statistics.
+ stats_all = StatsMgr::instance().getAll();
+ StatMap stats_one = {
+ { "update-sent", 3},
+ { "update-success", 1},
+ { "update-timeout", 0},
+ { "update-error", 2}
+ };
+ checkStats("one.com.", stats_one);
+ checkStats("two.com.", stats_key);
+ StatMap stats_upd = {
+ { "update-sent", 5},
+ { "update-signed", 3},
+ { "update-unsigned", 2},
+ { "update-success", 3},
+ { "update-timeout", 0},
+ { "update-error", 2}
+ };
+ checkStats(stats_upd);
}
// Verify that the DNSClient receives the response from DNS and the received
--- /dev/null
+// Copyright (C) 2021 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#include <config.h>
+
+#include <stats_test_utils.h>
+
+using namespace isc::data;
+using namespace isc::stats;
+using namespace std;
+
+namespace isc {
+namespace d2 {
+namespace test {
+
+D2StatTest::D2StatTest() {
+ StatsMgr::instance().removeAll();
+}
+
+D2StatTest::~D2StatTest() {
+ StatsMgr::instance().removeAll();
+}
+
+void
+D2StatTest::checkStat(const string& name, const int64_t expected_value) {
+ ObservationPtr obs = StatsMgr::instance().getObservation(name);
+ ASSERT_TRUE(obs) << " stat: " << name << " not found ";
+ ASSERT_EQ(expected_value, obs->getInteger().first)
+ << " stat: " << name << " value wrong";
+}
+
+void
+D2StatTest::checkStats(const StatMap& expected_stats) {
+ for (const auto& it : expected_stats) {
+ checkStat(it.first, it.second);
+ }
+}
+
+void
+D2StatTest::checkStats(const string& key_name, const StatMap& expected_stats) {
+ StatMap key_stats;
+ for (const auto& it : expected_stats) {
+ const string& stat_name =
+ StatsMgr::generateName("key", key_name, it.first);
+ key_stats[stat_name] = it.second;
+ }
+ checkStats(key_stats);
+}
+
+}
+}
+}
--- /dev/null
+// Copyright (C) 2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef STATS_TEST_UTILS_H
+#define STATS_TEST_UTILS_H
+
+#include <cc/data.h>
+#include <d2srv/d2_stats.h>
+#include <d2srv/d2_tsig_key.h>
+#include <stats/stats_mgr.h>
+
+#include <gtest/gtest.h>
+
+namespace isc {
+namespace d2 {
+namespace test {
+
+/// @brief Type of name x value for statistics.
+typedef std::map<std::string, int64_t> StatMap;
+
+/// @brief Test fixture class with utility functions to test statistics.
+class D2StatTest : public ::testing::Test {
+public:
+ /// @brief Constructor.
+ D2StatTest();
+
+ /// @brief Destructor.
+ virtual ~D2StatTest();
+
+ /// @brief Compares a statistic to an expected value.
+ ///
+ /// Attempt to fetch the named statistic from the StatsMgr and if
+ /// found, compare its observed value to the given value.
+ /// Fails if the stat is not found or if the values do not match.
+ ///
+ /// @param name StatsMgr name for the statistic to check.
+ /// @param expected_value expected value of the statistic.
+ void checkStat(const std::string& name, const int64_t expected_value);
+
+ /// @brief Compares StatsMgr statistics against expected values.
+ ///
+ /// Iterates over a list of statistic names and expected values, attempting
+ /// to fetch each from the StatsMgr and if found, compare its observed
+ /// value to the expected value. Fails if any of the expected stats are not
+ /// found or if the values do not match.
+ ///
+ /// @param expected_stats Map of expected static names and values.
+ void checkStats(const StatMap& expected_stats);
+
+ /// @brief Compares StatsMgr key statistics against expected values.
+ ///
+ /// Prepend key part of names before calling checkStats simpler variant.
+ ///
+ /// @param key_name Name of the key.
+ /// @param expected_stats Map of expected static names and values.
+ void checkStats(const std::string& key_name, const StatMap& expected_stats);
+};
+
+}
+}
+}
+
+#endif // STATS_TEST_UTILS_H