From 02fba3b2b67e062fb8ca0f2aeb8177309002a451 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Tue, 20 Jun 2023 07:45:51 -0400
Subject: [PATCH] factor some duplication out of the tests

---
 src/allmydata/test/cli/test_run.py | 90 ++++++++++++++----------------
 1 file changed, 43 insertions(+), 47 deletions(-)

diff --git a/src/allmydata/test/cli/test_run.py b/src/allmydata/test/cli/test_run.py
index 731269d3d..30d5cd893 100644
--- a/src/allmydata/test/cli/test_run.py
+++ b/src/allmydata/test/cli/test_run.py
@@ -174,37 +174,55 @@ class DaemonizeStopTests(SyncTestCase):
 
         super().setUp()
 
-    def test_stop_on_stdin_close(self):
+    def _make_daemon(self, extra_argv: list[str]) -> DaemonizeTheRealService:
         """
-        We stop when stdin is closed.
+        Create the daemonization service.
+
+        :param extra_argv: Extra arguments to pass between ``run`` and the
+            node path.
         """
-        options = parse_options(["run", self.nodedir.path])
+        options = parse_options(["run"] + extra_argv + [self.nodedir.path])
         options.stdout = StringIO()
         options.stderr = StringIO()
         options.stdin = StringIO()
         run_options = options.subOptions
+        return DaemonizeTheRealService(
+            "client",
+            self.nodedir.path,
+            run_options,
+        )
 
+    def _run_daemon(self) -> None:
+        """
+        Simulate starting up the reactor so the daemon plugin can do its
+        stuff.
+        """
+        # We happen to know that the service uses reactor.callWhenRunning
+        # to schedule all its work (though I couldn't tell you *why*).
+        # Make sure those scheduled calls happen.
+        waiting = self.reactor.whenRunningHooks[:]
+        del self.reactor.whenRunningHooks[:]
+        for f, a, k in waiting:
+            f(*a, **k)
+
+    def _close_stdin(self) -> None:
+        """
+        Simulate closing the daemon plugin's stdin.
+        """
+        # there should be a single reader: our StandardIO process
+        # reader for stdin. Simulate it closing.
+        for r in self.reactor.getReaders():
+            r.connectionLost(Failure(ConnectionDone()))
+
+    def test_stop_on_stdin_close(self):
+        """
+        We stop when stdin is closed.
+        """
         with AlternateReactor(self.reactor):
-            service = DaemonizeTheRealService(
-                "client",
-                self.nodedir.path,
-                run_options,
-            )
+            service = self._make_daemon([])
             service.startService()
-
-            # We happen to know that the service uses reactor.callWhenRunning
-            # to schedule all its work (though I couldn't tell you *why*).
-            # Make sure those scheduled calls happen.
-            waiting = self.reactor.whenRunningHooks[:]
-            del self.reactor.whenRunningHooks[:]
-            for f, a, k in waiting:
-                f(*a, **k)
-
-            # there should be a single reader: our StandardIO process
-            # reader for stdin. Simulate it closing.
-            for r in self.reactor.getReaders():
-                r.connectionLost(Failure(ConnectionDone()))
-
+            self._run_daemon()
+            self._close_stdin()
             self.assertEqual(len(self.stop_calls), 1)
 
     def test_allow_stdin_close(self):
@@ -212,33 +230,11 @@ class DaemonizeStopTests(SyncTestCase):
         If --allow-stdin-close is specified then closing stdin doesn't
         stop the process
         """
-        options = parse_options(["run", "--allow-stdin-close", self.nodedir.path])
-        options.stdout = StringIO()
-        options.stderr = StringIO()
-        options.stdin = StringIO()
-        run_options = options.subOptions
-
         with AlternateReactor(self.reactor):
-            service = DaemonizeTheRealService(
-                "client",
-                self.nodedir.path,
-                run_options,
-            )
+            service = self._make_daemon(["--allow-stdin-close"])
             service.startService()
-
-            # We happen to know that the service uses reactor.callWhenRunning
-            # to schedule all its work (though I couldn't tell you *why*).
-            # Make sure those scheduled calls happen.
-            waiting = self.reactor.whenRunningHooks[:]
-            del self.reactor.whenRunningHooks[:]
-            for f, a, k in waiting:
-                f(*a, **k)
-
-            # kind of cheating -- there are no readers, because we
-            # never instantiated a StandardIO in this case..
-            for r in self.reactor.getReaders():
-                r.connectionLost(Failure(ConnectionDone()))
-
+            self._run_daemon()
+            self._close_stdin()
             self.assertEqual(self.stop_calls, [])