You've already forked cpp-httplib
							
							Fix benchmark test issue on Windows (#2258)
This commit is contained in:
		
							
								
								
									
										108
									
								
								test/test.cc
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								test/test.cc
									
									
									
									
									
								
							@@ -11,6 +11,7 @@
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include <gtest/gtest.h>
 | 
					#include <gtest/gtest.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
#include <atomic>
 | 
					#include <atomic>
 | 
				
			||||||
#include <chrono>
 | 
					#include <chrono>
 | 
				
			||||||
#include <cstdio>
 | 
					#include <cstdio>
 | 
				
			||||||
@@ -78,6 +79,73 @@ static void read_file(const std::string &path, std::string &out) {
 | 
				
			|||||||
  fs.read(&out[0], static_cast<std::streamsize>(size));
 | 
					  fs.read(&out[0], static_cast<std::streamsize>(size));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void performance_test(const char *host) {
 | 
				
			||||||
 | 
					  auto port = 1234;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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"); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UnixSocketTest : public ::testing::Test {
 | 
					class UnixSocketTest : public ::testing::Test {
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
  void TearDown() override { std::remove(pathname_.c_str()); }
 | 
					  void TearDown() override { std::remove(pathname_.c_str()); }
 | 
				
			||||||
@@ -3634,46 +3702,6 @@ TEST_F(ServerTest, GetMethod200) {
 | 
				
			|||||||
  EXPECT_EQ("Hello World!", res->body);
 | 
					  EXPECT_EQ("Hello World!", res->body);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void performance_test(const char *host) {
 | 
					 | 
				
			||||||
  auto port = 1234;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  auto start = std::chrono::high_resolution_clock::now();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  auto res = cli.Get("/benchmark");
 | 
					 | 
				
			||||||
  ASSERT_TRUE(res);
 | 
					 | 
				
			||||||
  EXPECT_EQ(StatusCode::OK_200, res->status);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  auto end = std::chrono::high_resolution_clock::now();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  auto elapsed =
 | 
					 | 
				
			||||||
      std::chrono::duration_cast<std::chrono::milliseconds>(end - start)
 | 
					 | 
				
			||||||
          .count();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  EXPECT_LE(elapsed, 5) << "Performance is too slow: " << elapsed
 | 
					 | 
				
			||||||
                        << "ms (Issue #1777)";
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(BenchmarkTest, localhost) { performance_test("localhost"); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST(BenchmarkTest, v6) { performance_test("::1"); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST_F(ServerTest, GetEmptyFile) {
 | 
					TEST_F(ServerTest, GetEmptyFile) {
 | 
				
			||||||
  auto res = cli_.Get("/empty_file");
 | 
					  auto res = cli_.Get("/empty_file");
 | 
				
			||||||
  ASSERT_TRUE(res);
 | 
					  ASSERT_TRUE(res);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user