Skip to content

Commit da38149

Browse files
committed
[test] Add support for --enforce-compile-to-ewasm.
1 parent 2969bc0 commit da38149

File tree

7 files changed

+115
-63
lines changed

7 files changed

+115
-63
lines changed

test/Common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ CommonOptions::CommonOptions(std::string _caption):
103103
("no-smt", po::bool_switch(&disableSMT), "disable SMT checker")
104104
("optimize", po::bool_switch(&optimize), "enables optimization")
105105
("enforce-via-yul", po::bool_switch(&enforceViaYul), "Enforce compiling all tests via yul to see if additional tests can be activated.")
106+
("enforce-compile-to-ewasm", po::bool_switch(&enforceCompileToEwasm), "Enforce compiling all tests to Ewasm to see if additional tests can be activated.")
106107
("enforce-gas-cost", po::bool_switch(&enforceGasTest), "Enforce checking gas cost in semantic tests.")
107108
("enforce-gas-cost-min-value", po::value(&enforceGasTestMinValue), "Threshold value to enforce adding gas checks to a test.")
108109
("abiencoderv1", po::bool_switch(&useABIEncoderV1), "enables abi encoder v1")

test/Common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct CommonOptions
5959
bool ewasm = false;
6060
bool optimize = false;
6161
bool enforceViaYul = false;
62+
bool enforceCompileToEwasm = false;
6263
bool enforceGasTest = false;
6364
u256 enforceGasTestMinValue = 100000;
6465
bool disableSMT = false;

test/TestCase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class TestCase
4141
langutil::EVMVersion evmVersion;
4242
std::vector<boost::filesystem::path> vmPaths;
4343
bool enforceCompileViaYul = false;
44+
bool enforceCompileToEwasm = false;
4445
bool enforceGasCost = false;
4546
u256 enforceGasCostMinValue;
4647
};

test/boostTest.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ int registerTests(
6565
boost::filesystem::path const& _basepath,
6666
boost::filesystem::path const& _path,
6767
bool _enforceViaYul,
68+
bool _enforceCompileToEwasm,
6869
vector<string> const& _labels,
6970
TestCase::TestCaseCreator _testCaseCreator
7071
)
@@ -76,8 +77,9 @@ int registerTests(
7677
solidity::test::CommonOptions::get().evmVersion(),
7778
solidity::test::CommonOptions::get().vmPaths,
7879
_enforceViaYul,
80+
_enforceCompileToEwasm,
7981
solidity::test::CommonOptions::get().enforceGasTest,
80-
solidity::test::CommonOptions::get().enforceGasTestMinValue
82+
solidity::test::CommonOptions::get().enforceGasTestMinValue,
8183
};
8284
if (fs::is_directory(fullpath))
8385
{
@@ -91,6 +93,7 @@ int registerTests(
9193
*sub_suite,
9294
_basepath, _path / entry.path().filename(),
9395
_enforceViaYul,
96+
_enforceCompileToEwasm,
9497
_labels,
9598
_testCaseCreator
9699
);
@@ -195,6 +198,7 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
195198
options.testPath / ts.path,
196199
ts.subpath,
197200
options.enforceViaYul,
201+
options.enforceCompileToEwasm,
198202
ts.labels,
199203
ts.testCaseCreator
200204
) > 0, std::string("no ") + ts.title + " tests found");

test/libsolidity/SemanticTest.cpp

Lines changed: 97 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ SemanticTest::SemanticTest(
5050
langutil::EVMVersion _evmVersion,
5151
vector<boost::filesystem::path> const& _vmPaths,
5252
bool _enforceViaYul,
53+
bool _enforceCompileToEwasm,
5354
bool _enforceGasCost,
5455
u256 _enforceGasCostMinValue
5556
):
@@ -58,51 +59,43 @@ SemanticTest::SemanticTest(
5859
m_sources(m_reader.sources()),
5960
m_lineOffset(m_reader.lineNumber()),
6061
m_enforceViaYul(_enforceViaYul),
62+
m_enforceCompileToEwasm(_enforceCompileToEwasm),
6163
m_enforceGasCost(_enforceGasCost),
62-
m_enforceGasCostMinValue(_enforceGasCostMinValue)
64+
m_enforceGasCostMinValue(std::move(_enforceGasCostMinValue))
6365
{
6466
initializeBuiltins();
6567

66-
string choice = m_reader.stringSetting("compileViaYul", "default");
67-
if (choice == "also")
68-
{
69-
m_runWithYul = true;
70-
m_runWithoutYul = true;
71-
}
72-
else if (choice == "true")
73-
{
74-
m_runWithYul = true;
75-
m_runWithoutYul = false;
76-
}
77-
else if (choice == "false")
68+
static set<string> const compileViaYulAllowedValues{"also", "true", "false", "default"};
69+
static set<string> const yulRunTriggers{"also", "true"};
70+
static set<string> const legacyRunTriggers{"also", "false", "default"};
71+
72+
string compileViaYul = m_reader.stringSetting("compileViaYul", "default");
73+
if (!contains(compileViaYulAllowedValues, compileViaYul))
74+
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileViaYul value: " + compileViaYul + "."));
75+
m_testCaseWantsYulRun = contains(yulRunTriggers, compileViaYul);
76+
m_testCaseWantsLegacyRun = contains(legacyRunTriggers, compileViaYul);
77+
78+
// Do not enforce via yul and ewasm, if via yul was explicitly denied.
79+
if (compileViaYul == "false")
7880
{
79-
m_runWithYul = false;
80-
m_runWithoutYul = true;
81-
// Do not try to run via yul if explicitly denied.
8281
m_enforceViaYul = false;
82+
m_enforceCompileToEwasm = false;
8383
}
84-
else if (choice == "default")
85-
{
86-
m_runWithYul = false;
87-
m_runWithoutYul = true;
88-
}
89-
else
90-
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileViaYul value: " + choice + "."));
9184

9285
string compileToEwasm = m_reader.stringSetting("compileToEwasm", "false");
9386
if (compileToEwasm == "also")
94-
m_runWithEwasm = true;
87+
m_testCaseWantsEwasmRun = true;
9588
else if (compileToEwasm == "false")
96-
m_runWithEwasm = false;
89+
m_testCaseWantsEwasmRun = false;
9790
else
9891
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileToEwasm value: " + compileToEwasm + "."));
9992

100-
if (m_runWithEwasm && !m_runWithYul)
93+
if (m_testCaseWantsEwasmRun && !m_testCaseWantsYulRun)
10194
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileToEwasm value: " + compileToEwasm + ", compileViaYul need to be enabled."));
10295

103-
// run ewasm tests only, if an ewasm evmc vm was defined
104-
if (m_runWithEwasm && !m_supportsEwasm)
105-
m_runWithEwasm = false;
96+
// run ewasm tests only if an ewasm evmc vm was defined
97+
if (m_testCaseWantsEwasmRun && !m_supportsEwasm)
98+
m_testCaseWantsEwasmRun = false;
10699

107100
m_runWithABIEncoderV1Only = m_reader.boolSetting("ABIEncoderV1Only", false);
108101
if (m_runWithABIEncoderV1Only && !solidity::test::CommonOptions::get().useABIEncoderV1)
@@ -136,49 +129,61 @@ void SemanticTest::initializeBuiltins()
136129
TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
137130
{
138131
TestResult result = TestResult::Success;
139-
bool compileViaYul = m_runWithYul || m_enforceViaYul;
140132

141-
if (m_runWithoutYul)
133+
if (m_testCaseWantsLegacyRun)
142134
result = runTest(_stream, _linePrefix, _formatted, false, false);
143135

144-
if (compileViaYul && result == TestResult::Success)
136+
if ((m_testCaseWantsYulRun || m_enforceViaYul) && result == TestResult::Success)
145137
result = runTest(_stream, _linePrefix, _formatted, true, false);
146138

147-
if (m_runWithEwasm && result == TestResult::Success)
148-
result = runTest(_stream, _linePrefix, _formatted, true, true);
149-
139+
if ((m_testCaseWantsEwasmRun || m_enforceCompileToEwasm) && result == TestResult::Success)
140+
{
141+
// TODO: Once we have full Ewasm support, we could remove try/catch here.
142+
try
143+
{
144+
result = runTest(_stream, _linePrefix, _formatted, true, true);
145+
}
146+
catch (...)
147+
{
148+
if (!m_enforceCompileToEwasm)
149+
throw;
150+
}
151+
}
150152
return result;
151153
}
152154

153155
TestCase::TestResult SemanticTest::runTest(
154156
ostream& _stream,
155157
string const& _linePrefix,
156158
bool _formatted,
157-
bool _compileViaYul,
158-
bool _compileToEwasm
159-
)
159+
bool _isYulRun,
160+
bool _isEwasmRun)
160161
{
161162
bool success = true;
162163
m_gasCostFailure = false;
163164

164-
if (_compileViaYul && _compileToEwasm)
165+
if (_isEwasmRun)
166+
{
167+
soltestAssert(_isYulRun, "");
165168
selectVM(evmc_capabilities::EVMC_CAPABILITY_EWASM);
169+
}
166170
else
167171
selectVM(evmc_capabilities::EVMC_CAPABILITY_EVM1);
168172

169173
reset();
170174

171-
m_compileViaYul = _compileViaYul;
172-
if (_compileToEwasm)
175+
m_compileViaYul = _isYulRun;
176+
if (_isEwasmRun)
173177
{
174178
soltestAssert(m_compileViaYul, "");
175-
m_compileToEwasm = _compileToEwasm;
179+
m_compileToEwasm = _isEwasmRun;
176180
}
177181

178-
m_compileViaYulCanBeSet = false;
182+
m_canEnableYulRun = false;
183+
m_canEnableEwasmRun = false;
179184

180-
if (_compileViaYul)
181-
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Running via Yul:" << endl;
185+
if (_isYulRun)
186+
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Running via Yul" << (_isEwasmRun ? " (ewasm):" : ":") << endl;
182187

183188
for (TestFunctionCall& test: m_tests)
184189
test.reset();
@@ -230,7 +235,7 @@ TestCase::TestResult SemanticTest::runTest(
230235
{
231236
if (m_transactionSuccessful == test.call().expectations.failure)
232237
success = false;
233-
if (success && !checkGasCostExpectation(test, _compileViaYul))
238+
if (success && !checkGasCostExpectation(test, _isYulRun))
234239
m_gasCostFailure = true;
235240

236241
test.setFailure(!m_transactionSuccessful);
@@ -268,7 +273,7 @@ TestCase::TestResult SemanticTest::runTest(
268273
}
269274

270275
bool outputMismatch = (output != test.call().expectations.rawBytes());
271-
if (!outputMismatch && !checkGasCostExpectation(test, _compileViaYul))
276+
if (!outputMismatch && !checkGasCostExpectation(test, _isYulRun))
272277
{
273278
success = false;
274279
m_gasCostFailure = true;
@@ -287,9 +292,9 @@ TestCase::TestResult SemanticTest::runTest(
287292
}
288293
}
289294

290-
if (!m_runWithYul && _compileViaYul)
295+
if (!m_testCaseWantsYulRun && _isYulRun)
291296
{
292-
m_compileViaYulCanBeSet = success;
297+
m_canEnableYulRun = success;
293298
string message = success ?
294299
"Test can pass via Yul, but marked with \"compileViaYul: false.\"" :
295300
"Test compiles via Yul, but it gives different test results.";
@@ -299,8 +304,31 @@ TestCase::TestResult SemanticTest::runTest(
299304
return TestResult::Failure;
300305
}
301306

302-
if (!success && (m_runWithYul || !_compileViaYul))
307+
// Right now we have sometimes different test results in Yul vs. Ewasm.
308+
// The main reason is that Ewasm just returns a failure in some cases.
309+
// TODO: If Ewasm support got fully implemented, we could implement this in the same way as above.
310+
if (success && !m_testCaseWantsEwasmRun && _isEwasmRun)
303311
{
312+
// TODO: There is something missing in Ewasm to support other types of revert strings:
313+
// for now, we just ignore test-cases that do not use RevertStrings::Default.
314+
if (m_revertStrings != RevertStrings::Default)
315+
return TestResult::Success;
316+
317+
m_canEnableEwasmRun = true;
318+
AnsiColorized(_stream, _formatted, {BOLD, YELLOW}) <<
319+
_linePrefix << endl <<
320+
_linePrefix << "Test can pass via Yul (Ewasm), but marked with \"compileToEwasm: false.\"" << endl;
321+
return TestResult::Failure;
322+
}
323+
324+
if (!success)
325+
{
326+
// Ignore failing tests that can't yet get compiled to Ewasm:
327+
// if the test run was not successful and enforce compiling to ewasm was set,
328+
// but the test case did not want to get run with Ewasm, we just ignore this failure.
329+
if (m_enforceCompileToEwasm && !m_testCaseWantsEwasmRun)
330+
return TestResult::Success;
331+
304332
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
305333
for (TestFunctionCall const& test: m_tests)
306334
{
@@ -331,13 +359,13 @@ TestCase::TestResult SemanticTest::runTest(
331359
AnsiColorized(_stream, _formatted, {BOLD, RED})
332360
<< _linePrefix << endl
333361
<< _linePrefix << "Attention: Updates on the test will apply the detected format displayed." << endl;
334-
if (_compileViaYul && m_runWithoutYul)
362+
if (_isYulRun && m_testCaseWantsLegacyRun)
335363
{
336364
_stream << _linePrefix << endl << _linePrefix;
337365
AnsiColorized(_stream, _formatted, {RED_BACKGROUND}) << "Note that the test passed without Yul.";
338366
_stream << endl;
339367
}
340-
else if (!_compileViaYul && m_runWithYul)
368+
else if (!_isYulRun && m_testCaseWantsYulRun)
341369
AnsiColorized(_stream, _formatted, {BOLD, YELLOW})
342370
<< _linePrefix << endl
343371
<< _linePrefix << "Note that the test also has to pass via Yul." << endl;
@@ -431,15 +459,27 @@ void SemanticTest::printUpdatedExpectations(ostream& _stream, string const&) con
431459
void SemanticTest::printUpdatedSettings(ostream& _stream, string const& _linePrefix)
432460
{
433461
auto& settings = m_reader.settings();
434-
if (settings.empty() && !m_compileViaYulCanBeSet)
462+
if (settings.empty() && !m_canEnableYulRun)
435463
return;
436464

437465
_stream << _linePrefix << "// ====" << endl;
438-
if (m_compileViaYulCanBeSet)
466+
if (m_canEnableEwasmRun)
467+
{
468+
soltestAssert(m_canEnableYulRun || m_testCaseWantsYulRun, "");
469+
string compileViaYul = m_reader.stringSetting("compileViaYul", "");
470+
if (!compileViaYul.empty())
471+
_stream << _linePrefix << "// compileViaYul: " << compileViaYul << "\n";
472+
_stream << _linePrefix << "// compileToEwasm: also\n";
473+
}
474+
else if (m_canEnableYulRun)
439475
_stream << _linePrefix << "// compileViaYul: also\n";
440-
for (auto const& setting: settings)
441-
if (!m_compileViaYulCanBeSet || setting.first != "compileViaYul")
442-
_stream << _linePrefix << "// " << setting.first << ": " << setting.second << endl;
476+
477+
for (auto const& [settingName, settingValue]: settings)
478+
if (
479+
!(settingName == "compileToEwasm" && m_canEnableEwasmRun) &&
480+
!(settingName == "compileViaYul" && (m_canEnableYulRun || m_canEnableEwasmRun))
481+
)
482+
_stream << _linePrefix << "// " << settingName << ": " << settingValue<< endl;
443483
}
444484

445485
void SemanticTest::parseExpectations(istream& _stream)

test/libsolidity/SemanticTest.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
4646
_options.evmVersion,
4747
_options.vmPaths,
4848
_options.enforceCompileViaYul,
49+
_options.enforceCompileToEwasm,
4950
_options.enforceGasCost,
5051
_options.enforceGasCostMinValue
5152
);
@@ -56,6 +57,7 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
5657
langutil::EVMVersion _evmVersion,
5758
std::vector<boost::filesystem::path> const& _vmPaths,
5859
bool _enforceViaYul = false,
60+
bool _enforceCompileToEwasm = false,
5961
bool _enforceGasCost = false,
6062
u256 _enforceGasCostMinValue = 100000
6163
);
@@ -76,19 +78,21 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
7678
bool deploy(std::string const& _contractName, u256 const& _value, bytes const& _arguments, std::map<std::string, solidity::test::Address> const& _libraries = {});
7779

7880
private:
79-
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _compileViaYul, bool _compileToEwasm);
81+
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _isYulRun, bool _isEwasmRun);
8082
bool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const;
8183
void initializeBuiltins();
8284
SourceMap m_sources;
8385
std::size_t m_lineOffset;
8486
std::vector<TestFunctionCall> m_tests;
85-
bool m_runWithYul = false;
86-
bool m_runWithEwasm = false;
87-
bool m_runWithoutYul = true;
87+
bool m_testCaseWantsYulRun = false;
88+
bool m_testCaseWantsEwasmRun = false;
89+
bool m_testCaseWantsLegacyRun = true;
8890
bool m_enforceViaYul = false;
91+
bool m_enforceCompileToEwasm = false;
8992
bool m_runWithABIEncoderV1Only = false;
9093
bool m_allowNonExistingFunctions = false;
91-
bool m_compileViaYulCanBeSet = false;
94+
bool m_canEnableYulRun = false;
95+
bool m_canEnableEwasmRun = false;
9296
std::map<std::string, Builtin> m_builtins{};
9397

9498
bool m_gasCostFailure = false;

test/tools/isoltest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ TestTool::Result TestTool::process()
163163
m_options.evmVersion(),
164164
m_options.vmPaths,
165165
m_options.enforceViaYul,
166+
m_options.enforceCompileToEwasm,
166167
m_options.enforceGasTest,
167168
m_options.enforceGasTestMinValue
168169
});

0 commit comments

Comments
 (0)