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

Commit 8f013b16 authored by Mike Yu's avatar Mike Yu Committed by Automerger Merge Worker
Browse files

Add getAverageLatencyMs in DnsStats am: 4b30ae6e

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/DnsResolver/+/14883337

Change-Id: I122f72ec693aa4a7a07f7b0fa530e8de2e5fd3df
parents 5b172592 4b30ae6e
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -239,6 +239,20 @@ std::vector<IPSockAddr> DnsStats::getSortedServers(Protocol protocol) const {
    return ret;
}

std::optional<microseconds> DnsStats::getAverageLatencyUs(Protocol protocol) const {
    const auto stats = getStats(protocol);

    int count = 0;
    microseconds sum;
    for (const auto& v : stats) {
        count += v.total;
        sum += v.latencyUs;
    }

    if (count == 0) return std::nullopt;
    return sum / count;
}

std::vector<StatsData> DnsStats::getStats(Protocol protocol) const {
    std::vector<StatsData> ret;

+3 −1
Original line number Diff line number Diff line
@@ -121,9 +121,11 @@ class DnsStats {

    std::vector<netdutils::IPSockAddr> getSortedServers(Protocol protocol) const;

    // Returns the average query latency in microseconds.
    std::optional<std::chrono::microseconds> getAverageLatencyUs(Protocol protocol) const;

    void dump(netdutils::DumpWriter& dw);

    // For testing.
    std::vector<StatsData> getStats(Protocol protocol) const;

    // TODO: Compatible support for getResolverInfo().
+56 −27
Original line number Diff line number Diff line
@@ -26,12 +26,24 @@ namespace android::net {

using namespace std::chrono_literals;
using android::netdutils::IPSockAddr;
using std::chrono::microseconds;
using std::chrono::milliseconds;
using ::testing::IsEmpty;
using ::testing::UnorderedElementsAreArray;

namespace {

constexpr auto NO_AVERAGE_LATENCY = std::nullopt;

// A helper which can propagate the failure to outside of the stmt to know which line
// of stmt fails. The expectation fails only for the first failed stmt.
#define EXPECT_NO_FAILURE(stmt)                                         \
    do {                                                                \
        bool alreadyFailed = HasFailure();                              \
        stmt;                                                           \
        if (!alreadyFailed && HasFailure()) EXPECT_FALSE(HasFailure()); \
    } while (0)

DnsQueryEvent makeDnsQueryEvent(const Protocol protocol, const NsRcode rcode,
                                const milliseconds& latency) {
    DnsQueryEvent event;
@@ -41,11 +53,11 @@ DnsQueryEvent makeDnsQueryEvent(const Protocol protocol, const NsRcode rcode,
    return event;
}

StatsData makeStatsData(const IPSockAddr& server, const int total, const milliseconds& latencyMs,
StatsData makeStatsData(const IPSockAddr& server, const int total, const microseconds& latencyUs,
                        const std::map<int, int>& rcodeCounts) {
    StatsData ret(server);
    ret.total = total;
    ret.latencyUs = latencyMs;
    ret.latencyUs = latencyUs;
    ret.rcodeCounts = rcodeCounts;
    return ret;
}
@@ -143,6 +155,17 @@ class DnsStatsTest : public ::testing::Test {
        EXPECT_EQ(dumpString, "\n");
    }

    void verifyDnsStatsContent(Protocol protocol, const std::vector<StatsData>& expectedStats,
                               const std::optional<microseconds>& expectedAvgLatency) {
        if (expectedStats.empty()) {
            EXPECT_THAT(mDnsStats.getStats(protocol), IsEmpty());
        } else {
            EXPECT_THAT(mDnsStats.getStats(protocol), UnorderedElementsAreArray(expectedStats));
        }

        EXPECT_EQ(mDnsStats.getAverageLatencyUs(protocol), expectedAvgLatency);
    }

    DnsStats mDnsStats;
};

@@ -200,9 +223,9 @@ TEST_F(DnsStatsTest, SetServers) {
            expectedStats.push_back(makeStatsData(IPSockAddr::toIPSockAddr(exp, 53), 0, 0ms, {}));
        }

        EXPECT_THAT(mDnsStats.getStats(PROTO_TCP), UnorderedElementsAreArray(expectedStats));
        EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
        EXPECT_THAT(mDnsStats.getStats(PROTO_DOT), UnorderedElementsAreArray(expectedStats));
        EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY));
        EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY));
        EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY));
    }

    verifyDumpOutput({}, {}, {});
@@ -221,9 +244,9 @@ TEST_F(DnsStatsTest, SetServersDifferentPorts) {
    EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_UDP));
    EXPECT_FALSE(mDnsStats.setServers(servers, PROTO_DOT));

    EXPECT_THAT(mDnsStats.getStats(PROTO_TCP), IsEmpty());
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), IsEmpty());
    EXPECT_THAT(mDnsStats.getStats(PROTO_DOT), IsEmpty());
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY));
    verifyDumpOutput({}, {}, {});

    EXPECT_TRUE(mDnsStats.setServers(std::vector(servers.begin() + 2, servers.end()), PROTO_TCP));
@@ -236,9 +259,9 @@ TEST_F(DnsStatsTest, SetServersDifferentPorts) {
            makeStatsData(servers[6], 0, 0ms, {}), makeStatsData(servers[7], 0, 0ms, {}),
    };

    EXPECT_THAT(mDnsStats.getStats(PROTO_TCP), UnorderedElementsAreArray(expectedStats));
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
    EXPECT_THAT(mDnsStats.getStats(PROTO_DOT), UnorderedElementsAreArray(expectedStats));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, NO_AVERAGE_LATENCY));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, NO_AVERAGE_LATENCY));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, NO_AVERAGE_LATENCY));
    verifyDumpOutput(expectedStats, expectedStats, expectedStats);
}

@@ -269,18 +292,18 @@ TEST_F(DnsStatsTest, AddStatsAndClear) {
            makeStatsData(servers[1], 1, 10ms, {{NS_R_NO_ERROR, 1}}),
    };

    EXPECT_THAT(mDnsStats.getStats(PROTO_TCP), UnorderedElementsAreArray(expectedStatsForTcp));
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStatsForUdp));
    EXPECT_THAT(mDnsStats.getStats(PROTO_DOT), IsEmpty());
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStatsForTcp, NO_AVERAGE_LATENCY));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStatsForUdp, 10ms));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY));
    verifyDumpOutput(expectedStatsForTcp, expectedStatsForUdp, {});

    // Clear stats.
    EXPECT_TRUE(mDnsStats.setServers({}, PROTO_TCP));
    EXPECT_TRUE(mDnsStats.setServers({}, PROTO_UDP));
    EXPECT_TRUE(mDnsStats.setServers({}, PROTO_DOT));
    EXPECT_THAT(mDnsStats.getStats(PROTO_TCP), IsEmpty());
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), IsEmpty());
    EXPECT_THAT(mDnsStats.getStats(PROTO_DOT), IsEmpty());
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, {}, NO_AVERAGE_LATENCY));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, {}, NO_AVERAGE_LATENCY));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, {}, NO_AVERAGE_LATENCY));
    verifyDumpOutput({}, {}, {});
}

@@ -308,6 +331,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) {
            makeStatsData(servers[1], 4, 520ms, {{NS_R_NO_ERROR, 2}, {NS_R_TIMEOUT, 2}}),
    };
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms));
    verifyDumpOutput({}, expectedStats, {});

    // Update the server list, the stats of 127.0.0.2 will remain.
@@ -323,6 +347,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) {
            makeStatsData(servers[2], 0, 0ms, {}),
    };
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 130ms));
    verifyDumpOutput({}, expectedStats, {});

    // Let's add a record to 127.0.0.2 again.
@@ -333,6 +358,7 @@ TEST_F(DnsStatsTest, StatsRemainsInExistentServer) {
            makeStatsData(servers[2], 0, 0ms, {}),
    };
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 106ms));
    verifyDumpOutput({}, expectedStats, {});
}

@@ -363,9 +389,9 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) {

    for (size_t i = 0; i < operations; i++) {
        const NsRcode rcode = static_cast<NsRcode>(rcodes[i % rcodeNum]);
        const auto eventTcp = makeDnsQueryEvent(PROTO_TCP, rcode, 10ms);
        const auto eventUdp = makeDnsQueryEvent(PROTO_UDP, rcode, 10ms);
        const auto eventDot = makeDnsQueryEvent(PROTO_DOT, rcode, 10ms);
        const auto eventTcp = makeDnsQueryEvent(PROTO_TCP, rcode, milliseconds(i));
        const auto eventUdp = makeDnsQueryEvent(PROTO_UDP, rcode, milliseconds(i));
        const auto eventDot = makeDnsQueryEvent(PROTO_DOT, rcode, milliseconds(i));
        for (const auto& server : servers) {
            SCOPED_TRACE(server.toString() + "-" + std::to_string(i));
            ASSERT_TRUE(mDnsStats.addStats(server, eventTcp));
@@ -378,16 +404,19 @@ TEST_F(DnsStatsTest, AddStatsRecords_100000) {
    for (const auto& rcode : rcodes) {
        expectedRcodeCounts.try_emplace(rcode, 32);
    }

    // The average latency 99935.5 ms is derived from (99872ms + 99873ms + ... + 99999ms) / logSize,
    // where logSize is 128.
    const std::vector<StatsData> expectedStats = {
            makeStatsData(servers[0], logSize, logSize * 10ms, expectedRcodeCounts),
            makeStatsData(servers[1], logSize, logSize * 10ms, expectedRcodeCounts),
            makeStatsData(servers[2], logSize, logSize * 10ms, expectedRcodeCounts),
            makeStatsData(servers[3], logSize, logSize * 10ms, expectedRcodeCounts),
            makeStatsData(servers[0], logSize, logSize * 99935500us, expectedRcodeCounts),
            makeStatsData(servers[1], logSize, logSize * 99935500us, expectedRcodeCounts),
            makeStatsData(servers[2], logSize, logSize * 99935500us, expectedRcodeCounts),
            makeStatsData(servers[3], logSize, logSize * 99935500us, expectedRcodeCounts),
    };

    EXPECT_THAT(mDnsStats.getStats(PROTO_TCP), UnorderedElementsAreArray(expectedStats));
    EXPECT_THAT(mDnsStats.getStats(PROTO_UDP), UnorderedElementsAreArray(expectedStats));
    EXPECT_THAT(mDnsStats.getStats(PROTO_DOT), UnorderedElementsAreArray(expectedStats));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_TCP, expectedStats, 99935500us));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_UDP, expectedStats, 99935500us));
    EXPECT_NO_FAILURE(verifyDnsStatsContent(PROTO_DOT, expectedStats, 99935500us));
    verifyDumpOutput(expectedStats, expectedStats, expectedStats);
}