290 lines
9.5 KiB
Python
290 lines
9.5 KiB
Python
"""Tests for allplayalls.py"""
|
|
|
|
from __future__ import with_statement
|
|
|
|
from textwrap import dedent
|
|
import cPickle as pickle
|
|
|
|
from gomill import competitions
|
|
from gomill import allplayalls
|
|
from gomill.gtp_games import Game_result
|
|
from gomill.game_jobs import Game_job, Game_job_result
|
|
from gomill.competitions import (
|
|
Player_config, NoGameAvailable, CompetitionError, ControlFileError)
|
|
from gomill.allplayalls import Competitor_config
|
|
|
|
from gomill_tests import competition_test_support
|
|
from gomill_tests import gomill_test_support
|
|
from gomill_tests import test_framework
|
|
from gomill_tests.competition_test_support import (
|
|
fake_response, check_screen_report)
|
|
|
|
def make_tests(suite):
|
|
suite.addTests(gomill_test_support.make_simple_tests(globals()))
|
|
|
|
|
|
def check_short_report(tc, comp,
|
|
expected_grid, expected_matchups, expected_players,
|
|
competition_name="testcomp"):
|
|
"""Check that an allplayall's short report is as expected."""
|
|
expected = ("allplayall: %s\n\n%s\n%s\n%s\n" %
|
|
(competition_name, expected_grid,
|
|
expected_matchups, expected_players))
|
|
tc.assertMultiLineEqual(competition_test_support.get_short_report(comp),
|
|
expected)
|
|
|
|
class Allplayall_fixture(test_framework.Fixture):
|
|
"""Fixture setting up a Allplayall.
|
|
|
|
attributes:
|
|
comp -- Allplayall
|
|
|
|
"""
|
|
def __init__(self, tc, config=None):
|
|
if config is None:
|
|
config = default_config()
|
|
self.tc = tc
|
|
self.comp = allplayalls.Allplayall('testcomp')
|
|
self.comp.initialise_from_control_file(config)
|
|
self.comp.set_clean_status()
|
|
|
|
def check_screen_report(self, expected):
|
|
"""Check that the screen report is as expected."""
|
|
check_screen_report(self.tc, self.comp, expected)
|
|
|
|
def check_short_report(self, *args, **kwargs):
|
|
"""Check that the short report is as expected."""
|
|
check_short_report(self.tc, self.comp, *args, **kwargs)
|
|
|
|
|
|
def default_config():
|
|
return {
|
|
'players' : {
|
|
't1' : Player_config("test1"),
|
|
't2' : Player_config("test2"),
|
|
't3' : Player_config("test3"),
|
|
},
|
|
'board_size' : 13,
|
|
'komi' : 7.5,
|
|
'competitors' : [
|
|
Competitor_config('t1'),
|
|
Competitor_config('t2'),
|
|
't3',
|
|
],
|
|
}
|
|
|
|
|
|
|
|
def test_default_config(tc):
|
|
comp = allplayalls.Allplayall('test')
|
|
config = default_config()
|
|
comp.initialise_from_control_file(config)
|
|
comp.set_clean_status()
|
|
tr = comp.get_tournament_results()
|
|
tc.assertListEqual(tr.get_matchup_ids(), ['AvB', 'AvC', 'BvC'])
|
|
mBvC = tr.get_matchup('BvC')
|
|
tc.assertEqual(mBvC.player_1, 't2')
|
|
tc.assertEqual(mBvC.player_2, 't3')
|
|
tc.assertEqual(mBvC.board_size, 13)
|
|
tc.assertEqual(mBvC.komi, 7.5)
|
|
tc.assertEqual(mBvC.move_limit, 1000)
|
|
tc.assertEqual(mBvC.scorer, 'players')
|
|
tc.assertEqual(mBvC.internal_scorer_handicap_compensation, 'full')
|
|
tc.assertEqual(mBvC.number_of_games, None)
|
|
tc.assertIs(mBvC.alternating, True)
|
|
tc.assertIs(mBvC.handicap, None)
|
|
tc.assertEqual(mBvC.handicap_style, 'fixed')
|
|
|
|
def test_basic_config(tc):
|
|
comp = allplayalls.Allplayall('test')
|
|
config = default_config()
|
|
config['description'] = "default\nconfig"
|
|
config['board_size'] = 9
|
|
config['komi'] = 0.5
|
|
config['move_limit'] = 200
|
|
config['scorer'] = 'internal'
|
|
config['internal_scorer_handicap_compensation'] = 'short'
|
|
config['rounds'] = 20
|
|
comp.initialise_from_control_file(config)
|
|
tc.assertEqual(comp.description, "default\nconfig")
|
|
comp.set_clean_status()
|
|
mBvC = comp.get_tournament_results().get_matchup('BvC')
|
|
tc.assertEqual(mBvC.player_1, 't2')
|
|
tc.assertEqual(mBvC.player_2, 't3')
|
|
tc.assertEqual(mBvC.board_size, 9)
|
|
tc.assertEqual(mBvC.komi, 0.5)
|
|
tc.assertEqual(mBvC.move_limit, 200)
|
|
tc.assertEqual(mBvC.scorer, 'internal')
|
|
tc.assertEqual(mBvC.internal_scorer_handicap_compensation, 'short')
|
|
tc.assertEqual(mBvC.number_of_games, 20)
|
|
tc.assertIs(mBvC.alternating, True)
|
|
tc.assertIs(mBvC.handicap, None)
|
|
tc.assertEqual(mBvC.handicap_style, 'fixed')
|
|
|
|
def test_unknown_player(tc):
|
|
comp = allplayalls.Allplayall('test')
|
|
config = default_config()
|
|
config['competitors'].append('nonex')
|
|
tc.assertRaisesRegexp(
|
|
ControlFileError, "competitor nonex: unknown player",
|
|
comp.initialise_from_control_file, config)
|
|
|
|
def test_duplicate_player(tc):
|
|
comp = allplayalls.Allplayall('test')
|
|
config = default_config()
|
|
config['competitors'].append('t2')
|
|
tc.assertRaisesRegexp(
|
|
ControlFileError, "duplicate competitor: t2",
|
|
comp.initialise_from_control_file, config)
|
|
|
|
def test_game_id_format(tc):
|
|
config = default_config()
|
|
config['rounds'] = 1000
|
|
fx = Allplayall_fixture(tc, config)
|
|
tc.assertEqual(fx.comp.get_game().game_id, 'AvB_000')
|
|
|
|
def test_get_player_checks(tc):
|
|
fx = Allplayall_fixture(tc)
|
|
checks = fx.comp.get_player_checks()
|
|
tc.assertEqual(len(checks), 3)
|
|
tc.assertEqual(checks[0].board_size, 13)
|
|
tc.assertEqual(checks[0].komi, 7.5)
|
|
tc.assertEqual(checks[0].player.code, "t1")
|
|
tc.assertEqual(checks[0].player.cmd_args, ['test1'])
|
|
tc.assertEqual(checks[1].player.code, "t2")
|
|
tc.assertEqual(checks[1].player.cmd_args, ['test2'])
|
|
tc.assertEqual(checks[2].player.code, "t3")
|
|
tc.assertEqual(checks[2].player.cmd_args, ['test3'])
|
|
|
|
def test_play(tc):
|
|
fx = Allplayall_fixture(tc)
|
|
tc.assertIsNone(fx.comp.description)
|
|
|
|
job1 = fx.comp.get_game()
|
|
tc.assertIsInstance(job1, Game_job)
|
|
tc.assertEqual(job1.game_id, 'AvB_0')
|
|
tc.assertEqual(job1.player_b.code, 't1')
|
|
tc.assertEqual(job1.player_w.code, 't2')
|
|
tc.assertEqual(job1.board_size, 13)
|
|
tc.assertEqual(job1.komi, 7.5)
|
|
tc.assertEqual(job1.move_limit, 1000)
|
|
tc.assertIs(job1.use_internal_scorer, False)
|
|
tc.assertEqual(job1.internal_scorer_handicap_compensation, 'full')
|
|
tc.assertEqual(job1.game_data, ('AvB', 0))
|
|
tc.assertIsNone(job1.sgf_filename)
|
|
tc.assertIsNone(job1.sgf_dirname)
|
|
tc.assertIsNone(job1.void_sgf_dirname)
|
|
tc.assertEqual(job1.sgf_event, 'testcomp')
|
|
tc.assertIsNone(job1.gtp_log_pathname)
|
|
|
|
job2 = fx.comp.get_game()
|
|
tc.assertIsInstance(job2, Game_job)
|
|
tc.assertEqual(job2.game_id, 'AvC_0')
|
|
tc.assertEqual(job2.player_b.code, 't1')
|
|
tc.assertEqual(job2.player_w.code, 't3')
|
|
|
|
response1 = fake_response(job1, 'b')
|
|
fx.comp.process_game_result(response1)
|
|
response2 = fake_response(job2, None)
|
|
fx.comp.process_game_result(response2)
|
|
|
|
expected_grid = dedent("""\
|
|
2 games played
|
|
|
|
A B C
|
|
A t1 1-0 0.5-0.5
|
|
B t2 0-1 0-0
|
|
C t3 0.5-0.5 0-0
|
|
""")
|
|
expected_matchups = dedent("""\
|
|
t1 v t2 (1 games)
|
|
board size: 13 komi: 7.5
|
|
wins
|
|
t1 1 100.00% (black)
|
|
t2 0 0.00% (white)
|
|
|
|
t1 v t3 (1 games)
|
|
board size: 13 komi: 7.5
|
|
wins
|
|
t1 0.5 50.00% (black)
|
|
t3 0.5 50.00% (white)
|
|
""")
|
|
expected_players = dedent("""\
|
|
player t1: t1 engine:v1.2.3
|
|
player t2: t2 engine
|
|
testdescription
|
|
player t3: t3 engine
|
|
testdescription
|
|
""")
|
|
fx.check_screen_report(expected_grid)
|
|
fx.check_short_report(expected_grid, expected_matchups, expected_players)
|
|
|
|
avb_results = fx.comp.get_tournament_results().get_matchup_results('AvB')
|
|
tc.assertEqual(avb_results, [response1.game_result])
|
|
|
|
def test_play_many(tc):
|
|
config = default_config()
|
|
config['rounds'] = 30
|
|
fx = Allplayall_fixture(tc, config)
|
|
|
|
jobs = [fx.comp.get_game() for _ in xrange(57)]
|
|
for i in xrange(57):
|
|
response = fake_response(jobs[i], 'b')
|
|
fx.comp.process_game_result(response)
|
|
|
|
fx.check_screen_report(dedent("""\
|
|
57/90 games played
|
|
|
|
A B C
|
|
A t1 10-9 10-9
|
|
B t2 9-10 10-9
|
|
C t3 9-10 9-10
|
|
"""))
|
|
|
|
tc.assertEqual(
|
|
len(fx.comp.get_tournament_results().get_matchup_results('AvB')), 19)
|
|
|
|
comp2 = competition_test_support.check_round_trip(tc, fx.comp, config)
|
|
jobs2 = [comp2.get_game() for _ in range(4)]
|
|
tc.assertListEqual([job.game_id for job in jobs2],
|
|
['AvB_19', 'AvC_19', 'BvC_19', 'AvB_20'])
|
|
tr = comp2.get_tournament_results()
|
|
tc.assertEqual(len(tr.get_matchup_results('AvB')), 19)
|
|
ms = tr.get_matchup_stats('AvB')
|
|
tc.assertEqual(ms.total, 19)
|
|
tc.assertEqual(ms.wins_1, 10)
|
|
tc.assertIs(ms.alternating, True)
|
|
|
|
def test_competitor_change(tc):
|
|
fx = Allplayall_fixture(tc)
|
|
status = pickle.loads(pickle.dumps(fx.comp.get_status()))
|
|
|
|
config2 = default_config()
|
|
del config2['competitors'][2]
|
|
comp2 = allplayalls.Allplayall('testcomp')
|
|
comp2.initialise_from_control_file(config2)
|
|
with tc.assertRaises(CompetitionError) as ar:
|
|
comp2.set_status(status)
|
|
tc.assertEqual(
|
|
str(ar.exception),
|
|
"competitor has been removed from control file")
|
|
|
|
config3 = default_config()
|
|
config3['players']['t4'] = Player_config("test4")
|
|
config3['competitors'][2] = 't4'
|
|
comp3 = allplayalls.Allplayall('testcomp')
|
|
comp3.initialise_from_control_file(config3)
|
|
with tc.assertRaises(CompetitionError) as ar:
|
|
comp3.set_status(status)
|
|
tc.assertEqual(
|
|
str(ar.exception),
|
|
"competitors have changed in the control file")
|
|
|
|
config4 = default_config()
|
|
config4['players']['t4'] = Player_config("test4")
|
|
config4['competitors'].append('t4')
|
|
comp4 = allplayalls.Allplayall('testcomp')
|
|
comp4.initialise_from_control_file(config4)
|
|
comp4.set_status(status)
|
|
|