Loading Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ cc_test { "libstatssocket", "libsysutils", "libutils", "resolv_stats_test_utils", "server_configurable_flags", "stats_proto", ], Loading TEST_MAPPING +2 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ { "name": "resolv_integration_test" }, { "name": "resolv_gold_test" }, { "name": "resolv_unit_test" }, { "name": "resolv_stress_test" } { "name": "resolv_stress_test" }, { "name": "resolv_stats_test_utils_test" } ] } resolv_unit_test.cpp +170 −6 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <gtest/gtest.h> #include <netdb.h> #include <netdutils/InternetAddresses.h> #include <resolv_stats_test_utils.h> #include "dns_responder.h" #include "getaddrinfo.h" Loading Loading @@ -391,6 +392,62 @@ TEST_F(ResolvGetAddrInfoTest, InvalidParameters_PortNameAndNumber) { TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname_NoData) { constexpr char v4_host_name[] = "v4only.example.com."; // Following fields will not be verified during the test in proto NetworkDnsEventReported. // So don't need to config those values: event_type, return_code, latency_micros, // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. constexpr char event_ipv6[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, }, { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, }, { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, }, { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, } ] } })Event"; test::DNSResponder dns; dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3"); ASSERT_TRUE(dns.startServer()); Loading @@ -401,6 +458,7 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname_NoData) { const addrinfo hints = {.ai_family = AF_INET6}; NetworkDnsEventReported event; int rv = resolv_getaddrinfo("v4only", nullptr, &hints, &mNetcontext, &result, &event); EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(event_ipv6))); ScopedAddrinfo result_cleanup(result); EXPECT_LE(1U, GetNumQueries(dns, v4_host_name)); EXPECT_EQ(nullptr, result); Loading @@ -411,7 +469,66 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname) { constexpr char host_name[] = "sawadee.example.com."; constexpr char v4addr[] = "1.2.3.4"; constexpr char v6addr[] = "::1.2.3.4"; // Following fields will not be verified during the test in proto NetworkDnsEventReported. // So don't need to config those values: event_type, return_code, latency_micros, // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. constexpr char event_ipv4[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 1, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, }, { rcode: 0, type: 1, cache_hit: 2, ip_version: 0, protocol: 0, retry_times: 0, dns_server_index: 0, connected: 0, } ] } })Event"; constexpr char event_ipv6[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, }, { rcode: 0, type: 28, cache_hit: 2, ip_version: 0, protocol: 0, retry_times: 0, dns_server_index: 0, connected: 0, } ] } })Event"; test::DNSResponder dns; dns.addMapping(host_name, ns_type::ns_t_a, v4addr); dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr); Loading @@ -421,9 +538,10 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname) { static const struct TestConfig { int ai_family; const std::string expected_addr; const std::string expected_event; } testConfigs[]{ {AF_INET, v4addr}, {AF_INET6, v6addr}, {AF_INET, v4addr, event_ipv4}, {AF_INET6, v6addr, event_ipv6}, }; for (const auto& config : testConfigs) { Loading @@ -434,6 +552,8 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname) { const addrinfo hints = {.ai_family = config.ai_family}; NetworkDnsEventReported event; int rv = resolv_getaddrinfo("sawadee", nullptr, &hints, &mNetcontext, &result, &event); EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(config.expected_event))); ScopedAddrinfo result_cleanup(result); EXPECT_EQ(0, rv); EXPECT_TRUE(result != nullptr); Loading Loading @@ -694,7 +814,48 @@ TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { constexpr char host_name[] = "jiababuei.example.com."; constexpr char v4addr[] = "1.2.3.4"; constexpr char v6addr[] = "::1.2.3.4"; // Following fields will not be verified during the test in proto NetworkDnsEventReported. // So don't need to config those values: event_type, return_code, latency_micros, // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. constexpr char event_ipv4[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 1, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, } ] } })Event"; constexpr char event_ipv6[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, } ] } })Event"; test::DNSResponder dns; dns.addMapping(host_name, ns_type::ns_t_a, v4addr); dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr); Loading @@ -704,9 +865,10 @@ TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { static const struct TestConfig { int ai_family; const std::string expected_addr; const std::string expected_event; } testConfigs[]{ {AF_INET, v4addr}, {AF_INET6, v6addr}, {AF_INET, v4addr, event_ipv4}, {AF_INET6, v6addr, event_ipv6}, }; for (const auto& config : testConfigs) { Loading @@ -719,6 +881,8 @@ TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { NetworkDnsEventReported event; int rv = resolv_gethostbyname("jiababuei", config.ai_family, &hbuf, tmpbuf, sizeof(tmpbuf), &mNetcontext, &hp, &event); EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(config.expected_event))); EXPECT_EQ(0, rv); EXPECT_TRUE(hp != nullptr); EXPECT_EQ(1U, GetNumQueries(dns, host_name)); Loading tests/Android.bp +34 −0 Original line number Diff line number Diff line Loading @@ -144,3 +144,37 @@ cc_test { }, }, } cc_test_library { name: "resolv_stats_test_utils", srcs: [ "resolv_stats_test_utils.cpp" ], defaults: ["netd_defaults"], export_include_dirs: ["."], static_libs: [ "libbase", "libgmock", "liblog", "libnetdutils", "libprotobuf-cpp-lite", "stats_proto", ], } cc_test { name: "resolv_stats_test_utils_test", srcs: [ "resolv_stats_test_utils_test.cpp", ], defaults: ["netd_defaults"], test_suites: ["device-tests"], static_libs: [ "libbase", "libgmock", "liblog", "libprotobuf-cpp-lite", "resolv_stats_test_utils", "stats_proto", ], } tests/resolv_stats_test_utils.cpp 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "resolv_stats_test_utils.h" #include <iostream> #include <regex> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> #include <gmock/gmock.h> #include <stats.pb.h> namespace android::net { using android::net::NetworkDnsEventReported; // The fromNetworkDnsEventReportedStr is a function to generate a protocol buffer message // NetworkDnsEventReported from a string. How to define the sting for NetworkDnsEventReported, // please refer to test case AlphabeticalHostname. // There are 3 proto messages(1. NetworkDnsEventReported 2. dns_query_events 3. dns_query_event) // The names of these 3 messages will not be verified, please do not change. // Each field will be parsed into corresponding message by those char pairs "{" & "}". // Example: (Don't need to fill Level 1 fields in NetworkDnsEventReported. Currently, // no verification is performed.) // NetworkDnsEventReported { <= construct the NetworkDnsEventReported message (Level 1) // dns_query_events:(Level 2) // { <= construct the dns_query_events message // dns_query_event:(Level 3) // { <= construct the 1st dns_query_event message // [field]: value, // [field]: value, // } <= finish the 1st dns_query_event message // dns_query_event:(Level 3) // { <= construct 2nd dns_query_event message // [field]: value, // [field]: value, // } <= finish the 1nd dns_query_event message // } <= finish the dns_query_events message // } <= finish the NetworkDnsEventReported message NetworkDnsEventReported fromNetworkDnsEventReportedStr(const std::string& str) { using android::base::ParseInt; using android::base::Split; // Remove unnecessary space std::regex re(": "); std::string s = std::regex_replace(str, re, ":"); // Using space to separate each parse line static const std::regex words_regex("[^\\s]+"); auto words_begin = std::sregex_iterator(s.begin(), s.end(), words_regex); auto words_end = std::sregex_iterator(); // Using strproto to identify the position of NetworkDnsEventReported proto int strproto = 0; NetworkDnsEventReported event; DnsQueryEvent* dnsQueryEvent = nullptr; for (std::sregex_iterator i = words_begin; i != words_end; ++i) { std::string match_str = (*i).str(); // Using "{" and "}" to identify the Start/End of each proto if (match_str == "{") { // strproto 1.NetworkDnsEventReported 2.dns_query_events 3.dns_query_event if (++strproto == 3) { dnsQueryEvent = event.mutable_dns_query_events()->add_dns_query_event(); } continue; } if (match_str == "}" | match_str == "},") { strproto--; continue; } // Parsing each field of the proto and fill it into NetworkDnsEventReported event static const std::regex pieces_regex("([a-zA-Z0-9_]+)\\:([0-9]+),"); std::smatch protoField; std::regex_match(match_str, protoField, pieces_regex); int value = 0; LOG(DEBUG) << "Str:" << match_str << " Name:" << protoField[1] << " Value:" << protoField[2]; // Parsing each field of the proto NetworkDnsEventReported if (strproto == 1) { if (protoField[1] == "event_type" && ParseInt(protoField[2], &value)) { event.set_event_type(static_cast<EventType>(value)); } else if (protoField[1] == "return_code" && ParseInt(protoField[2], &value)) { event.set_return_code(static_cast<ReturnCode>(value)); } else if (protoField[1] == "latency_micros" && ParseInt(protoField[2], &value)) { event.set_latency_micros(value); } else if (protoField[1] == "hints_ai_flags" && ParseInt(protoField[2], &value)) { event.set_hints_ai_flags(value); } else if (protoField[1] == "res_nsend_flags" && ParseInt(protoField[2], &value)) { event.set_res_nsend_flags(value); } else if (protoField[1] == "network_type" && ParseInt(protoField[2], &value)) { event.set_network_type(static_cast<NetworkType>(value)); } else if (protoField[1] == "private_dns_modes" && ParseInt(protoField[2], &value)) { event.set_private_dns_modes(static_cast<PrivateDnsModes>(value)); } else if (protoField[1] == "sampling_rate_denom" && ParseInt(protoField[2], &value)) { event.set_sampling_rate_denom(value); } } // Parsing each field of the proto DnsQueryEvent if (strproto == 3) { if (dnsQueryEvent == nullptr) continue; if (protoField[1] == "rcode" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_rcode(static_cast<NsRcode>(value)); } else if (protoField[1] == "type" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_type(static_cast<NsType>(value)); } else if (protoField[1] == "cache_hit" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_cache_hit(static_cast<CacheStatus>(value)); } else if (protoField[1] == "ip_version" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_ip_version(static_cast<IpVersion>(value)); } else if (protoField[1] == "protocol" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_protocol(static_cast<Protocol>(value)); } else if (protoField[1] == "retry_times" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_retry_times(value); } else if (protoField[1] == "dns_server_index" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_dns_server_index(value); } else if (protoField[1] == "connected" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_connected(static_cast<bool>(value)); } else if (protoField[1] == "latency_micros" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_latency_micros(value); } } } return event; } void PrintTo(const DnsQueryEvents& event, std::ostream* os) { *os << "query events: {\n"; *os << " dns_query_event_size: " << event.dns_query_event_size() << "\n"; *os << "}"; } void PrintTo(const DnsQueryEvent& event, std::ostream* os) { *os << "dns query event: {\n"; *os << " rcode: " << event.rcode() << "\n"; *os << " ns_type: " << event.type() << "\n"; *os << " cache_hit: " << event.cache_hit() << "\n"; *os << " ip_version: " << event.ip_version() << "\n"; *os << " protocol: " << event.protocol() << "\n"; *os << " retry_times: " << event.retry_times() << "\n"; *os << " dns_server_index: " << event.dns_server_index() << "\n"; *os << " connected: " << event.connected() << "\n"; *os << " latency_micros: " << event.latency_micros() << "\n"; *os << "}"; } void PrintTo(const NetworkDnsEventReported& event, std::ostream* os) { *os << "network dns event: {\n"; *os << " event_type: " << event.event_type() << "\n"; *os << " return_code: " << event.return_code() << "\n"; *os << " latency_micros: " << event.latency_micros() << "\n"; *os << " hints_ai_flags: " << event.hints_ai_flags() << "\n"; *os << " res_nsend_flags: " << event.res_nsend_flags() << "\n"; *os << " network_type: " << event.network_type() << "\n"; *os << " private_dns_modes: " << event.private_dns_modes() << "\n"; *os << " dns_query_event_size: " << event.dns_query_events().dns_query_event_size() << "\n"; *os << "}"; } } // namespace android::net Loading
Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -198,6 +198,7 @@ cc_test { "libstatssocket", "libsysutils", "libutils", "resolv_stats_test_utils", "server_configurable_flags", "stats_proto", ], Loading
TEST_MAPPING +2 −1 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ { "name": "resolv_integration_test" }, { "name": "resolv_gold_test" }, { "name": "resolv_unit_test" }, { "name": "resolv_stress_test" } { "name": "resolv_stress_test" }, { "name": "resolv_stats_test_utils_test" } ] }
resolv_unit_test.cpp +170 −6 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <gtest/gtest.h> #include <netdb.h> #include <netdutils/InternetAddresses.h> #include <resolv_stats_test_utils.h> #include "dns_responder.h" #include "getaddrinfo.h" Loading Loading @@ -391,6 +392,62 @@ TEST_F(ResolvGetAddrInfoTest, InvalidParameters_PortNameAndNumber) { TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname_NoData) { constexpr char v4_host_name[] = "v4only.example.com."; // Following fields will not be verified during the test in proto NetworkDnsEventReported. // So don't need to config those values: event_type, return_code, latency_micros, // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. constexpr char event_ipv6[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, }, { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, }, { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, }, { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, } ] } })Event"; test::DNSResponder dns; dns.addMapping(v4_host_name, ns_type::ns_t_a, "1.2.3.3"); ASSERT_TRUE(dns.startServer()); Loading @@ -401,6 +458,7 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname_NoData) { const addrinfo hints = {.ai_family = AF_INET6}; NetworkDnsEventReported event; int rv = resolv_getaddrinfo("v4only", nullptr, &hints, &mNetcontext, &result, &event); EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(event_ipv6))); ScopedAddrinfo result_cleanup(result); EXPECT_LE(1U, GetNumQueries(dns, v4_host_name)); EXPECT_EQ(nullptr, result); Loading @@ -411,7 +469,66 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname) { constexpr char host_name[] = "sawadee.example.com."; constexpr char v4addr[] = "1.2.3.4"; constexpr char v6addr[] = "::1.2.3.4"; // Following fields will not be verified during the test in proto NetworkDnsEventReported. // So don't need to config those values: event_type, return_code, latency_micros, // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. constexpr char event_ipv4[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 1, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, }, { rcode: 0, type: 1, cache_hit: 2, ip_version: 0, protocol: 0, retry_times: 0, dns_server_index: 0, connected: 0, } ] } })Event"; constexpr char event_ipv6[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, }, { rcode: 0, type: 28, cache_hit: 2, ip_version: 0, protocol: 0, retry_times: 0, dns_server_index: 0, connected: 0, } ] } })Event"; test::DNSResponder dns; dns.addMapping(host_name, ns_type::ns_t_a, v4addr); dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr); Loading @@ -421,9 +538,10 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname) { static const struct TestConfig { int ai_family; const std::string expected_addr; const std::string expected_event; } testConfigs[]{ {AF_INET, v4addr}, {AF_INET6, v6addr}, {AF_INET, v4addr, event_ipv4}, {AF_INET6, v6addr, event_ipv6}, }; for (const auto& config : testConfigs) { Loading @@ -434,6 +552,8 @@ TEST_F(ResolvGetAddrInfoTest, AlphabeticalHostname) { const addrinfo hints = {.ai_family = config.ai_family}; NetworkDnsEventReported event; int rv = resolv_getaddrinfo("sawadee", nullptr, &hints, &mNetcontext, &result, &event); EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(config.expected_event))); ScopedAddrinfo result_cleanup(result); EXPECT_EQ(0, rv); EXPECT_TRUE(result != nullptr); Loading Loading @@ -694,7 +814,48 @@ TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { constexpr char host_name[] = "jiababuei.example.com."; constexpr char v4addr[] = "1.2.3.4"; constexpr char v6addr[] = "::1.2.3.4"; // Following fields will not be verified during the test in proto NetworkDnsEventReported. // So don't need to config those values: event_type, return_code, latency_micros, // hints_ai_flags, res_nsend_flags, network_type, private_dns_modes. constexpr char event_ipv4[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 1, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, } ] } })Event"; constexpr char event_ipv6[] = R"Event( NetworkDnsEventReported { dns_query_events: { dns_query_event:[ { rcode: 0, type: 28, cache_hit: 1, ip_version: 1, protocol: 1, retry_times: 0, dns_server_index: 0, connected: 0, latency_micros: 0, } ] } })Event"; test::DNSResponder dns; dns.addMapping(host_name, ns_type::ns_t_a, v4addr); dns.addMapping(host_name, ns_type::ns_t_aaaa, v6addr); Loading @@ -704,9 +865,10 @@ TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { static const struct TestConfig { int ai_family; const std::string expected_addr; const std::string expected_event; } testConfigs[]{ {AF_INET, v4addr}, {AF_INET6, v6addr}, {AF_INET, v4addr, event_ipv4}, {AF_INET6, v6addr, event_ipv6}, }; for (const auto& config : testConfigs) { Loading @@ -719,6 +881,8 @@ TEST_F(GetHostByNameForNetContextTest, AlphabeticalHostname) { NetworkDnsEventReported event; int rv = resolv_gethostbyname("jiababuei", config.ai_family, &hbuf, tmpbuf, sizeof(tmpbuf), &mNetcontext, &hp, &event); EXPECT_THAT(event, NetworkDnsEventEq(fromNetworkDnsEventReportedStr(config.expected_event))); EXPECT_EQ(0, rv); EXPECT_TRUE(hp != nullptr); EXPECT_EQ(1U, GetNumQueries(dns, host_name)); Loading
tests/Android.bp +34 −0 Original line number Diff line number Diff line Loading @@ -144,3 +144,37 @@ cc_test { }, }, } cc_test_library { name: "resolv_stats_test_utils", srcs: [ "resolv_stats_test_utils.cpp" ], defaults: ["netd_defaults"], export_include_dirs: ["."], static_libs: [ "libbase", "libgmock", "liblog", "libnetdutils", "libprotobuf-cpp-lite", "stats_proto", ], } cc_test { name: "resolv_stats_test_utils_test", srcs: [ "resolv_stats_test_utils_test.cpp", ], defaults: ["netd_defaults"], test_suites: ["device-tests"], static_libs: [ "libbase", "libgmock", "liblog", "libprotobuf-cpp-lite", "resolv_stats_test_utils", "stats_proto", ], }
tests/resolv_stats_test_utils.cpp 0 → 100644 +172 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "resolv_stats_test_utils.h" #include <iostream> #include <regex> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> #include <gmock/gmock.h> #include <stats.pb.h> namespace android::net { using android::net::NetworkDnsEventReported; // The fromNetworkDnsEventReportedStr is a function to generate a protocol buffer message // NetworkDnsEventReported from a string. How to define the sting for NetworkDnsEventReported, // please refer to test case AlphabeticalHostname. // There are 3 proto messages(1. NetworkDnsEventReported 2. dns_query_events 3. dns_query_event) // The names of these 3 messages will not be verified, please do not change. // Each field will be parsed into corresponding message by those char pairs "{" & "}". // Example: (Don't need to fill Level 1 fields in NetworkDnsEventReported. Currently, // no verification is performed.) // NetworkDnsEventReported { <= construct the NetworkDnsEventReported message (Level 1) // dns_query_events:(Level 2) // { <= construct the dns_query_events message // dns_query_event:(Level 3) // { <= construct the 1st dns_query_event message // [field]: value, // [field]: value, // } <= finish the 1st dns_query_event message // dns_query_event:(Level 3) // { <= construct 2nd dns_query_event message // [field]: value, // [field]: value, // } <= finish the 1nd dns_query_event message // } <= finish the dns_query_events message // } <= finish the NetworkDnsEventReported message NetworkDnsEventReported fromNetworkDnsEventReportedStr(const std::string& str) { using android::base::ParseInt; using android::base::Split; // Remove unnecessary space std::regex re(": "); std::string s = std::regex_replace(str, re, ":"); // Using space to separate each parse line static const std::regex words_regex("[^\\s]+"); auto words_begin = std::sregex_iterator(s.begin(), s.end(), words_regex); auto words_end = std::sregex_iterator(); // Using strproto to identify the position of NetworkDnsEventReported proto int strproto = 0; NetworkDnsEventReported event; DnsQueryEvent* dnsQueryEvent = nullptr; for (std::sregex_iterator i = words_begin; i != words_end; ++i) { std::string match_str = (*i).str(); // Using "{" and "}" to identify the Start/End of each proto if (match_str == "{") { // strproto 1.NetworkDnsEventReported 2.dns_query_events 3.dns_query_event if (++strproto == 3) { dnsQueryEvent = event.mutable_dns_query_events()->add_dns_query_event(); } continue; } if (match_str == "}" | match_str == "},") { strproto--; continue; } // Parsing each field of the proto and fill it into NetworkDnsEventReported event static const std::regex pieces_regex("([a-zA-Z0-9_]+)\\:([0-9]+),"); std::smatch protoField; std::regex_match(match_str, protoField, pieces_regex); int value = 0; LOG(DEBUG) << "Str:" << match_str << " Name:" << protoField[1] << " Value:" << protoField[2]; // Parsing each field of the proto NetworkDnsEventReported if (strproto == 1) { if (protoField[1] == "event_type" && ParseInt(protoField[2], &value)) { event.set_event_type(static_cast<EventType>(value)); } else if (protoField[1] == "return_code" && ParseInt(protoField[2], &value)) { event.set_return_code(static_cast<ReturnCode>(value)); } else if (protoField[1] == "latency_micros" && ParseInt(protoField[2], &value)) { event.set_latency_micros(value); } else if (protoField[1] == "hints_ai_flags" && ParseInt(protoField[2], &value)) { event.set_hints_ai_flags(value); } else if (protoField[1] == "res_nsend_flags" && ParseInt(protoField[2], &value)) { event.set_res_nsend_flags(value); } else if (protoField[1] == "network_type" && ParseInt(protoField[2], &value)) { event.set_network_type(static_cast<NetworkType>(value)); } else if (protoField[1] == "private_dns_modes" && ParseInt(protoField[2], &value)) { event.set_private_dns_modes(static_cast<PrivateDnsModes>(value)); } else if (protoField[1] == "sampling_rate_denom" && ParseInt(protoField[2], &value)) { event.set_sampling_rate_denom(value); } } // Parsing each field of the proto DnsQueryEvent if (strproto == 3) { if (dnsQueryEvent == nullptr) continue; if (protoField[1] == "rcode" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_rcode(static_cast<NsRcode>(value)); } else if (protoField[1] == "type" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_type(static_cast<NsType>(value)); } else if (protoField[1] == "cache_hit" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_cache_hit(static_cast<CacheStatus>(value)); } else if (protoField[1] == "ip_version" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_ip_version(static_cast<IpVersion>(value)); } else if (protoField[1] == "protocol" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_protocol(static_cast<Protocol>(value)); } else if (protoField[1] == "retry_times" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_retry_times(value); } else if (protoField[1] == "dns_server_index" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_dns_server_index(value); } else if (protoField[1] == "connected" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_connected(static_cast<bool>(value)); } else if (protoField[1] == "latency_micros" && ParseInt(protoField[2], &value)) { dnsQueryEvent->set_latency_micros(value); } } } return event; } void PrintTo(const DnsQueryEvents& event, std::ostream* os) { *os << "query events: {\n"; *os << " dns_query_event_size: " << event.dns_query_event_size() << "\n"; *os << "}"; } void PrintTo(const DnsQueryEvent& event, std::ostream* os) { *os << "dns query event: {\n"; *os << " rcode: " << event.rcode() << "\n"; *os << " ns_type: " << event.type() << "\n"; *os << " cache_hit: " << event.cache_hit() << "\n"; *os << " ip_version: " << event.ip_version() << "\n"; *os << " protocol: " << event.protocol() << "\n"; *os << " retry_times: " << event.retry_times() << "\n"; *os << " dns_server_index: " << event.dns_server_index() << "\n"; *os << " connected: " << event.connected() << "\n"; *os << " latency_micros: " << event.latency_micros() << "\n"; *os << "}"; } void PrintTo(const NetworkDnsEventReported& event, std::ostream* os) { *os << "network dns event: {\n"; *os << " event_type: " << event.event_type() << "\n"; *os << " return_code: " << event.return_code() << "\n"; *os << " latency_micros: " << event.latency_micros() << "\n"; *os << " hints_ai_flags: " << event.hints_ai_flags() << "\n"; *os << " res_nsend_flags: " << event.res_nsend_flags() << "\n"; *os << " network_type: " << event.network_type() << "\n"; *os << " private_dns_modes: " << event.private_dns_modes() << "\n"; *os << " dns_query_event_size: " << event.dns_query_events().dns_query_event_size() << "\n"; *os << "}"; } } // namespace android::net