@@ -761,32 +761,57 @@ struct Client
761761 bool stdout_contains (const std::string& expected) const {
762762 return stdout_buffer.find (expected) != std::string::npos;
763763 }
764+ bool stdout_contains (const std::regex& expected) const {
765+ std::smatch match;
766+ std::regex_search (stdout_buffer, match, expected);
767+ return !match.empty ();
768+ }
764769};
765770
766771class RunClient {
767772public:
768773 using host_t = Host;
769774 using port_t = Port;
770775
776+ struct CommandHelp
777+ {
778+ static constexpr bool contacts_server = false ;
779+
780+ std::vector<std::string> options () const { return {" --help" }; }
781+ };
782+
783+ struct CommandVersion
784+ {
785+ static constexpr bool contacts_server = false ;
786+
787+ std::vector<std::string> options () const { return {" --version" }; }
788+ };
789+
771790 struct CommandPing
772791 {
773- std::vector<std::string> options () const { return { " --ping " , " -d " }; }
792+ static constexpr bool contacts_server = true ;
774793
775- void process_output ( const std::string& output ) const {}
794+ std::vector<std:: string> options ( ) const { return { " --ping " , " -d " }; }
776795 };
777796
778797 struct CommandGet
779798 {
799+ static constexpr bool contacts_server = true ;
800+
780801 std::vector<std::string> options () const { return {" --get" }; }
781802 };
782803
783804 struct CommandGetState
784805 {
806+ static constexpr bool contacts_server = true ;
807+
785808 std::vector<std::string> options () const { return {" --get_state" }; }
786809 };
787810
788811 struct CommandLoad
789812 {
813+ static constexpr bool contacts_server = true ;
814+
790815 explicit CommandLoad (fs::path defs)
791816 : defs_{defs} {}
792817
@@ -797,6 +822,8 @@ class RunClient {
797822
798823 struct CommandReplace
799824 {
825+ static constexpr bool contacts_server = true ;
826+
800827 explicit CommandReplace (fs::path defs, std::string node)
801828 : defs_{defs},
802829 node_{std::move (node)} {}
@@ -809,6 +836,8 @@ class RunClient {
809836
810837 struct CommandDelete
811838 {
839+ static constexpr bool contacts_server = true ;
840+
812841 explicit CommandDelete (std::string path)
813842 : path_{path} {}
814843
@@ -819,6 +848,8 @@ class RunClient {
819848
820849 struct CommandUpdateLabel
821850 {
851+ static constexpr bool contacts_server = true ;
852+
822853 explicit CommandUpdateLabel (std::string path, std::string label, std::string value)
823854 : path_{path},
824855 label_{label},
@@ -833,6 +864,8 @@ class RunClient {
833864
834865 struct CommandReloadWhitelist
835866 {
867+ static constexpr bool contacts_server = true ;
868+
836869 explicit CommandReloadWhitelist () {}
837870
838871 std::vector<std::string> options () const { return {" --reloadwsfile" }; }
@@ -885,16 +918,26 @@ class RunClient {
885918 const User* user,
886919 const Directory* cwd,
887920 const Command& command) {
888- BOOST_REQUIRE_MESSAGE (host != nullptr , " The server host is non-null" );
889- BOOST_REQUIRE_MESSAGE (port != nullptr , " The server port is non-null" );
890- BOOST_REQUIRE_MESSAGE (cwd != nullptr , " The working directory is non-null" );
921+ if constexpr (Command::contacts_server) {
922+ BOOST_REQUIRE_MESSAGE (host != nullptr , " The server host is non-null" );
923+ BOOST_REQUIRE_MESSAGE (port != nullptr , " The server port is non-null" );
924+ BOOST_REQUIRE_MESSAGE (cwd != nullptr , " The working directory is non-null" );
925+ }
891926
892927 auto client_path = find_ecflow_client_path ();
893928
894929 BOOST_REQUIRE_MESSAGE (!client_path.empty (), " The ecflow client path is non-empty" );
895930 BOOST_REQUIRE_MESSAGE (fs::exists (client_path), " The ecflow client executable exist at " << client_path);
896931
897- auto options = std::vector<std::string>{" --host" , host->value (), " --port" , std::to_string (port->value ())};
932+ auto options = std::vector<std::string>{};
933+ if (host != nullptr ) {
934+ options.push_back (" --host" );
935+ options.push_back (host->value ());
936+ }
937+ if (port != nullptr ) {
938+ options.push_back (" --port" );
939+ options.push_back (std::to_string (port->value ()));
940+ }
898941 if (user != nullptr ) {
899942 options.push_back (" --user" );
900943 options.push_back (user->username );
@@ -905,7 +948,9 @@ class RunClient {
905948 options.push_back (option);
906949 }
907950
908- auto ecflow_client = Process (client_path, options, cwd->path ());
951+ auto wd = cwd != nullptr ? cwd->path () : fs::current_path ();
952+
953+ auto ecflow_client = Process (client_path, options, wd);
909954
910955 auto print = [](const auto & executable, const auto & options) {
911956 std::string buffer = " [ " + pretty_print_path (executable) + (options.empty () ? " " : " , " );
@@ -922,22 +967,22 @@ class RunClient {
922967 ECF_TEST_DBG (" Executed " << print (client_path, options));
923968 ECF_TEST_DBG (" result: [OK]" );
924969 ECF_TEST_DBG (" pid: " << ecflow_client.pid ());
925- ECF_TEST_DBG (" cwd: " << cwd-> path () .string ());
926- auto [stdout_buffer, stderr_buffer] = dump_client_execution_report (*cwd , ecflow_client);
970+ ECF_TEST_DBG (" cwd: " << wd .string ());
971+ auto [stdout_buffer, stderr_buffer] = dump_client_execution_report (wd , ecflow_client);
927972 return Outcome<Client>::success (Client{r, stdout_buffer, stderr_buffer});
928973 }
929974 else {
930975 ECF_TEST_DBG (" Executed " << print (client_path, options));
931976 ECF_TEST_DBG (" result: [FAIL]" );
932977 ECF_TEST_DBG (" pid: " << ecflow_client.pid ());
933- ECF_TEST_DBG (" cwd: " << cwd-> path () .string ());
934- auto [stdout_buffer, stderr_buffer] = dump_client_execution_report (*cwd , ecflow_client);
978+ ECF_TEST_DBG (" cwd: " << wd .string ());
979+ auto [stdout_buffer, stderr_buffer] = dump_client_execution_report (wd , ecflow_client);
935980 return Outcome<Client>::failure (" ecflow_client failed, return code: " + std::to_string (r) +
936981 " , stdout: " + stdout_buffer + " , stderr: " + stderr_buffer);
937982 }
938983 }
939984
940- static std::tuple<std::string, std::string> dump_client_execution_report (const Directory& cwd ,
985+ static std::tuple<std::string, std::string> dump_client_execution_report (const fs::path& wd ,
941986 const Process& server) {
942987 auto out = server.read_stdout ();
943988 auto err = server.read_stderr ();
@@ -946,8 +991,8 @@ class RunClient {
946991 std::string{" ecflow_client__execution_report." } + std::to_string (server.pid ()) + " .stdout.txt" ;
947992 std::string report_stderr_file =
948993 std::string{" ecflow_client__execution_report." } + std::to_string (server.pid ()) + " .stderr.txt" ;
949- fs::path report_stdout_path = cwd. path () / report_stdout_file;
950- fs::path report_stderr_path = cwd. path () / report_stderr_file;
994+ fs::path report_stdout_path = wd / report_stdout_file;
995+ fs::path report_stderr_path = wd / report_stderr_file;
951996
952997 {
953998 std::ofstream ofs (report_stdout_path.c_str ());
0 commit comments