1013d15a677f70aa9c91fa09707e5d4248146b99dMichael J. Spencer//===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
2f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//
3f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//                     The LLVM Compiler Infrastructure
4f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//
5f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer// This file is distributed under the University of Illinois Open Source
6f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer// License. See LICENSE.TXT for details.
7f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//
8f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer//===----------------------------------------------------------------------===//
9f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
103cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer#include "llvm/Support/FileSystem.h"
111f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/PathV2.h"
12753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer#include "llvm/Support/ErrorHandling.h"
13f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer#include "llvm/Support/raw_ostream.h"
14861ef4b1cffcf30ecd5b6a2216b88345f892f0b7Michael J. Spencer
15f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer#include "gtest/gtest.h"
16f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
17dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencerusing namespace llvm;
183cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencerusing namespace llvm::sys;
19dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
20ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer#define ASSERT_NO_ERROR(x) \
21f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer  if (error_code ASSERT_NO_ERROR_ec = x) { \
22f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer    SmallString<128> MessageStorage; \
23f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer    raw_svector_ostream Message(MessageStorage); \
24f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer    Message << #x ": did not return errc::success.\n" \
25f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer            << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
26f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer            << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
27f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer    GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
28ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  } else {}
29ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer
30f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencernamespace {
31f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
3263cc3a85cc10093f83f76ea9192f77929b58569eZhanyong WanTEST(is_separator, Works) {
3363cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_TRUE(path::is_separator('/'));
3463cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator('\0'));
3563cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator('-'));
3663cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator(' '));
3763cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan
3863cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#ifdef LLVM_ON_WIN32
3963cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_TRUE(path::is_separator('\\'));
4063cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#else
4163cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan  EXPECT_FALSE(path::is_separator('\\'));
4263cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan#endif
4363cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan}
4463cc3a85cc10093f83f76ea9192f77929b58569eZhanyong Wan
45013d15a677f70aa9c91fa09707e5d4248146b99dMichael J. SpencerTEST(Support, Path) {
46dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  SmallVector<StringRef, 40> paths;
47dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("");
48dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back(".");
49dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("..");
50dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo");
51dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/");
52dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/foo");
53dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/");
54dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/foo/");
55dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/bar");
56dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/foo/bar");
57dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("//net");
58dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("//net/foo");
59dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("///foo///");
60dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("///foo///bar");
61dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/.");
62dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("./");
63dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("/..");
64dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("../");
65dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/.");
66dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/..");
67dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/./");
68dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/./bar");
69dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/..");
70dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/../");
71dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("foo/../bar");
72dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:");
73dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/");
74dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo");
75dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo");
76dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo/");
77dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo/");
78dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo/bar");
79dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("prn:");
80dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\");
81dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo");
82dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\foo");
83dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:foo\\");
84dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\foo\\");
85dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:\\foo/");
86dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  paths.push_back("c:/foo\\bar");
87dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
88dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
89dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  e = paths.end();
90dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  i != e;
91dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                                  ++i) {
92dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    for (sys::path::const_iterator ci = sys::path::begin(*i),
93dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                   ce = sys::path::end(*i);
94dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                   ci != ce;
95dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer                                   ++ci) {
96371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer      ASSERT_FALSE(ci->empty());
97dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer    }
98dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer
99506e579aa034ae84319a36854c8401e23b82f83eMichael J. Spencer#if 0 // Valgrind is whining about this.
100a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    outs() << "    Reverse Iteration: [";
101a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
102a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer                                     ce = sys::path::rend(*i);
103a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer                                     ci != ce;
104a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer                                     ++ci) {
105a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer      outs() << *ci << ',';
106a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    }
107a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer    outs() << "]\n";
108506e579aa034ae84319a36854c8401e23b82f83eMichael J. Spencer#endif
109a42cf73c779fe4210cedce0a7a0b2ada2085b55bMichael J. Spencer
1105029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_root_path(*i);
1115029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::root_path(*i);
1125029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_root_name(*i);
1135029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::root_name(*i);
1145029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_root_directory(*i);
1155029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::root_directory(*i);
1165029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_parent_path(*i);
1175029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::parent_path(*i);
1185029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_filename(*i);
1195029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::filename(*i);
1205029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_stem(*i);
1215029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::stem(*i);
1225029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::has_extension(*i);
1235029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::extension(*i);
1245029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::is_absolute(*i);
1255029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    path::is_relative(*i);
1261d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer
127ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer    SmallString<128> temp_store;
128371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    temp_store = *i;
129ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer    ASSERT_NO_ERROR(fs::make_absolute(temp_store));
130371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    temp_store = *i;
131936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::remove_filename(temp_store);
1321d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer
133371716cdee6442c5cb51831dc949518f0fb7a281Michael J. Spencer    temp_store = *i;
134936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::replace_extension(temp_store, "ext");
1351d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer    StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
1365029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    stem = path::stem(filename);
1375029159fbe7c267c9322fc6c38064e9ab2ce91bcMichael J. Spencer    ext  = path::extension(filename);
1381d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer    EXPECT_EQ(*(--sys::path::end(filename)), (stem + ext).str());
1391d3896232a1c54c171c2bf60eda52a42006ff17bMichael J. Spencer
140936671b2eaa0a6b27903f8d85a8f4b28fcf8ee84Michael J. Spencer    path::native(*i, temp_store);
141dffde9964480f946d4308ce936b667b6c37b1059Michael J. Spencer  }
1422558516859ac52a17c85afff01073303bd522979Michael J. Spencer}
1432558516859ac52a17c85afff01073303bd522979Michael J. Spencer
1442558516859ac52a17c85afff01073303bd522979Michael J. Spencerclass FileSystemTest : public testing::Test {
1452558516859ac52a17c85afff01073303bd522979Michael J. Spencerprotected:
1462558516859ac52a17c85afff01073303bd522979Michael J. Spencer  /// Unique temporary directory in which all created filesystem entities must
1472558516859ac52a17c85afff01073303bd522979Michael J. Spencer  /// be placed. It is recursively removed at the end of each test.
1482558516859ac52a17c85afff01073303bd522979Michael J. Spencer  SmallString<128> TestDirectory;
1492558516859ac52a17c85afff01073303bd522979Michael J. Spencer
1502558516859ac52a17c85afff01073303bd522979Michael J. Spencer  virtual void SetUp() {
151f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    int fd;
1522558516859ac52a17c85afff01073303bd522979Michael J. Spencer    ASSERT_NO_ERROR(
153f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer      fs::unique_file("file-system-test-%%-%%-%%-%%/test-directory.anchor", fd,
154f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer                      TestDirectory));
1552558516859ac52a17c85afff01073303bd522979Michael J. Spencer    // We don't care about this specific file.
156f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    ::close(fd);
157f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    TestDirectory = path::parent_path(TestDirectory);
158f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    errs() << "Test Directory: " << TestDirectory << '\n';
159f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    errs().flush();
1602558516859ac52a17c85afff01073303bd522979Michael J. Spencer  }
1613cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
1622558516859ac52a17c85afff01073303bd522979Michael J. Spencer  virtual void TearDown() {
163f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    uint32_t removed;
164f94f7325ad28f804eb87463821b0a89f7bf08612Michael J. Spencer    ASSERT_NO_ERROR(fs::remove_all(TestDirectory.str(), removed));
1652558516859ac52a17c85afff01073303bd522979Michael J. Spencer  }
1662558516859ac52a17c85afff01073303bd522979Michael J. Spencer};
1672558516859ac52a17c85afff01073303bd522979Michael J. Spencer
1682558516859ac52a17c85afff01073303bd522979Michael J. SpencerTEST_F(FileSystemTest, TempFiles) {
1699ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Create a temp file.
1703cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  int FileDescriptor;
1713cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  SmallString<64> TempPath;
172ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(
173ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer    fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath));
1743cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
1759ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Make sure it exists.
1763cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  bool TempFileExists;
177ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(sys::fs::exists(Twine(TempPath), TempFileExists));
1783cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  EXPECT_TRUE(TempFileExists);
1793cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
1809ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Create another temp tile.
1819ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  int FD2;
1829ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  SmallString<64> TempPath2;
183ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::unique_file("%%-%%-%%-%%.temp", FD2, TempPath2));
1849ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  ASSERT_NE(TempPath.str(), TempPath2.str());
1859ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
186d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  fs::file_status A, B;
187d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
188d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
189d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  EXPECT_FALSE(fs::equivalent(A, B));
190d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer
1919ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Try to copy the first to the second.
192ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  EXPECT_EQ(
193ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer    fs::copy_file(Twine(TempPath), Twine(TempPath2)), errc::file_exists);
1949ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
1959ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  ::close(FD2);
1969ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Try again with the proper options.
197ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::copy_file(Twine(TempPath), Twine(TempPath2),
198ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer                                fs::copy_option::overwrite_if_exists));
1999ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Remove Temp2.
200ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
2019ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  EXPECT_TRUE(TempFileExists);
2029ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
2039ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Make sure Temp2 doesn't exist.
204ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::exists(Twine(TempPath2), TempFileExists));
2059ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  EXPECT_FALSE(TempFileExists);
2069ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
2079ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Create a hard link to Temp1.
208ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::create_hard_link(Twine(TempPath), Twine(TempPath2)));
2099ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  bool equal;
210ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
2119ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  EXPECT_TRUE(equal);
212d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
213d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
214d45fbe62270eaf826419b93f1da66f1850f37fafMichael J. Spencer  EXPECT_TRUE(fs::equivalent(A, B));
2159ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
2169ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Remove Temp1.
2173cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer  ::close(FileDescriptor);
218ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::remove(Twine(TempPath), TempFileExists));
219106aa731bf86c632a6362497742c6df7bce61a07Michael J. Spencer  EXPECT_TRUE(TempFileExists);
2203cb84ef65dd417bc152fdaa173127966ca949318Michael J. Spencer
2219ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Remove the hard link.
222ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::remove(Twine(TempPath2), TempFileExists));
2239ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  EXPECT_TRUE(TempFileExists);
2249ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer
2259ad8221bcb26643ae5837d7f27b41610eeec98a7Michael J. Spencer  // Make sure Temp1 doesn't exist.
226ba64b9706a1f83e8388c3c722953de16d102de27Michael J. Spencer  ASSERT_NO_ERROR(fs::exists(Twine(TempPath), TempFileExists));
2276d6d16a5fc054fb3f7032297d0a15abb659be7efBenjamin Kramer  EXPECT_FALSE(TempFileExists);
2282558516859ac52a17c85afff01073303bd522979Michael J. Spencer}
229753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer
2302558516859ac52a17c85afff01073303bd522979Michael J. SpencerTEST_F(FileSystemTest, DirectoryIteration) {
231753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  error_code ec;
232f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer  for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
233f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer    ASSERT_NO_ERROR(ec);
234a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer
235a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // Create a known hierarchy to recurse over.
236a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  bool existed;
237a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
238a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer                  + "/recursive/a0/aa1", existed));
239a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
240a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer                  + "/recursive/a0/ab1", existed));
241a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
242a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer                  + "/recursive/dontlookhere/da1", existed));
243a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
244a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer                  + "/recursive/z0/za1", existed));
245a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory)
246a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer                  + "/recursive/pop/p1", existed));
247a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  typedef std::vector<std::string> v_t;
248a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t visited;
249a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  for (fs::recursive_directory_iterator i(Twine(TestDirectory)
250a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer         + "/recursive", ec), e; i != e; i.increment(ec)){
251a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer    ASSERT_NO_ERROR(ec);
25252ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi    if (path::filename(i->path()) == "p1") {
253a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer      i.pop();
25452ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi      // FIXME: recursive_directory_iterator should be more robust.
25552ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi      if (i == e) break;
25652ee230f6e06c4ec38b1953e1182d22431b88ddbNAKAMURA Takumi    }
257bd3825ecd1e7101ba8da024557e9f8d97686e70dMichael J. Spencer    if (path::filename(i->path()) == "dontlookhere")
258bd3825ecd1e7101ba8da024557e9f8d97686e70dMichael J. Spencer      i.no_push();
259a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer    visited.push_back(path::filename(i->path()));
260a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  }
261a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator a0 = std::find(visited.begin(), visited.end(), "a0");
262a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator aa1 = std::find(visited.begin(), visited.end(), "aa1");
263a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator ab1 = std::find(visited.begin(), visited.end(), "ab1");
264a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator dontlookhere = std::find(visited.begin(), visited.end(),
265a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer                                               "dontlookhere");
266a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator da1 = std::find(visited.begin(), visited.end(), "da1");
267a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator z0 = std::find(visited.begin(), visited.end(), "z0");
268a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator za1 = std::find(visited.begin(), visited.end(), "za1");
269a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator pop = std::find(visited.begin(), visited.end(), "pop");
270a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  v_t::const_iterator p1 = std::find(visited.begin(), visited.end(), "p1");
271a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer
272a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // Make sure that each path was visited correctly.
273a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(a0, visited.end());
274a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(aa1, visited.end());
275a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(ab1, visited.end());
276a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(dontlookhere, visited.end());
277a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_EQ(da1, visited.end()); // Not visited.
278a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(z0, visited.end());
279a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(za1, visited.end());
280a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_NE(pop, visited.end());
281a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_EQ(p1, visited.end()); // Not visited.
282a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer
283a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // Make sure that parents were visited before children. No other ordering
284a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  // guarantees can be made across siblings.
285a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_LT(a0, aa1);
286a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_LT(a0, ab1);
287a81ac8f2b5d4f61f7bc353f95cc1d0a05266f51cMichael J. Spencer  ASSERT_LT(z0, za1);
288f9fd07864e992e6d934f05d5760e5600c399c6f0Michael J. Spencer}
289238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer
290238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. SpencerTEST_F(FileSystemTest, Magic) {
291238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer  struct type {
292238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    const char *filename;
293238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    const char *magic_str;
294238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    size_t      magic_str_len;
295238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer  } types [] = {{"magic.archive", "!<arch>\x0A", 8}};
296238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer
297238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer  // Create some files filled with magic.
298238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer  for (type *i = types, *e = types + (sizeof(types) / sizeof(type)); i != e;
299238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer                                                                     ++i) {
300238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    SmallString<128> file_pathname(TestDirectory);
301238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    path::append(file_pathname, i->filename);
302238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    std::string ErrMsg;
303238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    raw_fd_ostream file(file_pathname.c_str(), ErrMsg,
304238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer                        raw_fd_ostream::F_Binary);
305238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    ASSERT_FALSE(file.has_error());
306238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    StringRef magic(i->magic_str, i->magic_str_len);
307238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    file << magic;
308248f9f280756a1d6eb20a97ee4ab457ec18170f6Michael J. Spencer    file.close();
309238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    bool res = false;
310238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    ASSERT_NO_ERROR(fs::has_magic(file_pathname.c_str(), magic, res));
311238589ebf571a4acefbb02e47812f8e0cfaaec7fMichael J. Spencer    EXPECT_TRUE(res);
312753cbbbd3ce28253f381caff83ce2a7f6e08785bMichael J. Spencer  }
313f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer}
314f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer
315ebbd6fef846e9f9e347f09a39703d6967541ed4eNAKAMURA Takumi#if !defined(_WIN32) // FIXME: Win32 has different permission schema.
316ca077ec5ea41f4537ae58e141781be622d09c786Nick KledzikTEST_F(FileSystemTest, Permissions) {
317ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Create a temp file.
318ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  int FileDescriptor;
319ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  SmallString<64> TempPath;
320ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  ASSERT_NO_ERROR(
321ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik    fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath));
322ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
323ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Mark file as read-only
324ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  const fs::perms AllWrite = fs::owner_write|fs::group_write|fs::others_write;
325ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  ASSERT_NO_ERROR(fs::permissions(Twine(TempPath), fs::remove_perms|AllWrite));
326ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
327ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Verify file is read-only
328ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  fs::file_status Status;
329ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status));
330ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  bool AnyWriteBits = (Status.permissions() & AllWrite);
331ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  EXPECT_FALSE(AnyWriteBits);
332ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
333ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Mark file as read-write
334ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  ASSERT_NO_ERROR(fs::permissions(Twine(TempPath), fs::add_perms|AllWrite));
335ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
336ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Verify file is read-write
337ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  ASSERT_NO_ERROR(fs::status(Twine(TempPath), Status));
338ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  AnyWriteBits = (Status.permissions() & AllWrite);
339ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  EXPECT_TRUE(AnyWriteBits);
340ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik}
341ebbd6fef846e9f9e347f09a39703d6967541ed4eNAKAMURA Takumi#endif
342ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
343ca077ec5ea41f4537ae58e141781be622d09c786Nick KledzikTEST_F(FileSystemTest, FileMapping) {
344ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Create a temp file.
345ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  int FileDescriptor;
346ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  SmallString<64> TempPath;
347ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  ASSERT_NO_ERROR(
348ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik    fs::unique_file("%%-%%-%%-%%.temp", FileDescriptor, TempPath));
349ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Map in temp file and add some content
3501ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  error_code EC;
3511ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  StringRef Val("hello there");
3521ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  {
3531ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    fs::mapped_file_region mfr(FileDescriptor,
3541ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                               fs::mapped_file_region::readwrite,
3551ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                               4096,
3561ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                               0,
3571ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                               EC);
3581ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    ASSERT_NO_ERROR(EC);
3591ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    std::copy(Val.begin(), Val.end(), mfr.data());
3601ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    // Explicitly add a 0.
3611ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    mfr.data()[Val.size()] = 0;
3621ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer    // Unmap temp file
3631ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  }
364ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
365ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Map it back in read-only
3661ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  fs::mapped_file_region mfr(Twine(TempPath),
3671ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             fs::mapped_file_region::readonly,
3681ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             0,
3691ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             0,
3701ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             EC);
3711ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  ASSERT_NO_ERROR(EC);
372ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
373ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Verify content
3741ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  EXPECT_EQ(StringRef(mfr.const_data()), Val);
375ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
376ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik  // Unmap temp file
377ca077ec5ea41f4537ae58e141781be622d09c786Nick Kledzik
3783651e7dfec0444eb74ee3d4ab9c9f4adf1971362Michael J. Spencer#if LLVM_USE_RVALUE_REFERENCES
3791ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  fs::mapped_file_region m(Twine(TempPath),
3801ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             fs::mapped_file_region::readonly,
3811ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             0,
3821ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             0,
3831ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer                             EC);
3841ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  ASSERT_NO_ERROR(EC);
3851ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  const char *Data = m.const_data();
3861ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  fs::mapped_file_region mfrrv(llvm_move(m));
3871ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer  EXPECT_EQ(mfrrv.const_data(), Data);
3881ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer#endif
3891ebd25e438444ae80ec3d9504fe2173b8306501dMichael J. Spencer}
390f2ca4cb86df1d38c439f35774210b16f36841531Michael J. Spencer} // anonymous namespace
391