def test1_trans_topology_a(): ao = ActiveObject() ao.start_at(outer) pp(ao.spy_full()) assert (ao.spy_full() == [ 'START', 'SEARCH_FOR_SUPER_SIGNAL:outer', 'ENTRY_SIGNAL:outer', 'INIT_SIGNAL:outer', '<- Queued:(0) Deferred:(0)' ]) pp(ao.spy_full()) print(ao.trace()) event_w = Event(signal=signals.WaitComplete) ao.clear_trace() ao.post_fifo(event_w) import time time.sleep(0.1) pp(ao.spy_rtc()) print(ao.trace()) # clear the spy and the trace ao.clear_spy() ao.clear_trace() # post a number of events and see what happens event_wait_complete = Event(signal=signals.WaitComplete) event_reset_chart = Event(signal=signals.ResetChart) ao.post_fifo(event_wait_complete) ao.post_fifo(event_reset_chart) ao.post_fifo(event_wait_complete) ao.post_fifo(event_reset_chart) time.sleep(0.3) print(ao.trace()) pp(ao.spy_full())
def breaker_open(self, e): status = return_status.UNHANDLED if(e.signal == signals.ENTRY_SIGNAL): self.history = breaker_open self.relay_driver.initiate_open() self.post_fifo( Event(signal=signals.Test_Relay_Hardware), period=1.0, deferred=True) status = return_status.HANDLED elif(e.signal == signals.Test_Relay_Hardware): if self.relay_driver.is_closed(): self.open_failed() status = return_status.HANDLED elif(e.signal == signals.Failed_Opening): status = self.trans(breaker_error) elif(e.signal == signals.Closed): status = self.trans(breaker_closed) elif(e.signal == signals.Failed_Opening): status = self.trans(equipment_error) elif(e.signal == signals.EXIT_SIGNAL): self.cancel_events(Event(signals.Test_Relay_Hardware)) status = return_status.HANDLED else: self.temp.fun = circuit_breaker_outer_state status = return_status.SUPER return status
def volts_across_terminals(self, volts, sample_time=None): if sample_time is None: self.post_fifo(Event(signal=signals.volts, payload=Volts(volts))) else: self.post_fifo( Event(signal=signals.volts_and_time, payload=VoltsAndTime(volts=volts, time=sample_time)))
def amps_through_terminals(self, amps, sample_time=None): if sample_time is None: self.post_fifo(Event(signal=signals.amps, payload=Amps(amps))) else: self.post_fifo( Event(signal=signals.amps_and_time, payload=AmpsAndTime(amps=amps, time=sample_time)))
def test_subscribe_lilo(fabric_fixture): '''the feature actually determines if we are using the post_lifo or post_fifo method of the active object, so we just need to make sure our queues are working for this part of the system... we do not need to change the ordering of the items in the queue''' input_queue_1 = deque(maxlen=5) event_a = Event(signal=signals.A) event_b = Event(signal=signals.B) input_queue_1.append(event_b) af = ActiveFabric() af.subscribe(input_queue_1, event_a, queue_type='lifo') af.subscribe(input_queue_1, event_b, queue_type='lifo') af.start() af.publish(event_a) time.sleep(0.11) assert (len(input_queue_1) == 2) popped_event = input_queue_1.pop() assert (popped_event.signal_name == 'A') assert (len(input_queue_1) == 1) popped_event = input_queue_1.pop() assert (popped_event.signal_name == 'B') af.publish(event_a) af.publish(event_b) time.sleep(0.11) popped_event = input_queue_1.pop() assert (popped_event.signal_name == 'B') assert (len(input_queue_1) == 1) popped_event = input_queue_1.pop() assert (popped_event.signal_name == 'A') assert (len(input_queue_1) == 0)
def test_thread_safe_in_active_object(): global expected_results with open(alog_file, 'w') as fp: fp.write("") ao = Example1('example') ao.live_spy = True #ao.live_trace = True ao.start_at(c) ao.thread_safe_attr_1 = False ao.thread_safe_attr_2 = True ao.post_fifo(Event(signal=signals.A)) ao.post_fifo(Event(signal=signals.B)) ao.post_fifo(Event(signal=signals.A)) ao.post_fifo(Event(signal=signals.B)) ao.post_fifo(Event(signal=signals.A)) time.sleep(2) results = get_spy_as_list(alog_file) eresults = expected_results.split("\n") for i, item in enumerate(results): assert (results[i] == eresults[i]) # remove comment if debugging this test os.remove(alog_file)
def outer_init(chart, e): chart.post_fifo(Event(signal=signals.to_inner), times=1, period=random.randint(2, 7), deferred=True) chart.transmit(Event(signal=signals.other_to_outer, payload=chart.name)) return return_status.HANDLED
def charging_entry_signal(self, e): status = return_status.HANDLED self.cancel_events(Event(signal=signals.Pulse)) self.post_fifo(Event(signal=signals.Pulse), period=self.pulse_sec / self.time_compression_scalar, deferred=True, times=0) return status
def test_event(): signals = SignalSource() event = Event(signal=signals.ENTRY_SIGNAL) assert (event.signal is 1) assert (event.signal_name == "ENTRY_SIGNAL") event = Event(signal="BOB") assert (event.signal >= 6) assert (event.signal_name == "BOB")
def wait_for_electrical_interface_entry_signal(self, e): status = return_status.HANDLED self._fn_sample_current = None self._fn_sample_voltage = None self.subscribe(Event(signal=signals.SET_CURRENT_SAMPLER)) self.subscribe(Event(signal=signals.SET_VOLTAGE_SAMPLER)) self.publish(Event(signal=signals.REQUEST_FOR_SAMPLERS)) return status
def charge_into_battery(self, amp_hours, sample_time=None): if sample_time is None: self.post_fifo( Event(signal=signals.amp_hours, payload=AmpsHours(amps_hours))) else: self.post_fifo( Event(signal=signals.amps_and_time, payload=AmpsAndTime(amps=amps, time=sample_time)))
def faw_entry(cache, e): '''The file_access_waiting state ENTRY_SIGNAL event handler''' cache.subscribe(Event(signal=signals.CACHE_FILE_READ)) cache.subscribe(Event(signal=signals.CACHE_FILE_WRITE)) # check if file exists, if not make it with nothing in it if not os.path.isfile(cache.file_path): open(cache.file_path, 'a').close() return return_status.HANDLED
def inner_entry(chart, e): chart.post_fifo(Event(signal=signals.to_outer), times=1, period=random.randint(2, 7), deferred=True) chart.transmit(Event(signal=signals.other_to_inner, payload=chart.name)) chart.snoop_scribble(chart.this_url()) return return_status.HANDLED
def common_behaviors_entry_signal(chart, e): status = return_status.HANDLED chart.subscribe(Event(signal=signals.WEATHER)) chart.turn_off_sprinkler() chart.post_fifo(Event(signal=signals.heart_beat), times=0, period=Sprinkler.SPRINKLER_HEART_BEAT_SEC, deferred=True) return status
def test_signal_singletons(): '''The signals object from the event.py class is the growing signals enumeration''' local_signals = SignalSource() e = Event(signal="MARY") assert (e.signal_name == "MARY") assert (signals.MARY > local_signals.REFLECTION_SIGNAL) e = Event(signal="JANE") assert (e.signal_name == "JANE") assert (signals.JANE > signals.REFLECTION_SIGNAL)
def charging_pulse(self, e): status = return_status.HANDLED self.amps = self.sample_current() self.volts = self.sample_voltage() if (self.volts < self.battery_spec.bulk_entry_volts): self.post_fifo(Event(signal=signals.To_Bulk)) self.sec += self.pulse_sec self.post_fifo( Event(signal=signals.Tick, payload=SecInCharge(sec=self.sec))) return status
def __init__(self, name, number_of_philosophers): super().__init__(name) self.subscribe(Event(signal=signals.DONE)) self.subscribe(Event(signal=signals.HUNGRY)) self.forks = [Fork.Free for i in range(number_of_philosophers)] self.is_hungry = [False for i in range(number_of_philosophers)] self.to_the_right_of = partial(right, num=number_of_philosophers) self.to_the_left_of = partial(left, num=number_of_philosophers)
def spy_on_heater_off(): oven = ToasterOvenMock(name="oven") # The light should be turned off when we start oven.start_at(door_closed) oven.post_fifo(Event(signal=signals.Toasting)) oven.clear_spy() oven.post_fifo(Event(signal=signals.Off)) time.sleep(0.01) # turn our array into a paragraph return "\n".join(oven.spy())
def weather_worker_entry_signal(chart, e): status = return_status.HANDLED chart.subscribe(Event(signal=signals.GET_WEATHER)) chart.subscribe(Event(signal=signals.CITY_DETAILS)) chart.subscribe(Event(signal=signals.WEATHER)) chart.publish( Event(signal=signals.REQUEST_CITY_DETAILS, payload=RequestDetailsForCityPayload(city=chart.city, country=chart.country))) return status
def example_state_entry(ex, e): status = return_status.HANDLED # we don't use these, we just start them... # the stop method should cancel these events ex.post_fifo(Event(signal=signals.multi_shot_signal_10_times_1), deferred=True, period=1.0, times=10) ex.post_fifo(Event(signal=signals.multi_shot_signal_10_times_2), deferred=True, period=1.0, times=10) return status
def get_id_file_from_network_entry_signal(chart, e): status = return_status.HANDLED try: r = requests.get(chart.lookup_file_url) with open(str(chart.lookup_file_path), 'wb') as f: f.write(r.content) chart.post_fifo(Event(signal=signals.read_file)) except: chart.post_fifo(Event(signal=signals.retry_after_network_error), times=1, period=CityWeather.NETWORK_ERROR_RETRY_TIME_IN_SEC, deferred=True) return status
def test_that_stopping_the_fabric_stops_the_tasks(): ssc = StartStopChart('bob') ssc.post_fifo( Event(signal=signals.do_some_useful_work, payload=Payload(item=1))) time.sleep(0.1) assert (len(ssc.posted_events_queue) == 2) assert (ssc.get_item() == 1) assert (ssc.thread.is_alive() == True) ssc.fabric.stop() # the active object dies after it is woken by an event ssc.post_fifo( Event(signal=signals.do_some_useful_work, payload=Payload(item=1))) time.sleep(0.1) assert (ssc.thread.is_alive() == False)
def hsm_queues_graph_g1_s01(chart, e): status = return_status.UNHANDLED if (e.signal == signals.ENTRY_SIGNAL): chart.post_fifo(Event(signal=signals.A)) chart.post_lifo(Event(signal=signals.F)) chart.recall() status = return_status.HANDLED elif (e.signal == signals.EXIT_SIGNAL): status = return_status.HANDLED elif (e.signal == signals.C): status = chart.trans(hsm_queues_graph_g1_s22) else: status, chart.temp.fun = return_status.SUPER, hsm_queues_graph_g1_s0 return status
def toasting(oven, e): status = return_status.UNHANDLED if (e.signal == signals.ENTRY_SIGNAL): oven.history = toasting oven.cook_time(oven.toast_time_in_sec) status = return_status.HANDLED elif (e.signal == signals.EXIT_SIGNAL): oven.cancel_events(Event(signal=signals.Done)) oven.cancel_events(Event(signal=signals.Get_Ready)) status = return_status.HANDLED else: oven.temp.fun = heating status = return_status.SUPER return status
def g1_s01_active_objects_graph(chart, e): status = return_status.UNHANDLED if(e.signal == signals.ENTRY_SIGNAL): chart.scribble("Demonstrating chart will react to F before A") chart.post_fifo(Event(signal=signals.A)) chart.post_lifo(Event(signal=signals.F)) chart.recall() status = return_status.HANDLED elif(e.signal == signals.EXIT_SIGNAL): status = return_status.HANDLED elif(e.signal == signals.C): status = chart.trans(g1_s22_active_objects_graph) else: status, chart.temp.fun = return_status.SUPER, g1_s0_active_objects_graph return status
def api_live_entry_signal(chart, e): status = return_status.HANDLED try: weather_results_dict = chart.query_api() chart.cached_payload = \ chart.to_weather_payload(weather_results_dict) chart.publish( Event(signal=signals.WEATHER, payload=chart.cached_payload)) except: chart.post_lifo(Event(signal=signals.network_error)) chart.post_fifo(Event(signal=signals.GET_WEATHER), times=1, period=CityWeather.NETWORK_ERROR_RETRY_TIME_IN_SEC, deferred=True) return status
def test_that_chart_is_working(): ssc = StartStopChart('whatever') ssc.post_fifo( Event(signal=signals.do_some_useful_work, payload=Payload(item=1))) time.sleep(0.1) assert (len(ssc.posted_events_queue) == 2) assert (ssc.get_item() == 1)
def test_start_stop_c(fabric_fixture): ao1 = ActiveObject() ao1.start_at(c2_s3) time.sleep(0.2) ao1.post_fifo(Event(signal=signals.A)) time.sleep(0.2) pp(ao1.spy_full())
def next_generation(self): '''create the next row of the 2d cellular automata, update the color map Z''' Z = self.Z if self.generation == self.generations - 1: # draw the first row for i, machine in enumerate(self.machines): Z[self.generations - 1, i] = machine.color_number() else: # draw every other row Z = self.Z new_machines = [] for i in range(1, (len(self.machines) - 1)): old_left_machine = self.machines[i - 1] old_machine = self.machines[i] old_right_machine = self.machines[i + 1] new_machine = self.machine_cls() new_machine.start_at(old_machine.state_fn) new_machine.left = old_left_machine new_machine.right = old_right_machine new_machines.append(new_machine) left_wall = self.make_and_start_left_wall_machine() right_wall = self.make_and_start_right_wall_machine() new_machines = [left_wall] + new_machines + [right_wall] for i, machine in enumerate(new_machines): machine.dispatch(Event(signal=signals.Next)) Z[self.generation, i] = machine.color_number() self.machines = new_machines[:] self.Z = Z self.generation -= 1
def test_interior_postings_example(): ao = ActiveObject() ao.start_at(middle) time.sleep(0.4) ao.post_fifo(Event(signal=signals.D)) time.sleep(0.5) # if you don't wait it won't look like it is working pp(ao.spy) assert (ao.spy_full() == [ 'START', 'SEARCH_FOR_SUPER_SIGNAL:middle', 'SEARCH_FOR_SUPER_SIGNAL:outer', 'ENTRY_SIGNAL:outer', 'ENTRY_SIGNAL:middle', 'INIT_SIGNAL:middle', '<- Queued:(0) Deferred:(0)', 'A:middle', 'SEARCH_FOR_SUPER_SIGNAL:inner', 'ENTRY_SIGNAL:inner', 'POST_DEFERRED:B', 'INIT_SIGNAL:inner', '<- Queued:(0) Deferred:(1)', 'A:inner', 'A:middle', 'EXIT_SIGNAL:inner', 'SEARCH_FOR_SUPER_SIGNAL:inner', 'ENTRY_SIGNAL:inner', 'POST_DEFERRED:B', 'INIT_SIGNAL:inner', '<- Queued:(0) Deferred:(2)', 'A:inner', 'A:middle', 'EXIT_SIGNAL:inner', 'SEARCH_FOR_SUPER_SIGNAL:inner', 'ENTRY_SIGNAL:inner', 'POST_DEFERRED:B', 'INIT_SIGNAL:inner', '<- Queued:(0) Deferred:(3)', 'D:inner', 'D:middle', 'D:outer', 'RECALL:B', 'POST_FIFO:B', 'D:outer:HOOK', '<- Queued:(1) Deferred:(2)', 'B:inner', 'B:middle', 'B:outer', 'EXIT_SIGNAL:inner', 'EXIT_SIGNAL:middle', 'EXIT_SIGNAL:outer', 'ENTRY_SIGNAL:outer', 'RECALL:B', 'POST_FIFO:B', 'INIT_SIGNAL:outer', '<- Queued:(1) Deferred:(1)', 'B:outer', 'EXIT_SIGNAL:outer', 'ENTRY_SIGNAL:outer', 'RECALL:B', 'POST_FIFO:B', 'INIT_SIGNAL:outer', '<- Queued:(1) Deferred:(0)', 'B:outer', 'EXIT_SIGNAL:outer', 'ENTRY_SIGNAL:outer', 'INIT_SIGNAL:outer', '<- Queued:(0) Deferred:(0)' ])
def test_if_event_can_take_payload(): e = Event(signal=signals.whatever, payload="Bob") assert(e.has_payload() is True) assert(e.payload == "Bob")
def test_automatic_construction_of_signals(): '''We don't want to have to define a signal number and signal name twice, if it is referenced, it is invented''' e = Event(signal=signals.NOT_INVENTED_YET) assert(e.signal_name is 'NOT_INVENTED_YET') assert(e.has_payload() is False)