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 |