#!/usr/bin/env python3 # Copyright (c) 2019 The Bitcoin Unlimited developers """ Tests for shutting down Bitcoin Unlimited on electrum server failure """ import asyncio import os import subprocess import logging import tempfile from test_framework.test_framework import BitcoinTestFramework from test_framework.util import is_bitcoind_running, wait_for def create_exiting_program(): """ Create a program that exists after 10 seconds. """ with tempfile.NamedTemporaryFile(suffix=".c", mode="w", delete=False) as tmpfh: tmpfh.write("#include \n") tmpfh.write("int main(int argc, char** argv) { sleep(10); return 0; }\n") tmpfh.close() path_in = tmpfh.name path_out = tmpfh.name + ".out" try: subprocess.check_call(["gcc", "-o", path_out, path_in]) finally: os.unlink(path_in) return path_out class ElectrumShutdownTests(BitcoinTestFramework): skip = False dummy_electrum_path = None def __init__(self): super().__init__() try: self.dummy_electrum_path = create_exiting_program() except Exception as e: print("SKIPPING TEST - failed to create dummy electrum program: " + str(e)) self.skip = True self.setup_clean_chain = True self.num_nodes = 2 async def run_test(self): if self.skip: return # We need to start them individually. Otherwise, they all exit when # one exits. self.stop_nodes() common_args = [ "-electrum=1", f"-electrum.exec={self.dummy_electrum_path}", "-printtoconsole", ] extra_args = [common_args, common_args + ["-electrum.shutdownonerror=1"]] await asyncio.sleep(5) logging.info("Starting node #1") node1 = await self.start_node(1, extra_args) logging.info("Starting node #0") node0 = await self.start_node(0, extra_args) logging.info("node #1 should shutdown when 'rostrum' does...") await wait_for(30, lambda: not is_bitcoind_running(node1)) logging.info("node #0 should keep running when 'rostrum' exits...") print("node 0", node0.process.poll()) print("node 1", node1.process.poll()) assert is_bitcoind_running(node0) if self.dummy_electrum_path: os.unlink(self.dummy_electrum_path) async def setup_network(self, _dummy=None): self.nodes = await self.setup_nodes() if __name__ == "__main__": asyncio.run(ElectrumShutdownTests().main())