1 /* 2 This file is part of solidity. 3 solidity is free software: you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation, either version 3 of the License, or 6 (at your option) any later version. 7 solidity is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11 You should have received a copy of the GNU General Public License 12 along with solidity. If not, see <http://www.gnu.org/licenses/>. 13 */ 14 15 #pragma once 16 17 #include <test/libsolidity/util/TestFileParser.h> 18 #include <test/libsolidity/util/TestFunctionCall.h> 19 #include <test/libsolidity/SolidityExecutionFramework.h> 20 #include <test/libsolidity/AnalysisFramework.h> 21 #include <test/TestCase.h> 22 #include <liblangutil/Exceptions.h> 23 #include <libsolutil/AnsiColorized.h> 24 25 #include <iosfwd> 26 #include <string> 27 #include <vector> 28 #include <utility> 29 30 namespace solidity::frontend::test 31 { 32 33 struct AnnotatedEventSignature 34 { 35 std::string signature; 36 std::vector<std::string> indexedTypes; 37 std::vector<std::string> nonIndexedTypes; 38 }; 39 40 /** 41 * Class that represents a semantic test (or end-to-end test) and allows running it as part of the 42 * boost unit test environment or isoltest. It reads the Solidity source and an additional comment 43 * section from the given file. This comment section should define a set of functions to be called 44 * and an expected result they return after being executed. 45 */ 46 class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrictedTestCase 47 { 48 public: create(Config const & _options)49 static std::unique_ptr<TestCase> create(Config const& _options) 50 { 51 return std::make_unique<SemanticTest>( 52 _options.filename, 53 _options.evmVersion, 54 _options.vmPaths, 55 _options.enforceCompileViaYul, 56 _options.enforceCompileToEwasm, 57 _options.enforceGasCost, 58 _options.enforceGasCostMinValue 59 ); 60 } 61 62 explicit SemanticTest( 63 std::string const& _filename, 64 langutil::EVMVersion _evmVersion, 65 std::vector<boost::filesystem::path> const& _vmPaths, 66 bool _enforceViaYul = false, 67 bool _enforceCompileToEwasm = false, 68 bool _enforceGasCost = false, 69 u256 _enforceGasCostMinValue = 100000 70 ); 71 72 TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool _formatted = false) override; 73 void printSource(std::ostream &_stream, std::string const& _linePrefix = "", bool _formatted = false) const override; 74 void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix = "") const override; 75 void printUpdatedSettings(std::ostream& _stream, std::string const& _linePrefix = "") override; 76 77 /// Instantiates a test file parser that parses the additional comment section at the end of 78 /// the input stream \param _stream. Each function call is represented using a `FunctionCallTest` 79 /// and added to the list of call to be executed when `run()` is called. 80 /// Throws if parsing expectations failed. 81 void parseExpectations(std::istream& _stream); 82 83 /// Compiles and deploys currently held source. 84 /// Returns true if deployment was successful, false otherwise. 85 bool deploy(std::string const& _contractName, u256 const& _value, bytes const& _arguments, std::map<std::string, solidity::test::Address> const& _libraries = {}); 86 87 private: 88 TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _isYulRun, bool _isEwasmRun); 89 bool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const; 90 std::map<std::string, Builtin> makeBuiltins(); 91 std::vector<SideEffectHook> makeSideEffectHooks() const; 92 std::vector<std::string> eventSideEffectHook(FunctionCall const&) const; 93 std::optional<AnnotatedEventSignature> matchEvent(util::h256 const& hash) const; 94 static std::string formatEventParameter(std::optional<AnnotatedEventSignature> _signature, bool _indexed, size_t _index, bytes const& _data); 95 SourceMap m_sources; 96 std::size_t m_lineOffset; 97 std::vector<TestFunctionCall> m_tests; 98 std::map<std::string, Builtin> const m_builtins; 99 std::vector<SideEffectHook> const m_sideEffectHooks; 100 bool m_testCaseWantsYulRun = false; 101 bool m_testCaseWantsEwasmRun = false; 102 bool m_testCaseWantsLegacyRun = true; 103 bool m_enforceViaYul = false; 104 bool m_enforceCompileToEwasm = false; 105 bool m_runWithABIEncoderV1Only = false; 106 bool m_allowNonExistingFunctions = false; 107 bool m_canEnableYulRun = false; 108 bool m_canEnableEwasmRun = false; 109 bool m_gasCostFailure = false; 110 bool m_enforceGasCost = false; 111 u256 m_enforceGasCostMinValue; 112 }; 113 114 } 115