mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +01:00
tests: make test_libplugin use the datastore.
It's a bit convoluted, but it exercises all our datastore fetch APIs. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
7b24ea60e3
commit
d1b5943e90
@@ -6,11 +6,31 @@
|
||||
#include <common/memleak.h>
|
||||
#include <plugins/libplugin.h>
|
||||
|
||||
|
||||
const char *name_option;
|
||||
static const char *somearg;
|
||||
static bool self_disable = false;
|
||||
static bool dont_shutdown = false;
|
||||
|
||||
static struct command_result *get_ds_done(struct command *cmd,
|
||||
const char *val,
|
||||
char *arg)
|
||||
{
|
||||
if (!val)
|
||||
val = "NOT FOUND";
|
||||
return command_success(cmd, json_out_obj(cmd, arg, val));
|
||||
}
|
||||
|
||||
static struct command_result *get_ds_bin_done(struct command *cmd,
|
||||
const u8 *val,
|
||||
char *arg)
|
||||
{
|
||||
plugin_log(cmd->plugin, LOG_INFORM, "get_ds_bin_done: %s",
|
||||
val ? tal_hex(tmpctx, val) : "NOT FOUND");
|
||||
|
||||
return jsonrpc_get_datastore_string(cmd->plugin, cmd,
|
||||
"test_libplugin/name",
|
||||
get_ds_done, arg);
|
||||
}
|
||||
|
||||
static struct command_result *json_helloworld(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *params)
|
||||
@@ -23,8 +43,12 @@ static struct command_result *json_helloworld(struct command *cmd,
|
||||
return command_param_failed();
|
||||
|
||||
plugin_notify_message(cmd, LOG_INFORM, "Notification from %s", "json_helloworld");
|
||||
|
||||
if (!name)
|
||||
name = name_option ? name_option : tal_strdup(tmpctx, "world");
|
||||
return jsonrpc_get_datastore_binary(cmd->plugin, cmd,
|
||||
"test_libplugin/name",
|
||||
get_ds_bin_done,
|
||||
"hello");
|
||||
|
||||
return command_success(cmd, json_out_obj(cmd, "hello", name));
|
||||
}
|
||||
@@ -103,26 +127,35 @@ static struct command_result *json_testrpc(struct command *cmd,
|
||||
return send_outreq(cmd->plugin, req);
|
||||
}
|
||||
|
||||
#if DEVELOPER
|
||||
static void memleak_mark(struct plugin *p, struct htable *memtable)
|
||||
{
|
||||
/* name_option is not a leak! */
|
||||
memleak_ptr(memtable, name_option);
|
||||
}
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
static const char *init(struct plugin *p,
|
||||
const char *buf UNUSED,
|
||||
const jsmntok_t *config UNUSED)
|
||||
{
|
||||
const char *name;
|
||||
const u8 *binname;
|
||||
|
||||
plugin_log(p, LOG_DBG, "test_libplugin initialised!");
|
||||
if (somearg)
|
||||
plugin_log(p, LOG_DBG, "somearg = %s", somearg);
|
||||
somearg = tal_free(somearg);
|
||||
|
||||
if (self_disable)
|
||||
return "Disabled via selfdisable option";
|
||||
|
||||
#if DEVELOPER
|
||||
plugin_set_memleak_handler(p, memleak_mark);
|
||||
#endif
|
||||
/* Test rpc_scan_datastore funcs */
|
||||
if (!rpc_scan_datastore_str(p, "test_libplugin/name",
|
||||
JSON_SCAN_TAL(tmpctx, json_strdup,
|
||||
&name)))
|
||||
name = NULL;
|
||||
if (!rpc_scan_datastore_hex(p, "test_libplugin/name",
|
||||
JSON_SCAN_TAL(tmpctx, json_tok_bin_from_hex,
|
||||
&binname)))
|
||||
binname = NULL;
|
||||
|
||||
plugin_log(p, LOG_INFORM, "String name from datastore: %s",
|
||||
name ? name : "NOT FOUND");
|
||||
plugin_log(p, LOG_INFORM, "Hex name from datastore: %s",
|
||||
binname ? tal_hex(tmpctx, binname) : "NOT FOUND");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -180,14 +213,14 @@ int main(int argc, char *argv[])
|
||||
commands, ARRAY_SIZE(commands),
|
||||
notifs, ARRAY_SIZE(notifs), hooks, ARRAY_SIZE(hooks),
|
||||
NULL, 0, /* Notification topics we publish */
|
||||
plugin_option("name",
|
||||
plugin_option("somearg",
|
||||
"string",
|
||||
"Who to say hello to.",
|
||||
charp_option, &name_option),
|
||||
plugin_option_deprecated("name-deprecated",
|
||||
"Argument to print at init.",
|
||||
charp_option, &somearg),
|
||||
plugin_option_deprecated("somearg-deprecated",
|
||||
"string",
|
||||
"Who to say hello to.",
|
||||
charp_option, &name_option),
|
||||
"Deprecated arg for init.",
|
||||
charp_option, &somearg),
|
||||
plugin_option("selfdisable",
|
||||
"flag",
|
||||
"Whether to disable.",
|
||||
|
||||
@@ -1490,12 +1490,22 @@ def test_libplugin(node_factory):
|
||||
plugin = os.path.join(os.getcwd(), "tests/plugins/test_libplugin")
|
||||
l1 = node_factory.get_node(options={"plugin": plugin,
|
||||
'allow-deprecated-apis': False,
|
||||
'log-level': 'io'})
|
||||
'log-level': 'io'},
|
||||
allow_broken_log=True)
|
||||
|
||||
# Test startup
|
||||
assert l1.daemon.is_in_log("test_libplugin initialised!")
|
||||
assert l1.daemon.is_in_log("String name from datastore: NOT FOUND")
|
||||
assert l1.daemon.is_in_log("Hex name from datastore: NOT FOUND")
|
||||
|
||||
# This will look on datastore for default, won't find it.
|
||||
assert l1.rpc.call("helloworld") == {"hello": "NOT FOUND"}
|
||||
l1.daemon.wait_for_log("get_ds_bin_done: NOT FOUND")
|
||||
|
||||
# Test dynamic startup
|
||||
l1.rpc.plugin_stop(plugin)
|
||||
# Non-string datastore value:
|
||||
l1.rpc.datastore(["test_libplugin", "name"], hex="00010203")
|
||||
l1.rpc.plugin_start(plugin)
|
||||
l1.rpc.check("helloworld")
|
||||
|
||||
@@ -1505,14 +1515,24 @@ def test_libplugin(node_factory):
|
||||
# yet whether strings are allowed:
|
||||
l1.daemon.wait_for_log(r"test_libplugin: [0-9]*\[OUT\]")
|
||||
|
||||
l1.daemon.wait_for_log("String name from datastore: NOT FOUND")
|
||||
l1.daemon.wait_for_log("Hex name from datastore: 00010203")
|
||||
|
||||
# Test commands
|
||||
assert l1.rpc.call("helloworld") == {"hello": "world"}
|
||||
assert l1.rpc.call("helloworld") == {"hello": "NOT FOUND"}
|
||||
l1.daemon.wait_for_log("get_ds_bin_done: 00010203")
|
||||
l1.daemon.wait_for_log("BROKEN.* Datastore gave nonstring result.*00010203")
|
||||
assert l1.rpc.call("helloworld", {"name": "test"}) == {"hello": "test"}
|
||||
l1.stop()
|
||||
l1.daemon.opts["plugin"] = plugin
|
||||
l1.daemon.opts["name"] = "test_opt"
|
||||
l1.daemon.opts["somearg"] = "test_opt"
|
||||
l1.start()
|
||||
assert l1.rpc.call("helloworld") == {"hello": "test_opt"}
|
||||
assert l1.daemon.is_in_log("somearg = test_opt")
|
||||
l1.rpc.datastore(["test_libplugin", "name"], "foobar", mode="must-replace")
|
||||
|
||||
assert l1.rpc.call("helloworld") == {"hello": "foobar"}
|
||||
l1.daemon.wait_for_log("get_ds_bin_done: 666f6f626172")
|
||||
|
||||
# But param takes over!
|
||||
assert l1.rpc.call("helloworld", {"name": "test"}) == {"hello": "test"}
|
||||
|
||||
@@ -1536,17 +1556,17 @@ def test_libplugin(node_factory):
|
||||
with pytest.raises(RpcError, match=r"Deprecated command.*testrpc-deprecated"):
|
||||
l1.rpc.help('testrpc-deprecated')
|
||||
|
||||
assert 'name-deprecated' not in str(l1.rpc.listconfigs())
|
||||
assert 'somearg-deprecated' not in str(l1.rpc.listconfigs())
|
||||
|
||||
l1.stop()
|
||||
l1.daemon.opts["name-deprecated"] = "test_opt"
|
||||
l1.daemon.opts["somearg-deprecated"] = "test_opt"
|
||||
|
||||
l1.daemon.start(wait_for_initialized=False, stderr_redir=True)
|
||||
# Will exit with failure code.
|
||||
assert l1.daemon.wait() == 1
|
||||
assert l1.daemon.is_in_stderr(r"name-deprecated: deprecated option")
|
||||
assert l1.daemon.is_in_stderr(r"somearg-deprecated: deprecated option")
|
||||
|
||||
del l1.daemon.opts["name-deprecated"]
|
||||
del l1.daemon.opts["somearg-deprecated"]
|
||||
l1.start()
|
||||
|
||||
|
||||
@@ -1554,10 +1574,10 @@ def test_libplugin_deprecated(node_factory):
|
||||
"""Sanity checks for plugins made with libplugin using deprecated args"""
|
||||
plugin = os.path.join(os.getcwd(), "tests/plugins/test_libplugin")
|
||||
l1 = node_factory.get_node(options={"plugin": plugin,
|
||||
'name-deprecated': 'test_opt depr',
|
||||
'somearg-deprecated': 'test_opt depr',
|
||||
'allow-deprecated-apis': True})
|
||||
|
||||
assert l1.rpc.call("helloworld") == {"hello": "test_opt depr"}
|
||||
assert l1.daemon.is_in_log("somearg = test_opt depr")
|
||||
l1.rpc.help('testrpc-deprecated')
|
||||
assert l1.rpc.call("testrpc-deprecated") == l1.rpc.getinfo()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user