Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 238e2760 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Add test cases in resolv_unit_test for proto NetworkDnsEventReported...

Merge "Add test cases in resolv_unit_test for proto NetworkDnsEventReported verification" am: f79e246d am: a5c853f9 am: e54d1804

Change-Id: I3c4db5d53480222cc7cc20440d60fe442891a0d7
parents 62b76aaa e54d1804
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ cc_test {
        "libstatssocket",
        "libsysutils",
        "libutils",
        "resolv_stats_test_utils",
        "server_configurable_flags",
        "stats_proto",
    ],
+2 −1
Original line number Diff line number Diff line
@@ -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" }
    ]
}
+170 −6
Original line number Diff line number Diff line
@@ -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"
@@ -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());
@@ -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);
@@ -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);
@@ -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) {
@@ -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);
@@ -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);
@@ -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) {
@@ -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));
+34 −0
Original line number Diff line number Diff line
@@ -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",
    ],
}
+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