start writing unit tests for SetHook

This commit is contained in:
Richard Holland
2022-08-29 10:42:19 +00:00
parent 8d85c87233
commit 5123736c51
6 changed files with 241 additions and 0 deletions

View File

@@ -733,6 +733,7 @@ if (tests)
src/test/app/ValidatorKeys_test.cpp
src/test/app/ValidatorList_test.cpp
src/test/app/ValidatorSite_test.cpp
src/test/app/SetHook_test.cpp
src/test/app/tx/apply_test.cpp
#[===============================[
test sources:
@@ -832,6 +833,7 @@ if (tests)
src/test/jtx/impl/JSONRPCClient.cpp
src/test/jtx/impl/ManualTimeKeeper.cpp
src/test/jtx/impl/WSClient.cpp
src/test/jtx/impl/hook.cpp
src/test/jtx/impl/acctdelete.cpp
src/test/jtx/impl/account_txn_id.cpp
src/test/jtx/impl/amount.cpp

View File

@@ -54,6 +54,7 @@ JSS(CheckCancel); // transaction type.
JSS(CheckCash); // transaction type.
JSS(CheckCreate); // transaction type.
JSS(ClearFlag); // field.
JSS(CreateCode); // field.
JSS(DeliverMin); // in: TransactionSign
JSS(DepositPreauth); // transaction and ledger type.
JSS(Destination); // in: TransactionSign; field.
@@ -68,6 +69,10 @@ JSS(Fee); // in/out: TransactionSign; field.
JSS(FeeSettings); // ledger type.
JSS(Flags); // in/out: TransactionSign; field.
JSS(incomplete_shards); // out: OverlayImpl, PeerImp
JSS(HookApiVersion); // field
JSS(HookNamespace); // field
JSS(HookOn); // field
JSS(Hooks); // field
JSS(Invalid); //
JSS(LastLedgerSequence); // in: TransactionSign; field
JSS(LedgerHashes); // ledger type.

View File

@@ -0,0 +1,111 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012-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 <ripple/protocol/TxFlags.h>
#include <ripple/protocol/jss.h>
#include <test/jtx.h>
#include <test/jtx/hook.h>
namespace ripple {
namespace test {
class SetHook_test : public beast::unit_test::suite
{
private:
std::vector<uint8_t> const
accept_wasm =
{
/*
(module
(type (;0;) (func (param i32 i32 i64) (result i64)))
(type (;1;) (func (param i32 i32) (result i32)))
(type (;2;) (func (param i32) (result i64)))
(import "env" "accept" (func (;0;) (type 0)))
(import "env" "_g" (func (;1;) (type 1)))
(func (;2;) (type 2) (param i32) (result i64)
(local i32)
i32.const 0
i32.const 0
i64.const 0
call 0
drop
i32.const 1
i32.const 1
call 1
drop
i64.const 0)
(memory (;0;) 2)
(export "hook" (func 2)))
*/
0x00U,0x61U,0x73U,0x6dU,0x01U,0x00U,0x00U,0x00U,0x01U,0x13U,0x03U,0x60U,0x03U,0x7fU,0x7fU,0x7eU,0x01U,0x7eU,
0x60U,0x02U,0x7fU,0x7fU,0x01U,0x7fU,0x60U,0x01U,0x7fU,0x01U,0x7eU,0x02U,0x17U,0x02U,0x03U,0x65U,0x6eU,0x76U,
0x06U,0x61U,0x63U,0x63U,0x65U,0x70U,0x74U,0x00U,0x00U,0x03U,0x65U,0x6eU,0x76U,0x02U,0x5fU,0x67U,0x00U,0x01U,
0x03U,0x02U,0x01U,0x02U,0x05U,0x03U,0x01U,0x00U,0x02U,0x07U,0x08U,0x01U,0x04U,0x68U,0x6fU,0x6fU,0x6bU,0x00U,
0x02U,0x0aU,0x18U,0x01U,0x16U,0x01U,0x01U,0x7fU,0x41U,0x00U,0x41U,0x00U,0x42U,0x00U,0x10U,0x00U,0x1aU,0x41U,
0x01U,0x41U,0x01U,0x10U,0x01U,0x1aU,0x42U,0x00U,0x0bU
};
public:
void
testHooksDisabled()
{
testcase("SetHook checks for disabled amendment");
using namespace jtx;
Env env{*this, supported_amendments() - featureHooks};
auto const alice = Account{"alice"};
env.fund(XRP(10000), alice);
env(ripple::test::jtx::hook(alice, {}, 0), ter(temDISABLED));
}
void
testMalformedTransaction()
{
testcase("SetHook checks for malformed transactions");
using namespace jtx;
Env env{*this, supported_amendments()};
auto const alice = Account{"alice"};
env.fund(XRP(10000), alice);
// Must have a "Hooks" field
env(ripple::test::jtx::hook(alice, {}, 0), ter(temMALFORMED));
// Must have at least one non-empty subfield
env(ripple::test::jtx::hook(alice, {{}}, 0), ter(temMALFORMED));
// Trivial single hook
env(ripple::test::jtx::hook(alice, {{hso(accept_wasm)}}, 0));
// RH TODO
}
void
run() override
{
//testTicketSetHook(); // RH TODO
testHooksDisabled();
testMalformedTransaction();
}
};
BEAST_DEFINE_TESTSUITE(SetHook, tx, ripple);
} // namespace test
} // namespace ripple

View File

@@ -63,5 +63,6 @@
#include <test/jtx/trust.h>
#include <test/jtx/txflags.h>
#include <test/jtx/utility.h>
#include <test/jtx/hook.h>
#endif

41
src/test/jtx/hook.h Normal file
View File

@@ -0,0 +1,41 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 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_JTX_HOOK_H_INCLUDED
#define RIPPLE_TEST_JTX_HOOK_H_INCLUDED
#include <ripple/json/json_value.h>
#include <test/jtx/Account.h>
#include <optional>
namespace ripple {
namespace test {
namespace jtx {
Json::Value
hook(Account const& account, std::optional<std::vector<Json::Value>> hooks, std::uint32_t flags);
Json::Value
hso(std::vector<uint8_t> wasmBytes, uint64_t hookOn = 0, uint256 ns = beast::zero, uint8_t apiversion = 0);
} // namespace jtx
} // namespace test
} // namespace ripple
#endif

View File

@@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 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 <ripple/basics/contract.h>
#include <ripple/protocol/jss.h>
#include <stdexcept>
#include <test/jtx/hook.h>
namespace ripple {
namespace test {
namespace jtx {
Json::Value
hook(Account const& account, std::optional<std::vector<Json::Value>> hooks, std::uint32_t flags)
{
Json::Value jv;
jv[jss::Account] = account.human();
jv[jss::TransactionType] = jss::SetHook;
jv[jss::Flags] = flags;
if (hooks)
{
jv[jss::Hooks] =
Json::Value{Json::arrayValue};
for (uint64_t i = 0; i < hooks->size(); ++i)
jv[jss::Hooks][i][jss::Hook] = (*hooks)[i];
}
return jv;
}
inline std::string uint64_hex(uint64_t x)
{
auto const nibble = [](uint64_t n) -> char
{
n &= 0x0FU;
return
n <= 9 ? '0' + n :
'A' + (n - 10);
};
return std::string("") +
nibble(x >> 60U) + nibble(x >> 56U) +
nibble(x >> 52U) + nibble(x >> 48U) +
nibble(x >> 44U) + nibble(x >> 40U) +
nibble(x >> 36U) + nibble(x >> 32U) +
nibble(x >> 28U) + nibble(x >> 24U) +
nibble(x >> 20U) + nibble(x >> 16U) +
nibble(x >> 12U) + nibble(x >> 8U) +
nibble(x >> 4U) + nibble(x >> 0U);
}
Json::Value
hso(std::vector<uint8_t> wasmBytes, uint64_t hookOn, uint256 ns, uint8_t apiversion)
{
Json::Value jv;
jv[jss::CreateCode] = strHex(wasmBytes);
jv[jss::HookOn] = uint64_hex(hookOn);
jv[jss::HookNamespace] = to_string(ns);
jv[jss::HookApiVersion] = Json::Value{apiversion};
return jv;
}
} // namespace jtx
} // namespace test
} // namespace ripple