"""External regression for the frozen lane's PID-reuse cleanup observation.

Run with the path to local-lane.py (or the separately patched specimen).
No OS process is killed or launched by this regression.
"""
import importlib.util
from pathlib import Path
import sys
import unittest

sys.dont_write_bytecode = True
path = Path(sys.argv.pop(1)).resolve()
spec = importlib.util.spec_from_file_location("cleanup_subject", path)
subject = importlib.util.module_from_spec(spec)
spec.loader.exec_module(subject)


class ReusedIdentity:
    pid = 30480

    def __init__(self):
        self.killed = False

    def is_running(self):
        # Retained (pid,birth) is gone; the numeric PID belongs to someone else.
        return False

    def kill(self):
        self.killed = True
        raise AssertionError("must not kill the replacement process")

    def wait(self, timeout=None):
        # psutil's Windows wait uses numeric PID and can fail after reuse.
        raise subject.psutil.NoSuchProcess(self.pid)


class OwnedIdentity:
    pid = 99999

    def __init__(self):
        self.alive = True

    def is_running(self):
        return self.alive

    def kill(self):
        self.alive = False

    def wait(self, timeout=None):
        return 0


class CleanupIdentityRegression(unittest.TestCase):
    def test_reused_pid_is_finished_not_a_cleanup_failure(self):
        reused = ReusedIdentity()
        owned = OwnedIdentity()
        errors, survivors = subject.stop_observed([reused, owned])
        self.assertEqual(errors, [], "a proven-gone identity must not fail cleanup")
        self.assertEqual(survivors, [])
        self.assertFalse(reused.killed, "replacement process is not owned")
        self.assertFalse(owned.alive, "the live owned identity must still be reaped")


if __name__ == "__main__":
    unittest.main()
