66from olmo_eval .common import beaker_status
77
88
9+ class InlineThread :
10+ """Run a thread target synchronously to keep status reporter tests deterministic."""
11+
12+ def __init__ (self , * , target , name : str , daemon : bool ) -> None :
13+ self .target = target
14+ self .name = name
15+ self .daemon = daemon
16+
17+ def start (self ) -> None :
18+ self .target ()
19+
20+
921class BeakerStatusReporterTest (unittest .TestCase ):
1022 def test_disabled_when_beaker_config_missing (self ) -> None :
1123 with (
@@ -27,15 +39,15 @@ def test_throttles_updates_within_interval(self) -> None:
2739 "GIT_BRANCH" : "main" ,
2840 }
2941 fake_client = mock .MagicMock ()
30- fake_workload = mock .MagicMock ()
31- fake_client .workload .get .return_value = fake_workload
3242 with (
3343 mock .patch .dict ("os.environ" , env , clear = True ),
3444 mock .patch .object (beaker_status .Beaker , "from_env" , return_value = fake_client ),
45+ mock .patch .object (beaker_status , "Thread" , InlineThread ),
3546 ):
3647 reporter = beaker_status .BeakerStatusReporter (min_interval = 60.0 )
3748
3849 self .assertIsNotNone (reporter ._client )
50+ fake_client .workload .get .assert_not_called ()
3951
4052 with mock .patch ("time.monotonic" , side_effect = [0.0 , 1.0 , 61.0 ]):
4153 reporter .update ("first" )
@@ -44,30 +56,36 @@ def test_throttles_updates_within_interval(self) -> None:
4456
4557 self .assertEqual (fake_client .workload .update .call_count , 2 )
4658 suffix = "git_commit: abc123 git_branch: main"
47- fake_client .workload .update .assert_any_call (fake_workload , description = f"first { suffix } " )
48- fake_client .workload .update .assert_any_call (fake_workload , description = f"third { suffix } " )
59+ workload = beaker_status .BeakerWorkload (
60+ experiment = beaker_status .BeakerExperiment (id = "wl_123" )
61+ )
62+ fake_client .workload .update .assert_any_call (workload , description = f"first { suffix } " )
63+ fake_client .workload .update .assert_any_call (workload , description = f"third { suffix } " )
4964
5065 def test_git_suffix_uses_unknown_when_env_missing (self ) -> None :
5166 env = {"BEAKER_WORKLOAD_ID" : "wl_123" }
5267 fake_client = mock .MagicMock ()
53- fake_workload = mock .MagicMock ()
54- fake_client .workload .get .return_value = fake_workload
5568 with (
5669 mock .patch .dict ("os.environ" , env , clear = True ),
5770 mock .patch .object (beaker_status .Beaker , "from_env" , return_value = fake_client ),
71+ mock .patch .object (beaker_status , "Thread" , InlineThread ),
5872 ):
5973 reporter = beaker_status .BeakerStatusReporter (min_interval = 0.0 )
6074 reporter .update ("hello" )
6175
76+ workload = beaker_status .BeakerWorkload (
77+ experiment = beaker_status .BeakerExperiment (id = "wl_123" )
78+ )
6279 fake_client .workload .update .assert_called_once_with (
63- fake_workload , description = "hello git_commit: unknown git_branch: unknown"
80+ workload , description = "hello git_commit: unknown git_branch: unknown"
6481 )
6582
6683 def test_force_bypasses_throttle (self ) -> None :
6784 fake_client = mock .MagicMock ()
6885 with (
6986 mock .patch .dict ("os.environ" , {"BEAKER_WORKLOAD_ID" : "wl_xyz" }, clear = True ),
7087 mock .patch .object (beaker_status .Beaker , "from_env" , return_value = fake_client ),
88+ mock .patch .object (beaker_status , "Thread" , InlineThread ),
7189 ):
7290 reporter = beaker_status .BeakerStatusReporter (min_interval = 60.0 )
7391
@@ -77,6 +95,35 @@ def test_force_bypasses_throttle(self) -> None:
7795
7896 self .assertEqual (fake_client .workload .update .call_count , 2 )
7997
98+ def test_update_failure_is_nonfatal_and_disables_reporting (self ) -> None :
99+ fake_client = mock .MagicMock ()
100+ fake_client .workload .update .side_effect = RuntimeError ("API unavailable" )
101+ with (
102+ mock .patch .dict ("os.environ" , {"BEAKER_WORKLOAD_ID" : "wl_xyz" }, clear = True ),
103+ mock .patch .object (beaker_status .Beaker , "from_env" , return_value = fake_client ),
104+ mock .patch .object (beaker_status , "Thread" , InlineThread ),
105+ ):
106+ reporter = beaker_status .BeakerStatusReporter ()
107+ reporter .update ("starting" )
108+
109+ self .assertIsNone (reporter ._client )
110+
111+ def test_update_starts_a_daemon_thread (self ) -> None :
112+ fake_client = mock .MagicMock ()
113+ fake_thread = mock .MagicMock ()
114+ with (
115+ mock .patch .dict ("os.environ" , {"BEAKER_WORKLOAD_ID" : "wl_xyz" }, clear = True ),
116+ mock .patch .object (beaker_status .Beaker , "from_env" , return_value = fake_client ),
117+ mock .patch .object (beaker_status , "Thread" , return_value = fake_thread ) as thread_class ,
118+ ):
119+ reporter = beaker_status .BeakerStatusReporter ()
120+ reporter .update ("starting" )
121+
122+ thread_class .assert_called_once ()
123+ self .assertEqual (thread_class .call_args .kwargs ["name" ], "beaker-status-update" )
124+ self .assertTrue (thread_class .call_args .kwargs ["daemon" ])
125+ fake_thread .start .assert_called_once_with ()
126+
80127
81128if __name__ == "__main__" :
82129 unittest .main ()
0 commit comments