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