#include "stx-execpipe.h"
#include <assert.h>
#include <iostream>
#include <sstream>
#include <iomanip>
void test_none_program_string()
{
stx::ExecPipe ep;
std::string output;
ep.set_output_string(&output);
ep.add_exec("/bin/echo", "test123");
assert( ep.run().all_return_codes_zero() );
assert( output == "test123\n" );
}
void test_string_program_string()
{
stx::ExecPipe ep;
std::string input = "test123";
input += std::string(1024*1024, '\1');
ep.set_input_string(&input);
std::string output;
ep.set_output_string(&output);
ep.add_exec("/bin/cat");
assert( ep.run().all_return_codes_zero() );
assert( output == input );
}
void test_string_program_program_string()
{
stx::ExecPipe ep;
std::string input = "test123";
ep.set_input_string(&input);
std::string output;
ep.set_output_string(&output);
ep.add_exec("/bin/cat");
ep.add_execp("md5sum");
assert( ep.run().all_return_codes_zero() );
assert( output == "cc03e747a6afbbcbf8be7668acfebee5 -\n" );
}
void test_file_program_string()
{
stx::ExecPipe ep;
ep.set_input_file("/proc/uptime");
std::string output;
ep.set_output_string(&output);
ep.add_execp("sort");
assert( ep.run().all_return_codes_zero() );
assert( output.size() );
}
class TestSink : public stx::PipeSink
{
public:
std::string m_save;
bool m_ok;
TestSink()
: m_ok(false)
{
}
virtual void process(const void* data, unsigned int datalen)
{
m_save.append(reinterpret_cast<const char*>(data), datalen);
}
virtual void eof()
{
m_ok = (m_save == "cc03e747a6afbbcbf8be7668acfebee5 -\n");
}
};
void test_string_program_object()
{
stx::ExecPipe ep;
std::string input = "test123";
ep.set_input_string(&input);
TestSink sink;
ep.set_output_sink(&sink);
ep.add_execp("md5sum");
assert( ep.run().all_return_codes_zero() );
assert( sink.m_ok );
}
class TestSource : public stx::PipeSource
{
public:
unsigned int m_count;
std::string m_wrote;
TestSource()
: m_count(100*1024)
{
}
virtual bool poll()
{
for (unsigned int i = 0; i < 1000 && m_count > 0; ++i, --m_count)
{
write(&i, sizeof(unsigned char));
m_wrote.append(reinterpret_cast<const char*>(&i), sizeof(unsigned char));
}
return (m_count > 0);
}
};
void test_object_program_string()
{
stx::ExecPipe ep;
TestSource source;
ep.set_input_source(&source);
std::string output;
ep.set_output_string(&output);
ep.add_execp("cat");
assert( ep.run().all_return_codes_zero() );
assert( source.m_wrote == output );
}
#include <openssl/md5.h>
class TestFunctionMD5 : public stx::PipeFunction
{
public:
MD5_CTX m_ctx;
std::string m_digest;
TestFunctionMD5()
{
MD5_Init(&m_ctx);
}
virtual void process(const void* data, unsigned int datalen)
{
MD5_Update(&m_ctx, data, datalen);
write(data, datalen);
}
virtual void eof()
{
unsigned char digest[MD5_DIGEST_LENGTH];
MD5_Final(digest, &m_ctx);
m_digest.assign(reinterpret_cast<char*>(digest), sizeof(digest));
}
};
std::string HexString(const std::string& str)
{
std::ostringstream os;
os << std::hex << std::setfill('0');
for (std::string::const_iterator si = str.begin();
si != str.end(); ++si)
{
os << std::setw(2) << (static_cast<unsigned int>(*si) & 0xFF);
}
return os.str();
}
void test_object_program_object_program_string()
{
stx::ExecPipe ep;
TestSource source;
ep.set_input_source(&source);
std::string output;
ep.set_output_string(&output);
ep.add_execp("cat");
TestFunctionMD5 func;
ep.add_function(&func);
ep.add_execp("md5sum");
assert( ep.run().all_return_codes_zero() );
assert( HexString(func.m_digest) == "0b66fcadf3a46cce7184487c4dabaf0f" );
assert( output == "0b66fcadf3a46cce7184487c4dabaf0f -\n" );
}
void test_none_program_set_string()
{
stx::ExecPipe ep;
std::vector<std::string> args;
args.push_back("/bin/sh");
args.push_back("-c");
args.push_back("set");
std::vector<std::string> envs;
envs.push_back("TEST=123");
ep.add_exece("/bin/sh", &args, &envs);
std::string output;
ep.set_output_string(&output);
assert( ep.run().all_return_codes_zero() );
assert( output.find("TEST=123") != std::string::npos );
}
void test_error_debug_output_null(const char*)
{
}
void test_error_none_program_none()
{
stx::ExecPipe ep;
ep.set_debug_level(stx::ExecPipe::DL_INFO);
ep.set_debug_output(test_error_debug_output_null);
ep.add_exec("xyz-non-existing-program");
ep.run();
assert( !ep.all_return_codes_zero() );
assert( ep.get_return_code(0) == 255 );
}
void test_segfault_none_program_none()
{
stx::ExecPipe ep;
ep.add_exec("./test_segfault");
ep.run();
assert( !ep.all_return_codes_zero() );
assert( ep.get_return_signal(0) == 11 );
}
int main()
{
test_none_program_string();
test_string_program_string();
test_string_program_program_string();
test_file_program_string();
test_string_program_object();
test_object_program_string();
test_object_program_object_program_string();
test_none_program_set_string();
test_error_none_program_none();
test_segfault_none_program_none();
return 0;
}