1 #include "TestInstance.hpp"
3 #include <cppunit/extensions/HelperMacros.h>
13 Process::Arguments combine_args(
15 const Process::Arguments &in,
19 Process::Arguments out;
20 out.reserve(in.size() + (cmd ? 5 : 3));
21 out.emplace_back("blank");
22 out.insert(out.end(), in.begin(), in.end());
24 out.emplace_back("--save-path");
25 out.emplace_back(dir.Path());
28 out.emplace_back("--cmd-port");
29 out.emplace_back("12354");
36 TestInstance::TestInstance(const Process::Arguments &args, bool cmd, bool temp_save)
38 , proc("./blank" BLANK_SUFFIX, combine_args(dir, args, cmd, temp_save))
43 , name("blank" BLANK_SUFFIX) {
45 // wait for command service startup
46 WaitOutputLine("listening on TCP port 12354");
47 // connect to command service
48 conn = tcp::Socket("localhost", 12354);
50 for (const auto &arg : args) {
56 TestInstance::~TestInstance() {
61 void TestInstance::WriteInput(const string &data) {
63 const char *i = data.c_str();
64 const char *end = i + data.length();
66 size_t len = proc.WriteIn(i, end - i);
68 throw runtime_error("failed write to stdin of " + name);
74 void TestInstance::ReadOutputLine(string &line) {
75 while (!out_buf.Extract(line)) {
76 // buffer exhausted, fetch more data
77 int len = proc.ReadOut(out_buf.WriteHead(), out_buf.Remain(), 10000);
79 throw runtime_error("failed read from stdout of " + name);
85 void TestInstance::AssertOutputLine(const string &expected) {
87 if (past_out.empty()) {
90 line = past_out.front();
93 CPPUNIT_ASSERT_EQUAL_MESSAGE(
94 "unexpected line in stdout of " + name,
98 void TestInstance::WaitOutputLine(const string &expected) {
99 for (list<string>::iterator i(past_out.begin()); i != past_out.end(); ++i) {
100 if (*i == expected) {
107 ReadOutputLine(line);
108 if (line == expected) {
111 past_out.push_back(line);
116 void TestInstance::ExhaustOutput(string &output) {
118 for (const auto &line : past_out) {
125 if (out_buf.Extract(line)) {
129 // buffer exhausted, fetch more data
130 int len = proc.ReadOut(out_buf.WriteHead(), out_buf.Remain(), 10000);
140 void TestInstance::AssertNoOutput() {
142 ExhaustOutput(output);
143 CPPUNIT_ASSERT_EQUAL_MESSAGE(
144 "unexpected output of test instance " + name,
149 void TestInstance::ReadErrorLine(string &line) {
150 while (!err_buf.Extract(line)) {
151 // buffer exhausted, fetch more data
152 int len = proc.ReadErr(err_buf.WriteHead(), err_buf.Remain(), 10000);
154 throw runtime_error("failed read from stderr of " + name);
160 void TestInstance::AssertErrorLine(const string &expected) {
162 if (past_err.empty()) {
165 line = past_err.front();
166 past_err.pop_front();
168 CPPUNIT_ASSERT_EQUAL_MESSAGE(
169 "unexpected line in stderr",
173 void TestInstance::WaitErrorLine(const string &expected) {
174 for (list<string>::iterator i(past_err.begin()); i != past_err.end(); ++i) {
175 if (*i == expected) {
183 if (line == expected) {
186 past_err.push_back(line);
191 void TestInstance::ExhaustError(string &error) {
193 for (const auto &line : past_err) {
200 if (err_buf.Extract(line)) {
204 // buffer exhausted, fetch more data
205 int len = proc.ReadErr(err_buf.WriteHead(), err_buf.Remain(), 10000);
215 void TestInstance::AssertNoError() {
218 CPPUNIT_ASSERT_EQUAL_MESSAGE(
219 "unexpected error output of test instance " + name,
224 void TestInstance::Terminate() {
225 if (!proc.Terminated()) {
230 void TestInstance::AssertRunning() {
231 CPPUNIT_ASSERT_MESSAGE(
232 "test instance " + name + " terminated unexpectedly",
236 void TestInstance::AssertTerminated() {
237 CPPUNIT_ASSERT_MESSAGE(
238 "test instance " + name + " did not terminate as expected",
242 void TestInstance::AssertExitStatus(int expected) {
243 CPPUNIT_ASSERT_EQUAL_MESSAGE(
244 "unexpected exit status from child program " + name,
245 expected, proc.Join());
249 void TestInstance::WaitCommandMessage(const string &line) {
250 WaitCommandLine(" > " + line);
253 void TestInstance::WaitCommandError(const string &line) {
254 WaitCommandLine(" ! " + line);
257 void TestInstance::WaitCommandBroadcast(const string &line) {
258 WaitCommandLine(" @ " + line);
261 void TestInstance::WaitCommandLine(const string &expected) {
264 if (!cmd_buf.Extract(line)) {
265 // buffer exhausted, fetch more data
266 cmd_buf.Update(conn.Recv(cmd_buf.WriteHead(), cmd_buf.Remain()));
269 if (line == expected) {