|
|
@@ -197,7 +197,7 @@ bool doReadWrite(size_t bufSize, |
|
|
|
}
|
|
|
|
|
|
|
|
// Verify exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << " Failure in testChildNonblockingReadWrite2: "
|
|
|
@@ -257,7 +257,7 @@ bool testChildStreamIsDone() { |
|
|
|
child.flush();
|
|
|
|
|
|
|
|
// Sleep to let the child exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << "isDone() failure; returned false." << std::endl;
|
|
|
@@ -884,7 +884,7 @@ bool testChildIsDone() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Sleep to let the child exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << "isDone() failure; returned false." << std::endl;
|
|
|
@@ -928,7 +928,7 @@ bool testChildIsRunning() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Sleep to let the child exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
|
|
|
|
child.close();
|
|
|
|
|
|
|
@@ -974,7 +974,7 @@ bool testChildResult() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for the child to exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
int32_t result = child.result();
|
|
|
|
|
|
|
@@ -1016,7 +1016,7 @@ bool testChildClose() { |
|
|
|
try {
|
|
|
|
CodeDweller::Child child(childName);
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
child.close();
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
EXCEPTION_TERM("close() with 100 ms waiting");
|
|
|
@@ -1036,7 +1036,7 @@ bool testChildClose() { |
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
|
|
|
|
child.close();
|
|
|
|
|
|
|
@@ -1099,7 +1099,7 @@ bool testChildStdInClose() { |
|
|
|
|
|
|
|
child.closeStdIn();
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
int32_t result = child.result();
|
|
|
|
|
|
|
@@ -1135,7 +1135,7 @@ bool testChildStdInClose() { |
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
|
|
|
|
child.closeStdIn();
|
|
|
|
|
|
|
@@ -1159,6 +1159,131 @@ bool testChildStdInClose() { |
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool testChildrenStdInClose() {
|
|
|
|
|
|
|
|
std::string errorDescription;
|
|
|
|
|
|
|
|
int const nChildren = 5;
|
|
|
|
|
|
|
|
// Test with no child process.
|
|
|
|
try {
|
|
|
|
CodeDweller::Child child;
|
|
|
|
|
|
|
|
child.closeStdIn();
|
|
|
|
|
|
|
|
NO_EXCEPTION_TERM("closeStdIn() with no child process");
|
|
|
|
return false;
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test with no waiting.
|
|
|
|
try {
|
|
|
|
CodeDweller::Child child[nChildren];
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
child[i].open(childName);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
child[i].closeStdIn();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
child[i].close();
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
EXCEPTION_TERM("closeStdIn() with no waiting");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run child that waits for stdin to close.
|
|
|
|
std::vector<std::string> cmd;
|
|
|
|
|
|
|
|
cmd.push_back(childName);
|
|
|
|
cmd.push_back("checkStdinEOF");
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
CodeDweller::Child child[nChildren];
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++ ) {
|
|
|
|
child[i].open(cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
child[i].closeStdIn();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
|
|
|
|
int32_t result = child[i].result();
|
|
|
|
|
|
|
|
if (15 != result) {
|
|
|
|
std::cout << "closeStdIn() failure for child " << i << "; returned "
|
|
|
|
<< result << " instead of 15." << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
child[i].close();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
|
|
|
|
if (child[i].errorOccurred(errorDescription)) {
|
|
|
|
std::ostringstream temp;
|
|
|
|
|
|
|
|
temp << " Failure in: testChildStdInClose for child " << i
|
|
|
|
<< ": " << errorDescription;
|
|
|
|
RETURN_FALSE(temp.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
EXCEPTION_TERM("closeStdIn() or close()");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test after the child exits.
|
|
|
|
cmd.clear();
|
|
|
|
cmd.push_back(childName);
|
|
|
|
cmd.push_back("quit");
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
CodeDweller::Child child[nChildren];
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
child[i].open(cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
if (!child[i].write("q")) {
|
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
|
|
|
|
for (int i = 0; i < nChildren; i++) {
|
|
|
|
child[i].closeStdIn();
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
EXCEPTION_TERM("closeStdIn() after child exits");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool testChildOpen() {
|
|
|
|
|
|
|
|
// Test with no waiting.
|
|
|
@@ -1175,10 +1300,10 @@ bool testChildOpen() { |
|
|
|
// Test with waiting.
|
|
|
|
try {
|
|
|
|
CodeDweller::Child child(childName);
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
child.close();
|
|
|
|
child.open(childName);
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
child.close();
|
|
|
|
} catch (std::exception &e) {
|
|
|
|
EXCEPTION_TERM("close()/open() with 100 ms waiting");
|
|
|
@@ -1304,6 +1429,8 @@ bool testChildReadWrite() { |
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (0 != nCharToRead) {
|
|
|
@@ -1341,7 +1468,7 @@ bool testChildReadWrite() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Verify exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << " Failure in testReadWrite: Child program did not exit."
|
|
|
@@ -1417,7 +1544,7 @@ bool testChildIsFinishedWriting() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Verify exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << " Failure in testIsFinishedWriting: "
|
|
|
@@ -1481,7 +1608,7 @@ bool testChildRead() { |
|
|
|
RETURN_FALSE(temp.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
@@ -1495,7 +1622,13 @@ bool testChildRead() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Sleep to let the child exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
for (int i = 0; i < 100; i++) {
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
|
|
|
|
if (child.isDone())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << "first isDone() failure in testReader." << std::endl;
|
|
|
@@ -1541,7 +1674,7 @@ bool testChildNonBlockingReadWrite1() { |
|
|
|
RETURN_FALSE(" first write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
// Read one character.
|
|
|
|
std::string readBuf;
|
|
|
@@ -1609,7 +1742,7 @@ bool testChildNonBlockingReadWrite1() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for reader thread to fill input buffer.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(25));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
|
|
|
|
|
|
|
if (child.read(readBuf) != expectedLeftOver) {
|
|
|
|
RETURN_FALSE(" read() failure");
|
|
|
@@ -1625,7 +1758,7 @@ bool testChildNonBlockingReadWrite1() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Verify exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << " Failure in testChildNonblockingReadWrite1: "
|
|
|
@@ -1718,7 +1851,7 @@ bool testChildVectorReadWrite() { |
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
// Read one character.
|
|
|
|
std::vector<char> readBuf;
|
|
|
@@ -1816,7 +1949,7 @@ bool testChildVectorReadWrite() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Verify exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << " Failure in testChildVectorReadWrite: "
|
|
|
@@ -1868,7 +2001,7 @@ bool testChildReadDelimited() { |
|
|
|
RETURN_FALSE(" write() failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
// Check
|
|
|
|
std::vector<char> readVec;
|
|
|
@@ -1984,7 +2117,7 @@ bool testChildReadDelimited() { |
|
|
|
}
|
|
|
|
|
|
|
|
// Verify exit.
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
|
|
|
|
|
|
|
|
if (!child.isDone()) {
|
|
|
|
std::cout << " Failure in testChildReadDelimited: "
|
|
|
@@ -2040,6 +2173,7 @@ int main() |
|
|
|
RUN_TEST(testChildResult);
|
|
|
|
RUN_TEST(testChildClose);
|
|
|
|
RUN_TEST(testChildStdInClose);
|
|
|
|
RUN_TEST(testChildrenStdInClose);
|
|
|
|
RUN_TEST(testChildOpen);
|
|
|
|
RUN_TEST(testChildIsFinishedWriting);
|
|
|
|
RUN_TEST(testChildRead);
|