def test_parallel_play(self): # Test that we get an instance of ResultSet tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) results = tournament.play(processes=2, progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(tournament.num_interactions, 75) # The following relates to #516 players = [ axelrod.Cooperator(), axelrod.Defector(), axelrod.BackStabber(), axelrod.PSOGambler2_2_2(), axelrod.ThueMorse(), axelrod.DoubleCrosser(), ] tournament = axelrod.Tournament( name=self.test_name, players=players, game=self.game, turns=20, repetitions=self.test_repetitions, ) scores = tournament.play(processes=2, progress_bar=False).scores self.assertEqual(len(scores), len(players))
def test_score_with_particular_players(self): """ These are players that are known to be difficult to pickle """ name = "score" turns = 10 noise = 0 repetitions = 5 num_states = 2 opponents = [axl.ThueMorse(), axl.MetaHunter(), axl.BackStabber(), axl.Alexei()] size = 10 objective = dojo.prepare_objective(name=name, turns=turns, noise=noise, repetitions=repetitions) population = dojo.Population(player_class=player_class, params_kwargs={"num_states": num_states}, size=size, objective=objective, output_filename=self.temporary_file.name, opponents=opponents, bottleneck=2, mutation_probability = .01, processes=0) generations = 4 axl.seed(0) population.run(generations, print_output=False) self.assertEqual(population.generation, 4)
def test_parallel_play(self): # Test that we get an instance of ResultSet tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions, processes=2) results = tournament.play() self.assertIsInstance(results, axelrod.ResultSet) # The following relates to #516 players = [axelrod.Cooperator(), axelrod.Defector(), axelrod.BackStabber(), axelrod.PSOGambler(), axelrod.ThueMorse(), axelrod.DoubleCrosser()] tournament = axelrod.Tournament( name=self.test_name, players=players, game=self.game, turns=20, repetitions=self.test_repetitions, processes=2) scores = tournament.play().scores self.assertEqual(len(scores), len(players))
class TestProbEndTournament(unittest.TestCase): @classmethod def setUpClass(cls): cls.game = axelrod.Game() cls.players = [s() for s in test_strategies] cls.test_name = 'test' cls.test_repetitions = test_repetitions cls.test_prob_end = test_prob_end def test_init(self): tournament = axelrod.ProbEndTournament(name=self.test_name, players=self.players, game=self.game, prob_end=self.test_prob_end, noise=0.2) self.assertEqual(tournament.match_generator.prob_end, tournament.prob_end) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertEqual(tournament.game.score(('C', 'C')), (3, 3)) self.assertEqual(tournament.turns, float("inf")) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, 'test') self.assertTrue(tournament._with_morality) self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) anonymous_tournament = axelrod.Tournament(players=self.players) self.assertEqual(anonymous_tournament.name, 'axelrod') @given(tournament=prob_end_tournaments(min_size=2, max_size=5, min_prob_end=.1, max_prob_end=.9, min_repetitions=2, max_repetitions=4)) @settings(max_examples=50, timeout=0) @example(tournament=axelrod.ProbEndTournament( players=[s() for s in test_strategies], prob_end=.2, repetitions=test_repetitions)) # These two examples are to make sure #465 is fixed. # As explained there: https://github.com/Axelrod-Python/Axelrod/issues/465, # these two examples were identified by hypothesis. @example(tournament=axelrod.ProbEndTournament( players=[axelrod.BackStabber(), axelrod.MindReader()], prob_end=.2, repetitions=1)) @example(tournament=axelrod.ProbEndTournament( players=[axelrod.ThueMorse(), axelrod.MindReader()], prob_end=.2, repetitions=1)) def test_property_serial_play(self, tournament): """Test serial play using hypothesis""" # Test that we get an instance of ResultSet results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(results.nplayers, len(tournament.players)) self.assertEqual(results.players, [str(p) for p in tournament.players])
def test_sequence_player(self): inline_transformed_thue = axl.strategy_transformers.IdentityTransformer( name_prefix="Transformed")(axl.ThueMorse)() for player in [ axl.ThueMorse(), axl.ThueMorseInverse(), MetaThue(), TransformedMetaThue(), inline_transformed_thue, TransformedThue(), ]: self.assert_equals_instance_from_pickling(player) opponents = (axl.Defector, axl.Cooperator, axl.Random, axl.CyclerCCCDCD) for opponent_class in opponents: player.reset() opponent = opponent_class() match_1 = axl.Match((player, opponent), turns=20, seed=10) _ = match_1.play() self.assert_equals_instance_from_pickling(player)
def test_sequence_player(self): player = axl.ThueMorse() self.assert_orignal_equals_pickled(player)
class TestTournament(unittest.TestCase): @classmethod def setUpClass(cls): cls.game = axelrod.Game() cls.players = [s() for s in test_strategies] cls.test_name = "test" cls.test_repetitions = test_repetitions cls.test_turns = test_turns cls.expected_payoff = [ [600, 600, 0, 600, 600], [600, 600, 199, 600, 600], [1000, 204, 200, 204, 204], [600, 600, 199, 600, 600], [600, 600, 199, 600, 600], ] cls.expected_cooperation = [ [200, 200, 200, 200, 200], [200, 200, 1, 200, 200], [0, 0, 0, 0, 0], [200, 200, 1, 200, 200], [200, 200, 1, 200, 200], ] cls.filename = "test_outputs/test_tournament.csv" def setUp(self): self.test_tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=2, repetitions=1, ) def test_init(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=self.test_turns, noise=0.2, ) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertIsInstance(tournament.players[0].match_attributes["game"], axelrod.Game) self.assertEqual(tournament.game.score((C, C)), (3, 3)) self.assertEqual(tournament.turns, self.test_turns) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, "test") self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) anonymous_tournament = axelrod.Tournament(players=self.players) self.assertEqual(anonymous_tournament.name, "axelrod") def test_init_with_match_attributes(self): tournament = axelrod.Tournament( players=self.players, match_attributes={"length": float("inf")}) mg = tournament.match_generator match_params = mg.build_single_match_params() self.assertEqual(match_params["match_attributes"], {"length": float("inf")}) def test_warning(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=10, repetitions=1, ) with warnings.catch_warnings(record=True) as w: # Check that a warning is raised if no results set is built and no # filename is given results = tournament.play(build_results=False, progress_bar=False) self.assertEqual(len(w), 1) with warnings.catch_warnings(record=True) as w: # Check that no warning is raised if no results set is built and a # is filename given tournament.play(build_results=False, filename=self.filename, progress_bar=False) self.assertEqual(len(w), 0) def test_setup_output_with_filename(self): self.test_tournament.setup_output(self.filename) self.assertEqual(self.test_tournament.filename, self.filename) self.assertIsNone(self.test_tournament._temp_file_descriptor) self.assertFalse(hasattr(self.test_tournament, "interactions_dict")) def test_setup_output_no_filename(self): self.test_tournament.setup_output() self.assertIsInstance(self.test_tournament.filename, str) self.assertIsInstance(self.test_tournament._temp_file_descriptor, int) self.assertFalse(hasattr(self.test_tournament, "interactions_dict")) os.close(self.test_tournament._temp_file_descriptor) os.remove(self.test_tournament.filename) def test_play_resets_num_interactions(self): self.assertEqual(self.test_tournament.num_interactions, 0) self.test_tournament.play(progress_bar=False) self.assertEqual(self.test_tournament.num_interactions, 15) self.test_tournament.play(progress_bar=False) self.assertEqual(self.test_tournament.num_interactions, 15) def test_play_changes_use_progress_bar(self): self.assertTrue(self.test_tournament.use_progress_bar) self.test_tournament.play(progress_bar=False) self.assertFalse(self.test_tournament.use_progress_bar) self.test_tournament.play(progress_bar=True) self.assertTrue(self.test_tournament.use_progress_bar) def test_play_changes_temp_file_descriptor(self): self.assertIsNone(self.test_tournament._temp_file_descriptor) # No file descriptor for a named file. self.test_tournament.play(filename=self.filename, progress_bar=False) self.assertIsNone(self.test_tournament._temp_file_descriptor) # Temp file creates file descriptor. self.test_tournament.play(filename=None, progress_bar=False) self.assertIsInstance(self.test_tournament._temp_file_descriptor, int) def test_play_tempfile_removed(self): self.test_tournament.play(filename=None, progress_bar=False) self.assertFalse(os.path.isfile(self.test_tournament.filename)) def test_play_resets_filename_and_temp_file_descriptor_each_time(self): self.test_tournament.play(progress_bar=False) self.assertIsInstance(self.test_tournament._temp_file_descriptor, int) self.assertIsInstance(self.test_tournament.filename, str) old_filename = self.test_tournament.filename self.test_tournament.play(filename=self.filename, progress_bar=False) self.assertIsNone(self.test_tournament._temp_file_descriptor) self.assertEqual(self.test_tournament.filename, self.filename) self.assertNotEqual(old_filename, self.test_tournament.filename) self.test_tournament.play(progress_bar=False) self.assertIsInstance(self.test_tournament._temp_file_descriptor, int) self.assertIsInstance(self.test_tournament.filename, str) self.assertNotEqual(old_filename, self.test_tournament.filename) self.assertNotEqual(self.test_tournament.filename, self.filename) def test_get_file_objects_no_filename(self): file, writer = self.test_tournament._get_file_objects() self.assertIsNone(file) self.assertIsNone(writer) def test_get_file_object_with_filename(self): self.test_tournament.filename = self.filename file_object, writer = self.test_tournament._get_file_objects() self.assertIsInstance(file_object, io.TextIOWrapper) self.assertEqual(writer.__class__.__name__, "writer") file_object.close() def test_get_progress_bar(self): self.test_tournament.use_progress_bar = False pbar = self.test_tournament._get_progress_bar() self.assertIsNone(pbar) self.test_tournament.use_progress_bar = True pbar = self.test_tournament._get_progress_bar() self.assertIsInstance(pbar, tqdm) self.assertEqual(pbar.desc, "Playing matches") self.assertEqual(pbar.n, 0) self.assertEqual(pbar.total, self.test_tournament.match_generator.size) new_edges = [(0, 1), (1, 2), (2, 3), (3, 4)] new_tournament = axelrod.Tournament(players=self.players, edges=new_edges) new_tournament.use_progress_bar = True pbar = new_tournament._get_progress_bar() self.assertEqual(pbar.desc, "Playing matches") self.assertEqual(pbar.n, 0) self.assertEqual(pbar.total, len(new_edges)) def test_serial_play(self): # Test that we get an instance of ResultSet tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) # Test that _run_serial_repetitions is called with empty matches list tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) results = tournament.play(progress_bar=False) self.assertEqual(tournament.num_interactions, 75) def test_serial_play_with_different_game(self): # Test that a non default game is passed to the result set game = axelrod.Game(p=-1, r=-1, s=-1, t=-1) tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=game, turns=1, repetitions=1) results = tournament.play(progress_bar=False) self.assertLessEqual(np.max(results.scores), 0) @patch("tqdm.tqdm", RecordedTQDM) def test_no_progress_bar_play(self): """Test that progress bar is not created for progress_bar=False""" tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) # Test with build results RecordedTQDM.reset_record() results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) # Check that no progress bar was created. self.assertEqual(RecordedTQDM.record, []) # Test without build results RecordedTQDM.reset_record() results = tournament.play(progress_bar=False, build_results=False, filename=self.filename) self.assertIsNone(results) self.assertEqual(RecordedTQDM.record, []) def assert_play_pbar_correct_total_and_finished(self, pbar, total): self.assertEqual(pbar.desc, "Playing matches") self.assertEqual(pbar.total, total) self.assertEqual(pbar.n, total) self.assertTrue(pbar.disable, True) @patch("tqdm.tqdm", RecordedTQDM) def test_progress_bar_play(self): """Test that progress bar is created by default and with True argument""" tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) RecordedTQDM.reset_record() results = tournament.play() self.assertIsInstance(results, axelrod.ResultSet) # Check that progress bar was created, updated and closed. self.assertEqual(len(RecordedTQDM.record), 2) play_pbar = RecordedTQDM.record[0] self.assert_play_pbar_correct_total_and_finished(play_pbar, total=15) # Check all progress bars are closed. self.assertTrue(all(pbar.disable for pbar in RecordedTQDM.record)) RecordedTQDM.reset_record() results = tournament.play(progress_bar=True) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(len(RecordedTQDM.record), 2) play_pbar = RecordedTQDM.record[0] self.assert_play_pbar_correct_total_and_finished(play_pbar, total=15) # Test without build results RecordedTQDM.reset_record() results = tournament.play(progress_bar=True, build_results=False, filename=self.filename) self.assertIsNone(results) self.assertEqual(len(RecordedTQDM.record), 1) play_pbar = RecordedTQDM.record[0] self.assert_play_pbar_correct_total_and_finished(play_pbar, total=15) @patch("tqdm.tqdm", RecordedTQDM) def test_progress_bar_play_parallel(self): """Test that tournament plays when asking for progress bar for parallel tournament and that progress bar is created.""" tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) # progress_bar = False RecordedTQDM.reset_record() results = tournament.play(progress_bar=False, processes=2) self.assertEqual(RecordedTQDM.record, []) self.assertIsInstance(results, axelrod.ResultSet) # progress_bar = True RecordedTQDM.reset_record() results = tournament.play(progress_bar=True, processes=2) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(len(RecordedTQDM.record), 2) play_pbar = RecordedTQDM.record[0] self.assert_play_pbar_correct_total_and_finished(play_pbar, total=15) # progress_bar is default RecordedTQDM.reset_record() results = tournament.play(processes=2) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(len(RecordedTQDM.record), 2) play_pbar = RecordedTQDM.record[0] self.assert_play_pbar_correct_total_and_finished(play_pbar, total=15) @given(tournament=tournaments( min_size=2, max_size=5, min_turns=2, max_turns=5, min_repetitions=2, max_repetitions=4, )) @settings(max_examples=5, max_iterations=20) @example(tournament=axelrod.Tournament( players=[s() for s in test_strategies], turns=test_turns, repetitions=test_repetitions, )) # These two examples are to make sure #465 is fixed. # As explained there: https://github.com/Axelrod-Python/Axelrod/issues/465, # these two examples were identified by hypothesis. @example(tournament=axelrod.Tournament( players=[axelrod.BackStabber(), axelrod.MindReader()], turns=2, repetitions=1, )) @example(tournament=axelrod.Tournament( players=[axelrod.BackStabber(), axelrod.ThueMorse()], turns=2, repetitions=1)) def test_property_serial_play(self, tournament): """Test serial play using hypothesis""" # Test that we get an instance of ResultSet results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(results.num_players, len(tournament.players)) self.assertEqual(results.players, [str(p) for p in tournament.players]) def test_parallel_play(self): # Test that we get an instance of ResultSet tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) results = tournament.play(processes=2, progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(tournament.num_interactions, 75) # The following relates to #516 players = [ axelrod.Cooperator(), axelrod.Defector(), axelrod.BackStabber(), axelrod.PSOGambler2_2_2(), axelrod.ThueMorse(), axelrod.DoubleCrosser(), ] tournament = axelrod.Tournament( name=self.test_name, players=players, game=self.game, turns=20, repetitions=self.test_repetitions, ) scores = tournament.play(processes=2, progress_bar=False).scores self.assertEqual(len(scores), len(players)) def test_parallel_play_with_writing_to_file(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) results = tournament.play(processes=2, progress_bar=False, filename=self.filename) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(tournament.num_interactions, 75) def test_run_serial(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) tournament._write_interactions_to_file = MagicMock( name="_write_interactions_to_file") self.assertTrue(tournament._run_serial()) # Get the calls made to write_interactions calls = tournament._write_interactions_to_file.call_args_list self.assertEqual(len(calls), 15) def test_run_parallel(self): class PickleableMock(MagicMock): def __reduce__(self): return MagicMock, () tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) tournament._write_interactions_to_file = PickleableMock( name="_write_interactions_to_file") # For test coverage purposes. This confirms PickleableMock can be # pickled exactly once. Windows multi-processing must pickle this Mock # exactly once during testing. pickled = pickle.loads(pickle.dumps(tournament)) self.assertIsInstance(pickled._write_interactions_to_file, MagicMock) self.assertRaises(pickle.PicklingError, pickle.dumps, pickled) self.assertTrue(tournament._run_parallel()) # Get the calls made to write_interactions calls = tournament._write_interactions_to_file.call_args_list self.assertEqual(len(calls), 15) def test_n_workers(self): max_processes = cpu_count() tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) self.assertEqual(tournament._n_workers(processes=1), max_processes) tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) self.assertEqual(tournament._n_workers(processes=max_processes + 2), max_processes) @unittest.skipIf(cpu_count() < 2, "not supported on single processor machines") def test_2_workers(self): # This is a separate test with a skip condition because we # cannot guarantee that the tests will always run on a machine # with more than one processor tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) self.assertEqual(tournament._n_workers(processes=2), 2) def test_start_workers(self): workers = 2 work_queue = Queue() done_queue = Queue() tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) chunks = tournament.match_generator.build_match_chunks() for chunk in chunks: work_queue.put(chunk) tournament._start_workers(workers, work_queue, done_queue) stops = 0 while stops < workers: payoffs = done_queue.get() if payoffs == "STOP": stops += 1 self.assertEqual(stops, workers) def test_worker(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) work_queue = Queue() chunks = tournament.match_generator.build_match_chunks() count = 0 for chunk in chunks: work_queue.put(chunk) count += 1 work_queue.put("STOP") done_queue = Queue() tournament._worker(work_queue, done_queue) for r in range(count): new_matches = done_queue.get() for index_pair, matches in new_matches.items(): self.assertIsInstance(index_pair, tuple) self.assertEqual(len(matches), self.test_repetitions) queue_stop = done_queue.get() self.assertEqual(queue_stop, "STOP") def test_build_result_set(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) def test_no_build_result_set(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=axelrod.DEFAULT_TURNS, repetitions=self.test_repetitions, ) tournament._calculate_results = MagicMock(name="_calculate_results") # Mocking this as it is called by play self.assertIsNone( tournament.play(filename=self.filename, progress_bar=False, build_results=False)) # Get the calls made to write_interactions calls = tournament._calculate_results.call_args_list self.assertEqual(len(calls), 0) @given(turns=integers(min_value=1, max_value=200)) @settings(max_examples=5, max_iterations=20) @example(turns=3) @example(turns=axelrod.DEFAULT_TURNS) def test_play_matches(self, turns): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, repetitions=self.test_repetitions, ) def make_chunk_generator(): for player1_index in range(len(self.players)): for player2_index in range(player1_index, len(self.players)): index_pair = (player1_index, player2_index) match_params = {"turns": turns, "game": self.game} yield (index_pair, match_params, self.test_repetitions) chunk_generator = make_chunk_generator() interactions = {} for chunk in chunk_generator: result = tournament._play_matches(chunk) for index_pair, inters in result.items(): try: interactions[index_pair].append(inters) except KeyError: interactions[index_pair] = [inters] self.assertEqual(len(interactions), 15) for index_pair, inter in interactions.items(): self.assertEqual(len(index_pair), 2) for plays in inter: # Check that have the expected number of repetitions self.assertEqual(len(plays), self.test_repetitions) for repetition in plays: actions, results = repetition self.assertEqual(len(actions), turns) self.assertEqual(len(results), 10) # Check that matches no longer exist self.assertEqual((len(list(chunk_generator))), 0) def test_match_cache_is_used(self): """ Create two Random players that are classified as deterministic. As they are deterministic the cache will be used. """ FakeRandom = axelrod.Random FakeRandom.classifier["stochastic"] = False p1 = FakeRandom() p2 = FakeRandom() tournament = axelrod.Tournament((p1, p2), turns=5, repetitions=2) results = tournament.play(progress_bar=False) for player_scores in results.scores: self.assertEqual(player_scores[0], player_scores[1]) def test_write_interactions(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=2, repetitions=2, ) tournament._write_interactions_to_file = MagicMock( name="_write_interactions_to_file") # Mocking this as it is called by play self.assertIsNone( tournament.play(filename=self.filename, progress_bar=False, build_results=False)) # Get the calls made to write_interactions calls = tournament._write_interactions_to_file.call_args_list self.assertEqual(len(calls), 15) def test_write_to_csv_with_results(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=2, repetitions=2, ) tournament.play(filename=self.filename, progress_bar=False) df = pd.read_csv(self.filename) expected_df = pd.read_csv("test_outputs/expected_test_tournament.csv") self.assertTrue(df.equals(expected_df)) def test_write_to_csv_without_results(self): tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=2, repetitions=2, ) tournament.play(filename=self.filename, progress_bar=False, build_results=False) df = pd.read_csv(self.filename) expected_df = pd.read_csv( "test_outputs/expected_test_tournament_no_results.csv") self.assertTrue(df.equals(expected_df))
class TestTournament(unittest.TestCase): @classmethod def setUpClass(cls): cls.game = axelrod.Game() cls.players = [s() for s in test_strategies] cls.test_name = 'test' cls.test_repetitions = test_repetitions cls.test_turns = test_turns cls.expected_payoff = [[600, 600, 0, 600, 600], [600, 600, 199, 600, 600], [1000, 204, 200, 204, 204], [600, 600, 199, 600, 600], [600, 600, 199, 600, 600]] cls.expected_cooperation = [[200, 200, 200, 200, 200], [200, 200, 1, 200, 200], [0, 0, 0, 0, 0], [200, 200, 1, 200, 200], [200, 200, 1, 200, 200]] cls.filename = "test_outputs/test_tournament.csv" def test_init(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=self.test_turns, noise=0.2) self.assertEqual(len(tournament.players), len(test_strategies)) self.assertIsInstance(tournament.players[0].match_attributes['game'], axelrod.Game) self.assertEqual(tournament.game.score(('C', 'C')), (3, 3)) self.assertEqual(tournament.turns, self.test_turns) self.assertEqual(tournament.repetitions, 10) self.assertEqual(tournament.name, 'test') self.assertTrue(tournament._with_morality) self.assertIsInstance(tournament._logger, logging.Logger) self.assertEqual(tournament.noise, 0.2) anonymous_tournament = axelrod.Tournament(players=self.players) self.assertEqual(anonymous_tournament.name, 'axelrod') def test_warning(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=10, repetitions=1) with warnings.catch_warnings(record=True) as w: # Check that a warning is raised if no results set is built and no # filename is given results = tournament.play(build_results=False, progress_bar=False) self.assertEqual(len(w), 1) with warnings.catch_warnings(record=True) as w: # Check that no warning is raised if no results set is built and a # is filename given tournament.play(build_results=False, filename=self.filename, progress_bar=False) self.assertEqual(len(w), 0) def test_serial_play(self): # Test that we get an instance of ResultSet tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) # Test that _run_serial_repetitions is called with empty matches list tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) results = tournament.play(progress_bar=False) self.assertEqual(tournament.num_interactions, 75) def test_serial_play_with_different_game(self): # Test that a non default game is passed to the result set game = axelrod.Game(p=-1, r=-1, s=-1, t=-1) tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=game, turns=1, repetitions=1) results = tournament.play(progress_bar=False) self.assertEqual(results.game.RPST(), (-1, -1, -1, -1)) def test_no_progress_bar_play(self): """Test that progress bar is not created for progress_bar=False""" tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) # Test with build results results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) # Check that no progress bar was created call_progress_bar = lambda: tournament.progress_bar.total self.assertRaises(AttributeError, call_progress_bar) # Test without build results results = tournament.play(progress_bar=False, build_results=False, filename=self.filename) self.assertIsNone(results) results = axelrod.ResultSetFromFile(self.filename, progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) self.assertRaises(AttributeError, call_progress_bar) def test_progress_bar_play(self): """Test that progress bar is created by default and with True argument""" tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) results = tournament.play() self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(tournament.progress_bar.total, 15) self.assertEqual(tournament.progress_bar.total, tournament.progress_bar.n) results = tournament.play(progress_bar=True) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(tournament.progress_bar.total, 15) self.assertEqual(tournament.progress_bar.total, tournament.progress_bar.n) # Test without build results results = tournament.play(progress_bar=True, build_results=False, filename=self.filename) self.assertIsNone(results) results = axelrod.ResultSetFromFile(self.filename) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(tournament.progress_bar.total, 15) self.assertEqual(tournament.progress_bar.total, tournament.progress_bar.n) @unittest.skipIf(axelrod.on_windows, "Parallel processing not supported on Windows") def test_progress_bar_play_parallel(self): """Test that tournament plays when asking for progress bar for parallel tournament""" tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) results = tournament.play(processes=2) self.assertIsInstance(results, axelrod.ResultSet) results = tournament.play(progress_bar=True) self.assertIsInstance(results, axelrod.ResultSet) @given(tournament=tournaments(min_size=2, max_size=5, min_turns=2, max_turns=50, min_repetitions=2, max_repetitions=4)) @settings(max_examples=50, timeout=0) @example(tournament=axelrod.Tournament( players=[s() for s in test_strategies], turns=test_turns, repetitions=test_repetitions)) # These two examples are to make sure #465 is fixed. # As explained there: https://github.com/Axelrod-Python/Axelrod/issues/465, # these two examples were identified by hypothesis. @example( tournament=axelrod.Tournament( players=[axelrod.BackStabber(), axelrod.MindReader()], turns=2, repetitions=1), ) @example( tournament=axelrod.Tournament( players=[axelrod.BackStabber(), axelrod.ThueMorse()], turns=2, repetitions=1), ) def test_property_serial_play(self, tournament): """Test serial play using hypothesis""" # Test that we get an instance of ResultSet results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(results.nplayers, len(tournament.players)) self.assertEqual(results.players, [str(p) for p in tournament.players]) @unittest.skipIf(axelrod.on_windows, "Parallel processing not supported on Windows") def test_parallel_play(self): # Test that we get an instance of ResultSet tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) results = tournament.play(processes=2, progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) self.assertEqual(tournament.num_interactions, 75) # The following relates to #516 players = [ axelrod.Cooperator(), axelrod.Defector(), axelrod.BackStabber(), axelrod.PSOGambler2_2_2(), axelrod.ThueMorse(), axelrod.DoubleCrosser() ] tournament = axelrod.Tournament(name=self.test_name, players=players, game=self.game, turns=20, repetitions=self.test_repetitions) scores = tournament.play(processes=2, progress_bar=False).scores self.assertEqual(len(scores), len(players)) def test_run_serial(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) tournament._write_interactions = MagicMock(name='_write_interactions') self.assertTrue(tournament._run_serial()) # Get the calls made to write_interactions calls = tournament._write_interactions.call_args_list self.assertEqual(len(calls), 15) @unittest.skipIf(axelrod.on_windows, "Parallel processing not supported on Windows") def test_run_parallel(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) tournament._write_interactions = MagicMock(name='_write_interactions') self.assertTrue(tournament._run_parallel()) # Get the calls made to write_interactions calls = tournament._write_interactions.call_args_list self.assertEqual(len(calls), 15) @unittest.skipIf(axelrod.on_windows, "Parallel processing not supported on Windows") def test_n_workers(self): max_processes = cpu_count() tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) self.assertEqual(tournament._n_workers(processes=1), max_processes) tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) self.assertEqual(tournament._n_workers(processes=max_processes + 2), max_processes) @unittest.skipIf(axelrod.on_windows, "Parallel processing not supported on Windows") @unittest.skipIf(cpu_count() < 2, "not supported on single processor machines") def test_2_workers(self): # This is a separate test with a skip condition because we # cannot guarantee that the tests will always run on a machine # with more than one processor tournament = axelrod.Tournament( name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions, ) self.assertEqual(tournament._n_workers(processes=2), 2) @unittest.skipIf(axelrod.on_windows, "Parallel processing not supported on Windows") def test_start_workers(self): workers = 2 work_queue = Queue() done_queue = Queue() tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) chunks = tournament.match_generator.build_match_chunks() for chunk in chunks: work_queue.put(chunk) tournament._start_workers(workers, work_queue, done_queue) stops = 0 while stops < workers: payoffs = done_queue.get() if payoffs == 'STOP': stops += 1 self.assertEqual(stops, workers) @unittest.skipIf(axelrod.on_windows, "Parallel processing not supported on Windows") def test_worker(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) work_queue = Queue() chunks = tournament.match_generator.build_match_chunks() count = 0 for chunk in chunks: work_queue.put(chunk) count += 1 work_queue.put('STOP') done_queue = Queue() tournament._worker(work_queue, done_queue) for r in range(count): new_matches = done_queue.get() for index_pair, matches in new_matches.items(): self.assertIsInstance(index_pair, tuple) self.assertEqual(len(matches), self.test_repetitions) queue_stop = done_queue.get() self.assertEqual(queue_stop, 'STOP') def test_build_result_set(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) results = tournament.play(progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) # Test in memory results = tournament.play(progress_bar=False, in_memory=True) self.assertIsInstance(results, axelrod.ResultSet) def test_no_build_result_set(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=200, repetitions=self.test_repetitions) results = tournament.play(build_results=False, filename=self.filename, progress_bar=False) self.assertIsNone(results) # Checking that results were written properly results = axelrod.ResultSetFromFile(self.filename, progress_bar=False) self.assertIsInstance(results, axelrod.ResultSet) @given(turns=integers(min_value=1, max_value=200)) @example(turns=3) @example(turns=200) def test_play_matches(self, turns): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, repetitions=self.test_repetitions) def make_chunk_generator(): for player1_index in range(len(self.players)): for player2_index in range(player1_index, len(self.players)): index_pair = (player1_index, player2_index) match_params = (turns, self.game, None, 0) yield (index_pair, match_params, self.test_repetitions) chunk_generator = make_chunk_generator() interactions = {} for chunk in chunk_generator: result = tournament._play_matches(chunk) for index_pair, inters in result.items(): try: interactions[index_pair].append(inters) except KeyError: interactions[index_pair] = [inters] self.assertEqual(len(interactions), 15) for index_pair, inter in interactions.items(): self.assertEqual(len(index_pair), 2) for plays in inter: # Check that have the expected number of repetitions self.assertEqual(len(plays), self.test_repetitions) for repetition in plays: # Check that have the correct length for each rep self.assertEqual(len(repetition), turns) # Check that matches no longer exist self.assertEqual((len(list(chunk_generator))), 0) def test_write_interactions(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=2, repetitions=2) tournament._write_interactions = MagicMock(name='_write_interactions') tournament._build_result_set = MagicMock( name='_build_result_set') # Mocking this as it is called by play self.assertTrue( tournament.play(filename=self.filename, progress_bar=False)) tournament.outputfile.close( ) # This is normally closed by `build_result_set` # Get the calls made to write_interactions calls = tournament._write_interactions.call_args_list self.assertEqual(len(calls), 15) # Test when runnning in memory tournament._write_interactions = MagicMock(name='_write_interactions') self.assertTrue( tournament.play(filename=self.filename, progress_bar=False, in_memory=True)) # Get the calls made to write_interactions calls = tournament._write_interactions.call_args_list self.assertEqual(len(calls), 15) def test_write_to_csv(self): tournament = axelrod.Tournament(name=self.test_name, players=self.players, game=self.game, turns=2, repetitions=2) tournament.play(filename=self.filename, progress_bar=False) with open(self.filename, 'r') as f: written_data = [[int(r[0]), int(r[1])] + r[2:] for r in csv.reader(f)] expected_data = [ [0, 1, 'Cooperator', 'Tit For Tat', 'CC', 'CC'], [0, 1, 'Cooperator', 'Tit For Tat', 'CC', 'CC'], [1, 2, 'Tit For Tat', 'Defector', 'CD', 'DD'], [1, 2, 'Tit For Tat', 'Defector', 'CD', 'DD'], [0, 0, 'Cooperator', 'Cooperator', 'CC', 'CC'], [0, 0, 'Cooperator', 'Cooperator', 'CC', 'CC'], [3, 3, 'Grudger', 'Grudger', 'CC', 'CC'], [3, 3, 'Grudger', 'Grudger', 'CC', 'CC'], [2, 2, 'Defector', 'Defector', 'DD', 'DD'], [2, 2, 'Defector', 'Defector', 'DD', 'DD'], [ 4, 4, 'Soft Go By Majority', 'Soft Go By Majority', 'CC', 'CC' ], [ 4, 4, 'Soft Go By Majority', 'Soft Go By Majority', 'CC', 'CC' ], [1, 4, 'Tit For Tat', 'Soft Go By Majority', 'CC', 'CC'], [1, 4, 'Tit For Tat', 'Soft Go By Majority', 'CC', 'CC'], [1, 1, 'Tit For Tat', 'Tit For Tat', 'CC', 'CC'], [1, 1, 'Tit For Tat', 'Tit For Tat', 'CC', 'CC'], [1, 3, 'Tit For Tat', 'Grudger', 'CC', 'CC'], [1, 3, 'Tit For Tat', 'Grudger', 'CC', 'CC'], [2, 3, 'Defector', 'Grudger', 'DD', 'CD'], [2, 3, 'Defector', 'Grudger', 'DD', 'CD'], [0, 4, 'Cooperator', 'Soft Go By Majority', 'CC', 'CC'], [0, 4, 'Cooperator', 'Soft Go By Majority', 'CC', 'CC'], [2, 4, 'Defector', 'Soft Go By Majority', 'DD', 'CD'], [2, 4, 'Defector', 'Soft Go By Majority', 'DD', 'CD'], [0, 3, 'Cooperator', 'Grudger', 'CC', 'CC'], [0, 3, 'Cooperator', 'Grudger', 'CC', 'CC'], [3, 4, 'Grudger', 'Soft Go By Majority', 'CC', 'CC'], [3, 4, 'Grudger', 'Soft Go By Majority', 'CC', 'CC'], [0, 2, 'Cooperator', 'Defector', 'CC', 'DD'], [0, 2, 'Cooperator', 'Defector', 'CC', 'DD'] ] self.assertEqual(sorted(written_data), sorted(expected_data))