/*
 * Copyright (C) 2016 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.
 */

#define LOG_TAG "dns_benchmark"

/*
 * See README.md for general notes.
 *
 * This set of benchmarks measures the throughput of getaddrinfo() on between 1 and 32 threads for
 * the purpose of keeping track of the maximum load that netd can reasonably handle.
 *
 * Useful measurements
 * ===================
 *
 *  - real_time: the average time taken to make a single getaddrinfo lookup on a local DNS resolver
 *               run by DnsFixture. This will usually be higher on multithreaded tests as threads
 *               block on DNS lookups and Binder connections.
 *
 *  - iterations: total number of runs finished within the time limit. Higher is better. This is
 *                roughly proportional to MinTime * nThreads / real_time.
 *
 */

#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <android-base/stringprintf.h>
#include <benchmark/benchmark.h>

#include "NetdClient.h"
#include "dns_responder_client_ndk.h"

using android::base::StringPrintf;

constexpr int MIN_THREADS = 1;
constexpr int MAX_THREADS = 32;

class DnsFixture : public ::benchmark::Fixture {
protected:
    static constexpr unsigned num_hosts = 1000;
    DnsResponderClient dns;
    std::vector<DnsResponderClient::Mapping> mappings;
    std::vector<std::unique_ptr<test::DNSResponder>> mDns;

public:
    void SetUp(const ::benchmark::State& state) override {
        if (state.thread_index == 0) {
            dns.SetUp();

            std::vector<std::string> domains = { "example.com" };
            std::vector<std::string> servers;
            dns.SetupMappings(num_hosts, domains, &mappings);
            dns.SetupDNSServers(MAXNS, mappings, &mDns, &servers);
            dns.SetResolversFromParcel(ResolverParams::Builder()
                                               .setDnsServers(servers)
                                               .setDotServers({})
                                               .setDomains(domains)
                                               .build());
        }
    }

    void TearDown(const ::benchmark::State& state) override {
        if (state.thread_index == 0) {
            dns.TearDown();
        }
    }

    std::vector<DnsResponderClient::Mapping> const& getMappings() const {
        return mappings;
    }

    void benchmark(benchmark::State& state) {
        while (state.KeepRunning()) {
            const uint32_t ofs = arc4random_uniform(getMappings().size());
            const auto& mapping = getMappings()[ofs];
            addrinfo* result = nullptr;
            if (getaddrinfo(mapping.host.c_str(), nullptr, nullptr, &result)) {
                state.SkipWithError(StringPrintf("getaddrinfo failed with errno=%d",
                        errno).c_str());
                break;
            }
            if (result) {
                freeaddrinfo(result);
                result = nullptr;
            }
        }
    }
};

BENCHMARK_DEFINE_F(DnsFixture, getaddrinfo)(benchmark::State& state) {
    benchmark(state);
}
BENCHMARK_REGISTER_F(DnsFixture, getaddrinfo)
    ->ThreadRange(MIN_THREADS, MAX_THREADS)
    ->UseRealTime();
