windows: pass subprocess tests
authorEvan Martin <martine@danga.com>
Fri, 6 May 2011 21:20:34 +0000 (14:20 -0700)
committerEvan Martin <martine@danga.com>
Sun, 8 May 2011 20:52:51 +0000 (13:52 -0700)
src/subprocess-win32.cc
src/subprocess_test.cc

index 2efec00..4649ee3 100644 (file)
@@ -95,8 +95,10 @@ bool Subprocess::Start(struct SubprocessSet* set, const string& command) {
   startup_info.cb = sizeof(STARTUPINFO);
   startup_info.dwFlags = STARTF_USESTDHANDLES;
   startup_info.hStdOutput = child_pipe;
+  // TODO: what does this hook up stdin to?
   startup_info.hStdInput  = NULL;
-  startup_info.hStdError  = NULL;  // TODO: handle child stderr as well.
+  // TODO: is it ok to reuse pipe like this?
+  startup_info.hStdError  = child_pipe;
 
   PROCESS_INFORMATION process_info;
 
@@ -121,7 +123,7 @@ bool Subprocess::Start(struct SubprocessSet* set, const string& command) {
 
 void Subprocess::OnPipeReady() {
   DWORD bytes;
-  if (!GetOverlappedResult(pipe_, &overlapped_, &bytes, FALSE)) {
+  if (!GetOverlappedResult(pipe_, &overlapped_, &bytes, TRUE)) {
     if (GetLastError() == ERROR_BROKEN_PIPE) {
       CloseHandle(pipe_);
       pipe_ = NULL;
index c158810..b446e13 100644 (file)
 
 #include "test.h"
 
-TEST(Subprocess, Ls) {
+namespace {
+
+#ifdef _WIN32
+const char* kSimpleCommand = "dir \\";
+#else
+const char* kSimpleCommand = "ls /";
+#endif
+
+struct SubprocessTest : public testing::Test {
+  SubprocessSet subprocs_;
+};
+
+}  // anonymous namespace
+
+// Run a command that succeeds and emits to stdout.
+TEST_F(SubprocessTest, GoodCommandStdout) {
   Subprocess ls;
-  EXPECT_TRUE(ls.Start(NULL, "ls /"));
+  EXPECT_TRUE(ls.Start(&subprocs_, kSimpleCommand));
 
-  // Pretend we discovered that stdout was ready for writing.
-  ls.OnPipeReady();
+  while (!ls.Done()) {
+    // Pretend we discovered that stdout was ready for writing.
+    ls.OnPipeReady();
+  }
 
   EXPECT_TRUE(ls.Finish());
   EXPECT_NE("", ls.GetOutput());
 }
 
-TEST(Subprocess, BadCommand) {
+// Run a command that fails and emits to stderr.
+TEST_F(SubprocessTest, BadCommandStderr) {
   Subprocess subproc;
-  EXPECT_TRUE(subproc.Start(NULL, "ninja_no_such_command"));
+  EXPECT_TRUE(subproc.Start(&subprocs_, "ninja_no_such_command"));
 
-  // Pretend we discovered that stderr was ready for writing.
-  subproc.OnPipeReady();
+  while (!subproc.Done()) {
+    // Pretend we discovered that stderr was ready for writing.
+    subproc.OnPipeReady();
+  }
 
   EXPECT_FALSE(subproc.Finish());
   EXPECT_NE("", subproc.GetOutput());
 }
 
-TEST(SubprocessSet, Single) {
-  SubprocessSet subprocs;
-  Subprocess* ls = new Subprocess;
-  EXPECT_TRUE(ls->Start(NULL, "ls /"));
-  subprocs.Add(ls);
+TEST_F(SubprocessTest, SetWithSingle) {
+  Subprocess* subproc = new Subprocess;
+  EXPECT_TRUE(subproc->Start(&subprocs_, kSimpleCommand));
+  subprocs_.Add(subproc);
 
-  while (!ls->Done()) {
-    subprocs.DoWork();
+  while (!subproc->Done()) {
+    subprocs_.DoWork();
   }
-  ASSERT_TRUE(ls->Finish());
-  ASSERT_NE("", ls->GetOutput());
+  ASSERT_TRUE(subproc->Finish());
+  ASSERT_NE("", subproc->GetOutput());
 
-  ASSERT_EQ(1u, subprocs.finished_.size());
+  ASSERT_EQ(1u, subprocs_.finished_.size());
 }
 
-TEST(SubprocessSet, Multi) {
-  SubprocessSet subprocs;
+TEST_F(SubprocessTest, SetWithMulti) {
   Subprocess* processes[3];
   const char* kCommands[3] = {
-    "ls /",
+    kSimpleCommand,
+#ifdef _WIN32
+    "echo hi",
+    "time /t",
+#else
     "whoami",
     "pwd",
+#endif
   };
 
   for (int i = 0; i < 3; ++i) {
     processes[i] = new Subprocess;
-    EXPECT_TRUE(processes[i]->Start(NULL, kCommands[i]));
-    subprocs.Add(processes[i]);
+    EXPECT_TRUE(processes[i]->Start(&subprocs_, kCommands[i]));
+    subprocs_.Add(processes[i]);
   }
 
-  ASSERT_EQ(3u, subprocs.running_.size());
+  ASSERT_EQ(3u, subprocs_.running_.size());
   for (int i = 0; i < 3; ++i) {
     ASSERT_FALSE(processes[i]->Done());
     ASSERT_EQ("", processes[i]->GetOutput());
@@ -76,12 +99,12 @@ TEST(SubprocessSet, Multi) {
 
   while (!processes[0]->Done() || !processes[1]->Done() ||
          !processes[2]->Done()) {
-    ASSERT_GT(subprocs.running_.size(), 0u);
-    subprocs.DoWork();
+    ASSERT_GT(subprocs_.running_.size(), 0u);
+    subprocs_.DoWork();
   }
 
-  ASSERT_EQ(0u, subprocs.running_.size());
-  ASSERT_EQ(3u, subprocs.finished_.size());
+  ASSERT_EQ(0u, subprocs_.running_.size());
+  ASSERT_EQ(3u, subprocs_.finished_.size());
 
   for (int i = 0; i < 3; ++i) {
     ASSERT_TRUE(processes[i]->Finish());