Skip to content

Commit 3c4a4c2

Browse files
author
hoguni
committed
modify mock server
1 parent 3f899fb commit 3c4a4c2

1 file changed

Lines changed: 80 additions & 16 deletions

File tree

tests/AuthPluginTest.cc

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <boost/algorithm/string.hpp>
2525
#include <chrono>
2626
#include <future>
27+
#include <mutex>
2728
#include <sstream>
2829
#include <stdexcept>
2930
#ifdef USE_ASIO
@@ -542,6 +543,8 @@ TEST(AuthPluginTest, testAuthFactoryAthenz) {
542543
}
543544

544545
namespace testOauth2Tls {
546+
static const auto mockServerTimeout = std::chrono::seconds(10);
547+
545548
class MockOauth2Server {
546549
public:
547550
MockOauth2Server(const std::string& responseBody, const std::string& responseContentType, int listenPort,
@@ -563,23 +566,57 @@ class MockOauth2Server {
563566
const std::string& request() const { return request_; }
564567

565568
bool mockServe() {
566-
ASIO::ip::tcp::socket socket(io_);
567-
acceptor_.accept(socket);
568569
ASIO_ERROR error;
569-
ASIO::ssl::stream<ASIO::ip::tcp::socket&> sslStream(socket, sslCtx_);
570+
auto socket = std::make_shared<ASIO::ip::tcp::socket>(io_);
571+
{
572+
std::lock_guard<std::mutex> lock(mutex_);
573+
activeSocket_ = socket;
574+
}
575+
576+
acceptor_.accept(*socket, error);
577+
if (error) {
578+
clearActiveSocket();
579+
return false;
580+
}
581+
582+
ASIO::ssl::stream<ASIO::ip::tcp::socket&> sslStream(*socket, sslCtx_);
570583
sslStream.handshake(ASIO::ssl::stream_base::server, error);
571-
if (error) return false;
572-
if (!readRequest(sslStream)) return false;
584+
if (error || !readRequest(sslStream)) {
585+
clearActiveSocket();
586+
return false;
587+
}
573588

574-
const std::string response = "HTTP/1.1 200 OK\nContent-Type: " + responseContentType_ +
575-
"\nContent-Length: " + std::to_string(responseBody_.size()) +
576-
"\nConnection: close\n\n" + responseBody_;
589+
const std::string response = "HTTP/1.1 200 OK\r\nContent-Type: " + responseContentType_ +
590+
"\r\nContent-Length: " + std::to_string(responseBody_.size()) +
591+
"\r\nConnection: close\r\n\r\n" + responseBody_;
577592
ASIO::write(sslStream, ASIO::buffer(response.data(), response.size()), error);
593+
clearActiveSocket();
578594
if (error) return false;
579595
return true;
580596
}
581597

598+
void stop() {
599+
ASIO_ERROR error;
600+
{
601+
std::lock_guard<std::mutex> lock(mutex_);
602+
if (acceptor_.is_open()) {
603+
acceptor_.close(error);
604+
}
605+
if (activeSocket_ && activeSocket_->is_open()) {
606+
activeSocket_->cancel(error);
607+
activeSocket_->shutdown(ASIO::ip::tcp::socket::shutdown_both, error);
608+
activeSocket_->close(error);
609+
}
610+
}
611+
io_.stop();
612+
}
613+
582614
private:
615+
void clearActiveSocket() {
616+
std::lock_guard<std::mutex> lock(mutex_);
617+
activeSocket_.reset();
618+
}
619+
583620
bool readRequest(ASIO::ssl::stream<ASIO::ip::tcp::socket&>& sslStream) {
584621
SocketStream<ASIO::ssl::stream<ASIO::ip::tcp::socket&>> stream(sslStream);
585622
request_.clear();
@@ -615,8 +652,30 @@ class MockOauth2Server {
615652
ASIO::io_context io_;
616653
ASIO::ip::tcp::acceptor acceptor_;
617654
ASIO::ssl::context sslCtx_;
655+
std::shared_ptr<ASIO::ip::tcp::socket> activeSocket_;
656+
std::mutex mutex_;
618657
};
619658

659+
static bool awaitMockServeResult(std::future<bool>& future, MockOauth2Server& server, std::thread& thread,
660+
const char* serverName) {
661+
if (future.wait_for(mockServerTimeout) != std::future_status::ready) {
662+
server.stop();
663+
if (thread.joinable()) {
664+
thread.join();
665+
}
666+
ADD_FAILURE() << serverName << " did not complete within "
667+
<< std::chrono::duration_cast<std::chrono::seconds>(mockServerTimeout).count()
668+
<< " seconds";
669+
return false;
670+
}
671+
672+
const bool result = future.get();
673+
if (thread.joinable()) {
674+
thread.join();
675+
}
676+
return result;
677+
}
678+
620679
} // namespace testOauth2Tls
621680

622681
TEST(AuthPluginTest, testOauth2) {
@@ -821,13 +880,13 @@ TEST(AuthPluginTest, testOauth2TlsClientAuth) {
821880
ASSERT_TRUE(data->hasDataFromCommand());
822881
ASSERT_EQ(data->getCommandData(), "mockToken");
823882

824-
ASSERT_TRUE(wellKnownFuture.get());
825-
ASSERT_TRUE(tokenFuture.get());
883+
ASSERT_TRUE(testOauth2Tls::awaitMockServeResult(wellKnownFuture, *wellKnownServer, wellKnownThread,
884+
"Well-known mock server"));
885+
ASSERT_TRUE(
886+
testOauth2Tls::awaitMockServeResult(tokenFuture, *tokenServer, tokenThread, "Token mock server"));
826887
ASSERT_NE(wellKnownServer->request().find("GET /.well-known/openid-configuration "), std::string::npos);
827888
ASSERT_NE(tokenServer->request().find("POST /oauth/token "), std::string::npos);
828889
ASSERT_NE(tokenServer->request().find("grant_type=client_credentials"), std::string::npos);
829-
wellKnownThread.join();
830-
tokenThread.join();
831890
}
832891

833892
TEST(AuthPluginTest, testOauth2TlsClientAuthWrongCert) {
@@ -878,11 +937,11 @@ TEST(AuthPluginTest, testOauth2TlsClientAuthWrongCert) {
878937
AuthenticationPtr auth = AuthOauth2::create(params);
879938
ASSERT_EQ(auth->getAuthData(data), ResultAuthenticationError);
880939

881-
ASSERT_TRUE(wellKnownFuture.get());
882-
ASSERT_FALSE(tokenFuture.get());
940+
ASSERT_TRUE(testOauth2Tls::awaitMockServeResult(wellKnownFuture, *wellKnownServer, wellKnownThread,
941+
"Well-known mock server"));
942+
ASSERT_FALSE(
943+
testOauth2Tls::awaitMockServeResult(tokenFuture, *tokenServer, tokenThread, "Token mock server"));
883944
ASSERT_NE(wellKnownServer->request().find("GET /.well-known/openid-configuration "), std::string::npos);
884-
wellKnownThread.join();
885-
tokenThread.join();
886945
}
887946

888947
TEST(AuthPluginTest, testOauth2TlsClientAuthRequestBody) {
@@ -953,6 +1012,11 @@ TEST(AuthPluginTest, testOauth2TlsClientAuthFailure) {
9531012
params.erase("tls_key_file");
9541013
ASSERT_EQ(getAuthDataResult(), ResultAuthenticationError);
9551014

1015+
// Only cert
1016+
params["tls_cert_file"] = clientPublicKeyPath;
1017+
params.erase("tls_key_file");
1018+
ASSERT_EQ(getAuthDataResult(), ResultAuthenticationError);
1019+
9561020
// Invalid cert and key
9571021
params["tls_cert_file"] = TEST_CONF_DIR "/not-exist-cert.pem";
9581022
params["tls_key_file"] = TEST_CONF_DIR "/not-exist-key.pem";

0 commit comments

Comments
 (0)