diff --git a/clients/deadline.py b/clients/deadline.py index ae11918..f9abe47 100644 --- a/clients/deadline.py +++ b/clients/deadline.py @@ -40,6 +40,10 @@ def fraction_used(self) -> float: return 1.0 return ratio + def remaining_fraction(self) -> float: + """Return 1.0 - fraction_used(); timeout==0 yields 0.0.""" + return 1.0 - self.fraction_used() + def remaining(self) -> float: """Return seconds left before the deadline (never negative).""" elapsed = self._clock.monotonic() - self._started_at diff --git a/scenarios/cli.py b/scenarios/cli.py index de409fc..75881dc 100644 --- a/scenarios/cli.py +++ b/scenarios/cli.py @@ -74,6 +74,11 @@ def build_parser() -> argparse.ArgumentParser: "has", help="Check whether a scenario id is known" ) has_parser.add_argument("scenario_id", help="Scenario id from the catalog") + + location_parser = subparsers.add_parser( + "location", help="Print catalog location for a scenario id" + ) + location_parser.add_argument("scenario_id", help="Scenario id from the catalog") return parser @@ -184,6 +189,14 @@ def main(argv: list[str] | None = None) -> int: print(f"unknown scenario: {args.scenario_id}", file=sys.stderr) return 1 + if args.command == "location": + entry = lookup_scenario(args.scenario_id) + if entry is None: + print(f"unknown scenario: {args.scenario_id}", file=sys.stderr) + return 1 + print(entry.location) + return 0 + return 1 diff --git a/tests/test_cli.py b/tests/test_cli.py index 03fb37c..c780d21 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -236,5 +236,20 @@ def test_has_unknown_scenario_returns_error(self): + def test_location_prints_catalog_location(self): + buffer = io.StringIO() + with redirect_stdout(buffer): + code = main(["location", "retry"]) + self.assertEqual(code, 0) + self.assertEqual(buffer.getvalue().strip(), "scenarios/retry") + + def test_location_unknown_scenario_returns_error(self): + err = io.StringIO() + with redirect_stderr(err): + code = main(["location", "missing"]) + self.assertEqual(code, 1) + self.assertIn("unknown scenario: missing", err.getvalue()) + + if __name__ == "__main__": unittest.main() diff --git a/tests/test_deadline.py b/tests/test_deadline.py index bd918ca..ea8d3ac 100644 --- a/tests/test_deadline.py +++ b/tests/test_deadline.py @@ -68,5 +68,22 @@ def test_fraction_used_zero_timeout_is_one(self): self.assertEqual(deadline.fraction_used(), 1.0) + def test_remaining_fraction_complement_of_fraction_used(self): + clock = FakeClock() + deadline = Deadline(clock, timeout=1.0) + self.assertAlmostEqual(deadline.remaining_fraction(), 1.0) + clock.sleep(0.25) + self.assertAlmostEqual(deadline.remaining_fraction(), 0.75) + clock.sleep(0.75) + self.assertAlmostEqual(deadline.remaining_fraction(), 0.0) + clock.sleep(0.5) + self.assertAlmostEqual(deadline.remaining_fraction(), 0.0) + + def test_remaining_fraction_zero_timeout_is_zero(self): + clock = FakeClock() + deadline = Deadline(clock, timeout=0.0) + self.assertEqual(deadline.remaining_fraction(), 0.0) + + if __name__ == "__main__": unittest.main()