Skip to content

Commit 002b0a8

Browse files
authored
External move test refactor (#1162)
* Separate each external move source into own test * Create TEMP directory only when needed * Soft fail tests when online sources do not respond Report tests failing when online move sources respond with errors, but don't fail the tests since lichess-bot is not the source of the failure. * Fix alignment * Report when online move sources are down Rather than passing with no message.
1 parent 97fab31 commit 002b0a8

1 file changed

Lines changed: 133 additions & 45 deletions

File tree

test_bot/test_external_moves.py

Lines changed: 133 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Test the functions that get the external moves."""
2+
import pytest
23
import backoff
34
import requests
45
import yaml
@@ -109,26 +110,31 @@ def download_opening_book() -> None:
109110
"""Download gm2001.bin."""
110111
if os.path.exists("./TEMP/gm2001.bin"):
111112
return
113+
114+
os.makedirs("TEMP", exist_ok=True)
112115
response = requests.get("https://github.com/gmcheems-org/free-opening-books/raw/main/books/bin/gm2001.bin",
113116
allow_redirects=True)
117+
if response.status_code != 200:
118+
pytest.xfail("Could not download opening book.")
114119
with open("./TEMP/gm2001.bin", "wb") as file:
115120
file.write(response.content)
116121

117122

118-
os.makedirs("TEMP", exist_ok=True)
119-
120-
121123
def get_online_move_wrapper(li: Lichess, board: chess.Board, game: Game, online_moves_cfg: Configuration,
122-
draw_or_resign_cfg: Configuration) -> chess.engine.PlayResult:
124+
draw_or_resign_cfg: Configuration, *, expect_none: bool = False) -> chess.engine.PlayResult:
123125
"""Wrap `lib.engine_wrapper.get_online_move` so that it only returns a PlayResult type."""
124-
return cast(chess.engine.PlayResult, get_online_move(li, board, game, online_moves_cfg, draw_or_resign_cfg))
126+
online_move = get_online_move(li, board, game, online_moves_cfg, draw_or_resign_cfg)
127+
online_move = cast(chess.engine.PlayResult, online_move)
128+
if not expect_none and online_move.move is None:
129+
pytest.xfail("Could not contact external move source.")
130+
return online_move
125131

126132

127-
def test_external_moves() -> None:
133+
class TestExternalMoves:
128134
"""Test that the code for external moves works properly."""
135+
129136
li = MockLichess()
130137
game = get_game()
131-
download_opening_book()
132138
online_cfg, online_cfg_2, draw_or_resign_cfg, polyglot_cfg = get_configs()
133139

134140
starting_fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
@@ -138,49 +144,131 @@ def test_external_moves() -> None:
138144
endgame_wdl1_fen = "6N1/3n4/3k1b2/8/8/7Q/1r6/5K2 b - - 6 9"
139145
endgame_wdl0_fen = "6N1/3n4/3k1b2/8/8/7Q/5K2/1r6 b - - 8 10"
140146

141-
is_lichess_org_up = li.is_website_up("https://lichess.org/api/cloud-eval")
142-
is_lichess_ovh_up = li.is_website_up("https://tablebase.lichess.ovh/standard")
143-
is_chessdb_cn_up = li.is_website_up("https://www.chessdb.cn/cdb.php")
144-
145-
# Test lichess_cloud_analysis.
146-
if is_lichess_org_up:
147-
assert get_online_move_wrapper(li, chess.Board(starting_fen), game, online_cfg, draw_or_resign_cfg).move is not None
148-
assert get_online_move_wrapper(li, chess.Board(opening_fen), game, online_cfg, draw_or_resign_cfg).move is not None
149-
assert get_online_move_wrapper(li, chess.Board(middlegame_fen), game, online_cfg, draw_or_resign_cfg).move is None
150-
151-
# Test chessdb_book.
152-
if is_chessdb_cn_up:
153-
assert get_online_move_wrapper(li, chess.Board(starting_fen), game, online_cfg_2, draw_or_resign_cfg).move is not None
154-
assert get_online_move_wrapper(li, chess.Board(opening_fen), game, online_cfg_2, draw_or_resign_cfg).move is not None
155-
assert get_online_move_wrapper(li, chess.Board(middlegame_fen), game, online_cfg_2, draw_or_resign_cfg).move is None
156-
157-
# Test online_egtb with lichess.
158-
if is_lichess_ovh_up:
159-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl2_fen), game, online_cfg, draw_or_resign_cfg).resigned
160-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl0_fen), game, online_cfg, draw_or_resign_cfg).draw_offered
161-
wdl1_move = get_online_move_wrapper(li, chess.Board(endgame_wdl1_fen), game, online_cfg, draw_or_resign_cfg)
147+
def test_lichess_cloud_analysis(self) -> None:
148+
"""Test lichess_cloud_analysis."""
149+
if not self.li.is_website_up("https://lichess.org/api/cloud-eval"):
150+
pytest.xfail("Lichess cloud eval is down.")
151+
152+
assert get_online_move_wrapper(self.li,
153+
chess.Board(self.starting_fen),
154+
self.game,
155+
self.online_cfg,
156+
self.draw_or_resign_cfg).move is not None
157+
assert get_online_move_wrapper(self.li,
158+
chess.Board(self.opening_fen),
159+
self.game,
160+
self.online_cfg,
161+
self.draw_or_resign_cfg).move is not None
162+
assert get_online_move_wrapper(self.li,
163+
chess.Board(self.middlegame_fen),
164+
self.game,
165+
self.online_cfg,
166+
self.draw_or_resign_cfg,
167+
expect_none=True).move is None
168+
169+
def test_chessdb_book(self) -> None:
170+
"""Test chessdb_book."""
171+
if not self.li.is_website_up("https://www.chessdb.cn/cdb.php"):
172+
pytest.xfail("ChessDB is down.")
173+
174+
assert get_online_move_wrapper(self.li,
175+
chess.Board(self.starting_fen),
176+
self.game,
177+
self.online_cfg_2,
178+
self.draw_or_resign_cfg).move is not None
179+
assert get_online_move_wrapper(self.li,
180+
chess.Board(self.opening_fen),
181+
self.game,
182+
self.online_cfg_2,
183+
self.draw_or_resign_cfg).move is not None
184+
assert get_online_move_wrapper(self.li,
185+
chess.Board(self.middlegame_fen),
186+
self.game,
187+
self.online_cfg_2,
188+
self.draw_or_resign_cfg,
189+
expect_none=True).move is None
190+
191+
def test_online_egtb_with_lichess(self) -> None:
192+
"""Test online_egtb with lichess."""
193+
if not self.li.is_website_up("https://tablebase.lichess.ovh/standard"):
194+
pytest.xfail("Lichess tablebase is down.")
195+
196+
assert get_online_move_wrapper(self.li,
197+
chess.Board(self.endgame_wdl2_fen),
198+
self.game,
199+
self.online_cfg,
200+
self.draw_or_resign_cfg).resigned
201+
assert get_online_move_wrapper(self.li,
202+
chess.Board(self.endgame_wdl0_fen),
203+
self.game,
204+
self.online_cfg,
205+
self.draw_or_resign_cfg).draw_offered
206+
wdl1_move = get_online_move_wrapper(self.li,
207+
chess.Board(self.endgame_wdl1_fen),
208+
self.game,
209+
self.online_cfg,
210+
self.draw_or_resign_cfg)
162211
assert not wdl1_move.resigned and not wdl1_move.draw_offered
212+
163213
# Test with reversed colors.
164-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl2_fen).mirror(), game, online_cfg,
165-
draw_or_resign_cfg).resigned
166-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl0_fen).mirror(), game, online_cfg,
167-
draw_or_resign_cfg).draw_offered
168-
wdl1_move = get_online_move_wrapper(li, chess.Board(endgame_wdl1_fen).mirror(), game, online_cfg, draw_or_resign_cfg)
214+
assert get_online_move_wrapper(self.li,
215+
chess.Board(self.endgame_wdl2_fen).mirror(),
216+
self.game,
217+
self.online_cfg,
218+
self.draw_or_resign_cfg).resigned
219+
assert get_online_move_wrapper(self.li,
220+
chess.Board(self.endgame_wdl0_fen).mirror(),
221+
self.game,
222+
self.online_cfg,
223+
self.draw_or_resign_cfg).draw_offered
224+
wdl1_move = get_online_move_wrapper(self.li,
225+
chess.Board(self.endgame_wdl1_fen).mirror(),
226+
self.game,
227+
self.online_cfg,
228+
self.draw_or_resign_cfg)
169229
assert not wdl1_move.resigned and not wdl1_move.draw_offered
170230

171-
# Test online_egtb with chessdb.
172-
if is_chessdb_cn_up:
173-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl2_fen), game, online_cfg_2, draw_or_resign_cfg).resigned
174-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl0_fen), game, online_cfg_2, draw_or_resign_cfg).draw_offered
175-
wdl1_move = get_online_move_wrapper(li, chess.Board(endgame_wdl1_fen), game, online_cfg_2, draw_or_resign_cfg)
231+
def test_online_egtb_with_chessdb(self) -> None:
232+
"""Test online_egtb with chessdb."""
233+
if not self.li.is_website_up("https://www.chessdb.cn/cdb.php"):
234+
pytest.xfail("ChessDB is down.")
235+
236+
assert get_online_move_wrapper(self.li,
237+
chess.Board(self.endgame_wdl2_fen),
238+
self.game,
239+
self.online_cfg_2,
240+
self.draw_or_resign_cfg).resigned
241+
assert get_online_move_wrapper(self.li,
242+
chess.Board(self.endgame_wdl0_fen),
243+
self.game,
244+
self.online_cfg_2,
245+
self.draw_or_resign_cfg).draw_offered
246+
wdl1_move = get_online_move_wrapper(self.li,
247+
chess.Board(self.endgame_wdl1_fen),
248+
self.game,
249+
self.online_cfg_2,
250+
self.draw_or_resign_cfg)
176251
assert not wdl1_move.resigned and not wdl1_move.draw_offered
252+
177253
# Test with reversed colors.
178-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl2_fen).mirror(), game, online_cfg_2,
179-
draw_or_resign_cfg).resigned
180-
assert get_online_move_wrapper(li, chess.Board(endgame_wdl0_fen).mirror(), game, online_cfg_2,
181-
draw_or_resign_cfg).draw_offered
182-
wdl1_move = get_online_move_wrapper(li, chess.Board(endgame_wdl1_fen).mirror(), game, online_cfg_2, draw_or_resign_cfg)
254+
assert get_online_move_wrapper(self.li,
255+
chess.Board(self.endgame_wdl2_fen).mirror(),
256+
self.game,
257+
self.online_cfg_2,
258+
self.draw_or_resign_cfg).resigned
259+
assert get_online_move_wrapper(self.li,
260+
chess.Board(self.endgame_wdl0_fen).mirror(),
261+
self.game,
262+
self.online_cfg_2,
263+
self.draw_or_resign_cfg).draw_offered
264+
wdl1_move = get_online_move_wrapper(self.li,
265+
chess.Board(self.endgame_wdl1_fen).mirror(),
266+
self.game,
267+
self.online_cfg_2,
268+
self.draw_or_resign_cfg)
183269
assert not wdl1_move.resigned and not wdl1_move.draw_offered
184270

185-
# Test opening book.
186-
assert get_book_move(chess.Board(opening_fen), game, polyglot_cfg).move == chess.Move.from_uci("h4f6")
271+
def test_opening_book(self) -> None:
272+
"""Test opening book."""
273+
download_opening_book()
274+
assert get_book_move(chess.Board(self.opening_fen), self.game, self.polyglot_cfg).move == chess.Move.from_uci("h4f6")

0 commit comments

Comments
 (0)