I have a setup where my integration test is calling up a subprocess (the actual process that should be tested).
I also want to test the de-init behaviour, so I want to gracefully close the subprocess in that test.
I spawn the subprocess with:
auto process(ctx, "process.exe", {"-f", "config.ini"});
Later on I call:
process.request_exit();
process.wait();
However, the subprocess never closes.
For simple testing I added the following signal handler for my main process:
void signal_handler(int signal_num)
{
std::exit(signal_num);
}
int main()
{
std::signal(SIGTERM, signal_handler);
...
}
I am working on a windows machine. Am I missing something?
First, I installed windows. Then Boost 1.86. Then I went into libs\process\test\v2
and did ..\..\..\..\b2.exe
to check that the test run. They do.
In fact the request_exit
test case works as well:
So what's different about their setup?
BOOST_AUTO_TEST_CASE(request_exit)
{
asio::io_context ctx;
using boost::unit_test::framework::master_test_suite;
const auto pth = master_test_suite().argv[1];
bpv::process proc(ctx, pth, {"sigterm"}
#if defined(BOOST_PROCESS_V2_WINDOWS)
, bpv::windows::show_window_minimized_not_active
, bpv::windows::create_new_console
#endif
);
BOOST_CHECK(proc.running());
std::this_thread::sleep_for(std::chrono::milliseconds(250));
proc.request_exit();
proc.wait();
BOOST_CHECK_EQUAL(proc.exit_code() & ~SIGTERM, 0);
}
Noteworthy: the process creation flags. Let's add those:
#define _WIN32_WINNT 0x0601
#include <boost/process/v2/process.hpp>
#include <iostream>
#include <thread>
#if defined(BOOST_PROCESS_V2_WINDOWS)
#include <boost/process/v2/windows/creation_flags.hpp>
#include <boost/process/v2/windows/show_window.hpp>
#endif
using namespace std::chrono_literals;
namespace bp = boost::process::v2;
namespace asio = boost::asio;
int main(int, char** argv) {
static auto debug = [=](auto const&... m) {
((std::clog << std::setw(14) << std::quoted(argv[0]) << ": ") << ... << m) << std::endl;
};
debug("Working directory: ", boost::filesystem::current_path().string());
debug("Starting");
auto process = bp::process(asio::system_executor{}, "process.exe", {"-f", "config.ini"}
#if defined(BOOST_PROCESS_V2_WINDOWS)
, bp::windows::show_window_minimized_not_active
, bp::windows::create_new_console
#endif
);
debug("Started");
std::this_thread::sleep_for(3s);
debug("Requesting exit");
process.request_exit();
debug("Waiting for exit");
process.wait();
debug("Child exit: ", process.exit_code());
}
With the Process.exe
vain.cpp
:
#define _WIN32_WINNT 0x0601
#include <iostream>
#include <iomanip>
#include <boost/asio.hpp>
namespace asio = boost::asio;
int main(int, char** argv) {
asio::io_context ioc(1);
static auto debug = [=](auto const&... m) {
((std::clog << std::setw(14) << std::quoted(argv[0]) << ": ") << ... << m) << std::endl;
};
debug("Process.exe started");
asio::signal_set ss(ioc, SIGTERM);
ss.async_wait([](boost::system::error_code ec, int num) {
debug("signal ", num, " (", ec.message(), ")");
});
ioc.run();
debug("Process.exe exit");
}
Now it works: