wibble  0.1.28
childprocess.test.h
Go to the documentation of this file.
00001 /* -*- C++ -*- (c) 2007 Petr Rockai <me@mornfall.net>
00002    (c) 2007 Enrico Zini <enrico@enricozini.org> */
00003 #include <wibble/sys/childprocess.h>
00004 
00005 #ifdef POSIX
00006 #include <wibble/sys/process.h>
00007 #include <wibble/sys/exec.h>
00008 #include <cstdlib>
00009 #include <iostream>
00010 #include <unistd.h>
00011 
00012 #include <wibble/test.h>
00013 
00014 
00015 using namespace std;
00016 using namespace wibble::sys;
00017 
00018 class EndlessChild : public ChildProcess
00019 {
00020 protected:
00021     int main()
00022     {
00023         while (true)
00024             sleep(60);
00025         return 0;
00026     }
00027 };
00028 
00029 class TestChild : public ChildProcess
00030 {
00031 protected:
00032     int main()
00033     {
00034         cout << "antani" << endl;
00035         return 0;
00036     }
00037 };
00038 
00039 std::string suckFd(int fd)
00040 {
00041     std::string res;
00042     char c;
00043     while (true)
00044     {
00045         int r = read(fd, &c, 1);
00046         if (r == 0)
00047             break;
00048         if (r < 0)
00049             throw wibble::exception::System("reading data from file descriptor");
00050         res += c;
00051     }
00052     return res;
00053 }
00054 
00055 struct TestChildprocess {
00056 
00057     // Try running the child process and kill it
00058     Test kill() {
00059         EndlessChild child;
00060 
00061         // Start the child
00062         pid_t pid = child.fork();
00063 
00064         // We should get a nonzero pid
00065         assert(pid != 0);
00066 
00067         // Send SIGQUIT
00068         child.kill(2);
00069 
00070         // Wait for the child to terminate
00071         int res = child.wait();
00072 
00073         // Check that it was indeed terminated by signal 2
00074         assert(WIFSIGNALED(res));
00075         assert_eq(WTERMSIG(res), 2);
00076     }
00077 
00078     // Try getting the output of the child process
00079     Test output() {
00080         TestChild child;
00081         int out;
00082 
00083         // Fork the child redirecting its stdout
00084         pid_t pid = child.forkAndRedirect(0, &out, 0);
00085         assert(pid != 0);
00086 
00087         // Read the child output
00088         assert_eq(suckFd(out), "antani\n");
00089 
00090         // Wait for the child to terminate
00091         assert_eq(child.wait(), 0);
00092     }
00093 
00094     Test redirect() {
00095         Exec child("/bin/echo");
00096         child.args.push_back("antani");
00097         int out;
00098     
00099         // Fork the child redirecting its stdout
00100         pid_t pid = child.forkAndRedirect(0, &out, 0);
00101         assert(pid != 0);
00102 
00103         // Read the child output
00104         assert_eq(suckFd(out), "antani\n");
00105 
00106         // Wait for the child to terminate
00107         assert_eq(child.wait(), 0);
00108     }
00109 
00110     Test shellCommand() {
00111         ShellCommand child("A=antani; echo $A");
00112         int out;
00113     
00114         // Fork the child redirecting its stdout
00115         pid_t pid = child.forkAndRedirect(0, &out, 0);
00116         assert(pid != 0);
00117 
00118         // Read the child output
00119         assert_eq(suckFd(out), "antani\n");
00120 
00121         // Wait for the child to terminate
00122         assert_eq(child.wait(), 0);
00123     }
00124 
00125 };
00126 #endif
00127 // vim:set ts=4 sw=4: