]> git.localhorst.tv Git - blank.git/blob - tst/integration/TestInstance.cpp
495ba6cdd413d602b0034895b06386d381843c03
[blank.git] / tst / integration / TestInstance.cpp
1 #include "TestInstance.hpp"
2
3 #include <cppunit/extensions/HelperMacros.h>
4
5 using namespace std;
6
7
8 namespace blank {
9 namespace test {
10
11 namespace {
12
13 Process::Arguments combine_args(const TempDir &dir, const Process::Arguments &in, bool cmd) {
14         Process::Arguments out;
15         out.reserve(in.size() + (cmd ? 5 : 3));
16         out.emplace_back("blank");
17         out.insert(out.end(), in.begin(), in.end());
18         out.emplace_back("--save-path");
19         out.emplace_back(dir.Path());
20         if (cmd) {
21                 out.emplace_back("--cmd-port");
22                 out.emplace_back("12354");
23         }
24         return out;
25 }
26
27 }
28
29 TestInstance::TestInstance(const Process::Arguments &args, bool cmd)
30 : dir()
31 , proc(
32         "./blank" BLANK_SUFFIX,
33         combine_args(dir, args, cmd),
34         { })
35 , conn()
36 , out_buf()
37 , err_buf()
38 , cmd_buf() {
39         if (cmd) {
40                 // wait for command service startup
41                 // TODO: timeouts for reading from process
42                 WaitOutputLine("listening on TCP port 12354");
43                 // connect to command service
44                 conn = tcp::Socket("localhost", 12354);
45         }
46 }
47
48 TestInstance::~TestInstance() {
49         proc.Terminate();
50 }
51
52
53 void TestInstance::WriteInput(const string &data) {
54         AssertRunning();
55         const char *i = data.c_str();
56         const char *end = i + data.length();
57         while (i != end) {
58                 size_t len = proc.WriteIn(i, end - i);
59                 if (len == 0) {
60                         throw runtime_error("failed write to child process' stdin");
61                 }
62                 i += len;
63         }
64 }
65
66 void TestInstance::ReadOutputLine(string &line) {
67         while (!out_buf.Extract(line)) {
68                 // buffer exhausted, fetch more data
69                 int len = proc.ReadOut(out_buf.WriteHead(), out_buf.Remain());
70                 if (len == 0) {
71                         throw runtime_error("failed read from child process' stdout");
72                 }
73                 out_buf.Update(len);
74         }
75 }
76
77 void TestInstance::AssertOutputLine(const string &expected) {
78         string line;
79         ReadOutputLine(line);
80         CPPUNIT_ASSERT_EQUAL_MESSAGE(
81                 "unexpected line in stdout",
82                 expected, line);
83 }
84
85 void TestInstance::WaitOutputLine(const string &expected) {
86         string line;
87         while (true) {
88                 ReadOutputLine(line);
89                 if (line == expected) {
90                         return;
91                 }
92         }
93 }
94
95 void TestInstance::ExhaustOutput(string &output) {
96         while (!out_buf.Extract(output)) {
97                 // buffer exhausted, fetch more data
98                 int len = proc.ReadOut(out_buf.WriteHead(), out_buf.Remain());
99                 if (len == 0) {
100                         return;
101                 }
102                 out_buf.Update(len);
103         }
104 }
105
106 void TestInstance::AssertNoOutput() {
107         string output;
108         ExhaustOutput(output);
109         CPPUNIT_ASSERT_EQUAL_MESSAGE(
110                 "test instanced produced unexpected output",
111                 string(""), output);
112 }
113
114
115 void TestInstance::ReadErrorLine(string &line) {
116         while (!err_buf.Extract(line)) {
117                 // buffer exhausted, fetch more data
118                 int len = proc.ReadErr(err_buf.WriteHead(), err_buf.Remain());
119                 if (len == 0) {
120                         throw runtime_error("failed read from child process' stderr");
121                 }
122                 err_buf.Update(len);
123         }
124 }
125
126 void TestInstance::AssertErrorLine(const string &expected) {
127         string line;
128         ReadErrorLine(line);
129         CPPUNIT_ASSERT_EQUAL_MESSAGE(
130                 "unexpected line in stderr",
131                 expected, line);
132 }
133
134 void TestInstance::WaitErrorLine(const string &expected) {
135         string line;
136         while (true) {
137                 ReadErrorLine(line);
138                 if (line == expected) {
139                         return;
140                 }
141         }
142 }
143
144 void TestInstance::ExhaustError(string &error) {
145         while (!err_buf.Extract(error)) {
146                 // buffer exhausted, fetch more data
147                 int len = proc.ReadErr(err_buf.WriteHead(), err_buf.Remain());
148                 if (len == 0) {
149                         return;
150                 }
151                 err_buf.Update(len);
152         }
153 }
154
155 void TestInstance::AssertNoError() {
156         string error;
157         ExhaustError(error);
158         CPPUNIT_ASSERT_EQUAL_MESSAGE(
159                 "test instanced produced unexpected error output",
160                 string(""), error);
161 }
162
163
164 void TestInstance::Terminate() {
165         proc.Terminate();
166 }
167
168 void TestInstance::AssertRunning() {
169         CPPUNIT_ASSERT_MESSAGE(
170                 "test instance terminated unexpectedly",
171                 !proc.Terminated());
172 }
173
174 void TestInstance::AssertTerminated() {
175         CPPUNIT_ASSERT_MESSAGE(
176                 "test instance did not terminate as expected",
177                 proc.Terminated());
178 }
179
180 void TestInstance::AssertExitStatus(int expected) {
181         CPPUNIT_ASSERT_EQUAL_MESSAGE(
182                 "unexpected exit status from child program",
183                 expected, proc.Join());
184 }
185
186
187 void TestInstance::WaitCommandMessage(const string &line) {
188         WaitCommandLine(" > " + line);
189 }
190
191 void TestInstance::WaitCommandError(const string &line) {
192         WaitCommandLine(" ! " + line);
193 }
194
195 void TestInstance::WaitCommandBroadcast(const string &line) {
196         WaitCommandLine(" @ " + line);
197 }
198
199 void TestInstance::WaitCommandLine(const string &expected) {
200         string line;
201         while (true) {
202                 if (!cmd_buf.Extract(line)) {
203                         // buffer exhausted, fetch more data
204                         cmd_buf.Update(conn.Recv(cmd_buf.WriteHead(), cmd_buf.Remain()));
205                         continue;
206                 }
207                 if (line == expected) {
208                         return;
209                 }
210         }
211 }
212
213 }
214 }