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

Commit cb016931 authored by Ken Chen's avatar Ken Chen
Browse files

Test for thread creation failed

Netd should not crash when thread creation is failed on Asynchronous
API call.

Bug: 169105756
Test: run test w/ and w/o I9241a094653651e1bdda79eb753e7a53e5e51d8f
Change-Id: Iadd94eb661ea15adfffc8d8e31e7990901bedb28
parent d1d1507c
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -2705,6 +2705,54 @@ TEST_F(ResolverTest, Async_VerifyQueryID) {
    EXPECT_EQ(1U, GetNumQueries(dns, host_name));
}

// Run a large number of DNS queries through asynchronous API to create
// thousands of threads in resolver to simulate the failure of thread creation
// when memory per process is exhausted. (The current critical value is about
// 84xx threads.)
TEST_F(ResolverTest, Async_OutOfMemory) {
    constexpr char host_name[] = "howdy.example.com.";
    constexpr size_t AMOUNT_OF_UIDS = 40;
    constexpr size_t MAX_QUERIES_PER_UID = 256;
    constexpr size_t NUM_OF_QUERIES = AMOUNT_OF_UIDS * MAX_QUERIES_PER_UID;

    test::DNSResponder dns;
    StartDns(dns, {{host_name, ns_type::ns_t_a, "1.2.3.4"}});
    ASSERT_TRUE(mDnsClient.SetResolversForNetwork());
    dns.setDeferredResp(true);

    std::vector<int> fds;
    fds.reserve(NUM_OF_QUERIES);
    bool send_query = true;
    for (size_t i = 0; i < AMOUNT_OF_UIDS && send_query; i++) {
        ScopedChangeUID scopedChangeUID(TEST_UID - i);
        for (size_t j = 0; j < MAX_QUERIES_PER_UID; j++) {
            int fd = resNetworkQuery(TEST_NETID, "howdy.example.com", ns_c_in, ns_t_a, 0);
            if (fd >= 0) {
                fds.emplace_back(fd);
            } else {
                send_query = false;
                break;
            }
        }
    }

    dns.setDeferredResp(false);
    EXPECT_EQ(NUM_OF_QUERIES, fds.size());
    // TODO: AIBinder_DeathRecipient_new does not work (b/172178636), which
    // should be fixed. Fortunately, netd crash is still detectable at the point
    // of DumpResolverService() in TearDown(), where accesses mDnsClient. Also,
    // the fds size will be less than NUM_OF_QUERIES in that case.

    uint8_t buf[MAXPACKET];
    int rcode;
    for (auto fd : fds) {
        memset(buf, 0, MAXPACKET);
        getAsyncResponse(fd, &rcode, buf, MAXPACKET);
        // The results of each DNS query are not examined, since they won't all
        // succeed or all fail. Here we only focus on netd is crashed or not.
    }
}

// This test checks that the resolver should not generate the request containing OPT RR when using
// cleartext DNS. If we query the DNS server not supporting EDNS0 and it reponds with
// FORMERR_ON_EDNS, we will fallback to no EDNS0 and try again. If the server does no response, we