(node_factory)
| 2548 | |
| 2549 | |
| 2550 | def test_important_plugin(node_factory): |
| 2551 | # Cache it here. |
| 2552 | pluginsdir = os.path.join(os.path.dirname(__file__), "plugins") |
| 2553 | |
| 2554 | n = node_factory.get_node(options={"important-plugin": os.path.join(pluginsdir, "nonexistent")}, |
| 2555 | may_fail=True, expect_fail=True, |
| 2556 | # Other plugins can complain as lightningd stops suddenly: |
| 2557 | broken_log='Plugin marked as important, shutting down lightningd|Reading sync lightningd: Connection reset by peer|Lost connection to the RPC socket|Plugin terminated before replying to RPC call|plugin-cln-xpay: askrene-create-layer failed with.*Unknown command', |
| 2558 | start=False) |
| 2559 | |
| 2560 | n.daemon.start(wait_for_initialized=False, stderr_redir=True) |
| 2561 | # Will exit with failure code. |
| 2562 | assert n.daemon.wait() == 1 |
| 2563 | assert n.daemon.is_in_stderr(r"Failed to register .*nonexistent: No such file or directory") |
| 2564 | |
| 2565 | # Check we exit if the important plugin dies. |
| 2566 | n.daemon.opts['important-plugin'] = os.path.join(pluginsdir, "fail_by_itself.py") |
| 2567 | |
| 2568 | n.daemon.start(wait_for_initialized=False) |
| 2569 | # Will exit with failure code. |
| 2570 | assert n.daemon.wait() == 1 |
| 2571 | n.daemon.wait_for_log(r'fail_by_itself.py: Plugin marked as important, shutting down lightningd') |
| 2572 | |
| 2573 | # Check if the important plugin is disabled, we run as normal. |
| 2574 | n.daemon.opts['disable-plugin'] = "fail_by_itself.py" |
| 2575 | n.daemon.start() |
| 2576 | # Make sure we can call into a plugin RPC (this is from `bcli`) even |
| 2577 | # if fail_by_itself.py is disabled. |
| 2578 | n.rpc.call("estimatefees", {}) |
| 2579 | n.stop() |
| 2580 | |
| 2581 | # Check if an important plugin dies later, we fail. |
| 2582 | del n.daemon.opts['disable-plugin'] |
| 2583 | n.daemon.opts['important-plugin'] = os.path.join(pluginsdir, "suicidal_plugin.py") |
| 2584 | |
| 2585 | n.start() |
| 2586 | |
| 2587 | with pytest.raises(RpcError): |
| 2588 | n.rpc.call("die", {}) |
| 2589 | |
| 2590 | # Should exit with exitcode 1 |
| 2591 | n.daemon.wait_for_log('suicidal_plugin.py: Plugin marked as important, shutting down lightningd') |
| 2592 | assert n.daemon.wait() == 1 |
| 2593 | n.stop() |
| 2594 | |
| 2595 | # Check that if a builtin plugin dies, we fail. |
| 2596 | start = n.daemon.logsearch_start |
| 2597 | n.start() |
| 2598 | # Reset logsearch_start, since this will predate message that start() looks for. |
| 2599 | n.daemon.logsearch_start = start |
| 2600 | line = n.daemon.wait_for_log(r'.*started\([0-9]*\).*plugins/pay') |
| 2601 | pidstr = re.search(r'.*started\(([0-9]*)\).*plugins/pay', line).group(1) |
| 2602 | |
| 2603 | # Kill pay. |
| 2604 | os.kill(int(pidstr), signal.SIGKILL) |
| 2605 | n.daemon.wait_for_log('pay: Plugin marked as important, shutting down lightningd') |
| 2606 | # Should exit with exitcode 1 |
| 2607 | assert n.daemon.wait() == 1 |
nothing calls this directly
no test coverage detected