Coverage for mlos_bench/mlos_bench/tests/environments/test_status.py: 100%

40 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-14 00:55 +0000

1# 

2# Copyright (c) Microsoft Corporation. 

3# Licensed under the MIT License. 

4# 

5""" 

6Unit tests for the :py:class:`mlos_bench.environments.status.Status` class. 

7 

8Tests the :py:meth:`mlos_bench.environments.status.Status.from_str` static method 

9for correct parsing of both numeric and string representations of each Status, 

10as well as handling of invalid input. 

11""" 

12 

13from typing import Any 

14 

15import pytest 

16 

17from mlos_bench.environments.status import Status 

18 

19 

20@pytest.mark.parametrize( 

21 ["input_str", "expected_status"], 

22 [ 

23 ("UNKNOWN", Status.UNKNOWN), 

24 ("0", Status.UNKNOWN), 

25 ("PENDING", Status.PENDING), 

26 ("1", Status.PENDING), 

27 ("READY", Status.READY), 

28 ("2", Status.READY), 

29 ("RUNNING", Status.RUNNING), 

30 ("3", Status.RUNNING), 

31 ("SUCCEEDED", Status.SUCCEEDED), 

32 ("4", Status.SUCCEEDED), 

33 ("CANCELED", Status.CANCELED), 

34 ("5", Status.CANCELED), 

35 ("FAILED", Status.FAILED), 

36 ("6", Status.FAILED), 

37 ("TIMED_OUT", Status.TIMED_OUT), 

38 ("7", Status.TIMED_OUT), 

39 (" TIMED_OUT ", Status.TIMED_OUT), 

40 ], 

41) 

42def test_status_from_str_valid(input_str: str, expected_status: Status) -> None: 

43 """ 

44 Test :py:meth:`Status.from_str` with valid string and numeric representations. 

45 

46 Parameters 

47 ---------- 

48 input_str : str 

49 String representation of the status. 

50 expected_status : Status 

51 Expected Status enum value. 

52 """ 

53 assert ( 

54 Status.parse(input_str) == expected_status 

55 ), f"Expected {expected_status} for input: {input_str}" 

56 # Check lowercase representation 

57 assert ( 

58 Status.parse(input_str.lower()) == expected_status 

59 ), f"Expected {expected_status} for input: {input_str.lower()}" 

60 assert ( 

61 Status.parse(expected_status) == expected_status 

62 ), f"Expected {expected_status} for input: {expected_status}" 

63 if input_str.isdigit(): 

64 # Also test the numeric representation 

65 assert ( 

66 Status.parse(int(input_str)) == expected_status 

67 ), f"Expected {expected_status} for input: {int(input_str)}" 

68 

69 

70@pytest.mark.parametrize( 

71 "invalid_input", 

72 [ 

73 "UNKNOWABLE", 

74 "8", 

75 "-1", 

76 "successful", 

77 "", 

78 None, 

79 123, 

80 [], 

81 {}, 

82 ], 

83) 

84def test_status_from_str_invalid(invalid_input: Any) -> None: 

85 """Test :py:meth:`Status.from_str` returns :py:attr:`Status.UNKNOWN` for invalid 

86 input. 

87 """ 

88 assert ( 

89 Status.parse(invalid_input) == Status.UNKNOWN 

90 ), f"Expected Status.UNKNOWN for invalid input: {invalid_input}" 

91 

92 

93@pytest.mark.parametrize( 

94 ["status", "expected_result"], 

95 [ 

96 (Status.UNKNOWN, False), 

97 (Status.PENDING, True), 

98 (Status.READY, True), 

99 (Status.RUNNING, True), 

100 (Status.SUCCEEDED, True), 

101 (Status.CANCELED, False), 

102 (Status.FAILED, False), 

103 (Status.TIMED_OUT, False), 

104 ], 

105) 

106def test_status_is_good(status: Status, expected_result: bool) -> None: 

107 """ 

108 Test :py:meth:`Status.is_good` for various statuses. 

109 

110 Parameters 

111 ---------- 

112 status : Status 

113 The Status enum value to test. 

114 expected_result : bool 

115 Expected result of the is_good method. 

116 """ 

117 assert status.is_good() == expected_result, f"Expected {expected_result} for status: {status}" 

118 

119 

120@pytest.mark.parametrize( 

121 ["status", "expected_result"], 

122 [ 

123 (Status.UNKNOWN, False), 

124 (Status.PENDING, False), 

125 (Status.READY, False), 

126 (Status.RUNNING, False), 

127 (Status.SUCCEEDED, True), 

128 (Status.CANCELED, True), 

129 (Status.FAILED, True), 

130 (Status.TIMED_OUT, True), 

131 ], 

132) 

133def test_status_is_completed(status: Status, expected_result: bool) -> None: 

134 """ 

135 Test :py:meth:`Status.is_completed` for various statuses. 

136 

137 Parameters 

138 ---------- 

139 status : Status 

140 The Status enum value to test. 

141 expected_result : bool 

142 Expected result of the is_completed method. 

143 """ 

144 assert ( 

145 status.is_completed() == expected_result 

146 ), f"Expected {expected_result} for status: {status}" 

147 

148 

149@pytest.mark.parametrize( 

150 ["status", "expected_result"], 

151 [ 

152 (Status.UNKNOWN, False), 

153 (Status.PENDING, True), 

154 (Status.READY, False), 

155 (Status.RUNNING, False), 

156 (Status.SUCCEEDED, False), 

157 (Status.CANCELED, False), 

158 (Status.FAILED, False), 

159 (Status.TIMED_OUT, False), 

160 ], 

161) 

162def test_status_is_pending(status: Status, expected_result: bool) -> None: 

163 """ 

164 Test :py:meth:`Status.is_pending` for various statuses. 

165 

166 Parameters 

167 ---------- 

168 status : Status 

169 The Status enum value to test. 

170 expected_result : bool 

171 Expected result of the is_pending method. 

172 """ 

173 assert ( 

174 status.is_pending() == expected_result 

175 ), f"Expected {expected_result} for status: {status}" 

176 

177 

178@pytest.mark.parametrize( 

179 ["status", "expected_result"], 

180 [ 

181 (Status.UNKNOWN, False), 

182 (Status.PENDING, False), 

183 (Status.READY, True), 

184 (Status.RUNNING, False), 

185 (Status.SUCCEEDED, False), 

186 (Status.CANCELED, False), 

187 (Status.FAILED, False), 

188 (Status.TIMED_OUT, False), 

189 ], 

190) 

191def test_status_is_ready(status: Status, expected_result: bool) -> None: 

192 """ 

193 Test :py:meth:`Status.is_ready` for various statuses. 

194 

195 Parameters 

196 ---------- 

197 status : Status 

198 The Status enum value to test. 

199 expected_result : bool 

200 Expected result of the is_ready method. 

201 """ 

202 assert status.is_ready() == expected_result, f"Expected {expected_result} for status: {status}" 

203 

204 

205@pytest.mark.parametrize( 

206 ["status", "expected_result"], 

207 [ 

208 (Status.UNKNOWN, False), 

209 (Status.PENDING, False), 

210 (Status.READY, False), 

211 (Status.RUNNING, True), 

212 (Status.SUCCEEDED, False), 

213 (Status.CANCELED, False), 

214 (Status.FAILED, False), 

215 (Status.TIMED_OUT, False), 

216 ], 

217) 

218def test_status_is_running(status: Status, expected_result: bool) -> None: 

219 """ 

220 Test :py:meth:`Status.is_running` for various statuses. 

221 

222 Parameters 

223 ---------- 

224 status : Status 

225 The Status enum value to test. 

226 expected_result : bool 

227 Expected result of the is_running method. 

228 """ 

229 assert ( 

230 status.is_running() == expected_result 

231 ), f"Expected {expected_result} for status: {status}" 

232 

233 

234@pytest.mark.parametrize( 

235 ["status", "expected_result"], 

236 [ 

237 (Status.UNKNOWN, False), 

238 (Status.PENDING, False), 

239 (Status.READY, False), 

240 (Status.RUNNING, False), 

241 (Status.SUCCEEDED, True), 

242 (Status.CANCELED, False), 

243 (Status.FAILED, False), 

244 (Status.TIMED_OUT, False), 

245 ], 

246) 

247def test_status_is_succeeded(status: Status, expected_result: bool) -> None: 

248 """ 

249 Test :py:meth:`Status.is_succeeded` for various statuses. 

250 

251 Parameters 

252 ---------- 

253 status : Status 

254 The Status enum value to test. 

255 expected_result : bool 

256 Expected result of the is_succeeded method. 

257 """ 

258 assert ( 

259 status.is_succeeded() == expected_result 

260 ), f"Expected {expected_result} for status: {status}" 

261 

262 

263@pytest.mark.parametrize( 

264 ["status", "expected_result"], 

265 [ 

266 (Status.UNKNOWN, False), 

267 (Status.PENDING, False), 

268 (Status.READY, False), 

269 (Status.RUNNING, False), 

270 (Status.SUCCEEDED, False), 

271 (Status.CANCELED, True), 

272 (Status.FAILED, False), 

273 (Status.TIMED_OUT, False), 

274 ], 

275) 

276def test_status_is_canceled(status: Status, expected_result: bool) -> None: 

277 """ 

278 Test :py:meth:`Status.is_canceled` for various statuses. 

279 

280 Parameters 

281 ---------- 

282 status : Status 

283 The Status enum value to test. 

284 expected_result : bool 

285 Expected result of the is_canceled method. 

286 """ 

287 assert ( 

288 status.is_canceled() == expected_result 

289 ), f"Expected {expected_result} for status: {status}" 

290 

291 

292@pytest.mark.parametrize( 

293 ["status", "expected_result"], 

294 [ 

295 (Status.UNKNOWN, False), 

296 (Status.PENDING, False), 

297 (Status.READY, False), 

298 (Status.RUNNING, False), 

299 (Status.SUCCEEDED, False), 

300 (Status.CANCELED, False), 

301 (Status.FAILED, True), 

302 (Status.TIMED_OUT, False), 

303 ], 

304) 

305def test_status_is_failed(status: Status, expected_result: bool) -> None: 

306 """ 

307 Test :py:meth:`Status.is_failed` for various statuses. 

308 

309 Parameters 

310 ---------- 

311 status : Status 

312 The Status enum value to test. 

313 expected_result : bool 

314 Expected result of the is_failed method. 

315 """ 

316 assert ( 

317 status.is_failed() == expected_result 

318 ), f"Expected {expected_result} for status: {status}" 

319 

320 

321@pytest.mark.parametrize( 

322 ["status", "expected_result"], 

323 [ 

324 (Status.UNKNOWN, False), 

325 (Status.PENDING, False), 

326 (Status.READY, False), 

327 (Status.RUNNING, False), 

328 (Status.SUCCEEDED, False), 

329 (Status.CANCELED, False), 

330 (Status.FAILED, False), 

331 (Status.TIMED_OUT, True), 

332 ], 

333) 

334def test_status_is_timed_out(status: Status, expected_result: bool) -> None: 

335 """ 

336 Test :py:meth:`Status.is_timed_out` for various statuses. 

337 

338 Parameters 

339 ---------- 

340 status : Status 

341 The Status enum value to test. 

342 expected_result : bool 

343 Expected result of the is_timed_out method. 

344 """ 

345 assert ( 

346 status.is_timed_out() == expected_result 

347 ), f"Expected {expected_result} for status: {status}"