def sim_cancellable(): ll = [] sim = Simulator() id_event = [] for n in [1, 3, 5]: id_event.append(sim._schedule(n, append, n, ll)) return ll, sim, id_event
def test_queue_length(): sim = Simulator() queue = Queue() assert 0 == len(queue) log = [] for n in range(10): sim.add(queuer, n, queue, log, float(n + 1)) sim.run() assert 10 == len(queue) sim.add(dequeueing, queue, 0.0) sim.run() assert 0 == len(queue)
def __init__(self, sim: Simulator, num: str) -> None: self.num = num self._num_standing = 0 self._moment_empty = sim.now() self._time_empty = 0 self._travelers_waiting = Queue() self._traveler_ready = Signal() self._agents_working = Signal() sim.add(self._work_then_break) for name in ["alpha", "beta"]: sim.add(self._agent_accepting_travelers, name)
def test_schedule_multiple_events(): ll = [] sim = Simulator() sim._schedule(1.0, append, 1, ll) sim._schedule(0.7, append, 2, ll) sim._schedule(10.0, append, 3, ll) sim.run() assert ll == [2, 1, 3] assert sim.now() == 10.0
def test_auto_log_queue(auto_logger): def proc(q): local.name = "the-process" q.join() advance(100) sim = Simulator() queue = Queue(name="the-queue") sim.add(proc, queue) sim.run() queue.pop() sim.run(10) check_log( auto_logger, (logging.INFO, 0.0, "", "Simulator", sim.name, "add", dict(fn=proc, args=(queue, ), kwargs={})), (logging.INFO, 0.0, "", "Simulator", sim.name, "run", dict(duration=inf)), (logging.INFO, 0.0, "the-process", "Queue", "the-queue", "join", {}), (logging.INFO, 0.0, "the-process", "Process", "the-process", "pause", {}), (logging.INFO, 0.0, "", "Simulator", sim.name, "stop", {}), (logging.INFO, -1.0, "", "Queue", "the-queue", "pop", dict(process="the-process")), (logging.INFO, -1.0, "", "Process", "the-process", "resume", {}), (logging.INFO, 0.0, "", "Simulator", sim.name, "run", dict(duration=10.0)), (logging.INFO, 0.0, "the-process", "Process", "the-process", "advance", dict(delay=100.0)), (logging.INFO, 10.0, "", "Simulator", sim.name, "stop", {}))
def test_queue_pop_empty(): sim = Simulator() queue = Queue() log = [] sim.add(queuer, 1, queue, log, 1.0) sim.run() assert [] == log queue.pop() sim.run() assert [1] == log assert queue.is_empty() queue.pop( ) # Raises an exception unless empty queue is properly processed. sim.run() assert [1] == log
def run_test_queue_join_pop(queue: Queue) -> List[int]: sim = Simulator() log: List[int] = [] for n in range(10): sim.add(queuer, n, queue, log, float(n + 1)) sim.add(dequeueing, queue, 100.0) sim.run() return log
def test_tagged_constructor(): @tagged(TestTag.ALICE) def f(): pass proc = Process(Simulator(), f, None) assert proc.has_tag(TestTag.ALICE)
def test_signal_wait_a_while(): sim = Simulator() signal = Signal().turn_off() log = [] expectation = [3.0, 4.0] sim.add(wait_for, signal, expectation, 1.0, log) sim._schedule(3.0, signal.turn_on) sim.run() assert expectation == log
def test_simulator_step(): def process(ll): ll.append(now()) advance(1.0) ll.append(now()) advance(5.0) ll.append(now()) ll = [] sim = Simulator() sim.add(process, ll) sim.step() assert ll == pytest.approx([0.0]) sim.step() assert ll == pytest.approx([0.0, 1.0]) sim.step() assert ll == pytest.approx([0.0, 1.0, 6.0])
def do_test_with_interrupter(main, ll_expected, now_expected): def interrupter(main): advance(10.1) main.interrupt() ll = [] sim = Simulator() proc_main = sim.add(main, ll) sim.add(interrupter, proc_main) sim.run() assert ll == pytest.approx(ll_expected) assert sim.now() == pytest.approx(now_expected)
def test_auto_log_resource_take_again(auto_logger): def process(res): local.name = "proc" res.take(2) advance(10) res.take(3) advance(10) res.release(5) sim = Simulator(name="sim") resource = Resource(5, name="res") sim.add(process, resource) sim.run() check_log( auto_logger, (logging.INFO, 0.0, "", "Simulator", "sim", "add", dict(fn=process, args=(resource, ), kwargs={})), (logging.INFO, 0.0, "", "Simulator", "sim", "run", dict(duration=inf)), (logging.INFO, 0.0, "proc", "Resource", "res", "take", dict(num_instances=2, free=5)), (logging.INFO, 0.0, "proc", "Process", "proc", "advance", dict(delay=10.0)), (logging.INFO, 10.0, "proc", "Resource", "res", "take", dict(num_instances=3, free=3)), (logging.WARNING, 10.0, "proc", "Resource", "res", "take-again", dict(already=2, more=3)), (logging.INFO, 10.0, "proc", "Process", "proc", "advance", dict(delay=10.0)), (logging.INFO, 20.0, "proc", "Resource", "res", "release", dict(num_instances=5, keeping=0, free=5)), (logging.INFO, 20.0, "proc", "Process", "proc", "die-finish", {}), (logging.INFO, 20.0, "", "Simulator", "sim", "stop", {}))
def run_resource_test_incoherent(num_take: int, num_release: int): sim = Simulator() resource = Resource(5) sim.add(take_M_release_N, resource, num_take, num_release) with pytest.raises(ValueError): sim.run() assert resource.num_instances_free >= 0 assert resource.num_instances_total == 5
def test_signal_already_on(): sim = Simulator() signal = Signal().turn_on() log = [] expectation = [1.0] sim.add(wait_for, signal, expectation, 1.0, log) sim.run() assert expectation == log
def test_tracker_lifecycle(): def capture_pass(progress, rt_remaining, mc): pass sim = Simulator() tracker = sim.add(track_progress, sim_time, [1000.0], 100.0, capture_pass) assert has_tracker(sim, tracker) def check_tracker(): advance(150) assert has_tracker(sim, tracker) sim.add(check_tracker) sim.run(10000.0) assert not has_tracker(sim, tracker) assert sim.now() == pytest.approx(1000.0)
def test_progress_real_time(): log = [] def capture(_progress_min, rt_remaining, mc): log.append(rt_remaining) def sleeper(interval, rt_delay): while True: advance(interval) sim = Simulator() sim.add(track_progress, sim_time, [100.0], 20.0, capture) sim.add(sleeper, 10.0, 0.1) sim.run() assert log == pytest.approx([0.8, 0.6, 0.4, 0.2, 0.0])
def test_process_multiple(): def tick(name, period, log): while True: advance(period) log.append((int(now()), name)) sim = Simulator() log = [] sim.add(tick, "three", 3.0, log) sim.add(tick, "seven", 7.0, log) sim.add(tick, "eleven", 11.0, log) sim.run(100.0) expectation = [(n, "eleven") for n in range(11, 100, 11)] expectation += [(n, "seven") for n in range(7, 100, 7)] expectation += [(n, "three") for n in range(3, 100, 3)] assert sorted(expectation, key=lambda p: p[0]) == log
def test_signal_waiter_turning_off(): def waiter_turning_off(signal: Signal, log: List[float]): signal.wait() signal.turn_off() log.append(now()) sim = Simulator() signal = Signal().turn_off() log_time = [] for n in range(5): sim.add(waiter_turning_off, signal, log_time) schedule_signal_on = [4.0, 9.0, 9.1, 200.0, 3000.0] for moment in schedule_signal_on: sim._schedule(moment, signal.turn_on) sim.run() assert schedule_signal_on == pytest.approx(log_time)
def test_select_one_on(): has_passed = False def selecter(sigs: List[Signal]): nonlocal has_passed select(*sigs) has_passed = True sim = Simulator() signals = [Signal().turn_off() for n in range(5)] sim.add(selecter, signals) sim.run() assert not has_passed signals[3].turn_on() sim.run() assert has_passed
def test_schedule_functions(): def f1(sim, results): res = f"1 + {sim.now()}" results.append(res) def f2(sim, results): res = f"2 + {sim.now()}" results.append(res) sim = Simulator() results = [] sim._schedule(1, f1, sim, results) sim._schedule(2, f2, sim, results) sim._schedule(3, f1, sim, results) sim.run() assert ['1 + 1.0', '2 + 2.0', '1 + 3.0'] == results
def test_probing_current_process(): def proc(): assert Process.current_exists() assert not Process.current_exists() sim = Simulator() sim.add(proc) sim.run() assert not Process.current_exists()
def run_test_resource(resource_taker: ResourceTaker, num_instances: int, expected: List[float]) -> None: sim = Simulator() resource = Resource(num_instances) log: List[float] = [] for n in range(8): sim.add(resource_taker, resource, float(n + 1), log) sim.run() assert expected == pytest.approx(log)
def test_resource_timeout(): resource = Resource(1) log = [] def take_but_balk(name, delay_balk): try: with resource.using(timeout=delay_balk): advance(20.0) log.append((name, "finish")) except Timeout: log.append((name, "balk")) sim = Simulator() sim.add(take_but_balk, "a", 10.0) sim.add_in(5.0, take_but_balk, "b", 10.0) sim.run() assert log == [("b", "balk"), ("a", "finish")]
def test_resource_release_while_holding_none(): def proc(resource: Resource) -> None: resource.release() pytest.fail() sim = Simulator() resource = Resource(1) sim.add(proc, resource) with pytest.raises(RuntimeError): sim.run()
def test_getting_current_process(): def proc(): assert isinstance(Process.current(), Process) sim = Simulator() sim.add(proc) sim.run() with pytest.raises(TypeError): proc()
def test_happens_named(): @happens([5], name="my-process") def process(): advance(5) sim = Simulator() proc = sim.add(process) sim.run() assert proc.local.name == "my-process" assert 10.0 == pytest.approx(sim.now())
def run_test_process_add(launcher): when_last = 0.0 def last_proc(): nonlocal when_last when_last = now() sim = Simulator() sim.add(launcher, last_proc) sim.run() assert pytest.approx(50.0) == when_last
def test_happens(): sim = Simulator() log = [] @happens(repeat(2.0, 5)) def process(the_log): the_log.append(now()) sim.add(process, log) sim.run() assert pytest.approx([2.0, 4.0, 6.0, 8.0, 10.0]) == log
def test_schedule_recurring(): ll = [0] def _append(): if sim.now() <= 10.0: ll.append(ll[-1] + 1) sim._schedule(1.0, _append) else: sim.stop() sim = Simulator() sim._schedule(1.0, _append) sim.run() assert sim.now() == 11.0 assert ll == list(range(11))
def test_cancel_timeout(): queue = Queue() log = [] def join_and_balk(name): try: queue.join(100) log.append((name, "finish")) except Timeout: log.append((name, "balk")) def pop(): queue.pop() sim = Simulator() sim.add(join_and_balk, "a") sim.add_in(50, pop) sim.run() assert log == [("a", "finish")]