Skip to content

Commit 327571d

Browse files
authored
Merge pull request #11686 from ethereum/temporary-directory-extra-features
Convenience features in `TemporaryDirectory`
2 parents 5229ace + 92446cb commit 327571d

File tree

6 files changed

+104
-67
lines changed

6 files changed

+104
-67
lines changed

test/TemporaryDirectory.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818

1919
#include <test/TemporaryDirectory.h>
2020

21+
#include <test/libsolidity/util/SoltestErrors.h>
22+
23+
#include <boost/algorithm/string/predicate.hpp>
2124
#include <boost/filesystem.hpp>
2225

23-
#include <cassert>
2426
#include <regex>
2527
#include <iostream>
2628

@@ -31,21 +33,39 @@ using namespace solidity::test;
3133
namespace fs = boost::filesystem;
3234

3335
TemporaryDirectory::TemporaryDirectory(std::string const& _prefix):
34-
m_path(fs::temp_directory_path() / fs::unique_path(_prefix + "%%%%-%%%%-%%%%-%%%%"))
36+
m_path(fs::temp_directory_path() / fs::unique_path(_prefix + "-%%%%-%%%%-%%%%-%%%%"))
3537
{
3638
// Prefix should just be a file name and not contain anything that would make us step out of /tmp.
37-
assert(fs::path(_prefix) == fs::path(_prefix).stem());
39+
soltestAssert(fs::path(_prefix) == fs::path(_prefix).stem(), "");
3840

3941
fs::create_directory(m_path);
4042
}
4143

44+
TemporaryDirectory::TemporaryDirectory(
45+
vector<boost::filesystem::path> const& _subdirectories,
46+
string const& _prefix
47+
):
48+
TemporaryDirectory(_prefix)
49+
{
50+
for (boost::filesystem::path const& subdirectory: _subdirectories)
51+
{
52+
soltestAssert(!subdirectory.is_absolute() && subdirectory.root_path() != "/", "");
53+
soltestAssert(
54+
m_path.lexically_relative(subdirectory).empty() ||
55+
*m_path.lexically_relative(subdirectory).begin() != "..",
56+
""
57+
);
58+
boost::filesystem::create_directories(m_path / subdirectory);
59+
}
60+
}
61+
4262
TemporaryDirectory::~TemporaryDirectory()
4363
{
4464
// A few paranoid sanity checks just to be extra sure we're not deleting someone's homework.
45-
assert(m_path.string().find(fs::temp_directory_path().string()) == 0);
46-
assert(!fs::equivalent(m_path, fs::temp_directory_path()));
47-
assert(!fs::equivalent(m_path, m_path.root_path()));
48-
assert(!m_path.empty());
65+
soltestAssert(m_path.string().find(fs::temp_directory_path().string()) == 0, "");
66+
soltestAssert(!fs::equivalent(m_path, fs::temp_directory_path()), "");
67+
soltestAssert(!fs::equivalent(m_path, m_path.root_path()), "");
68+
soltestAssert(!m_path.empty(), "");
4969

5070
boost::system::error_code errorCode;
5171
uintmax_t numRemoved = fs::remove_all(m_path, errorCode);

test/TemporaryDirectory.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <boost/filesystem.hpp>
2626

2727
#include <string>
28+
#include <vector>
2829

2930
namespace solidity::test
3031
{
@@ -40,10 +41,15 @@ namespace solidity::test
4041
class TemporaryDirectory
4142
{
4243
public:
43-
TemporaryDirectory(std::string const& _prefix = "solidity-test-");
44+
TemporaryDirectory(std::string const& _prefix = "solidity-test");
45+
TemporaryDirectory(
46+
std::vector<boost::filesystem::path> const& _subdirectories,
47+
std::string const& _prefix = "solidity-test"
48+
);
4449
~TemporaryDirectory();
4550

4651
boost::filesystem::path const& path() const { return m_path; }
52+
operator boost::filesystem::path() const { return m_path; }
4753

4854
private:
4955
boost::filesystem::path m_path;
@@ -59,6 +65,7 @@ class TemporaryWorkingDirectory
5965
~TemporaryWorkingDirectory();
6066

6167
boost::filesystem::path const& originalWorkingDirectory() const { return m_originalWorkingDirectory; }
68+
operator boost::filesystem::path() const { return boost::filesystem::current_path(); }
6269

6370
private:
6471
boost::filesystem::path m_originalWorkingDirectory;

test/TemporaryDirectoryTest.cpp

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#include <test/TemporaryDirectory.h>
2020

21+
#include <test/libsolidity/util/SoltestErrors.h>
22+
2123
#include <boost/filesystem.hpp>
2224
#include <boost/test/unit_test.hpp>
2325

@@ -26,68 +28,79 @@
2628
using namespace std;
2729
using namespace boost::test_tools;
2830

29-
namespace fs = boost::filesystem;
30-
3131
namespace solidity::test
3232
{
3333

3434
BOOST_AUTO_TEST_SUITE(TemporaryDirectoryTest)
3535

3636
BOOST_AUTO_TEST_CASE(TemporaryDirectory_should_create_and_delete_a_unique_and_empty_directory)
3737
{
38-
fs::path dirPath;
38+
boost::filesystem::path dirPath;
3939
{
40-
TemporaryDirectory tempDir("temporary-directory-test-");
40+
TemporaryDirectory tempDir("temporary-directory-test");
4141
dirPath = tempDir.path();
4242

43-
BOOST_TEST(dirPath.stem().string().find("temporary-directory-test-") == 0);
44-
BOOST_TEST(fs::equivalent(dirPath.parent_path(), fs::temp_directory_path()));
45-
BOOST_TEST(fs::is_directory(dirPath));
46-
BOOST_TEST(fs::is_empty(dirPath));
43+
BOOST_TEST(dirPath.stem().string().find("temporary-directory-test") == 0);
44+
BOOST_TEST(boost::filesystem::equivalent(dirPath.parent_path(), boost::filesystem::temp_directory_path()));
45+
BOOST_TEST(boost::filesystem::is_directory(dirPath));
46+
BOOST_TEST(boost::filesystem::is_empty(dirPath));
4747
}
48-
BOOST_TEST(!fs::exists(dirPath));
48+
BOOST_TEST(!boost::filesystem::exists(dirPath));
4949
}
5050

5151
BOOST_AUTO_TEST_CASE(TemporaryDirectory_should_delete_its_directory_even_if_not_empty)
5252
{
53-
fs::path dirPath;
53+
boost::filesystem::path dirPath;
5454
{
55-
TemporaryDirectory tempDir("temporary-directory-test-");
55+
TemporaryDirectory tempDir("temporary-directory-test");
5656
dirPath = tempDir.path();
5757

58-
BOOST_TEST(fs::is_directory(dirPath));
58+
BOOST_TEST(boost::filesystem::is_directory(dirPath));
5959

6060
{
6161
ofstream tmpFile((dirPath / "test-file.txt").string());
6262
tmpFile << "Delete me!" << endl;
6363
}
64-
assert(fs::is_regular_file(dirPath / "test-file.txt"));
64+
soltestAssert(boost::filesystem::is_regular_file(dirPath / "test-file.txt"), "");
65+
}
66+
BOOST_TEST(!boost::filesystem::exists(dirPath / "test-file.txt"));
67+
}
68+
69+
BOOST_AUTO_TEST_CASE(TemporaryDirectory_should_create_subdirectories)
70+
{
71+
boost::filesystem::path dirPath;
72+
{
73+
TemporaryDirectory tempDir({"a", "a/", "a/b/c", "x.y/z"}, "temporary-directory-test");
74+
dirPath = tempDir.path();
75+
76+
BOOST_TEST(boost::filesystem::is_directory(dirPath / "a"));
77+
BOOST_TEST(boost::filesystem::is_directory(dirPath / "a/b/c"));
78+
BOOST_TEST(boost::filesystem::is_directory(dirPath / "x.y/z"));
6579
}
66-
BOOST_TEST(!fs::exists(dirPath / "test-file.txt"));
6780
}
6881

6982
BOOST_AUTO_TEST_CASE(TemporaryWorkingDirectory_should_change_and_restore_working_directory)
7083
{
71-
fs::path originalWorkingDirectory = fs::current_path();
84+
boost::filesystem::path originalWorkingDirectory = boost::filesystem::current_path();
7285

7386
try
7487
{
7588
{
76-
TemporaryDirectory tempDir("temporary-directory-test-");
77-
assert(fs::equivalent(fs::current_path(), originalWorkingDirectory));
78-
assert(!fs::equivalent(tempDir.path(), originalWorkingDirectory));
89+
TemporaryDirectory tempDir("temporary-directory-test");
90+
soltestAssert(boost::filesystem::equivalent(boost::filesystem::current_path(), originalWorkingDirectory), "");
91+
soltestAssert(!boost::filesystem::equivalent(tempDir.path(), originalWorkingDirectory), "");
7992

8093
TemporaryWorkingDirectory tempWorkDir(tempDir.path());
8194

82-
BOOST_TEST(fs::equivalent(fs::current_path(), tempDir.path()));
95+
BOOST_TEST(boost::filesystem::equivalent(boost::filesystem::current_path(), tempDir.path()));
8396
}
84-
BOOST_TEST(fs::equivalent(fs::current_path(), originalWorkingDirectory));
97+
BOOST_TEST(boost::filesystem::equivalent(boost::filesystem::current_path(), originalWorkingDirectory));
8598

86-
fs::current_path(originalWorkingDirectory);
99+
boost::filesystem::current_path(originalWorkingDirectory);
87100
}
88101
catch (...)
89102
{
90-
fs::current_path(originalWorkingDirectory);
103+
boost::filesystem::current_path(originalWorkingDirectory);
91104
}
92105
}
93106

test/libsolidity/interface/FileReader.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_absolute_path)
6565

6666
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_relative_path)
6767
{
68-
TemporaryDirectory tempDir(TEST_CASE_NAME);
69-
boost::filesystem::create_directories(tempDir.path() / "x/y/z");
68+
TemporaryDirectory tempDir({"x/y/z"}, TEST_CASE_NAME);
7069
TemporaryWorkingDirectory tempWorkDir(tempDir.path() / "x/y/z");
7170

7271
// NOTE: If path to work dir contains symlinks (often the case on macOS), boost might resolve
@@ -129,7 +128,7 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_redundant_slashes)
129128
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_unc_path)
130129
{
131130
TemporaryDirectory tempDir(TEST_CASE_NAME);
132-
TemporaryWorkingDirectory tempWorkDir(tempDir.path());
131+
TemporaryWorkingDirectory tempWorkDir(tempDir);
133132

134133
// On Windows tempDir.path() normally contains the drive letter while the normalized path should not.
135134
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::current_path().relative_path();
@@ -157,7 +156,7 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_unc_path)
157156
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_root_name_only)
158157
{
159158
TemporaryDirectory tempDir(TEST_CASE_NAME);
160-
TemporaryWorkingDirectory tempWorkDir(tempDir.path());
159+
TemporaryWorkingDirectory tempWorkDir(tempDir);
161160

162161
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::current_path().relative_path();
163162
soltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == "/", "");
@@ -187,7 +186,7 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_root_name_only)
187186
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_stripping_root_name)
188187
{
189188
TemporaryDirectory tempDir(TEST_CASE_NAME);
190-
TemporaryWorkingDirectory tempWorkDir(tempDir.path());
189+
TemporaryWorkingDirectory tempWorkDir(tempDir);
191190

192191
soltestAssert(boost::filesystem::current_path().is_absolute(), "");
193192
#if defined(_WIN32)
@@ -234,7 +233,7 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_path_beyond_root)
234233
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_case_sensitivity)
235234
{
236235
TemporaryDirectory tempDir(TEST_CASE_NAME);
237-
TemporaryWorkingDirectory tempWorkDir(tempDir.path());
236+
TemporaryWorkingDirectory tempWorkDir(tempDir);
238237

239238
boost::filesystem::path expectedPrefix = "/" / tempDir.path().relative_path();
240239
soltestAssert(expectedPrefix.is_absolute() || expectedPrefix.root_path() == "/", "");
@@ -253,9 +252,8 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_path_separators)
253252

254253
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_not_resolve_symlinks)
255254
{
256-
TemporaryDirectory tempDir(TEST_CASE_NAME);
255+
TemporaryDirectory tempDir({"abc/"}, TEST_CASE_NAME);
257256
soltestAssert(tempDir.path().is_absolute(), "");
258-
boost::filesystem::create_directories(tempDir.path() / "abc");
259257

260258
if (!createSymlinkIfSupportedByFilesystem(tempDir.path() / "abc", tempDir.path() / "sym", true))
261259
return;
@@ -269,9 +267,8 @@ BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_not_resolve_symlinks)
269267

270268
BOOST_AUTO_TEST_CASE(normalizeCLIPathForVFS_should_resolve_symlinks_in_workdir_when_path_is_relative)
271269
{
272-
TemporaryDirectory tempDir(TEST_CASE_NAME);
270+
TemporaryDirectory tempDir({"abc/"}, TEST_CASE_NAME);
273271
soltestAssert(tempDir.path().is_absolute(), "");
274-
boost::filesystem::create_directories(tempDir.path() / "abc");
275272

276273
if (!createSymlinkIfSupportedByFilesystem(tempDir.path() / "abc", tempDir.path() / "sym", true))
277274
return;

test/libsolutil/CommonIO.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,30 @@
3434
using namespace std;
3535
using namespace solidity::test;
3636

37+
#define TEST_CASE_NAME (boost::unit_test::framework::current_test_case().p_name)
38+
3739
namespace solidity::util::test
3840
{
3941

4042
BOOST_AUTO_TEST_SUITE(CommonIOTest)
4143

4244
BOOST_AUTO_TEST_CASE(readFileAsString_regular_file)
4345
{
44-
TemporaryDirectory tempDir("common-io-test-");
46+
TemporaryDirectory tempDir(TEST_CASE_NAME);
4547
createFileWithContent(tempDir.path() / "test.txt", "ABC\ndef\n");
4648

4749
BOOST_TEST(readFileAsString(tempDir.path() / "test.txt") == "ABC\ndef\n");
4850
}
4951

5052
BOOST_AUTO_TEST_CASE(readFileAsString_directory)
5153
{
52-
TemporaryDirectory tempDir("common-io-test-");
53-
BOOST_CHECK_THROW(readFileAsString(tempDir.path()), NotAFile);
54+
TemporaryDirectory tempDir(TEST_CASE_NAME);
55+
BOOST_CHECK_THROW(readFileAsString(tempDir), NotAFile);
5456
}
5557

5658
BOOST_AUTO_TEST_CASE(readFileAsString_symlink)
5759
{
58-
TemporaryDirectory tempDir("common-io-test-");
60+
TemporaryDirectory tempDir(TEST_CASE_NAME);
5961
createFileWithContent(tempDir.path() / "test.txt", "ABC\ndef\n");
6062

6163
if (!createSymlinkIfSupportedByFilesystem("test.txt", tempDir.path() / "symlink.txt", false))

0 commit comments

Comments
 (0)