2018-05-20 09:14:17 +02:00
# include <cpp-utils/process/subprocess.h>
# include <gtest/gtest.h>
2019-03-24 06:01:26 +01:00
# include <boost/filesystem.hpp>
2018-05-20 09:14:17 +02:00
2019-02-28 11:29:10 +01:00
# include <cpp-utils/lock/ConditionBarrier.h>
2019-03-24 06:01:26 +01:00
# include "my-gtest-main.h"
2019-02-28 11:29:10 +01:00
2018-05-20 09:14:17 +02:00
using cpputils : : Subprocess ;
using cpputils : : SubprocessError ;
2019-03-24 06:01:26 +01:00
using std : : string ;
namespace bf = boost : : filesystem ;
2018-05-20 09:14:17 +02:00
2021-12-12 13:01:04 +01:00
// TODO Test passing input to stdin of processes
2021-12-22 21:18:02 +01:00
// TODO Test stderr
2021-12-12 13:01:04 +01:00
2018-07-09 04:34:08 +02:00
# if defined(_MSC_VER)
2021-12-09 15:06:45 +01:00
constexpr const char * NEWLINE = " \r \n " ;
2018-07-09 04:34:08 +02:00
# else
2021-12-09 15:06:45 +01:00
constexpr const char * NEWLINE = " \n " ;
2018-07-09 04:34:08 +02:00
# endif
2021-12-09 15:06:45 +01:00
namespace
{
bf : : path exit_with_message_and_status ( )
{
# if defined(_MSC_VER)
auto executable = bf : : canonical ( get_executable ( ) . parent_path ( ) ) / " cpp-utils-test_exit_status.exe " ;
# else
auto executable = bf : : canonical ( get_executable ( ) . parent_path ( ) ) / " cpp-utils-test_exit_status " ;
# endif
if ( ! bf : : exists ( executable ) )
{
throw std : : runtime_error ( executable . string ( ) + " not found. " ) ;
}
return executable ;
2019-03-24 06:01:26 +01:00
}
2018-07-09 04:34:08 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_success_output )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( std : : string ( " hello " ) + NEWLINE , Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 0 " , " hello " } , " " ) . output_stdout ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_successwithemptyoutput_output )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( " " , Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 0 " } , " " ) . output_stdout ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_success_exitcode )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( 0 , Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 0 " , " hello " } , " " ) . exitcode ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_successwithemptyoutput_exitcode )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( 0 , Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 0 " } , " " ) . exitcode ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_error )
{
2018-05-20 09:14:17 +02:00
EXPECT_THROW (
2021-12-12 13:00:07 +01:00
Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 1 " } , " " ) ,
2021-12-09 15:06:45 +01:00
SubprocessError ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_error5 )
{
2018-05-20 09:14:17 +02:00
EXPECT_THROW (
2021-12-12 13:00:07 +01:00
Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 5 " } , " " ) ,
2021-12-09 15:06:45 +01:00
SubprocessError ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_errorwithoutput )
{
2018-05-20 09:14:17 +02:00
EXPECT_THROW (
2021-12-12 13:00:07 +01:00
Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 1 " , " hello " } , " " ) ,
2021-12-09 15:06:45 +01:00
SubprocessError ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CheckCall_error5withoutput )
{
2018-05-20 09:14:17 +02:00
EXPECT_THROW (
2021-12-12 13:00:07 +01:00
Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 5 " , " hello " } , " " ) ,
2021-12-09 15:06:45 +01:00
SubprocessError ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_success_exitcode )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( 0 , Subprocess : : call ( exit_with_message_and_status ( ) , { " 0 " , " hello " } , " " ) . exitcode ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_success_output )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( std : : string ( " hello " ) + NEWLINE , Subprocess : : call ( exit_with_message_and_status ( ) , { " 0 " , " hello " } , " " ) . output_stdout ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_error_exitcode )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( 1 , Subprocess : : call ( exit_with_message_and_status ( ) , { " 1 " } , " " ) . exitcode ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_error_output )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( " " , Subprocess : : call ( exit_with_message_and_status ( ) , { " 1 " } , " " ) . output_stdout ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_error5_exitcode )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( 5 , Subprocess : : call ( exit_with_message_and_status ( ) , { " 5 " } , " " ) . exitcode ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_error5_output )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( " " , Subprocess : : call ( exit_with_message_and_status ( ) , { " 1 " } , " " ) . output_stdout ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_errorwithoutput_output )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( std : : string ( " hello " ) + NEWLINE , Subprocess : : call ( exit_with_message_and_status ( ) , { " 1 " , " hello " } , " " ) . output_stdout ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_errorwithoutput_exitcode )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( 1 , Subprocess : : call ( exit_with_message_and_status ( ) , { " 1 " , " hello " } , " " ) . exitcode ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_error5withoutput_output )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( std : : string ( " hello " ) + NEWLINE , Subprocess : : call ( exit_with_message_and_status ( ) , { " 5 " , " hello " } , " " ) . output_stdout ) ;
2018-05-20 09:14:17 +02:00
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_error5withoutput_exitcode )
{
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( 5 , Subprocess : : call ( exit_with_message_and_status ( ) , { " 5 " , " hello " } , " " ) . exitcode ) ;
2018-05-20 09:14:17 +02:00
}
2019-02-28 11:29:10 +01:00
// TODO Move this test to a test suite for ThreadSystem/LoopThread
# include <cpp-utils/thread/LoopThread.h>
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , CallFromThreadSystemThread )
{
2019-02-28 11:29:10 +01:00
cpputils : : ConditionBarrier barrier ;
cpputils : : LoopThread thread (
2021-12-09 15:06:45 +01:00
[ & barrier ] ( )
{
2021-12-12 13:00:07 +01:00
auto result = Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 0 " , " hello " } , " " ) ;
2019-02-28 11:29:10 +01:00
EXPECT_EQ ( 0 , result . exitcode ) ;
2021-12-09 15:06:45 +01:00
EXPECT_EQ ( std : : string ( " hello " ) + NEWLINE , result . output_stdout ) ;
2019-02-28 11:29:10 +01:00
barrier . release ( ) ;
return false ; // don't run loop again
} ,
2021-12-09 15:06:45 +01:00
" child_thread " ) ;
2019-02-28 11:29:10 +01:00
thread . start ( ) ;
barrier . wait ( ) ;
thread . stop ( ) ; // just to make sure it's stopped before the test exits. Returning false above should already stop it, but we don't know when exactly. thread.stop() will block until it's actually stopped.
}
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_argumentwithspaces )
{
// Test that arguments can have spaces and are still treated as one argument
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( std : : string ( " hello world " ) + NEWLINE , Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 0 " , " hello world " } , " " ) . output_stdout ) ;
EXPECT_EQ ( std : : string ( " hello " ) + NEWLINE + " world " + NEWLINE , Subprocess : : check_call ( exit_with_message_and_status ( ) , { " 0 " , " hello " , " world " } , " " ) . output_stdout ) ;
2021-12-09 15:06:45 +01:00
}
2021-12-22 21:18:02 +01:00
# if !defined(_MSC_VER)
2021-12-09 15:06:45 +01:00
TEST ( SubprocessTest , Call_withcommandfrompath )
{
// Test that we can call a system command without specifying the full path
2021-12-12 13:00:07 +01:00
EXPECT_EQ ( " hello \n " , Subprocess : : check_call ( " echo " , { " hello " } , " " ) . output_stdout ) ;
2021-12-09 15:06:45 +01:00
}
2021-12-22 21:18:02 +01:00
# endif