| #include <httplib.h> |
| |
| #include <gtest/gtest.h> |
| |
| #include <algorithm> |
| #include <chrono> |
| #include <sstream> |
| #include <thread> |
| #include <vector> |
| |
| using namespace httplib; |
| |
| static const int PORT = 11134; |
| |
| static void performance_test(const char *host) { |
| Server svr; |
| |
| svr.Get("/benchmark", [&](const Request & /*req*/, Response &res) { |
| res.set_content("Benchmark Response", "text/plain"); |
| }); |
| |
| auto listen_thread = std::thread([&]() { svr.listen(host, PORT); }); |
| auto se = detail::scope_exit([&] { |
| svr.stop(); |
| listen_thread.join(); |
| ASSERT_FALSE(svr.is_running()); |
| }); |
| |
| svr.wait_until_ready(); |
| |
| Client cli(host, PORT); |
| |
| // Warm-up request to establish connection and resolve DNS |
| auto warmup_res = cli.Get("/benchmark"); |
| ASSERT_TRUE(warmup_res); // Ensure server is responding correctly |
| |
| // Run multiple trials and collect timings |
| const int num_trials = 20; |
| std::vector<int64_t> timings; |
| timings.reserve(num_trials); |
| |
| for (int i = 0; i < num_trials; i++) { |
| auto start = std::chrono::high_resolution_clock::now(); |
| auto res = cli.Get("/benchmark"); |
| auto end = std::chrono::high_resolution_clock::now(); |
| |
| auto elapsed = |
| std::chrono::duration_cast<std::chrono::milliseconds>(end - start) |
| .count(); |
| |
| // Assertions after timing measurement to avoid overhead |
| ASSERT_TRUE(res); |
| EXPECT_EQ(StatusCode::OK_200, res->status); |
| |
| timings.push_back(elapsed); |
| } |
| |
| // Calculate 25th percentile (lower quartile) |
| std::sort(timings.begin(), timings.end()); |
| auto p25 = timings[num_trials / 4]; |
| |
| // Format timings for output |
| std::ostringstream timings_str; |
| timings_str << "["; |
| for (size_t i = 0; i < timings.size(); i++) { |
| if (i > 0) timings_str << ", "; |
| timings_str << timings[i]; |
| } |
| timings_str << "]"; |
| |
| // Localhost HTTP GET should be fast even in CI environments |
| EXPECT_LE(p25, 5) << "25th percentile performance is too slow: " << p25 |
| << "ms (Issue #1777). Timings: " << timings_str.str(); |
| } |
| |
| TEST(BenchmarkTest, localhost) { performance_test("localhost"); } |
| |
| TEST(BenchmarkTest, v6) { performance_test("::1"); } |