|
|
@@ -1589,6 +1589,163 @@ bool testChildNonBlockingReadWrite2() { |
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool testChildVectorReadWrite() {
|
|
|
|
|
|
|
|
try {
|
|
|
|
std::vector<std::string> cmd;
|
|
|
|
|
|
|
|
cmd.push_back(childName);
|
|
|
|
|
|
|
|
size_t bufSize = 16;
|
|
|
|
std::uint16_t
|
|
|
|
nominalAboveMin_ms = 15,
|
|
|
|
delta_ms = 0;
|
|
|
|
CodeDweller::Child child(cmd,
|
|
|
|
bufSize,
|
|
|
|
nominalAboveMin_ms,
|
|
|
|
delta_ms);
|
|
|
|
|
|
|
|
// Check that write fails.
|
|
|
|
std::vector<char> badVector(bufSize + 1);
|
|
|
|
if (child.write(badVector)) {
|
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check write().
|
|
|
|
std::vector<char> childInput = {'a', 'b', 'c'};
|
|
|
|
|
|
|
|
if (!child.write(childInput)) {
|
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
|
|
|
|
// Read one character.
|
|
|
|
std::vector<char> readBuf;
|
|
|
|
|
|
|
|
if (child.read(readBuf, 1) != 1) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
if ('A' != readBuf[0]) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read.
|
|
|
|
if (child.read(readBuf, 2) != 2) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
if (std::vector<char>({'B', 'C'}) != readBuf) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that no input is available.
|
|
|
|
if (child.read(readBuf) != 0) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
if (!readBuf.empty()) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fill input buffer.
|
|
|
|
std::vector<char> output = {
|
|
|
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
|
|
|
'n', 'o', 'p', 'p', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
|
|
|
|
};
|
|
|
|
std::vector<char> expectedInput(output);
|
|
|
|
|
|
|
|
for (int i = 0; i < output.size(); i++) {
|
|
|
|
expectedInput[i] = std::toupper(output[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (child.write(output, bufSize) != bufSize) {
|
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
|
|
|
|
size_t nRequested = bufSize / 2;
|
|
|
|
|
|
|
|
// Check partial read.
|
|
|
|
size_t nRead = child.read(readBuf, nRequested);
|
|
|
|
|
|
|
|
if (nRead != nRequested) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (readBuf != std::vector<char>(expectedInput.begin(),
|
|
|
|
expectedInput.begin() + nRead)) {
|
|
|
|
RETURN_FALSE(" read() failure)");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check remainder.
|
|
|
|
readBuf.resize(bufSize * 2);
|
|
|
|
nRead = child.read(readBuf);
|
|
|
|
|
|
|
|
if ( (bufSize - nRequested) != nRead) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
if (readBuf != std::vector<char>(expectedInput.begin() + nRequested,
|
|
|
|
expectedInput.begin() + bufSize)) {
|
|
|
|
RETURN_FALSE(" read() failure)");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write remainder.
|
|
|
|
output.erase(output.begin(),
|
|
|
|
output.begin() + bufSize);
|
|
|
|
expectedInput.erase(expectedInput.begin(),
|
|
|
|
expectedInput.begin() + bufSize);
|
|
|
|
size_t nExpectedBytes = output.size();
|
|
|
|
|
|
|
|
if (child.writeAndShrink(output) != nExpectedBytes) {
|
|
|
|
RETURN_FALSE(" writeAndShrink() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
|
|
|
|
if (child.read(readBuf) != nExpectedBytes) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (readBuf != expectedInput) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Send exit message.
|
|
|
|
if (!child.write("q")) {
|
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << " Failure in testChildVectorReadWrite: "
|
|
|
|
<< "Child program did not exit." << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string errorDescription;
|
|
|
|
|
|
|
|
if (child.errorOccurred(errorDescription)) {
|
|
|
|
std::ostringstream temp;
|
|
|
|
|
|
|
|
temp << " Failure in: testChildVectorReadWrite: "
|
|
|
|
<< errorDescription;
|
|
|
|
RETURN_FALSE(temp.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
child.close();
|
|
|
|
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
EXCEPTION_TERM("testChildVectorReadWrite");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// End of tests ////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
@@ -1619,6 +1776,7 @@ int main() |
|
|
|
RUN_TEST(testChildReadWrite);
|
|
|
|
RUN_TEST(testChildNonBlockingReadWrite1);
|
|
|
|
RUN_TEST(testChildNonBlockingReadWrite2);
|
|
|
|
RUN_TEST(testChildVectorReadWrite);
|
|
|
|
|
|
|
|
SUMMARY;
|
|
|
|
|