You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by mp...@apache.org on 2016/04/10 01:48:34 UTC
[1/3] mesos git commit: Transition `filesystem_tests.cpp` to use
`path::join`.
Repository: mesos
Updated Branches:
refs/heads/master 8c6a55d10 -> 8d9eb5fb9
Transition `filesystem_tests.cpp` to use `path::join`.
This commit will fix a test that fails due to inconsistent usage of path
delimiting characters.
Historically in Mesos, it has been common to join paths by adding
strings. For example: `somePath + "/yourFile"`. The '/' character in
particular is contentious, and can cause problems if you're not
consistent in your usage. For example, if `somePath` already uses '\' as
a path separator, then joining the string `"/yourFile"` introduces
inconsistency in the path delimiter usage, resulting in undesirable
behavior.
Review: https://reviews.apache.org/r/45009/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/36214b8d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/36214b8d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/36214b8d
Branch: refs/heads/master
Commit: 36214b8d5637a30b4467a1c1e0b1f973621fbefd
Parents: 8c6a55d
Author: Alex Clemmer <cl...@gmail.com>
Authored: Sat Apr 9 16:25:13 2016 -0700
Committer: Michael Park <mp...@apache.org>
Committed: Sat Apr 9 16:25:13 2016 -0700
----------------------------------------------------------------------
.../stout/tests/os/filesystem_tests.cpp | 42 ++++++++++----------
1 file changed, 21 insertions(+), 21 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/36214b8d/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
index ab6f595..c93b827 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
@@ -57,13 +57,13 @@ class FsTest : public TemporaryDirectoryTest {};
TEST_F(FsTest, Find)
{
const string testdir = path::join(os::getcwd(), UUID::random().toString());
- const string subdir = testdir + "/test1";
+ const string subdir = path::join(testdir, "test1");
ASSERT_SOME(os::mkdir(subdir)); // Create the directories.
// Now write some files.
- const string file1 = testdir + "/file1.txt";
- const string file2 = subdir + "/file2.txt";
- const string file3 = subdir + "/file3.jpg";
+ const string file1 = path::join(testdir, "file1.txt");
+ const string file2 = path::join(subdir, "file2.txt");
+ const string file3 = path::join(subdir, "file3.jpg");
ASSERT_SOME(os::touch(file1));
ASSERT_SOME(os::touch(file2));
@@ -105,9 +105,9 @@ TEST_F(FsTest, Mkdir)
hashset<string> expectedListing = EMPTY;
EXPECT_EQ(expectedListing, listfiles(tmpdir));
- os::mkdir(tmpdir + "/a/b/c");
- os::mkdir(tmpdir + "/a/b/d");
- os::mkdir(tmpdir + "/e/f");
+ ASSERT_SOME(os::mkdir(path::join(tmpdir, "a", "b", "c")));
+ ASSERT_SOME(os::mkdir(path::join(tmpdir, "a", "b", "d")));
+ ASSERT_SOME(os::mkdir(path::join(tmpdir, "e", "f")));
expectedListing = EMPTY;
expectedListing.insert("a");
@@ -116,22 +116,22 @@ TEST_F(FsTest, Mkdir)
expectedListing = EMPTY;
expectedListing.insert("b");
- EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a"));
+ EXPECT_EQ(expectedListing, listfiles(path::join(tmpdir, "a")));
expectedListing = EMPTY;
expectedListing.insert("c");
expectedListing.insert("d");
- EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a/b"));
+ EXPECT_EQ(expectedListing, listfiles(path::join(tmpdir, "a", "b")));
expectedListing = EMPTY;
- EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a/b/c"));
- EXPECT_EQ(expectedListing, listfiles(tmpdir + "/a/b/d"));
+ EXPECT_EQ(expectedListing, listfiles(path::join(tmpdir, "a", "b", "c")));
+ EXPECT_EQ(expectedListing, listfiles(path::join(tmpdir, "a", "b", "d")));
expectedListing.insert("f");
- EXPECT_EQ(expectedListing, listfiles(tmpdir + "/e"));
+ EXPECT_EQ(expectedListing, listfiles(path::join(tmpdir, "e")));
expectedListing = EMPTY;
- EXPECT_EQ(expectedListing, listfiles(tmpdir + "/e/f"));
+ EXPECT_EQ(expectedListing, listfiles(path::join(tmpdir, "e", "f")));
}
@@ -146,7 +146,7 @@ TEST_F(FsTest, Touch)
TEST_F(FsTest, Symlink)
{
const string temp_path = os::getcwd();
- const string link = path::join(temp_path, "/sym.link");
+ const string link = path::join(temp_path, "sym.link");
const string file = path::join(temp_path, UUID::random().toString());
// Create file
@@ -155,7 +155,7 @@ TEST_F(FsTest, Symlink)
ASSERT_TRUE(os::exists(file));
// Create symlink
- fs::symlink(file, link);
+ ASSERT_SOME(fs::symlink(file, link));
// Test symlink
EXPECT_TRUE(os::stat::islink(link));
@@ -168,9 +168,9 @@ TEST_F(FsTest, List)
ASSERT_SOME(os::mkdir(testdir)); // Create the directories.
// Now write some files.
- const string file1 = testdir + "/file1.txt";
- const string file2 = testdir + "/file2.txt";
- const string file3 = testdir + "/file3.jpg";
+ const string file1 = path::join(testdir, "file1.txt");
+ const string file2 = path::join(testdir, "file2.txt");
+ const string file3 = path::join(testdir, "file3.jpg");
ASSERT_SOME(os::touch(file1));
ASSERT_SOME(os::touch(file2));
@@ -204,9 +204,9 @@ TEST_F(FsTest, Rename)
ASSERT_SOME(os::mkdir(testdir)); // Create the directories.
// Now write some files.
- const string file1 = testdir + "/file1.txt";
- const string file2 = testdir + "/file2.txt";
- const string file3 = testdir + "/file3.jpg";
+ const string file1 = path::join(testdir, "file1.txt");
+ const string file2 = path::join(testdir, "file2.txt");
+ const string file3 = path::join(testdir, "file3.jpg");
ASSERT_SOME(os::touch(file1));
ASSERT_SOME(os::touch(file2));
[2/3] mesos git commit: Windows: Fixed bug causing `os::exists` to
report invalid paths exist.
Posted by mp...@apache.org.
Windows: Fixed bug causing `os::exists` to report invalid paths exist.
Currently on Windows, `os::exists` will return true if a component of a
path does not exist. For example if you have `a/fancy/path`, and you ask
`os::exists("a/fake/path")`, the result currently reports `true`. In
other words, the Windows code path only checks for the error that a file
does not exist, and ignores the error that says the path is not valid.
This commit will fix this, and also add a test that will verify we don't
regress.
Review: https://reviews.apache.org/r/45015/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/387a62e5
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/387a62e5
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/387a62e5
Branch: refs/heads/master
Commit: 387a62e57e9021c006bbe9c780fde23edc40c8d2
Parents: 36214b8
Author: Alex Clemmer <cl...@gmail.com>
Authored: Sat Apr 9 16:25:50 2016 -0700
Committer: Michael Park <mp...@apache.org>
Committed: Sat Apr 9 16:25:50 2016 -0700
----------------------------------------------------------------------
.../stout/include/stout/os/windows/exists.hpp | 17 ++++++++---
.../stout/tests/os/filesystem_tests.cpp | 32 ++++++++++++++++++++
2 files changed, 45 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/387a62e5/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp
index 9211851..423e4a8 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/exists.hpp
@@ -31,15 +31,24 @@ inline bool exists(const std::string& path)
return false;
}
- // NOTE: GetFileAttributes does not support unicode natively. See also
- // "documentation"[1] for why this is a check-if-file-exists idiom.
+ // NOTE: `GetFileAttributes` redirects to either `GetFileAttributesA`
+ // (ASCII) or `GetFileAttributesW` (for `wchar`s). It returns
+ // `INVALID_FILE_ATTRIBUTES` if the file could not be opened for any reason.
+ // Checking for one of two 'not found' error codes (`ERROR_FILE_NOT_FOUND` or
+ // `ERROR_PATH_NOT_FOUND`) is a reliable test for whether the file or
+ // directory exists. See also [1] for more information on this technique.
//
// [1] http://blogs.msdn.com/b/oldnewthing/archive/2007/10/23/5612082.aspx
DWORD attributes = GetFileAttributes(absolutePath.get().c_str());
- bool fileNotFound = GetLastError() == ERROR_FILE_NOT_FOUND;
+ if (attributes == INVALID_FILE_ATTRIBUTES) {
+ DWORD error = GetLastError();
+ if (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND) {
+ return false;
+ }
+ }
- return !((attributes == INVALID_FILE_ATTRIBUTES) && fileNotFound);
+ return true;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/387a62e5/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
index c93b827..6262892 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
@@ -135,6 +135,38 @@ TEST_F(FsTest, Mkdir)
}
+TEST_F(FsTest, Exists)
+{
+ const hashset<string> EMPTY;
+ const string tmpdir = os::getcwd();
+
+ hashset<string> expectedListing = EMPTY;
+ ASSERT_EQ(expectedListing, listfiles(tmpdir));
+
+ // Create simple directory structure.
+ ASSERT_SOME(os::mkdir(path::join(tmpdir, "a", "b", "c")));
+
+ // Expect all the directories exist.
+ EXPECT_TRUE(os::exists(tmpdir));
+ EXPECT_TRUE(os::exists(path::join(tmpdir, "a")));
+ EXPECT_TRUE(os::exists(path::join(tmpdir, "a", "b")));
+ EXPECT_TRUE(os::exists(path::join(tmpdir, "a", "b", "c")));
+
+ // Return false if a component of the path does not exist.
+ EXPECT_FALSE(os::exists(path::join(tmpdir, "a", "fakeDir")));
+ EXPECT_FALSE(os::exists(path::join(tmpdir, "a", "fakeDir", "c")));
+
+ // Add file to directory tree.
+ ASSERT_SOME(os::touch(path::join(tmpdir, "a", "b", "c", "yourFile")));
+
+ // Assert it exists.
+ EXPECT_TRUE(os::exists(path::join(tmpdir, "a", "b", "c", "yourFile")));
+
+ // Return false if file is wrong.
+ EXPECT_FALSE(os::exists(path::join(tmpdir, "a", "b", "c", "yourFakeFile")));
+}
+
+
TEST_F(FsTest, Touch)
{
const string testfile = path::join(os::getcwd(), UUID::random().toString());
[3/3] mesos git commit: Windows: Add Windows-friendly implementation
of `rm.hpp`.
Posted by mp...@apache.org.
Windows: Add Windows-friendly implementation of `rm.hpp`.
We currently depend on arcane "POSIX-like" Windows APIs like `::remove`.
This API is incompatible with NT paths -- which we will eventually have
to transition to for the Windows integration -- and has no documented
behavior interacting with subsystems like the driver subsystem, which is
required for symlinks.
This commit will move us to proper core Windows API equivalents for
`::remove`.
Review: https://reviews.apache.org/r/45022/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8d9eb5fb
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8d9eb5fb
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8d9eb5fb
Branch: refs/heads/master
Commit: 8d9eb5fb90839b27a0acbcf4dcac44d01bf21f8d
Parents: 387a62e
Author: Alex Clemmer <cl...@gmail.com>
Authored: Sat Apr 9 16:26:20 2016 -0700
Committer: Michael Park <mp...@apache.org>
Committed: Sat Apr 9 16:26:20 2016 -0700
----------------------------------------------------------------------
.../3rdparty/stout/include/Makefile.am | 2 +
.../stout/include/stout/os/posix/rm.hpp | 37 ++++++++++++
.../3rdparty/stout/include/stout/os/rm.hpp | 26 +++------
.../stout/include/stout/os/windows/rm.hpp | 58 +++++++++++++++++++
.../stout/tests/os/filesystem_tests.cpp | 61 ++++++++++++++++++++
5 files changed, 165 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/8d9eb5fb/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
index 03f46d9..23b9309 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
+++ b/3rdparty/libprocess/3rdparty/stout/include/Makefile.am
@@ -112,6 +112,7 @@ nobase_include_HEADERS = \
stout/os/posix/pstree.hpp \
stout/os/posix/read.hpp \
stout/os/posix/rename.hpp \
+ stout/os/posix/rm.hpp \
stout/os/posix/rmdir.hpp \
stout/os/posix/sendfile.hpp \
stout/os/posix/shell.hpp \
@@ -133,6 +134,7 @@ nobase_include_HEADERS = \
stout/os/windows/pstree.hpp \
stout/os/windows/read.hpp \
stout/os/windows/rename.hpp \
+ stout/os/windows/rm.hpp \
stout/os/windows/rmdir.hpp \
stout/os/windows/sendfile.hpp \
stout/os/windows/shell.hpp \
http://git-wip-us.apache.org/repos/asf/mesos/blob/8d9eb5fb/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rm.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rm.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rm.hpp
new file mode 100644
index 0000000..b1ec881
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rm.hpp
@@ -0,0 +1,37 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#ifndef __STOUT_OS_POSIX_RM_HPP__
+#define __STOUT_OS_POSIX_RM_HPP__
+
+#include <stdio.h>
+
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+
+namespace os {
+
+inline Try<Nothing> rm(const std::string& path)
+{
+ if (::remove(path.c_str()) != 0) {
+ return ErrnoError();
+ }
+
+ return Nothing();
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_POSIX_RM_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/8d9eb5fb/3rdparty/libprocess/3rdparty/stout/include/stout/os/rm.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/rm.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/rm.hpp
index 52568b3..a2d48f5 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/rm.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/rm.hpp
@@ -13,26 +13,14 @@
#ifndef __STOUT_OS_RM_HPP__
#define __STOUT_OS_RM_HPP__
-#include <string>
-#include <stdio.h>
+// For readability, we minimize the number of #ifdef blocks in the code by
+// splitting platform specifc system calls into separate directories.
+#ifdef __WINDOWS__
+#include <stout/os/windows/rm.hpp>
+#else
+#include <stout/os/posix/rm.hpp>
+#endif // __WINDOWS__
-#include <stout/error.hpp>
-#include <stout/nothing.hpp>
-#include <stout/try.hpp>
-
-
-namespace os {
-
-inline Try<Nothing> rm(const std::string& path)
-{
- if (::remove(path.c_str()) != 0) {
- return ErrnoError();
- }
-
- return Nothing();
-}
-
-} // namespace os {
#endif // __STOUT_OS_RM_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/8d9eb5fb/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rm.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rm.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rm.hpp
new file mode 100644
index 0000000..6460b52
--- /dev/null
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rm.hpp
@@ -0,0 +1,58 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#ifndef __STOUT_OS_WINDOWS_RM_HPP__
+#define __STOUT_OS_WINDOWS_RM_HPP__
+
+#include <stdio.h>
+
+#include <string>
+
+#include <stout/error.hpp>
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+#include <stout/windows.hpp>
+
+#include <stout/os/stat.hpp>
+
+
+namespace os {
+
+inline Try<Nothing> rm(const std::string& path)
+{
+ // This function uses either `RemoveDirectory` or `DeleteFile` to remove the
+ // actual filesystem entry. These WinAPI functions are being used instead of
+ // the POSIX `remove` because their behavior when it comes to symbolic links
+ // is well documented in MSDN[1][2]. Whenever called on a symbolic link, both
+ // `RemoveDirectory` and `DeleteFile` act on the symlink itself, rather than
+ // its target.
+ //
+ // Because `RemoveDirectory` fails if the specified path is not an empty
+ // directory, its behavior is consistent with the POSIX[3] `remove`[3] (which
+ // uses `rmdir`[4]).
+ //
+ // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365488(v=vs.85).aspx
+ // [2] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365682(v=vs.85).aspx#deletefile_and_deletefiletransacted
+ // [3] http://pubs.opengroup.org/onlinepubs/009695399/functions/remove.html
+ // [4] http://pubs.opengroup.org/onlinepubs/009695399/functions/rmdir.html
+ const BOOL result = os::stat::isdir(path) ? ::RemoveDirectory(path.c_str())
+ : ::DeleteFile(path.c_str());
+
+ if (!result) {
+ return WindowsError("`os::rm` could not remove '" + path + "'");
+ }
+
+ return Nothing();
+}
+
+} // namespace os {
+
+#endif // __STOUT_OS_WINDOWS_RM_HPP__
http://git-wip-us.apache.org/repos/asf/mesos/blob/8d9eb5fb/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
index 6262892..269079f 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/os/filesystem_tests.cpp
@@ -28,6 +28,7 @@
#include <stout/os/mkdir.hpp>
#include <stout/os/read.hpp>
#include <stout/os/rename.hpp>
+#include <stout/os/rm.hpp>
#include <stout/os/touch.hpp>
#include <stout/os/write.hpp>
@@ -194,6 +195,66 @@ TEST_F(FsTest, Symlink)
}
+TEST_F(FsTest, Rm)
+{
+ const string tmpdir = os::getcwd();
+
+ hashset<string> expectedListing;
+ EXPECT_EQ(expectedListing, listfiles(tmpdir));
+
+ const string file1 = path::join(tmpdir, "file1.txt");
+ const string directory1 = path::join(tmpdir, "directory1");
+
+ const string fileSymlink1 = path::join(tmpdir, "fileSymlink1");
+ const string fileToSymlink = path::join(tmpdir, "fileToSymlink.txt");
+ const string directorySymlink1 = path::join(tmpdir, "directorySymlink1");
+ const string directoryToSymlink = path::join(tmpdir, "directoryToSymlink");
+
+ // Create a file, a directory, and a symlink to a file and a directory.
+ ASSERT_SOME(os::touch(file1));
+ expectedListing.insert("file1.txt");
+
+ ASSERT_SOME(os::mkdir(directory1));
+ expectedListing.insert("directory1");
+
+ ASSERT_SOME(os::touch(fileToSymlink));
+ ASSERT_SOME(fs::symlink(fileToSymlink, fileSymlink1));
+ expectedListing.insert("fileToSymlink.txt");
+ expectedListing.insert("fileSymlink1");
+
+ ASSERT_SOME(os::mkdir(directoryToSymlink));
+ ASSERT_SOME(fs::symlink(directoryToSymlink, directorySymlink1));
+ expectedListing.insert("directoryToSymlink");
+ expectedListing.insert("directorySymlink1");
+
+ EXPECT_EQ(expectedListing, listfiles(tmpdir));
+
+ // Verify `rm` of non-empty directory fails.
+ EXPECT_ERROR(os::rm(tmpdir));
+ EXPECT_EQ(expectedListing, listfiles(tmpdir));
+
+ // Remove all, and verify.
+ EXPECT_SOME(os::rm(file1));
+ expectedListing.erase("file1.txt");
+
+ EXPECT_SOME(os::rm(directory1));
+ expectedListing.erase("directory1");
+
+ EXPECT_SOME(os::rm(fileSymlink1));
+ expectedListing.erase("fileSymlink1");
+
+ EXPECT_SOME(os::rm(directorySymlink1));
+ expectedListing.erase("directorySymlink1");
+
+ // `os::rm` doesn't act on the target, therefore we must verify they each
+ // still exist.
+ EXPECT_EQ(expectedListing, listfiles(tmpdir));
+
+ // Verify that we error out for paths that don't exist.
+ EXPECT_ERROR(os::rm("fakeFile"));
+}
+
+
TEST_F(FsTest, List)
{
const string testdir = path::join(os::getcwd(), UUID::random().toString());