// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace isc::cc; using namespace isc::dns; using namespace isc::data; using namespace isc::auth::statistics; namespace { // ### STATISTICS ITEMS DEFINITION ### class CountersTest : public ::testing::Test { protected: CountersTest() : counters() {} ~CountersTest() {} Counters counters; }; void flatten(std::map& flat_map, const std::string& prefix, const isc::data::ConstElementPtr map_element) { std::map map = map_element->mapValue(); for (std::map::const_iterator i = map.begin(), e = map.end(); i != e; ++i) { switch (i->second->getType()) { case isc::data::Element::map: flatten(flat_map, i->first + ".", i->second); break; case isc::data::Element::integer: flat_map[prefix + i->first] = i->second->intValue(); break; default: EXPECT_FALSE("Element Parse Error"); } } } // Test if the values of the counters are all zero except for the items // specified in except_for. void checkCountersAllZeroExcept(const isc::data::ConstElementPtr counters, const std::set& except_for) { std::map stats_map; flatten(stats_map, "", counters); for (std::map::const_iterator i = stats_map.begin(), e = stats_map.end(); i != e; ++i) { int expect = 0; if (except_for.count(i->first) != 0) { expect = 1; } EXPECT_EQ(expect, i->second) << "Expected counter " << i->first << " = " << expect << ", actual: " << i->second; } } TEST_F(CountersTest, incrementNormalQuery) { Message response(Message::RENDER); QRAttributes qrattrs; std::set expect_nonzero; expect_nonzero.clear(); checkCountersAllZeroExcept(counters.get()->get("zones")->get("_SERVER_"), expect_nonzero); qrattrs.setQueryIPVersion(AF_INET6); qrattrs.setQueryTransportProtocol(IPPROTO_UDP); qrattrs.setQueryOpCode(Opcode::QUERY_CODE); qrattrs.setQueryEDNS(true, false); qrattrs.setQueryDO(true); response.setRcode(Rcode::REFUSED()); response.addQuestion(Question(Name("example.com"), RRClass::IN(), RRType::AAAA())); counters.inc(qrattrs, response, true); expect_nonzero.clear(); expect_nonzero.insert("opcode.query"); expect_nonzero.insert("request.v6"); expect_nonzero.insert("request.udp"); expect_nonzero.insert("request.edns0"); expect_nonzero.insert("request.dnssec_ok"); expect_nonzero.insert("responses"); expect_nonzero.insert("qrynoauthans"); expect_nonzero.insert("rcode.refused"); expect_nonzero.insert("authqryrej"); checkCountersAllZeroExcept(counters.get()->get("zones")->get("_SERVER_"), expect_nonzero); } int countTreeElements(const struct CounterTypeTree* tree) { int count = 0; for (int i = 0; tree[i].name != NULL; ++i) { if (tree[i].sub_tree == NULL) { ++count; } else { count += countTreeElements(tree[i].sub_tree); } } return (count); } TEST(StatisticsItemsTest, QRItemNamesCheck) { EXPECT_EQ(QR_COUNTER_TYPES, countTreeElements(QRCounterTree)); } }