windows: pass the DiskInterface tests
authorEvan Martin <martine@danga.com>
Sun, 8 May 2011 03:11:19 +0000 (20:11 -0700)
committerEvan Martin <martine@danga.com>
Sun, 8 May 2011 20:35:25 +0000 (13:35 -0700)
src/ninja_test.cc

index 93873b3..bec038e 100644 (file)
@@ -16,6 +16,7 @@
 
 #ifdef _WIN32
 #include <io.h>
+#include <windows.h>
 #endif
 
 #include <gtest/gtest.h>
@@ -205,52 +206,76 @@ TEST_F(StatTest, Middle) {
 
 #ifdef _WIN32
 #ifndef _mktemp_s
-/* mingw has no mktemp. */
+/// mingw has no mktemp.  Implement one with the same type as the one
+/// found in the Windows API.
 int _mktemp_s(const char* templ) {
   char* ofs = strchr(templ, 'X');
   sprintf(ofs, "%d", rand() % 1000000);
   return 0;
 }
 #endif
+
+/// Windows has no mkdtemp.  Implement it in terms of _mktemp_s.
+char* mkdtemp(char* name_template) {
+  int err = _mktemp_s(name_template);
+  if (err < 0) {
+    perror("_mktemp_s");
+    return NULL;
+  }
+
+  err = _mkdir(name_template);
+  if (err < 0) {
+    perror("mkdir");
+    return NULL;
+  }
+
+  return name_template;
+}
 #endif
 
 class DiskInterfaceTest : public testing::Test {
 public:
   virtual void SetUp() {
-    char buf[4 << 10];
-    ASSERT_TRUE(getcwd(buf, sizeof(buf)));
-    start_dir_ = buf;
-    temp_dir_name_ = SetupTempDir();
-    printf("temp dir: %s\n", temp_dir_name_.c_str());
+    // Because we do real disk accesses, we create a temp dir within
+    // the system temporary directory.
+
+    // First change into the system temp dir and save it for cleanup.
+    start_dir_ = GetSystemTempDir();
+    ASSERT_EQ(0, chdir(start_dir_.c_str()));
 
+    // Then create and change into a temporary subdirectory of that.
+    temp_dir_name_ = MakeTempDir();
     ASSERT_FALSE(temp_dir_name_.empty());
     ASSERT_EQ(0, chdir(temp_dir_name_.c_str()));
   }
 
   virtual void TearDown() {
+    // Move out of the directory we're about to clobber.
     ASSERT_EQ(0, chdir(start_dir_.c_str()));
+#ifdef _WIN32
+    ASSERT_EQ(0, system(("rmdir /s /q " + temp_dir_name_).c_str()));
+#else
     ASSERT_EQ(0, system(("rm -rf " + temp_dir_name_).c_str()));
+#endif
   }
 
-  string SetupTempDir() {
-    char name_template[] = "DiskInterfaceTest-XXXXXX";
-    char* name = NULL;
-
-    const char* tempdir = getenv("TMPDIR");
-    if (!tempdir)
-      tempdir = "/tmp";
-
+  string GetSystemTempDir() {
 #ifdef _WIN32
-    if (_chdir(tempdir) < 0)
+    char buf[1024];
+    if (!GetTempPath(sizeof(buf), buf))
       return "";
-    if (_mktemp_s(name_template) < 0)
-      return "";
-    name = name_template;
+    return buf;
 #else
-    if (chdir(tempdir) < 0)
-      return "";
-    name = mkdtemp(name_template);
+    const char* tempdir = getenv("TMPDIR");
+    if (tempdir)
+      return tempdir;
+    return "/tmp";
 #endif
+  }
+
+  string MakeTempDir() {
+    char name_template[] = "DiskInterfaceTest-XXXXXX";
+    char* name = mkdtemp(name_template);
     return name ? name : "";
   }
 
@@ -262,10 +287,18 @@ public:
 TEST_F(DiskInterfaceTest, Stat) {
   EXPECT_EQ(0, disk_.Stat("nosuchfile"));
 
+#ifdef _WIN32
+  // TODO: find something that stat fails on for Windows.
+#else
   string too_long_name(512, 'x');
   EXPECT_EQ(-1, disk_.Stat(too_long_name));
+#endif
 
+#ifdef _WIN32
+  ASSERT_EQ(0, system("cmd.exe /c echo hi > file"));
+#else
   ASSERT_EQ(0, system("touch file"));
+#endif
   EXPECT_GT(disk_.Stat("file"), 1);
 }
 
@@ -291,7 +324,11 @@ TEST_F(DiskInterfaceTest, MakeDirs) {
 
 TEST_F(DiskInterfaceTest, RemoveFile) {
   const char* kFileName = "file-to-remove";
+#ifdef _WIN32
+  string cmd = "cmd /c echo hi > ";
+#else
   string cmd = "touch ";
+#endif
   cmd += kFileName;
   ASSERT_EQ(0, system(cmd.c_str()));
   EXPECT_EQ(0, disk_.RemoveFile(kFileName));