From c763ddc9855e7f71b1cc93e4c138bc0d7abda55f Mon Sep 17 00:00:00 2001 From: Jianping Wu Date: Tue, 12 Feb 2019 18:45:29 -0800 Subject: [PATCH] Added feature_keva.py functional test case. --- src/rpc/rpckeva_nonwallet.cpp | 13 +++-- src/wallet/rpckeva.cpp | 13 ++--- test/functional/feature_keva.py | 96 +++++++++++++++++++++++++++++++++ test/functional/test_runner.py | 2 + 4 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 test/functional/feature_keva.py diff --git a/src/rpc/rpckeva_nonwallet.cpp b/src/rpc/rpckeva_nonwallet.cpp index 1d56498d0..cc8553fba 100644 --- a/src/rpc/rpckeva_nonwallet.cpp +++ b/src/rpc/rpckeva_nonwallet.cpp @@ -56,14 +56,14 @@ UniValue keva_get(const JSONRPCRequest& request) if (nameSpace.size() > MAX_NAMESPACE_LENGTH) throw JSONRPCError (RPC_INVALID_PARAMETER, "the namespace is too long"); - const std::string keyStr = request.params[1].get_str (); - const valtype key = ValtypeFromString (keyStr); + const std::string keyStr = request.params[1].get_str(); + const valtype key = ValtypeFromString(keyStr); if (key.size() > MAX_KEY_LENGTH) - throw JSONRPCError (RPC_INVALID_PARAMETER, "the key is too long"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "the key is too long"); CKevaData data; { - LOCK (cs_main); + LOCK(cs_main); pcoinsTip->GetName(nameSpace, key, data); } @@ -77,7 +77,10 @@ UniValue keva_get(const JSONRPCRequest& request) } } - return ValtypeToString(value); + UniValue obj(UniValue::VOBJ); + obj.pushKV("key", keyStr); + obj.pushKV("value", ValtypeToString(value)); + return obj; } /** diff --git a/src/wallet/rpckeva.cpp b/src/wallet/rpckeva.cpp index a7bdbdf25..8f6b696c6 100644 --- a/src/wallet/rpckeva.cpp +++ b/src/wallet/rpckeva.cpp @@ -100,13 +100,10 @@ UniValue keva_namespace(const JSONRPCRequest& request) LogPrintf("keva_namespace: namespace=%s, displayName=%s, tx=%s\n", kevaNamespaceBase58.c_str(), displayNameStr.c_str(), txid.c_str()); - UniValue res(UniValue::VARR); UniValue obj(UniValue::VOBJ); obj.pushKV("txid", txid); obj.pushKV("namespaceId", kevaNamespaceBase58); - res.push_back(obj); - - return res; + return obj; } UniValue keva_list_namespaces(const JSONRPCRequest& request) @@ -282,7 +279,9 @@ UniValue keva_put(const JSONRPCRequest& request) KEVA_LOCKED_AMOUNT, false, wtx, coinControl); keyName.KeepKey(); - return wtx.GetHash().GetHex(); + UniValue obj(UniValue::VOBJ); + obj.pushKV("txid", wtx.GetHash().GetHex()); + return obj; } UniValue keva_delete(const JSONRPCRequest& request) @@ -379,7 +378,9 @@ UniValue keva_delete(const JSONRPCRequest& request) keyName.KeepKey(); } - return wtx.GetHash().GetHex(); + UniValue obj(UniValue::VOBJ); + obj.pushKV("txid", wtx.GetHash().GetHex()); + return obj; } UniValue keva_pending(const JSONRPCRequest& request) diff --git a/test/functional/feature_keva.py b/test/functional/feature_keva.py new file mode 100644 index 000000000..f0450740d --- /dev/null +++ b/test/functional/feature_keva.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016-2017 The Bitcoin Core developers +# Copyright (c) 2018-2019 The Kevacoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test the Key-Value Store.""" + +from test_framework.blocktools import witness_script, send_to_witness +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.authproxy import JSONRPCException +from io import BytesIO +import re + + +class KevaTest(BitcoinTestFramework): + def set_test_params(self): + self.setup_clean_chain = True + self.num_nodes = 3 + + def setup_network(self): + super().setup_network() + connect_nodes(self.nodes[0], 2) + self.sync_all() + + def run_test(self): + self.nodes[0].generate(161) #block 161 + response = self.nodes[0].keva_namespace('first_namespace') + namespaceId = response['namespaceId'] + + self.log.info("Test basic put and get operations") + key = 'First Key' + value = 'This is the first value!' + self.nodes[0].keva_put(namespaceId, key, value) + response = self.nodes[0].keva_pending() + assert(response[0]['op'] == 'keva_namespace') + assert(response[1]['op'] == 'keva_put') + response = self.nodes[0].keva_get(namespaceId, key) + assert(response['value'] == value) + + self.nodes[0].generate(1) + response = self.nodes[0].keva_pending() + assert(len(response) == 0) + + self.log.info("Test batch of put operations without exceeding the mempool chain limit") + prefix = 'first-set-of-keys-' + for i in range(24): + key = prefix + str(i) + value = ('value-' + str(i) + '-') * 300 + self.nodes[0].keva_put(namespaceId, key, value) + + response = self.nodes[0].keva_pending() + assert(len(response) == 24) + + self.nodes[0].generate(1) + response = self.nodes[0].keva_pending() + assert(len(response) == 0) + + # This will throw "too-long-mempool-chain" exception + self.log.info("Test batch of put operations that exceeds the mempool chain limit") + throwException = False + secondPrefix = 'second-set-of-keys-' + try: + for i in range(30): + key = secondPrefix + '|' + str(i) + value = '-value-' * 320 + '|' + str(i) + self.nodes[0].keva_put(namespaceId, key, value) + except JSONRPCException: + throwException = True + + assert(throwException) + + self.nodes[0].generate(1) + response = self.nodes[0].keva_pending() + assert(len(response) == 0) + + self.log.info("Verify keva_filter works properly") + response = self.nodes[0].keva_filter(namespaceId, secondPrefix) + assert(len(response) == 25) + + for i in range(25): + m = re.search('\|(\d+)', response[i]['key']) + keyId = m.group(0) + m = re.search('\|(\d+)', response[i]['value']) + valueId = m.group(0) + assert(keyId == valueId) + + self.log.info("Test keva_delete") + keyToDelete = secondPrefix + '|13' + self.nodes[0].keva_delete(namespaceId, keyToDelete) + self.nodes[0].generate(1) + response = self.nodes[0].keva_get(namespaceId, keyToDelete) + assert(response['value'] == '') + +if __name__ == '__main__': + KevaTest().main() diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 2c50eef37..9103e0ea8 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -80,6 +80,8 @@ BASE_SCRIPTS= [ 'rpc_rawtransaction.py', 'wallet_address_types.py', 'feature_reindex.py', + # vv Tests Key-Value store vv + 'feature_keva.py', # vv Tests less than 30s vv 'wallet_keypool_topup.py', 'interface_zmq.py',