Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable support for HTTP communication between components ECFLOW-1957 #121

Draft
wants to merge 24 commits into
base: develop
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8d73a55
Refactor DefaultServer class template
marcosbento Feb 20, 2024
9906a73
Enable HTTP connection between Client/Server
marcosbento Feb 21, 2024
28bc5e7
Enable UI to use HTTP connection
marcosbento Jun 20, 2024
ac25b60
Enable REST/UDP proxies to use HTTP connection
marcosbento Sep 4, 2024
47004a3
Enable ecFlow REST API tests using HTTP backend
marcosbento Oct 2, 2024
6899cfc
Improve TestFixture by extracting ScratchDir
marcosbento Oct 10, 2024
f736cee
Improve TestFixture by extracting LocalServerLauncher
marcosbento Oct 11, 2024
a32ab82
Enable s_test with HTTP backend
marcosbento Oct 11, 2024
75933f2
Simplify tests AbortCmd and WaitCmd
marcosbento Oct 11, 2024
8623e09
Correct typo in source code comment
marcosbento Oct 11, 2024
ef822e6
Replace deprecated use of BOOST_GLOBAL_FIXTURE
marcosbento Oct 11, 2024
4028343
Allow REST API tests to run in parallel
marcosbento Oct 15, 2024
9674040
Remove the use of std::filesystem
marcosbento Oct 15, 2024
ebffe69
Ensure parallel s_test* do not use same port or directory
marcosbento Oct 16, 2024
fab3359
Test ecFlow Python using HTTP ecFlow server
marcosbento Oct 17, 2024
abe99b6
Enable HTTPS on the Client side
marcosbento Oct 18, 2024
e3c2683
Use notion of selected Protocol
marcosbento Oct 18, 2024
f42dd5d
Move test methods in ClientInvoker to SCPort
marcosbento Oct 21, 2024
fcf00c7
Use notion of selected Protocol
marcosbento Oct 21, 2024
d68b5d9
Add description to HttpServer
marcosbento Oct 21, 2024
2ee69df
Correct #include guards
marcosbento Oct 21, 2024
d36d36b
Correct outstanding compilation warnings
marcosbento Oct 21, 2024
d3f94ee
Update default HTTP connection timeouts
marcosbento Oct 24, 2024
f0e0adf
Replace use of io.post() with boost::asio::post
marcosbento Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Enable ecFlow REST API tests using HTTP backend
Re ECFLOW-1957
marcosbento committed Mar 12, 2025
commit 47004a37bee81a687af438b7b28be4139c24a07b
6 changes: 4 additions & 2 deletions libs/attribute/src/ecflow/attribute/Variable.cpp
Original file line number Diff line number Diff line change
@@ -49,10 +49,12 @@ int Variable::value() const {
}

bool Variable::operator==(const Variable& rhs) const {
if (v_ != rhs.v_)
if (v_ != rhs.v_) {
return false;
if (n_ != rhs.n_)
}
if (n_ != rhs.n_) {
return false;
}
return true;
}

3 changes: 3 additions & 0 deletions libs/base/src/ecflow/base/HttpClient.cpp
Original file line number Diff line number Diff line change
@@ -22,6 +22,8 @@ HttpClient::HttpClient(Cmd_ptr cmd_ptr, const std::string& host, const std::stri
port_(port),
client_(host, ecf::convert_to<int>(port)) {

client_.set_connection_timeout(std::chrono::seconds{timeout});

if (!cmd_ptr.get()) {
throw std::runtime_error("Client::Client: No request specified !");
}
@@ -36,6 +38,7 @@ void HttpClient::run() {
auto result = client_.Post("/v1/ecflow", outbound, "application/json");
if (result) {
auto response = result.value();
status_ = httplib::Error::Success;
ecf::restore_from_string(response.body, inbound_response_);
}
else {
2 changes: 1 addition & 1 deletion libs/base/src/ecflow/base/HttpClient.hpp
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@
class HttpClient {
public:
/// Constructor starts the asynchronous connect operation.
HttpClient(Cmd_ptr cmd_ptr, const std::string& host, const std::string& port, int timout = 0);
HttpClient(Cmd_ptr cmd_ptr, const std::string& host, const std::string& port, int timout = 60);

void run();

9 changes: 6 additions & 3 deletions libs/client/src/ecflow/client/ClientInvoker.cpp
Original file line number Diff line number Diff line change
@@ -431,8 +431,9 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const {
#endif
io.run();
}
if (clientEnv_.debug())
if (clientEnv_.debug()) {
cout << TimeStamp::now() << "ClientInvoker: >>> After: io_context::run() <<<" << endl;
}

/// Let see how the server responded if at all.
try {
@@ -451,8 +452,9 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const {
HttpClient theClient(cts_cmd, clientEnv_.host(), clientEnv_.port());
theClient.run();

if (clientEnv_.debug())
if (clientEnv_.debug()) {
cout << TimeStamp::now() << "ClientInvoker: >>> After: io_service.run() <<<" << endl;
}

/// Let see how the server responded if at all.
try {
@@ -477,8 +479,9 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const {
#endif
io.run();
}
if (clientEnv_.debug())
if (clientEnv_.debug()) {
cout << TimeStamp::now() << "ClientInvoker: >>> After: io_context::run() <<<" << endl;
}

/// Let see how the server responded if at all.
try {
28 changes: 28 additions & 0 deletions libs/rest/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -144,6 +144,34 @@ if (ENABLE_HTTP AND ENABLE_SERVER)
target_clangformat(s_http
CONDITION ENABLE_TESTS
)

ecbuild_add_test(
TARGET
s_http_using_http_backend
LABELS
integration nightly
SOURCES
${test_srcs}
INCLUDES
../base/test
DEFINITIONS
ECF_TEST_HTTP_BACKEND
LIBS
libhttp
ecflow_all
Boost::boost # Boost header-only libraries must be available (namely unit_test_framework)
$<$<BOOL:${OPENSSL_FOUND}>:OpenSSL::SSL>
test_support
DEPENDS
ecflow_server # the server is launched to support tests
ecflow_http
TEST_DEPENDS
u_base
s_client
)
target_clangformat(s_http_using_http_backend
CONDITION ENABLE_TESTS
)
else ()
message(WARNING "SSL not enabled - will not run HTTP server tests")
endif ()
16 changes: 14 additions & 2 deletions libs/rest/test/InvokeServer.hpp
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@

class InvokeServer {
public:
InvokeServer() {
InvokeServer(bool use_http_backend = false) : use_http_backend_(use_http_backend) {
std::string port;
ecf::environment::get(ecf::environment::ECF_PORT, port);
/// Remove check pt and backup check pt file, else server will load it & remove log file
@@ -43,13 +43,21 @@ class InvokeServer {

BOOST_TEST_MESSAGE("Using eclow_server from " << theServerInvokePath);

std::thread t([&] { system(theServerInvokePath.c_str()); });
std::string cmd = theServerInvokePath;
if (use_http_backend_) {
cmd += " --http";
}

std::thread t([&] { system(cmd.c_str()); });

t.detach();

sleep(1);

ClientInvoker theClient("localhost", port);
if (use_http_backend_) {
theClient.enable_http();
}
if (theClient.wait_for_server_reply()) {
theClient.restartServer();
server_started = true;
@@ -66,6 +74,9 @@ class InvokeServer {
BOOST_TEST_MESSAGE("*****InvokeServer:: Closing server on port " << port);
{
ClientInvoker theClient("localhost", port);
if (use_http_backend_) {
theClient.enable_http();
}
BOOST_REQUIRE_NO_THROW(theClient.terminateServer());
BOOST_REQUIRE_MESSAGE(theClient.wait_for_server_death(), "Failed to terminate server after 60 seconds\n");
}
@@ -83,6 +94,7 @@ class InvokeServer {
}

bool server_started{false};
bool use_http_backend_{false};
};

#endif /* ecflow_http_test_InvokeServer_HPP */
12 changes: 11 additions & 1 deletion libs/rest/test/TestApiV1.cpp
Original file line number Diff line number Diff line change
@@ -75,8 +75,13 @@ void start_api_server() {
}

std::thread t([] {
#if defined(ECF_TEST_HTTP_BACKEND)
int argc = 4;
char* argv[] = {(char*)"ecflow_http", (char*)"--polling_interval", (char*)"1", (char*)"--http", NULL};
#else
int argc = 3;
char* argv[] = {(char*)"ecflow_http", (char*)"--polling_interval", (char*)"1", NULL};
#endif

HttpServer server(argc, argv);
server.run();
@@ -91,7 +96,12 @@ std::unique_ptr<InvokeServer> start_ecflow_server() {
return nullptr;
}

auto srv = std::make_unique<InvokeServer>();
bool use_http_backend = false;
#if defined(ECF_TEST_HTTP_BACKEND)
use_http_backend = true;
#endif

auto srv = std::make_unique<InvokeServer>(use_http_backend);

auto port = ecf::environment::get("ECF_PORT");
BOOST_REQUIRE_MESSAGE(srv->server_started, "Server failed to start on port " << port);
19 changes: 19 additions & 0 deletions libs/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -63,6 +63,25 @@ if (ENABLE_ALL_TESTS)
)
target_clangformat(s_test CONDITION ENABLE_TESTS)

ecbuild_add_test(
TARGET
s_test_http
LABELS
integration
nightly
SOURCES
${test_srcs}
DEFINITIONS
ECFLOW_TEST_SERVER_HTTP
LIBS
libharness
$<$<BOOL:${OPENSSL_FOUND}>:OpenSSL::SSL>
test_support
TEST_DEPENDS
s_client
)
target_clangformat(s_test_http CONDITION ENABLE_TESTS)

ecbuild_add_test(
TARGET
s_zombies