test_benchmark.cc 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include <httplib.h>
  2. #include <gtest/gtest.h>
  3. #include <algorithm>
  4. #include <chrono>
  5. #include <sstream>
  6. #include <thread>
  7. #include <vector>
  8. using namespace httplib;
  9. static const int PORT = 11134;
  10. static void performance_test(const char *host) {
  11. Server svr;
  12. svr.Get("/benchmark", [&](const Request & /*req*/, Response &res) {
  13. res.set_content("Benchmark Response", "text/plain");
  14. });
  15. auto listen_thread = std::thread([&]() { svr.listen(host, PORT); });
  16. auto se = detail::scope_exit([&] {
  17. svr.stop();
  18. listen_thread.join();
  19. ASSERT_FALSE(svr.is_running());
  20. });
  21. svr.wait_until_ready();
  22. Client cli(host, PORT);
  23. // Warm-up request to establish connection and resolve DNS
  24. auto warmup_res = cli.Get("/benchmark");
  25. ASSERT_TRUE(warmup_res); // Ensure server is responding correctly
  26. // Run multiple trials and collect timings
  27. const int num_trials = 20;
  28. std::vector<int64_t> timings;
  29. timings.reserve(num_trials);
  30. for (int i = 0; i < num_trials; i++) {
  31. auto start = std::chrono::high_resolution_clock::now();
  32. auto res = cli.Get("/benchmark");
  33. auto end = std::chrono::high_resolution_clock::now();
  34. auto elapsed =
  35. std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
  36. .count();
  37. // Assertions after timing measurement to avoid overhead
  38. ASSERT_TRUE(res);
  39. EXPECT_EQ(StatusCode::OK_200, res->status);
  40. timings.push_back(elapsed);
  41. }
  42. // Calculate 25th percentile (lower quartile)
  43. std::sort(timings.begin(), timings.end());
  44. auto p25 = timings[num_trials / 4];
  45. // Format timings for output
  46. std::ostringstream timings_str;
  47. timings_str << "[";
  48. for (size_t i = 0; i < timings.size(); i++) {
  49. if (i > 0) timings_str << ", ";
  50. timings_str << timings[i];
  51. }
  52. timings_str << "]";
  53. // Localhost HTTP GET should be fast even in CI environments
  54. EXPECT_LE(p25, 5) << "25th percentile performance is too slow: " << p25
  55. << "ms (Issue #1777). Timings: " << timings_str.str();
  56. }
  57. TEST(BenchmarkTest, localhost) { performance_test("localhost"); }
  58. TEST(BenchmarkTest, v6) { performance_test("::1"); }