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:
Rusty Russell
2022-12-12 14:44:15 +10:30
committed by Christian Decker
parent 7b24ea60e3
commit d1b5943e90
2 changed files with 84 additions and 31 deletions

View File

@@ -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.",

View File

@@ -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()