diff options
author | Leonardo Alt <leo@ethereum.org> | 2018-11-15 23:47:52 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2018-11-23 18:51:06 +0800 |
commit | 0ff4cbe51ba653397a1937c8c08b3d09541492ef (patch) | |
tree | 03a8798bca8f2ef221d77fc8a4c6c5390105800c /test/libsolidity/SMTCheckerJSONTest.cpp | |
parent | 6251a289dd55cc54f8da5a907dc4982a4b5e57fa (diff) | |
download | dexon-solidity-0ff4cbe51ba653397a1937c8c08b3d09541492ef.tar dexon-solidity-0ff4cbe51ba653397a1937c8c08b3d09541492ef.tar.gz dexon-solidity-0ff4cbe51ba653397a1937c8c08b3d09541492ef.tar.bz2 dexon-solidity-0ff4cbe51ba653397a1937c8c08b3d09541492ef.tar.lz dexon-solidity-0ff4cbe51ba653397a1937c8c08b3d09541492ef.tar.xz dexon-solidity-0ff4cbe51ba653397a1937c8c08b3d09541492ef.tar.zst dexon-solidity-0ff4cbe51ba653397a1937c8c08b3d09541492ef.zip |
Add SMTChecker tests for standard JSON
Diffstat (limited to 'test/libsolidity/SMTCheckerJSONTest.cpp')
-rw-r--r-- | test/libsolidity/SMTCheckerJSONTest.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/test/libsolidity/SMTCheckerJSONTest.cpp b/test/libsolidity/SMTCheckerJSONTest.cpp new file mode 100644 index 00000000..6e1329a9 --- /dev/null +++ b/test/libsolidity/SMTCheckerJSONTest.cpp @@ -0,0 +1,128 @@ +/* + 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/>. +*/ + +#include <test/libsolidity/SMTCheckerJSONTest.h> +#include <test/Options.h> +#include <libsolidity/interface/StandardCompiler.h> +#include <libdevcore/JSON.h> +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/join.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/throw_exception.hpp> +#include <fstream> +#include <memory> +#include <stdexcept> +#include <sstream> + +using namespace dev; +using namespace solidity; +using namespace dev::solidity::test; +using namespace dev::solidity::test::formatting; +using namespace std; +using namespace boost::unit_test; + +SMTCheckerTest::SMTCheckerTest(string const& _filename) +: SyntaxTest(_filename) +{ + BOOST_REQUIRE_MESSAGE(boost::algorithm::ends_with(_filename, ".sol"), "Invalid test contract file name: \"" + _filename + "\"."); + + string jsonFilename = _filename.substr(0, _filename.size() - 4) + ".json"; + BOOST_CHECK(jsonParseFile(jsonFilename, m_smtResponses)); + BOOST_CHECK(m_smtResponses.isObject()); +} + +bool SMTCheckerTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted) +{ + StandardCompiler compiler; + + // Run the compiler and retrieve the smtlib2queries (1st run) + string versionPragma = "pragma solidity >=0.0;\n"; + Json::Value input = buildJson(versionPragma); + Json::Value result = compiler.compile(input); + + // This is the list of query hashes requested by the 1st run + vector<string> outHashes = hashesFromJson(result, "auxiliaryInputRequested", "smtlib2queries"); + + // This is the list of responses provided in the test + string auxInput("auxiliaryInput"); + BOOST_CHECK(m_smtResponses.isMember(auxInput)); + vector<string> inHashes = hashesFromJson(m_smtResponses, auxInput, "smtlib2responses"); + + // Ensure that the provided list matches the requested one + BOOST_CHECK_MESSAGE( + outHashes == inHashes, + "SMT query hashes differ: " + boost::algorithm::join(outHashes, ", ") + " x " + boost::algorithm::join(inHashes, ", ") + ); + + // Rerun the compiler with the provided hashed (2nd run) + input[auxInput] = m_smtResponses[auxInput]; + Json::Value endResult = compiler.compile(input); + + BOOST_CHECK(endResult.isMember("errors")); + Json::Value const& errors = endResult["errors"]; + for (auto const& error: errors) + { + BOOST_CHECK(error.isMember("type") && error["type"].isString()); + BOOST_CHECK(error.isMember("message") && error["message"].isString()); + if (!error.isMember("sourceLocation")) + continue; + Json::Value const& location = error["sourceLocation"]; + BOOST_CHECK(location.isMember("start") && location["start"].isInt()); + BOOST_CHECK(location.isMember("end") && location["end"].isInt()); + int start = location["start"].asInt(); + int end = location["end"].asInt(); + if (start >= static_cast<int>(versionPragma.size())) + start -= versionPragma.size(); + if (end >= static_cast<int>(versionPragma.size())) + end -= versionPragma.size(); + m_errorList.emplace_back(SyntaxTestError{ + error["type"].asString(), + error["message"].asString(), + start, + end + }); + } + + return printExpectationAndError(_stream, _linePrefix, _formatted); +} + +vector<string> SMTCheckerTest::hashesFromJson(Json::Value const& _jsonObj, string const& _auxInput, string const& _smtlib) +{ + vector<string> hashes; + Json::Value const& auxInputs = _jsonObj[_auxInput]; + if (!!auxInputs) + { + Json::Value const& smtlib = auxInputs[_smtlib]; + if (!!smtlib) + for (auto const& hashString: smtlib.getMemberNames()) + hashes.push_back(hashString); + } + return hashes; +} + +Json::Value SMTCheckerTest::buildJson(string const& _extra) +{ + string language = "\"language\": \"Solidity\""; + string sourceName = "\"A\""; + string sourceContent = "\"" + _extra + m_source + "\""; + string sourceObj = "{ \"content\": " + sourceContent + "}"; + string sources = " \"sources\": { " + sourceName + ": " + sourceObj + "}"; + string input = "{" + language + ", " + sources + "}"; + Json::Value source; + BOOST_REQUIRE(jsonParse(input, source)); + return source; +} |