plugins: refactor the tests for dynamic plugins

This adapts the test to the new 'plugin' command: no more sleeping,
since we are synchronous !

This tests the timeout by increasing the 'slowinit' plugin sleep
duration at init reception.

This adds a broken plugin to make sure we won't crash because of a
misbehaving plugin (unmet dependency is the most common case).
This commit is contained in:
darosior 2019-09-15 15:19:28 +02:00 committed by Rusty Russell
parent 05a747c5ba
commit 32d98f0a87
3 changed files with 39 additions and 16 deletions

19
tests/plugins/broken.py Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python3
"""Simple plugin to test that lightningd doesnt crash if it starts a
misbehaving plugin via RPC.
"""
from lightning import Plugin
import an_unexistent_module_that_will_make_me_crash
plugin = Plugin(dynamic=False)
@plugin.init()
def init(options, configuration, plugin):
plugin.log("broken.py initializing {}".format(configuration))
# We need to actually use the import to pass source checks..
an_unexistent_module_that_will_make_me_crash.hello()
plugin.run()

View File

@ -8,7 +8,7 @@ plugin = Plugin()
@plugin.init()
def init(options, configuration, plugin):
plugin.log("slow_init.py initializing {}".format(configuration))
time.sleep(1)
time.sleep(2)
plugin.run()

View File

@ -94,11 +94,10 @@ def test_plugin_dir(node_factory):
def test_plugin_slowinit(node_factory):
"""Tests the 'plugin' RPC command when init is slow"""
"""Tests that the 'plugin' RPC command times out if plugin doesnt respond"""
n = node_factory.get_node()
n.rpc.plugin_start(os.path.join(os.getcwd(), "tests/plugins/slow_init.py"))
n.daemon.wait_for_log("slow_init.py initializing.* 'startup': False")
# It's not actually configured yet, see what happens;
# make sure 'rescan' and 'list' controls dont crash
@ -116,42 +115,47 @@ def test_plugin_command(node_factory):
assert(len(cmd) == 0)
# Add the 'contrib/plugins' test dir
time.sleep(2)
n.rpc.plugin_startdir(directory=os.path.join(os.getcwd(), "contrib/plugins"))
n.daemon.wait_for_log(r"Plugin helloworld.py initialized")
# Make sure that the 'hello' command from the helloworld.py plugin
# is now available.
cmd = [hlp for hlp in n.rpc.help()["help"] if "hello" in hlp["command"]]
assert(len(cmd) == 1)
# Make sure 'rescan' and 'list' controls dont crash
# Make sure 'rescan' and 'list' subcommands dont crash
n.rpc.plugin_rescan()
n.rpc.plugin_list()
time.sleep(1)
# Make sure the plugin behaves normally after stop and restart
n.rpc.plugin_stop(plugin="helloworld.py")
assert("Successfully stopped helloworld.py." == n.rpc.plugin_stop(plugin="helloworld.py")[''])
n.daemon.wait_for_log(r"Killing plugin: helloworld.py")
time.sleep(1)
n.rpc.plugin_start(plugin=os.path.join(os.getcwd(), "contrib/plugins/helloworld.py"))
n.daemon.wait_for_log(r"Plugin helloworld.py initialized")
assert("Hello world" == n.rpc.call(method="hello"))
# Now stop the helloworld plugin
n.rpc.plugin_stop(plugin="helloworld.py")
assert("Successfully stopped helloworld.py." == n.rpc.plugin_stop(plugin="helloworld.py")[''])
n.daemon.wait_for_log(r"Killing plugin: helloworld.py")
time.sleep(1)
# Make sure that the 'hello' command from the helloworld.py plugin
# is not available anymore.
cmd = [hlp for hlp in n.rpc.help()["help"] if "hello" in hlp["command"]]
assert(len(cmd) == 0)
# Test that we cannot stop a plugin with 'dynamic' set to False in
# Test that we cannot start a plugin with 'dynamic' set to False in
# getmanifest
n.rpc.plugin_start(plugin=os.path.join(os.getcwd(), "tests/plugins/static.py"))
n.daemon.wait_for_log(r"Static plugin initialized.")
with pytest.raises(RpcError, match=r"plugin cannot be managed when lightningd is up"):
n.rpc.plugin_stop(plugin="static.py")
with pytest.raises(RpcError, match=r"Not a dynamic plugin"):
n.rpc.plugin_start(plugin=os.path.join(os.getcwd(), "tests/plugins/static.py"))
# Test that we cannot stop a started plugin with 'dynamic' flag set to
# False
n2 = node_factory.get_node(options={
"plugin": os.path.join(os.getcwd(), "tests/plugins/static.py")
})
with pytest.raises(RpcError, match=r"static.py cannot be managed when lightningd is up"):
n2.rpc.plugin_stop(plugin="static.py")
# Test that we don't crash when starting a broken plugin
with pytest.raises(RpcError, match=r"Timed out while waiting for plugin response"):
n2.rpc.plugin_start(plugin=os.path.join(os.getcwd(), "tests/plugins/broken.py"))
def test_plugin_disable(node_factory):