mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
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:
19
tests/plugins/broken.py
Executable file
19
tests/plugins/broken.py
Executable 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()
|
||||||
@@ -8,7 +8,7 @@ plugin = Plugin()
|
|||||||
@plugin.init()
|
@plugin.init()
|
||||||
def init(options, configuration, plugin):
|
def init(options, configuration, plugin):
|
||||||
plugin.log("slow_init.py initializing {}".format(configuration))
|
plugin.log("slow_init.py initializing {}".format(configuration))
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
|
|
||||||
|
|
||||||
plugin.run()
|
plugin.run()
|
||||||
|
|||||||
@@ -94,11 +94,10 @@ def test_plugin_dir(node_factory):
|
|||||||
|
|
||||||
|
|
||||||
def test_plugin_slowinit(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 = node_factory.get_node()
|
||||||
|
|
||||||
n.rpc.plugin_start(os.path.join(os.getcwd(), "tests/plugins/slow_init.py"))
|
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;
|
# It's not actually configured yet, see what happens;
|
||||||
# make sure 'rescan' and 'list' controls dont crash
|
# make sure 'rescan' and 'list' controls dont crash
|
||||||
@@ -116,42 +115,47 @@ def test_plugin_command(node_factory):
|
|||||||
assert(len(cmd) == 0)
|
assert(len(cmd) == 0)
|
||||||
|
|
||||||
# Add the 'contrib/plugins' test dir
|
# Add the 'contrib/plugins' test dir
|
||||||
time.sleep(2)
|
|
||||||
n.rpc.plugin_startdir(directory=os.path.join(os.getcwd(), "contrib/plugins"))
|
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
|
# Make sure that the 'hello' command from the helloworld.py plugin
|
||||||
# is now available.
|
# is now available.
|
||||||
cmd = [hlp for hlp in n.rpc.help()["help"] if "hello" in hlp["command"]]
|
cmd = [hlp for hlp in n.rpc.help()["help"] if "hello" in hlp["command"]]
|
||||||
assert(len(cmd) == 1)
|
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_rescan()
|
||||||
n.rpc.plugin_list()
|
n.rpc.plugin_list()
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# Make sure the plugin behaves normally after stop and restart
|
# 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")
|
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.rpc.plugin_start(plugin=os.path.join(os.getcwd(), "contrib/plugins/helloworld.py"))
|
||||||
n.daemon.wait_for_log(r"Plugin helloworld.py initialized")
|
n.daemon.wait_for_log(r"Plugin helloworld.py initialized")
|
||||||
assert("Hello world" == n.rpc.call(method="hello"))
|
assert("Hello world" == n.rpc.call(method="hello"))
|
||||||
|
|
||||||
# Now stop the helloworld plugin
|
# 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")
|
n.daemon.wait_for_log(r"Killing plugin: helloworld.py")
|
||||||
time.sleep(1)
|
|
||||||
# Make sure that the 'hello' command from the helloworld.py plugin
|
# Make sure that the 'hello' command from the helloworld.py plugin
|
||||||
# is not available anymore.
|
# is not available anymore.
|
||||||
cmd = [hlp for hlp in n.rpc.help()["help"] if "hello" in hlp["command"]]
|
cmd = [hlp for hlp in n.rpc.help()["help"] if "hello" in hlp["command"]]
|
||||||
assert(len(cmd) == 0)
|
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
|
# getmanifest
|
||||||
|
with pytest.raises(RpcError, match=r"Not a dynamic plugin"):
|
||||||
n.rpc.plugin_start(plugin=os.path.join(os.getcwd(), "tests/plugins/static.py"))
|
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"):
|
# Test that we cannot stop a started plugin with 'dynamic' flag set to
|
||||||
n.rpc.plugin_stop(plugin="static.py")
|
# 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):
|
def test_plugin_disable(node_factory):
|
||||||
|
|||||||
Reference in New Issue
Block a user