diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index da1cb6ced..e5c5b2c7c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,6 +8,8 @@ set(sources
EVMHost.h
ExecutionFramework.cpp
ExecutionFramework.h
+ FilesystemUtils.cpp
+ FilesystemUtils.h
InteractiveTests.h
Metadata.cpp
Metadata.h
diff --git a/test/FilesystemUtils.cpp b/test/FilesystemUtils.cpp
new file mode 100644
index 000000000..08d484504
--- /dev/null
+++ b/test/FilesystemUtils.cpp
@@ -0,0 +1,60 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+
+#include
+
+#include
+
+using namespace std;
+using namespace solidity;
+using namespace solidity::test;
+
+void solidity::test::createFileWithContent(boost::filesystem::path const& _path, string const& content)
+{
+ if (boost::filesystem::is_regular_file(_path))
+ BOOST_THROW_EXCEPTION(runtime_error("File already exists: \"" + _path.string() + "\".")); \
+
+ // Use binary mode to avoid line ending conversion on Windows.
+ ofstream newFile(_path.string(), std::ofstream::binary);
+ if (newFile.fail() || !boost::filesystem::is_regular_file(_path))
+ BOOST_THROW_EXCEPTION(runtime_error("Failed to create a file: \"" + _path.string() + "\".")); \
+
+ newFile << content;
+}
+
+bool solidity::test::createSymlinkIfSupportedByFilesystem(
+ boost::filesystem::path const& _targetPath,
+ boost::filesystem::path const& _linkName
+)
+{
+ boost::system::error_code symlinkCreationError;
+ boost::filesystem::create_symlink(_targetPath, _linkName, symlinkCreationError);
+
+ if (!symlinkCreationError)
+ return true;
+ else if (
+ symlinkCreationError == boost::system::errc::not_supported ||
+ symlinkCreationError == boost::system::errc::operation_not_supported
+ )
+ return false;
+ else
+ BOOST_THROW_EXCEPTION(runtime_error(
+ "Failed to create a symbolic link: \"" + _linkName.string() + "\""
+ " -> " + _targetPath.string() + "\"."
+ ));
+}
diff --git a/test/FilesystemUtils.h b/test/FilesystemUtils.h
new file mode 100644
index 000000000..f8ad32044
--- /dev/null
+++ b/test/FilesystemUtils.h
@@ -0,0 +1,45 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+/**
+ * Helpers for common filesystem operations used in multiple tests.
+ */
+
+#pragma once
+
+#include
+
+#include
+
+namespace solidity::test
+{
+
+/// Creates a file with the exact content specified in the second argument.
+/// Throws an exception if the file already exists or if the parent directory of the file does not.
+void createFileWithContent(boost::filesystem::path const& _path, std::string const& content);
+
+/// Creates a symlink between two paths.
+/// The target does not have to exist.
+/// @returns true if the symlink has been successfully created, false if the filesystem does not
+/// support symlinks.
+/// Throws an exception of the operation fails for a different reason.
+bool createSymlinkIfSupportedByFilesystem(
+ boost::filesystem::path const& _targetPath,
+ boost::filesystem::path const& _linkName
+);
+
+}