Unify preamble handling between test cases based on AnalysisFramework

This commit is contained in:
Kamil Śliwak 2023-08-04 18:54:06 +02:00
parent 0c2fce579a
commit 18db62cf41
9 changed files with 115 additions and 58 deletions

View File

@ -112,6 +112,8 @@ set(libsolidity_util_sources
libsolidity/util/BytesUtils.cpp
libsolidity/util/BytesUtilsTests.cpp
libsolidity/util/BytesUtils.h
libsolidity/util/Common.cpp
libsolidity/util/Common.h
libsolidity/util/ContractABIUtils.cpp
libsolidity/util/ContractABIUtils.h
libsolidity/util/SoltestErrors.h

View File

@ -21,6 +21,7 @@
#include <test/libsolidity/AnalysisFramework.h>
#include <test/libsolidity/util/Common.h>
#include <test/Common.h>
#include <libsolidity/interface/CompilerStack.h>
@ -51,13 +52,7 @@ AnalysisFramework::parseAnalyseAndReturnError(
)
{
compiler().reset();
// Do not insert license if it is already present.
bool insertLicense = _insertLicenseAndVersionPragma && _source.find("SPDX-License-Identifier:") == string::npos;
compiler().setSources({{"",
string{_insertLicenseAndVersionPragma ? "pragma solidity >=0.0;\n" : ""} +
string{insertLicense ? "// SPDX-License-Identifier: GPL-3.0\n" : ""} +
_source
}});
compiler().setSources({{"", _insertLicenseAndVersionPragma ? withPreamble(_source) : _source}});
compiler().setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
compiler().setParserErrorRecovery(_allowRecoveryErrors);
_allowMultipleErrors = _allowMultipleErrors || _allowRecoveryErrors;

View File

@ -17,6 +17,7 @@
// SPDX-License-Identifier: GPL-3.0
#include <test/libsolidity/GasTest.h>
#include <test/libsolidity/util/Common.h>
#include <test/Common.h>
#include <libsolutil/CommonIO.h>
#include <libsolutil/JSON.h>
@ -99,7 +100,6 @@ void GasTest::printUpdatedExpectations(ostream& _stream, string const& _linePref
TestCase::TestResult GasTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
{
string const preamble = "pragma solidity >=0.0;\n// SPDX-License-Identifier: GPL-3.0\n";
compiler().reset();
// Prerelease CBOR metadata varies in size due to changing version numbers and build dates.
// This leads to volatile creation cost estimates. Therefore we force the compiler to
@ -113,7 +113,7 @@ TestCase::TestResult GasTest::run(ostream& _stream, string const& _linePrefix, b
}
settings.expectedExecutionsPerDeployment = m_optimiseRuns;
compiler().setOptimiserSettings(settings);
compiler().setSources({{"", preamble + m_source}});
compiler().setSources({{"", withPreamble(m_source)}});
if (!compiler().parseAndAnalyze() || !compiler().compile())
{

View File

@ -18,6 +18,7 @@
#include <test/libsolidity/SyntaxTest.h>
#include <test/libsolidity/util/Common.h>
#include <test/Common.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
@ -43,24 +44,10 @@ SyntaxTest::SyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion
m_parserErrorRecovery = _parserErrorRecovery;
}
string SyntaxTest::addPreamble(string const& _sourceCode)
{
// Silence compiler version warning
string preamble = "pragma solidity >=0.0;\n";
// NOTE: this check is intentionally loose to match weird cases.
// We can manually adjust a test case where this causes problem.
if (_sourceCode.find("SPDX-License-Identifier:") == string::npos)
preamble += "// SPDX-License-Identifier: GPL-3.0\n";
return preamble + _sourceCode;
}
void SyntaxTest::setupCompiler()
{
compiler().reset();
auto sourcesWithPragma = m_sources.sources;
for (auto& source: sourcesWithPragma)
source.second = addPreamble(source.second);
compiler().setSources(sourcesWithPragma);
compiler().setSources(withPreamble(m_sources.sources));
compiler().setEVMVersion(m_evmVersion);
compiler().setParserErrorRecovery(m_parserErrorRecovery);
compiler().setOptimiserSettings(

View File

@ -48,9 +48,6 @@ public:
SyntaxTest(std::string const& _filename, langutil::EVMVersion _evmVersion, bool _parserErrorRecovery = false);
protected:
/// Returns @param _sourceCode prefixed with the version pragma and the SPDX license identifier.
static std::string addPreamble(std::string const& _sourceCode);
virtual void setupCompiler();
void parseAndAnalyze() override;
virtual void filterObtainedErrors();

View File

@ -0,0 +1,46 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#include <test/libsolidity/util/Common.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
string test::withPreamble(string const& _sourceCode)
{
static string const versionPragma = "pragma solidity >=0.0;\n";
static string const licenseComment = "// SPDX-License-Identifier: GPL-3.0\n";
// NOTE: this check is intentionally loose to match weird cases.
// We can manually adjust a test case where this causes problem.
bool licenseMissing = _sourceCode.find("SPDX-License-Identifier:") == string::npos;
return
versionPragma +
(licenseMissing ? licenseComment : "") +
_sourceCode;
}
StringMap test::withPreamble(StringMap _sources)
{
for (auto&& [sourceName, source]: _sources)
source = withPreamble(source);
return _sources;
}

View File

@ -0,0 +1,34 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
/// Utilities shared by multiple libsolidity tests.
#include <libsolidity/interface/CompilerStack.h>
#include <string>
namespace solidity::frontend::test
{
/// @returns @p _sourceCode prefixed with the version pragma and the SPDX license identifier.
std::string withPreamble(std::string const& _sourceCode);
/// @returns a copy of @p _sources with preamble prepended to all sources.
StringMap withPreamble(StringMap _sources);
} // namespace solidity::frontend::test

View File

@ -24,6 +24,7 @@
#include <test/solc/Common.h>
#include <test/Common.h>
#include <test/libsolidity/util/Common.h>
#include <test/libsolidity/util/SoltestErrors.h>
#include <liblangutil/SemVerHandler.h>
#include <test/FilesystemUtils.h>
@ -921,10 +922,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
TemporaryDirectory tempDir({"base/", "include/", "lib/nested/"}, TEST_CASE_NAME);
TemporaryWorkingDirectory tempWorkDir(tempDir);
string const preamble =
"// SPDX-License-Identifier: GPL-3.0\n"
"pragma solidity >=0.0;\n";
string const mainContractSource = preamble +
string const mainContractSource = withPreamble(
"import \"contract.sol\";\n"
"import \"contract_via_callback.sol\";\n"
"import \"include.sol\";\n"
@ -932,8 +930,10 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
"import \"nested.sol\";\n"
"import \"nested_via_callback.sol\";\n"
"import \"lib.sol\";\n"
"import \"lib_via_callback.sol\";\n";
"import \"lib_via_callback.sol\";\n"
);
string const onlyPreamble = withPreamble("");
createFilesWithParentDirs(
{
tempDir.path() / "base/contract.sol",
@ -945,7 +945,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
tempDir.path() / "lib/lib.sol",
tempDir.path() / "lib/lib_via_callback.sol",
},
preamble
onlyPreamble
);
createFilesWithParentDirs({tempDir.path() / "base/main.sol"}, mainContractSource);
@ -985,14 +985,14 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
map<string, string> expectedSources = {
{"main.sol", mainContractSource},
{"contract.sol", preamble},
{"contract_via_callback.sol", preamble},
{"include.sol", preamble},
{"include_via_callback.sol", preamble},
{"nested.sol", preamble},
{"nested_via_callback.sol", preamble},
{"lib.sol", preamble},
{"lib_via_callback.sol", preamble},
{"contract.sol", onlyPreamble},
{"contract_via_callback.sol", onlyPreamble},
{"include.sol", onlyPreamble},
{"include_via_callback.sol", onlyPreamble},
{"nested.sol", onlyPreamble},
{"nested_via_callback.sol", onlyPreamble},
{"lib.sol", onlyPreamble},
{"lib_via_callback.sol", onlyPreamble},
};
vector<boost::filesystem::path> expectedIncludePaths = {
@ -1066,14 +1066,12 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
TemporaryDirectory tempDir({"base/", "include/", "lib/nested/"}, TEST_CASE_NAME);
TemporaryWorkingDirectory tempWorkDir(tempDir);
string const preamble =
"// SPDX-License-Identifier: GPL-3.0\n"
"pragma solidity >=0.0;\n";
string const mainContractSource = preamble +
string const mainContractSource = withPreamble(
"import 'contract_via_callback.sol';\n"
"import 'include_via_callback.sol';\n"
"import 'nested_via_callback.sol';\n"
"import 'lib_via_callback.sol';\n";
"import 'lib_via_callback.sol';\n"
);
string const standardJsonInput = R"(
{
@ -1084,6 +1082,7 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
}
)";
string const onlyPreamble = withPreamble("");
createFilesWithParentDirs(
{
tempDir.path() / "base/contract_via_callback.sol",
@ -1091,7 +1090,7 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
tempDir.path() / "lib/nested/nested_via_callback.sol",
tempDir.path() / "lib/lib_via_callback.sol",
},
preamble
onlyPreamble
);
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::canonical(tempDir).relative_path();
@ -1121,10 +1120,10 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
// because FileReader is only used once to initialize the compiler stack and after that
// its sources are irrelevant (even though the callback still stores everything it loads).
map<string, string> expectedSources = {
{"contract_via_callback.sol", preamble},
{"include_via_callback.sol", preamble},
{"nested_via_callback.sol", preamble},
{"lib_via_callback.sol", preamble},
{"contract_via_callback.sol", onlyPreamble},
{"include_via_callback.sol", onlyPreamble},
{"nested_via_callback.sol", onlyPreamble},
{"lib_via_callback.sol", onlyPreamble},
};
vector<boost::filesystem::path> expectedIncludePaths = {
@ -1335,14 +1334,10 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_ambiguous_import)
TemporaryDirectory tempDir({"base/", "include/"}, TEST_CASE_NAME);
TemporaryWorkingDirectory tempWorkDir(tempDir);
string const preamble =
"// SPDX-License-Identifier: GPL-3.0\n"
"pragma solidity >=0.0;\n";
string const mainContractSource = preamble +
// Ambiguous: both base/contract.sol and include/contract.sol match the import.
"import \"contract.sol\";";
// Ambiguous: both base/contract.sol and include/contract.sol match the import.
string const mainContractSource = withPreamble("import \"contract.sol\";");
createFilesWithParentDirs({"base/contract.sol", "include/contract.sol"}, preamble);
createFilesWithParentDirs({"base/contract.sol", "include/contract.sol"}, withPreamble(""));
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::canonical(tempDir).relative_path();

View File

@ -19,6 +19,7 @@ add_executable(isoltest
../TestCase.cpp
../TestCaseReader.cpp
../libsolidity/util/BytesUtils.cpp
../libsolidity/util/Common.cpp
../libsolidity/util/ContractABIUtils.cpp
../libsolidity/util/TestFileParser.cpp
../libsolidity/util/TestFunctionCall.cpp