mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Refactor Env for AbstractClient:
Env is changed to use the AbstractClient interface, which generalizes the transport for submitting client requests to the Env server instance. The JSONRPCClient implementation is added, supporting a simple, synchronous interface. Env is changed to use the JSONRPCClient implementation instead of the built in JSON-RPC client.
This commit is contained in:
committed by
Nik Bougalis
parent
f9f2b8124d
commit
040d7ebb46
@@ -3406,16 +3406,24 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClInclude Include="..\..\src\ripple\shamap\TreeNodeCache.h">
|
<ClInclude Include="..\..\src\ripple\shamap\TreeNodeCache.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\AbstractClient.h">
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\BasicNetwork.h">
|
<ClInclude Include="..\..\src\ripple\test\BasicNetwork.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ripple\test\impl\BasicNetwork_test.cpp">
|
<ClCompile Include="..\..\src\ripple\test\impl\BasicNetwork_test.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\ripple\test\impl\JSONRPCClient.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple\test\impl\ManualTimeKeeper.cpp">
|
<ClCompile Include="..\..\src\ripple\test\impl\ManualTimeKeeper.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\JSONRPCClient.h">
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\Account.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\Account.h">
|
||||||
|
|||||||
@@ -3915,15 +3915,24 @@
|
|||||||
<ClInclude Include="..\..\src\ripple\shamap\TreeNodeCache.h">
|
<ClInclude Include="..\..\src\ripple\shamap\TreeNodeCache.h">
|
||||||
<Filter>ripple\shamap</Filter>
|
<Filter>ripple\shamap</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\AbstractClient.h">
|
||||||
|
<Filter>ripple\test</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\BasicNetwork.h">
|
<ClInclude Include="..\..\src\ripple\test\BasicNetwork.h">
|
||||||
<Filter>ripple\test</Filter>
|
<Filter>ripple\test</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClCompile Include="..\..\src\ripple\test\impl\BasicNetwork_test.cpp">
|
<ClCompile Include="..\..\src\ripple\test\impl\BasicNetwork_test.cpp">
|
||||||
<Filter>ripple\test\impl</Filter>
|
<Filter>ripple\test\impl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\ripple\test\impl\JSONRPCClient.cpp">
|
||||||
|
<Filter>ripple\test\impl</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\ripple\test\impl\ManualTimeKeeper.cpp">
|
<ClCompile Include="..\..\src\ripple\test\impl\ManualTimeKeeper.cpp">
|
||||||
<Filter>ripple\test\impl</Filter>
|
<Filter>ripple\test\impl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\JSONRPCClient.h">
|
||||||
|
<Filter>ripple\test</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx.h">
|
||||||
<Filter>ripple\test</Filter>
|
<Filter>ripple\test</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -74,13 +74,11 @@ struct Transaction_ordering_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto const result = env.rpc("tx", to_string(tx1.stx->getTransactionID()));
|
auto const result = env.rpc("tx", to_string(tx1.stx->getTransactionID()));
|
||||||
expect(result.first == rpcSUCCESS);
|
expect(result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
||||||
expect(result.second["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto const result = env.rpc("tx", to_string(tx2.stx->getTransactionID()));
|
auto const result = env.rpc("tx", to_string(tx2.stx->getTransactionID()));
|
||||||
expect(result.first == rpcSUCCESS);
|
expect(result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
||||||
expect(result.second["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,13 +110,11 @@ struct Transaction_ordering_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
{
|
{
|
||||||
auto const result = env.rpc("tx", to_string(tx1.stx->getTransactionID()));
|
auto const result = env.rpc("tx", to_string(tx1.stx->getTransactionID()));
|
||||||
expect(result.first == rpcSUCCESS);
|
expect(result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
||||||
expect(result.second["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto const result = env.rpc("tx", to_string(tx2.stx->getTransactionID()));
|
auto const result = env.rpc("tx", to_string(tx2.stx->getTransactionID()));
|
||||||
expect(result.first == rpcSUCCESS);
|
expect(result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
||||||
expect(result.second["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,8 +156,7 @@ struct Transaction_ordering_test : public beast::unit_test::suite
|
|||||||
for (auto i = 0; i < 5; ++i)
|
for (auto i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
auto const result = env.rpc("tx", to_string(tx[i].stx->getTransactionID()));
|
auto const result = env.rpc("tx", to_string(tx[i].stx->getTransactionID()));
|
||||||
expect(result.first == rpcSUCCESS);
|
expect(result["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
||||||
expect(result.second["result"]["meta"]["TransactionResult"] == "tesSUCCESS");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
58
src/ripple/test/AbstractClient.h
Normal file
58
src/ripple/test/AbstractClient.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2016 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_TEST_ABSTRACTCLIENT_H_INCLUDED
|
||||||
|
#define RIPPLE_TEST_ABSTRACTCLIENT_H_INCLUDED
|
||||||
|
|
||||||
|
#include <ripple/json/json_value.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
/* Abstract Ripple Client interface.
|
||||||
|
|
||||||
|
This abstracts the transport layer, allowing
|
||||||
|
commands to be submitted to a rippled server.
|
||||||
|
*/
|
||||||
|
class AbstractClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~AbstractClient() = default;
|
||||||
|
|
||||||
|
/** Submit a command synchronously.
|
||||||
|
|
||||||
|
The arguments to the function and the returned JSON
|
||||||
|
are in a normalized format, the same whether the client
|
||||||
|
is using the JSON-RPC over HTTP/S or WebSocket transport.
|
||||||
|
|
||||||
|
@param cmd The command to execute
|
||||||
|
@param params Json::Value of null or object type
|
||||||
|
with zero or more key/value pairs.
|
||||||
|
@return The server response in normalized format.
|
||||||
|
*/
|
||||||
|
virtual
|
||||||
|
Json::Value
|
||||||
|
invoke(std::string const& cmd,
|
||||||
|
Json::Value const& params = {}) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // test
|
||||||
|
} // ripple
|
||||||
|
|
||||||
|
#endif
|
||||||
37
src/ripple/test/JSONRPCClient.h
Normal file
37
src/ripple/test/JSONRPCClient.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2016 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_TEST_HTTPCLIENT_H_INCLUDED
|
||||||
|
#define RIPPLE_TEST_HTTPCLIENT_H_INCLUDED
|
||||||
|
|
||||||
|
#include <ripple/test/AbstractClient.h>
|
||||||
|
#include <ripple/core/Config.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
/** Returns a client using JSON-RPC over HTTP/S. */
|
||||||
|
std::unique_ptr<AbstractClient>
|
||||||
|
makeJSONRPCClient(Config const& cfg);
|
||||||
|
|
||||||
|
} // test
|
||||||
|
} // ripple
|
||||||
|
|
||||||
|
#endif
|
||||||
164
src/ripple/test/impl/JSONRPCClient.cpp
Normal file
164
src/ripple/test/impl/JSONRPCClient.cpp
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2016 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <BeastConfig.h>
|
||||||
|
#include <ripple/test/JSONRPCClient.h>
|
||||||
|
#include <ripple/json/json_reader.h>
|
||||||
|
#include <ripple/json/to_string.h>
|
||||||
|
#include <ripple/server/Port.h>
|
||||||
|
#include <beast/asio/streambuf.h>
|
||||||
|
#include <beast/http/parser.h>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
class JSONRPCClient : public AbstractClient
|
||||||
|
{
|
||||||
|
static
|
||||||
|
boost::asio::ip::tcp::endpoint
|
||||||
|
getEndpoint(BasicConfig const& cfg)
|
||||||
|
{
|
||||||
|
auto& log = std::cerr;
|
||||||
|
ParsedPort common;
|
||||||
|
parse_Port (common, cfg["server"], log);
|
||||||
|
for (auto const& name : cfg.section("server").values())
|
||||||
|
{
|
||||||
|
if (! cfg.exists(name))
|
||||||
|
continue;
|
||||||
|
ParsedPort pp;
|
||||||
|
parse_Port(pp, cfg[name], log);
|
||||||
|
if(pp.protocol.count("http") == 0)
|
||||||
|
continue;
|
||||||
|
using boost::asio::ip::address_v4;
|
||||||
|
if(*pp.ip == address_v4{0x00000000})
|
||||||
|
*pp.ip = address_v4{0x7f000001};
|
||||||
|
return { *pp.ip, *pp.port };
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Missing HTTP port");
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class ConstBufferSequence>
|
||||||
|
static
|
||||||
|
std::string
|
||||||
|
buffer_string (ConstBufferSequence const& b)
|
||||||
|
{
|
||||||
|
using namespace boost::asio;
|
||||||
|
std::string s;
|
||||||
|
s.resize(buffer_size(b));
|
||||||
|
buffer_copy(buffer(&s[0], s.size()), b);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::io_service ios_;
|
||||||
|
boost::asio::ip::tcp::socket stream_;
|
||||||
|
boost::asio::streambuf bin_;
|
||||||
|
beast::asio::streambuf bout_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit
|
||||||
|
JSONRPCClient(Config const& cfg)
|
||||||
|
: stream_(ios_)
|
||||||
|
{
|
||||||
|
stream_.connect(getEndpoint(cfg));
|
||||||
|
}
|
||||||
|
|
||||||
|
~JSONRPCClient() override
|
||||||
|
{
|
||||||
|
//stream_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||||
|
//stream_.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return value is an Object type with up to three keys:
|
||||||
|
status
|
||||||
|
error
|
||||||
|
result
|
||||||
|
*/
|
||||||
|
Json::Value
|
||||||
|
invoke(std::string const& cmd,
|
||||||
|
Json::Value const& params) override
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
{
|
||||||
|
Json::Value jr;
|
||||||
|
jr["method"] = cmd;
|
||||||
|
if(params)
|
||||||
|
{
|
||||||
|
Json::Value& ja = jr["params"] = Json::arrayValue;
|
||||||
|
ja.append(params);
|
||||||
|
}
|
||||||
|
s = to_string(jr);
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace boost::asio;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
std::string r;
|
||||||
|
r =
|
||||||
|
"POST / HTTP/1.1\r\n"
|
||||||
|
"Host: me\r\n"
|
||||||
|
"Connection: Keep-Alive\r\n"s +
|
||||||
|
"Content-Type: application/json; charset=UTF-8\r\n"s +
|
||||||
|
"Content-Length: " + std::to_string(s.size()) + "\r\n"
|
||||||
|
"\r\n";
|
||||||
|
write(stream_, buffer(r));
|
||||||
|
write(stream_, buffer(s));
|
||||||
|
|
||||||
|
read_until(stream_, bin_, "\r\n\r\n");
|
||||||
|
beast::asio::streambuf body;
|
||||||
|
beast::http::message m;
|
||||||
|
beast::http::parser p(
|
||||||
|
[&](void const* data, std::size_t size)
|
||||||
|
{
|
||||||
|
body.commit(buffer_copy(
|
||||||
|
body.prepare(size), const_buffer(data, size)));
|
||||||
|
}, m, false);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
auto const result = p.write(bin_.data());
|
||||||
|
if (result.first)
|
||||||
|
throw result.first;
|
||||||
|
bin_.consume(result.second);
|
||||||
|
if(p.complete())
|
||||||
|
break;
|
||||||
|
bin_.commit(stream_.read_some(
|
||||||
|
bin_.prepare(1024)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Reader jr;
|
||||||
|
Json::Value jv;
|
||||||
|
jr.parse(buffer_string(body.data()), jv);
|
||||||
|
if(jv["result"].isMember("error"))
|
||||||
|
jv["error"] = jv["result"]["error"];
|
||||||
|
if(jv["result"].isMember("status"))
|
||||||
|
jv["status"] = jv["result"]["status"];
|
||||||
|
return jv;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<AbstractClient>
|
||||||
|
makeJSONRPCClient(Config const& cfg)
|
||||||
|
{
|
||||||
|
return std::make_unique<JSONRPCClient>(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // test
|
||||||
|
} // ripple
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <ripple/test/jtx/JTx.h>
|
#include <ripple/test/jtx/JTx.h>
|
||||||
#include <ripple/test/jtx/require.h>
|
#include <ripple/test/jtx/require.h>
|
||||||
#include <ripple/test/jtx/tags.h>
|
#include <ripple/test/jtx/tags.h>
|
||||||
|
#include <ripple/test/AbstractClient.h>
|
||||||
#include <ripple/test/ManualTimeKeeper.h>
|
#include <ripple/test/ManualTimeKeeper.h>
|
||||||
#include <ripple/app/main/Application.h>
|
#include <ripple/app/main/Application.h>
|
||||||
#include <ripple/app/ledger/Ledger.h>
|
#include <ripple/app/ledger/Ledger.h>
|
||||||
@@ -36,7 +37,6 @@
|
|||||||
#include <ripple/json/json_value.h>
|
#include <ripple/json/json_value.h>
|
||||||
#include <ripple/json/to_string.h>
|
#include <ripple/json/to_string.h>
|
||||||
#include <ripple/ledger/CachedSLEs.h>
|
#include <ripple/ledger/CachedSLEs.h>
|
||||||
#include <ripple/net/RPCCall.h>
|
|
||||||
#include <ripple/protocol/Indexes.h>
|
#include <ripple/protocol/Indexes.h>
|
||||||
#include <ripple/protocol/Issue.h>
|
#include <ripple/protocol/Issue.h>
|
||||||
#include <ripple/protocol/STAmount.h>
|
#include <ripple/protocol/STAmount.h>
|
||||||
@@ -99,6 +99,7 @@ private:
|
|||||||
std::unique_ptr<Application> owned;
|
std::unique_ptr<Application> owned;
|
||||||
ManualTimeKeeper* timeKeeper;
|
ManualTimeKeeper* timeKeeper;
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
|
std::unique_ptr<AbstractClient> client;
|
||||||
|
|
||||||
AppBundle (std::unique_ptr<Config> config);
|
AppBundle (std::unique_ptr<Config> config);
|
||||||
AppBundle (Application* app_);
|
AppBundle (Application* app_);
|
||||||
@@ -161,7 +162,6 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Application&
|
Application&
|
||||||
app()
|
app()
|
||||||
{
|
{
|
||||||
@@ -185,6 +185,22 @@ public:
|
|||||||
return app().timeKeeper().now();
|
return app().timeKeeper().now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the connected client. */
|
||||||
|
AbstractClient&
|
||||||
|
client()
|
||||||
|
{
|
||||||
|
return *bundle_.client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Execute an RPC command.
|
||||||
|
|
||||||
|
The command is examined and used to build
|
||||||
|
the correct JSON as per the arguments.
|
||||||
|
*/
|
||||||
|
template<class... Args>
|
||||||
|
Json::Value
|
||||||
|
rpc(std::string const& cmd, Args&&... args);
|
||||||
|
|
||||||
/** Returns the current ledger.
|
/** Returns the current ledger.
|
||||||
|
|
||||||
This is a non-modifiable snapshot of the
|
This is a non-modifiable snapshot of the
|
||||||
@@ -423,11 +439,6 @@ public:
|
|||||||
std::shared_ptr<STObject const>
|
std::shared_ptr<STObject const>
|
||||||
meta();
|
meta();
|
||||||
|
|
||||||
/** Execute a client command */
|
|
||||||
template <class Arg, class... Args>
|
|
||||||
std::pair<int, Json::Value>
|
|
||||||
rpc (Arg&& arg0, Args&&... args);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
void
|
||||||
fund (bool setDefaultRipple,
|
fund (bool setDefaultRipple,
|
||||||
@@ -534,6 +545,9 @@ protected:
|
|||||||
uint256 txid_;
|
uint256 txid_;
|
||||||
TER ter_ = tesSUCCESS;
|
TER ter_ = tesSUCCESS;
|
||||||
|
|
||||||
|
Json::Value
|
||||||
|
do_rpc(std::vector<std::string> const& args);
|
||||||
|
|
||||||
void
|
void
|
||||||
autofill_sig (JTx& jt);
|
autofill_sig (JTx& jt);
|
||||||
|
|
||||||
@@ -628,16 +642,13 @@ protected:
|
|||||||
AccountID, Account> map_;
|
AccountID, Account> map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
template<class... Args>
|
||||||
|
Json::Value
|
||||||
template <class Arg, class... Args>
|
Env::rpc(std::string const& cmd, Args&&... args)
|
||||||
std::pair<int, Json::Value>
|
|
||||||
Env::rpc (Arg&& arg0, Args&&... args)
|
|
||||||
{
|
{
|
||||||
std::vector<std::string> v({ std::forward<Arg>(arg0),
|
std::vector<std::string> vs{cmd,
|
||||||
std::forward<Args>(args)... });
|
std::forward<Args>(args)...};
|
||||||
return rpcClient(v,
|
return do_rpc(vs);
|
||||||
app().config(), app().logs());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // jtx
|
} // jtx
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <ripple/test/jtx/seq.h>
|
#include <ripple/test/jtx/seq.h>
|
||||||
#include <ripple/test/jtx/sig.h>
|
#include <ripple/test/jtx/sig.h>
|
||||||
#include <ripple/test/jtx/utility.h>
|
#include <ripple/test/jtx/utility.h>
|
||||||
|
#include <ripple/test/JSONRPCClient.h>
|
||||||
#include <ripple/app/ledger/LedgerMaster.h>
|
#include <ripple/app/ledger/LedgerMaster.h>
|
||||||
#include <ripple/app/ledger/LedgerTiming.h>
|
#include <ripple/app/ledger/LedgerTiming.h>
|
||||||
#include <ripple/app/misc/NetworkOPs.h>
|
#include <ripple/app/misc/NetworkOPs.h>
|
||||||
@@ -37,6 +38,7 @@
|
|||||||
#include <ripple/core/ConfigSections.h>
|
#include <ripple/core/ConfigSections.h>
|
||||||
#include <ripple/json/to_string.h>
|
#include <ripple/json/to_string.h>
|
||||||
#include <ripple/net/HTTPClient.h>
|
#include <ripple/net/HTTPClient.h>
|
||||||
|
#include <ripple/net/RPCCall.h>
|
||||||
#include <ripple/protocol/ErrorCodes.h>
|
#include <ripple/protocol/ErrorCodes.h>
|
||||||
#include <ripple/protocol/HashPrefix.h>
|
#include <ripple/protocol/HashPrefix.h>
|
||||||
#include <ripple/protocol/Indexes.h>
|
#include <ripple/protocol/Indexes.h>
|
||||||
@@ -54,26 +56,29 @@ namespace ripple {
|
|||||||
namespace test {
|
namespace test {
|
||||||
|
|
||||||
void
|
void
|
||||||
setupConfigForUnitTests (Config& config)
|
setupConfigForUnitTests (Config& cfg)
|
||||||
{
|
{
|
||||||
config.overwrite (ConfigSection::nodeDatabase (), "type", "memory");
|
cfg.overwrite (ConfigSection::nodeDatabase (), "type", "memory");
|
||||||
config.overwrite (ConfigSection::nodeDatabase (), "path", "main");
|
cfg.overwrite (ConfigSection::nodeDatabase (), "path", "main");
|
||||||
|
cfg.deprecatedClearSection (ConfigSection::importNodeDatabase ());
|
||||||
config.deprecatedClearSection (ConfigSection::importNodeDatabase ());
|
cfg.legacy("database_path", "");
|
||||||
config.legacy("database_path", "");
|
cfg.RUN_STANDALONE = true;
|
||||||
|
cfg.QUIET = true;
|
||||||
config.RUN_STANDALONE = true;
|
cfg.SILENT = true;
|
||||||
config.QUIET = true;
|
cfg["server"].append("port_peer");
|
||||||
config.SILENT = true;
|
cfg["port_peer"].set("ip", "127.0.0.1");
|
||||||
config["server"].append("port_peer");
|
cfg["port_peer"].set("port", "8080");
|
||||||
config["port_peer"].set("ip", "127.0.0.1");
|
cfg["port_peer"].set("protocol", "peer");
|
||||||
config["port_peer"].set("port", "8080");
|
cfg["server"].append("port_http");
|
||||||
config["port_peer"].set("protocol", "peer");
|
cfg["port_http"].set("ip", "127.0.0.1");
|
||||||
config["server"].append("port_admin");
|
cfg["port_http"].set("port", "8081");
|
||||||
config["port_admin"].set("ip", "127.0.0.1");
|
cfg["port_http"].set("protocol", "http");
|
||||||
config["port_admin"].set("port", "8081");
|
cfg["port_http"].set("admin", "127.0.0.1");
|
||||||
config["port_admin"].set("protocol", "http");
|
cfg["server"].append("port_ws");
|
||||||
config["port_admin"].set("admin", "127.0.0.1");
|
cfg["port_ws"].set("ip", "127.0.0.1");
|
||||||
|
cfg["port_ws"].set("port", "8082");
|
||||||
|
cfg["port_ws"].set("protocol", "ws");
|
||||||
|
cfg["port_ws"].set("admin", "127.0.0.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -102,10 +107,13 @@ Env::AppBundle::AppBundle(std::unique_ptr<Config> config)
|
|||||||
app->doStart();
|
app->doStart();
|
||||||
thread = std::thread(
|
thread = std::thread(
|
||||||
[&](){ app->run(); });
|
[&](){ app->run(); });
|
||||||
|
|
||||||
|
client = makeJSONRPCClient(app->config());
|
||||||
}
|
}
|
||||||
|
|
||||||
Env::AppBundle::~AppBundle()
|
Env::AppBundle::~AppBundle()
|
||||||
{
|
{
|
||||||
|
client.reset();
|
||||||
app->signalStop();
|
app->signalStop();
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
@@ -131,8 +139,8 @@ Env::close(NetClock::time_point closeTime,
|
|||||||
app().getOPs().acceptLedger(consensusDelay);
|
app().getOPs().acceptLedger(consensusDelay);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto const result = rpc("ledger_accept");
|
rpc("ledger_accept");
|
||||||
test.expect(result.first == rpcSUCCESS);
|
// VFALCO No error check?
|
||||||
}
|
}
|
||||||
bundle_.timeKeeper->set(
|
bundle_.timeKeeper->set(
|
||||||
closed()->info().closeTime);
|
closed()->info().closeTime);
|
||||||
@@ -274,11 +282,10 @@ Env::submit (JTx const& jt)
|
|||||||
txid_ = jt.stx->getTransactionID();
|
txid_ = jt.stx->getTransactionID();
|
||||||
Serializer s;
|
Serializer s;
|
||||||
jt.stx->add(s);
|
jt.stx->add(s);
|
||||||
auto const result = rpc("submit", strHex(s.slice()));
|
auto const jr = rpc("submit", strHex(s.slice()));
|
||||||
if (result.first == rpcSUCCESS &&
|
if (jr["result"].isMember("engine_result_code"))
|
||||||
result.second["result"].isMember("engine_result_code"))
|
|
||||||
ter_ = static_cast<TER>(
|
ter_ = static_cast<TER>(
|
||||||
result.second["result"]["engine_result_code"].asInt());
|
jr["result"]["engine_result_code"].asInt());
|
||||||
else
|
else
|
||||||
ter_ = temINVALID;
|
ter_ = temINVALID;
|
||||||
didApply = isTesSuccess(ter_) || isTecClaim(ter_);
|
didApply = isTesSuccess(ter_) || isTecClaim(ter_);
|
||||||
@@ -408,6 +415,14 @@ Env::applyFlags() const
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Json::Value
|
||||||
|
Env::do_rpc(std::vector<std::string> const& args)
|
||||||
|
{
|
||||||
|
auto const jv = cmdLineToJSONRPC(args, journal);
|
||||||
|
return client().invoke(jv["method"].asString(),
|
||||||
|
jv["params"][0U]);
|
||||||
|
}
|
||||||
|
|
||||||
} // jtx
|
} // jtx
|
||||||
|
|
||||||
} // test
|
} // test
|
||||||
|
|||||||
@@ -48,4 +48,5 @@
|
|||||||
#include <ripple/test/mao/impl/Net.cpp>
|
#include <ripple/test/mao/impl/Net.cpp>
|
||||||
|
|
||||||
#include <ripple/test/impl/BasicNetwork_test.cpp>
|
#include <ripple/test/impl/BasicNetwork_test.cpp>
|
||||||
|
#include <ripple/test/impl/JSONRPCClient.cpp>
|
||||||
#include <ripple/test/impl/ManualTimeKeeper.cpp>
|
#include <ripple/test/impl/ManualTimeKeeper.cpp>
|
||||||
|
|||||||
Reference in New Issue
Block a user