def test_pickling_mechanism(tmp_path): import pickle file = tmp_path / "mechanism.pck" n_outcomes, n_negotiators = 5, 3 mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=3, offering_is_accepting=True, avoid_ultimatum=False, ) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i]) assert mechanism.state.step == 0 with open(file, "wb") as f: pickle.dump(mechanism, f) with open(file, "rb") as f: pickle.load(f) assert mechanism.state.step == 0 mechanism.step() with open(file, "wb") as f: pickle.dump(mechanism, f) with open(file, "rb") as f: pickle.load(f) assert mechanism.state.step == 1
def test_times_are_calculated(n_outcomes, n_negotiators, n_steps): mechanism = SAOMechanism(outcomes=n_outcomes, n_steps=8) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i]) assert mechanism.state.step == 0 _strt = time.perf_counter() for _ in range(n_steps): print(f"Stepping: {_}") mechanism.step() time.sleep(0.01) duration = time.perf_counter() - _strt # assert mechanism.current_step == n_steps assert mechanism._current_offer is not None assert len(mechanism.stats) == 3 stats = mechanism.stats assert "round_times" in stats.keys() assert 0 < sum(stats["round_times"]) < duration assert "times" in stats.keys() assert "exceptions" in stats.keys() assert stats["times"] is not None assert stats["exceptions"] is not None assert len(stats["times"]) == n_negotiators assert len(stats["exceptions"]) == 0 for i in range(n_negotiators): assert 0 < stats["times"][mechanism.negotiators[i].id] < duration assert len(stats["exceptions"][mechanism.negotiators[i].id]) == 0 assert 0 < sum(stats["times"].values()) < duration
def test_exceptions_are_saved(): n_outcomes, n_negotiators = 10, 2 mechanism = SAOMechanism(outcomes=n_outcomes, n_steps=n_outcomes, ignore_negotiator_exceptions=True) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=mechanism.outcomes) mechanism.add(AspirationNegotiator(name=f"agent{0}"), ufun=ufuns[0]) mechanism.add(MyRaisingNegotiator(name=f"agent{1}"), ufun=ufuns[1]) assert mechanism.state.step == 0 mechanism.step() mechanism.step() mechanism.step() assert mechanism.state.step == 1 assert mechanism._current_offer is not None assert len(mechanism.stats) == 3 stats = mechanism.stats assert "times" in stats.keys() assert "exceptions" in stats.keys() assert stats["exceptions"] is not None assert len(stats["exceptions"]) == 1 print(stats["exceptions"][mechanism.negotiators[1].id]) assert len(stats["exceptions"][mechanism.negotiators[1].id]) == 1 assert exception_str in stats["exceptions"][mechanism.negotiators[1].id][0] assert len(stats["exceptions"][mechanism.negotiators[0].id]) == 0
def test_mechanism_can_run(n_negotiators): n_outcomes = 5 mechanism = SAOMechanism(outcomes=n_outcomes, n_steps=3) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i]) assert mechanism.state.step == 0 mechanism.step() mechanism.run()
def test_ga_mechanism(n_negotiators, n_outcomes): mechanism = GAMechanism(outcomes=n_outcomes, n_steps=3) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(SorterNegotiator(name=f"agent{i}"), ufun=ufuns[i]) assert mechanism.state.step == 0 mechanism.step() assert mechanism.state.step == 1 assert mechanism.dominant_outcomes is not None mechanism.run()
def test_round_n_agents(n_negotiators): n_outcomes = 5 mechanism = SAOMechanism(outcomes=n_outcomes, n_steps=3) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i]) assert mechanism.state.step == 0 mechanism.step() assert mechanism.state.step == 1 assert mechanism._current_offer is not None
def test_hill_climbing_mechanism(n_negotiators, n_outcomes): mechanism = HillClimbingSTMechanism(outcomes=n_outcomes, n_steps=3) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(BinaryComparatorNegotiator(name=f"agent{i}"), ufun=ufuns[i]) assert mechanism.state.step == 0 mechanism.step() assert mechanism.state.step == 1 assert mechanism.current_offer is not None mechanism.run() assert mechanism.agreement is not None
def test_checkpointing_mechanism(tmp_path): file = tmp_path n_outcomes, n_negotiators = 5, 3 mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=3, offering_is_accepting=True, avoid_ultimatum=False, ) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i]) assert mechanism.state.step == 0 file_name = mechanism.checkpoint(file) info = SAOMechanism.checkpoint_info(file_name) assert isinstance(info["time"], str) assert info["step"] == 0 assert info["type"].endswith("SAOMechanism") assert info["id"] == mechanism.id assert info["name"] == mechanism.name mechanism, info = SAOMechanism.from_checkpoint(file_name, return_info=True) assert isinstance(info["time"], str) assert info["step"] == 0 assert info["type"].endswith("SAOMechanism") assert info["id"] == mechanism.id assert info["name"] == mechanism.name assert mechanism.state.step == 0 mechanism.step() file_name = mechanism.checkpoint(file) info = SAOMechanism.checkpoint_info(file_name) assert isinstance(info["time"], str) assert info["step"] == 1 assert info["type"].endswith("SAOMechanism") assert info["id"] == mechanism.id assert info["name"] == mechanism.name mechanism, info = SAOMechanism.from_checkpoint(file_name, return_info=True) assert isinstance(info["time"], str) assert info["step"] == 1 assert info["type"].endswith("SAOMechanism") assert info["id"] == mechanism.id assert info["name"] == mechanism.name mechanism.run()
def test_auto_checkpoint(tmp_path, single_checkpoint, checkpoint_every, exist_ok): import shutil new_folder: Path = tmp_path / unique_name("empty", sep="") new_folder.mkdir(parents=True, exist_ok=True) shutil.rmtree(new_folder) new_folder.mkdir(parents=True, exist_ok=True) filename = "mechanism" n_outcomes, n_negotiators = 5, 3 n_steps = 50 mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=n_steps, offering_is_accepting=True, avoid_ultimatum=False, checkpoint_every=checkpoint_every, checkpoint_folder=new_folder, checkpoint_filename=filename, extra_checkpoint_info=None, exist_ok=exist_ok, single_checkpoint=single_checkpoint, ) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add( AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i], aspiration_type="conceder", ) mechanism.run() if 0 < checkpoint_every <= n_steps: if single_checkpoint: assert len(list(new_folder.glob("*"))) == 2 else: assert len(list(new_folder.glob("*"))) >= 2 * (max( 1, mechanism.state.step // checkpoint_every)) elif checkpoint_every > n_steps: assert len(list(new_folder.glob("*"))) == 2 else: assert len(list(new_folder.glob("*"))) == 0
def test_mechanism_runall(n_negotiators, oia): n_outcomes = 5 mechanisms = [] for _ in range(10): mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=random.randint(3, 20), offering_is_accepting=oia, avoid_ultimatum=False, ) ufuns = MappingUtilityFunction.generate_random(1, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[0]) mechanisms.append(mechanism) states = SAOMechanism.runall(mechanisms) assert len(states) == 10 assert not any(_.running for _ in states)
def test_mechanism_runs_with_offering_not_accepting(n_negotiators, oia): n_outcomes = 5 mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=3, offering_is_accepting=oia, avoid_ultimatum=False ) ufuns = MappingUtilityFunction.generate_random(1, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[0]) assert mechanism.state.step == 0 mechanism.step() assert mechanism._current_proposer.name == "agent0" assert mechanism._n_accepting == n_negotiators + int(oia) - 1 assert (mechanism.agreement is not None) is oia if mechanism.agreement is not None: return mechanism.step() assert mechanism._current_proposer.name == "agent0" assert mechanism._n_accepting == n_negotiators assert mechanism.agreement is not None
def test_sync_controller(n_negotiations, n_negotiators, oia): n_outcomes = 2 mechanisms = [] controller = MySAOSync() for i in range(n_negotiators): mechanisms.append( SAOMechanism( outcomes=n_outcomes, n_steps=5, offering_is_accepting=oia, avoid_ultimatum=False, )) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanisms[-1].add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i]) mechanisms[-1].add(controller.create_negotiator()) states = SAOMechanism.runall(mechanisms) assert all(_.agreement is not None for _ in states)
def test_can_run_from_checkpoint(tmp_path, single_checkpoint, checkpoint_every, exist_ok): import shutil new_folder: Path = tmp_path / unique_name("empty", sep="") second_folder: Path = tmp_path / unique_name("second", sep="") new_folder.mkdir(parents=True, exist_ok=True) shutil.rmtree(new_folder) new_folder.mkdir(parents=True, exist_ok=True) filename = "mechanism" second_folder.mkdir(parents=True, exist_ok=True) n_outcomes, n_negotiators = 5, 3 n_steps = 50 mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=n_steps, offering_is_accepting=True, avoid_ultimatum=False, checkpoint_every=checkpoint_every, checkpoint_folder=new_folder, checkpoint_filename=filename, extra_checkpoint_info=None, exist_ok=exist_ok, single_checkpoint=single_checkpoint, ) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add(AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i]) mechanism.run() files = list(new_folder.glob("*")) if 0 < checkpoint_every <= n_steps: if single_checkpoint: assert len(list(new_folder.glob("*"))) == 2 else: assert len(list(new_folder.glob("*"))) >= 2 * (max( 1, mechanism.state.step // checkpoint_every)) elif checkpoint_every > n_steps: assert len(list(new_folder.glob("*"))) == 2 else: assert len(list(new_folder.glob("*"))) == 0 runner = CheckpointRunner(folder=new_folder) assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.step() assert runner.current_step == (0 if not single_checkpoint else runner.steps[-1]) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.goto(runner.last_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.next_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.previous_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.first_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() runner.run()
def test_can_run_from_checkpoint(tmp_path, checkpoint_every, exist_ok, copy, fork_after_reset): import shutil new_folder: Path = tmp_path / unique_name("empty", sep="") second_folder: Path = tmp_path / unique_name("second", sep="") new_folder.mkdir(parents=True, exist_ok=True) shutil.rmtree(new_folder) new_folder.mkdir(parents=True, exist_ok=True) second_folder.mkdir(parents=True, exist_ok=True) shutil.rmtree(second_folder) second_folder.mkdir(parents=True, exist_ok=True) filename = "mechanism" n_outcomes, n_negotiators = 5, 3 n_steps = 50 mechanism = SAOMechanism( outcomes=n_outcomes, n_steps=n_steps, offering_is_accepting=True, avoid_ultimatum=False, checkpoint_every=checkpoint_every, checkpoint_folder=new_folder, checkpoint_filename=filename, extra_checkpoint_info=None, exist_ok=exist_ok, single_checkpoint=False, ) ufuns = MappingUtilityFunction.generate_random(n_negotiators, outcomes=n_outcomes) for i in range(n_negotiators): mechanism.add( AspirationNegotiator(name=f"agent{i}"), ufun=ufuns[i], aspiration_type="conceder", ) mechanism.run() files = list(new_folder.glob("*")) if 0 < checkpoint_every <= n_steps: assert len(list(new_folder.glob("*"))) >= 2 * (max( 1, mechanism.state.step // checkpoint_every)) elif checkpoint_every > n_steps: assert len(list(new_folder.glob("*"))) == 2 else: assert len(list(new_folder.glob("*"))) == 0 runner = CheckpointRunner(folder=new_folder) assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.step() assert runner.current_step == 0 assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.goto(runner.last_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.next_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.previous_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.first_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() if fork_after_reset: m = runner.fork(copy_past_checkpoints=copy, folder=second_folder) assert m is None return runner.step() m = runner.fork(copy_past_checkpoints=copy, folder=second_folder) if copy: step = runner.current_step assert len(list(second_folder.glob("*"))) >= 2 assert len(list(second_folder.glob(f"*{step}.mechanism"))) > 0 else: assert len(list(second_folder.glob("*"))) == 0 assert isinstance(m, SAOMechanism) step = m.current_step m.step() assert m.current_step == step + 1 state = m.run() assert state.agreement is not None runner.reset() assert len(runner.steps) * 2 == len(files) assert runner.current_step == -1 assert runner.loaded_object is None runner.goto(runner.last_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.next_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.previous_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.goto(runner.first_step, exact=True) assert isinstance(runner.loaded_object, SAOMechanism) assert runner.loaded_object.state.step == runner.current_step runner.reset() runner.run()