Fix some documentation issues with the heavy-duty command-line inteface tests
Marco Ricci

Marco Ricci commited on 2025-08-31 21:18:26
Zeige 1 geänderte Dateien mit 88 Einfügungen und 11 Löschungen.


Fix both docstrings and inline commentary.
... ...
@@ -780,8 +780,7 @@ def run_actions_handler(
780 780
     [`multiprocessing.Process`][] -- to run a single action from the
781 781
     [`FakeConfigurationMutexStateMachine`][].  Output from this function
782 782
     must be sent down the output queue instead of relying on the call
783
-    stack.  Additionally, because this runs in a separate process, we
784
-    need to restart coverage tracking if it is currently running.
783
+    stack.
785 784
 
786 785
     Args:
787 786
         id_num:
... ...
@@ -865,6 +864,14 @@ class FakeConfigurationMutexStateMachine(stateful.RuleBasedStateMachine):
865 864
             A bundle for single-service settings.
866 865
         configuration:
867 866
             A bundle for full vault configurations.
867
+        actions:
868
+            A list of [actions][FakeConfigurationMutexAction] to
869
+            take.  These will be executed in [`run_actions`][].
870
+        step_count:
871
+            The currently valid `hypothesis` step count for state
872
+            machine testing (if we can successfully determine it;
873
+            else a default value).
874
+
868 875
 
869 876
     """
870 877
 
... ...
@@ -1015,6 +1022,7 @@ class FakeConfigurationMutexStateMachine(stateful.RuleBasedStateMachine):
1015 1022
         """Initialize the state machine."""
1016 1023
         super().__init__(*args, **kwargs)
1017 1024
         self.actions: list[FakeConfigurationMutexAction] = []
1025
+        """"""
1018 1026
         # Determine the step count by poking around in the hypothesis
1019 1027
         # internals. As this isn't guaranteed to be stable, turn off
1020 1028
         # coverage.
... ...
@@ -1023,9 +1031,10 @@ class FakeConfigurationMutexStateMachine(stateful.RuleBasedStateMachine):
1023 1031
             settings = FakeConfigurationMutexStateMachine.TestCase.settings
1024 1032
         except AttributeError:  # pragma: no cover
1025 1033
             settings = None
1026
-        self.step_count = hypothesis_machinery.get_concurrency_step_count(
1034
+        self.step_count: int = hypothesis_machinery.get_concurrency_step_count(
1027 1035
             settings
1028 1036
         )
1037
+        """"""
1029 1038
 
1030 1039
     @staticmethod
1031 1040
     def overwrite_or_merge_commands(*, overwrite: bool = False) -> list[str]:
... ...
@@ -1323,8 +1332,9 @@ class FakeConfigurationMutexStateMachine(stateful.RuleBasedStateMachine):
1323 1332
         mp = multiprocessing.get_context()
1324 1333
         # Coverage tracking writes coverage data to the current working
1325 1334
         # directory, but because the subprocesses are spawned within the
1326
-        # `pytest_machinery.isolated_vault_config` context manager, their starting
1327
-        # working directory is the isolated one, not the original one.
1335
+        # `pytest_machinery.isolated_vault_config` context manager,
1336
+        # their starting working directory is the isolated one, not the
1337
+        # original one.
1328 1338
         orig_cwd = pathlib.Path.cwd()
1329 1339
 
1330 1340
         fatal_process_creation_errnos = {
... ...
@@ -1454,12 +1464,12 @@ class FakeConfigurationMutexStateMachine(stateful.RuleBasedStateMachine):
1454 1464
                             break
1455 1465
                 finally:
1456 1466
                     # The subprocesses have this
1457
-                    # `pytest_machinery.isolated_vault_config` directory as their
1458
-                    # startup and working directory, so systems like
1459
-                    # coverage tracking write their data files to this
1460
-                    # directory.  We need to manually move them back to
1461
-                    # the starting working directory if they are to
1462
-                    # survive this test.
1467
+                    # `pytest_machinery.isolated_vault_config` directory
1468
+                    # as their startup and working directory, so systems
1469
+                    # like coverage tracking write their data files to
1470
+                    # this directory.  We need to manually move them
1471
+                    # back to the starting working directory if they are
1472
+                    # to survive this test.
1463 1473
                     for coverage_file in pathlib.Path.cwd().glob(
1464 1474
                         ".coverage.*"
1465 1475
                     ):
... ...
@@ -1495,6 +1505,73 @@ class FakeConfigurationMutexStateMachine(stateful.RuleBasedStateMachine):
1495 1505
         processes_pending: set[multiprocessing.process.BaseProcess],
1496 1506
         block: bool = True,
1497 1507
     ) -> None:
1508
+        """Run a single step of the IPC main loop operation.
1509
+
1510
+        We check for a message (in a blocking manner, or not, depending
1511
+        on the options) on the common child output queue and react to
1512
+        it, accordingly.  This may entail sending other child processes
1513
+        a message via their input queue, or otherwise updating the
1514
+        bookkeeping data structures.
1515
+
1516
+        Specifically, we take the following actions:
1517
+
1518
+        1.  We re-raise any exceptions that occurred in a child process.
1519
+
1520
+        2.  We issue work clearance for child number 0 once all child
1521
+            processes have signalled readiness.
1522
+
1523
+        3.  We store any results that a child process sends via the
1524
+            output queue.
1525
+
1526
+        4.  We react to any child process exiting by checking its return
1527
+            status and by issuing work clearance to the next child
1528
+            process, if any.
1529
+
1530
+        We take a number of arguments, many of which are data structures
1531
+        that, once they are set up, will be managed by us exclusively.
1532
+        These are marked as "managed by us" below.  **Do not
1533
+        manipulate** these arguments once they have been passed in to us
1534
+        **unless you are absolutely 100% sure you know what you're
1535
+        doing**.
1536
+
1537
+        Args:
1538
+            timeout:
1539
+                The maximum time to wait for sending or receiving an IPC
1540
+                message on a queue.
1541
+            block:
1542
+                If true, block until a message has been sent or
1543
+                received, else return immediately.
1544
+            intermediate_configs:
1545
+                A `dict` in which to store the `vault` configurations
1546
+                returned from the child processes.  Each configuration
1547
+                is keyed by the step number (which is equal to the child
1548
+                process ID).
1549
+            intermediate_results:
1550
+                A `dict` in which to store the result tuples of running
1551
+                the chain of actions at the given step number, based on
1552
+                the results of the previous step number.  Each result
1553
+                tuple contains the exit status (`True` if successful,
1554
+                else `False`), the contents of standard output, and the
1555
+                contents of standard error.
1556
+
1557
+        Other args:
1558
+            child_output_queue:
1559
+                The common output queue of all child processes.  Managed
1560
+                by us.
1561
+            child_input_queues:
1562
+                A list of input queues for the child processes.  Managed
1563
+                by us.
1564
+            ready_wait:
1565
+                The set of child process IDs who have yet to signal
1566
+                readiness.  Managed by us.
1567
+            processes:
1568
+                The child process objects sitting at the other end of
1569
+                the respective input queue.  Managed by us.
1570
+            processes_pending:
1571
+                The set of child processes currently still alive.
1572
+                Managed by us.
1573
+
1574
+        """
1498 1575
         IPCMessage: TypeAlias = FakeConfigurationMutexStateMachine.IPCMessage
1499 1576
         msg = child_output_queue.get(block=block, timeout=timeout)
1500 1577
         # TODO(the-13th-letter): Rewrite using structural pattern
1501 1578