def test_passthrough_as_a_method(self): """Verify that, when passthrough is used as a method, it can still take thunks. """ scheduler = Scheduler(asyncio.get_event_loop()) luxpub = SensorAsOutputThing(ValueListSensor('lux-2', lux_data)) vs1 = ValidationInputThing([450, 600], self) vs2 = ValidationInputThing(lux_data, self) luxpub.passthrough(compose(where(lambda evt: evt.val > 300), vs1)).connect(vs2) scheduler.schedule_periodic(luxpub, 0.5) scheduler.run_forever() self.assertTrue(vs1.completed) self.assertTrue(vs2.completed)
def test_function_filter(self): """Verify the function filter class """ s = ValueListSensor(1, value_stream) st = SensorAsOutputThing(s) captured_list_ref = [[]] got_completed_ref = [ False, ] def on_next(self, x): captured_list_ref[0].append(x.val) self._dispatch_next(x) def on_completed(self): got_completed_ref[0] = True self._dispatch_completed() ff = FunctionFilter(st, on_next=on_next, on_completed=on_completed) vo = ValidationInputThing(value_stream, self.test_function_filter) ff.connect(vo) st.print_downstream() scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(st, 0.5) # sample twice every second scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") self.assertEqual(value_stream, captured_list_ref[0]) self.assertTrue(got_completed_ref[0]) print("That's all folks")
def test_sensor_event_sliding_window(self): vs = ValidationInputThing(mean_stream, self) self.scheduler.schedule_sensor(self.sensor, 0.1, transduce(SensorSlidingMean(4)), parallel(vs, output())) self.scheduler.run_forever() self.assertTrue(vs.completed)
def test_case(self): sensor = sensor_from_sequence(1, input_sequence) sensor.connect(print) dispatcher = sensor.transduce(RunningAvg(2)) \ .dispatch([(lambda v: v[2]>=T1, 't1'), (lambda v: v[2]<=T2, 't2')]) controller = Controller() dispatcher.connect(controller, port_mapping=('t1', 't1')) dispatcher.connect(controller, port_mapping=('t2', 't2')) # we only push the between message to the controller for the first # event - it is only needed for emitting an output from the initial # state. dispatcher.first().connect(controller, port_mapping=('default', 'between')) controller.connect(print) vo = ValidationInputThing(expected_sequence, self) controller.connect(vo) sensor.print_downstream() scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(sensor, 0.5) scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") print("got to the end")
def test_mqtt(self): loop = asyncio.get_event_loop() s = Scheduler(loop) sensor = make_test_output_thing_from_vallist(1, sensor_data) mqtt_writer = MQTTWriter('localhost', topics=[ ('bogus/bogus', 0), ]) sensor.to_json().connect(mqtt_writer) s.schedule_periodic(sensor, 0.5) mqtt_reader = MQTTReader("localhost", topics=[ ('bogus/bogus', 0), ]) vs = ValidationInputThing(sensor_data, self) mqtt_reader.take(5).select(mqtt_msg_to_unicode).from_json(constructor=SensorEvent) \ .output().connect(vs) c = s.schedule_on_private_event_loop(mqtt_reader) stop = StopLoopAfter(5, c) mqtt_reader.connect(stop) mqtt_reader.print_downstream() sensor.print_downstream() s.run_forever() loop.stop() self.assertTrue(vs.completed) print("that's it")
def test_periodic_median_transducer(self): vs = ValidationInputThing(periodic_median_stream, self) self.scheduler.schedule_sensor(self.sensor, 0.1, transduce(PeriodicMedianTransducer(3)), parallel(vs, output())) self.scheduler.run_forever() self.assertTrue(vs.completed)
def test_function_filter_error_handling(self): """Verify the error handling functionality of the function filter. We do this by connecting two downstream paths to the sensor. The first includes a function filter that throws an error when it encouters a sensor reading of 120. This should disconnect th stream at this point. The second is a normal validation input thing. It is connected directly to the sensor, and thus should not see any errors. """ s = ValueListSensor(1, value_stream) st = SensorAsOutputThing(s) captured_list_ref = [[]] got_completed_ref = [ False, ] got_on_error_ref = [ False, ] def on_next_throw_exc(self, x): if x.val == 120: raise Exception("expected exc") else: captured_list_ref[0].append(x.val) self._dispatch_next(x) def on_completed(self): got_completed_ref[0] = True self._dispatch_completed() def on_error(self, e): got_on_error_ref[0] = True self._dispatch_error(e) ff = FunctionFilter(st, on_next=on_next_throw_exc, on_completed=on_completed, on_error=on_error) ct = CaptureInputThing(expecting_error=True) ff.map(lambda x: x.val).connect(ct) vo = ValidationInputThing(value_stream, self.test_function_filter_error_handling) st.connect(vo) st.print_downstream() scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(st, 0.5) # sample twice every second scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") self.assertFalse(ct.completed, "Capture thing should not have completed") self.assertTrue(ct.errored, "Capture thing should have seen an error") self.assertFalse(got_completed_ref[0]) self.assertTrue(got_on_error_ref[0]) self.assertEqual([20, 30, 100], ct.events, "Capture thing event mismatch") self.assertEqual([20, 30, 100], captured_list_ref[0], "captured_list_ref mismatch") print("That's all folks")
def test_first(self): """Test the first() operator """ p = make_test_output_thing_from_vallist(1, [1, 2, 3, 4, 5, 6]) vs = ValidationInputThing([1], self) p.first().connect(vs) scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_recurring(p) scheduler.run_forever() self.assertTrue(vs.completed)
def test_tracing(self): s = ValueListSensor(1, values) p = SensorAsOutputThing(s) v = ValidationInputThing([v+1 for v in values], self, extract_value_fn=lambda x:x) p.passthrough(output).map(lambda x : x.val+1).passthrough(output).connect(v) p.trace_downstream() scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(p, 0.5) # sample twice every second scheduler.run_forever()
def test_blocking_output_thing(self): o = BlockingOutputThing() o.output() scheduler = Scheduler(asyncio.get_event_loop()) c = scheduler.schedule_periodic_on_separate_thread(o, 1) vs = ValidationInputThing([i + 1 for i in range(EVENTS)], self, extract_value_fn=lambda v: v) o.connect(vs) o.connect(StopLoopAfter(EVENTS, c)) o.print_downstream() scheduler.run_forever() print("that's it")
def test_blocking_sensor(self): s = BlockingSensor(1, stop_after=EVENTS) scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_sensor_on_separate_thread( s, 1, passthrough(output()), ValidationInputThing([i + 1 for i in range(EVENTS)], self, extract_value_fn=lambda v: v), make_event_fn=lambda s, v: v) scheduler.run_forever() print("that's it")
def test_complex_workflow(self): THRESHOLD = 300 lux = ValueListSensor('lux-1', lux_data) scheduler = Scheduler(asyncio.get_event_loop()) vs1 = ValidationInputThing(lux_data, self) vs2 = ValidationInputThing( [False, False, False, True, False, False, True], self, extract_value_fn=lambda v: v) scheduler.schedule_sensor( lux, 0.5, passthrough(output()), passthrough(vs1), map(lambda event: event.val > THRESHOLD), passthrough(lambda v: print('ON' if v else 'OFF')), vs2, print_downstream=True) scheduler.run_forever() self.assertTrue(vs1.completed) self.assertTrue(vs2.completed) print("That's all folks")
def test_schedule_sensor(self): """In this version, we pass the sensor directly to the scheduler and use a functional style to compose the filters""" s = ValueListSensor(1, value_stream) vo = ValidationInputThing(expected_stream, self.test_schedule_sensor) scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_sensor(s, 0.5, where(predicate), passthrough(vo), output()) scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") print("That's all folks")
def test_where(self): s = make_test_output_thing_from_vallist(1, value_stream) w = s.where(predicate) w.output() vo = ValidationInputThing(expected_stream, self) w.connect(vo) scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(s, 0.5) # sample twice every second s.print_downstream() scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") self.assertTrue(vo.completed) print("That's all folks")
def test_thunk_builder_handling(self): """We have logic where we can pass a thunk builder into a combinator and it will do the right thing. Check that it works""" scheduler = Scheduler(asyncio.get_event_loop()) lux = ValueListSensor('lux-2', lux_data) vs = ValidationInputThing(lux_data, self) scheduler.schedule_sensor( lux, 0.5, passthrough(output()), # output() evaluates to a thunk passthrough(output), # output is a thunk builder passthrough(output(sys.stdout)), # output can take an arg vs, print_downstream=True) scheduler.run_forever() self.assertTrue(vs.completed)
def test_where(self): """In this version, we create a publisher and use method chaining to compose the filters""" s = ValueListSensor(1, value_stream) p = SensorAsOutputThing(s) w = p.where(predicate) w.output() vo = ValidationInputThing(expected_stream, self.test_where) w.connect(vo) scheduler = Scheduler(asyncio.get_event_loop()) scheduler.schedule_periodic(p, 0.5) # sample twice every second p.print_downstream() scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed") print("That's all folks")
def test_multiple_timeouts(self): """In this testcase, we pass two events, drop two events, etc. We set the timeout to a bit longer than the event interval. The last good value is supplied when the timeout expires. Thus, we should see two good events, two repeats of the first event, two good events, etc. """ sensor = make_test_output_thing_from_vallist(1, sensor_values) drop = DropPeriodic(sensor, N=2) scheduler = Scheduler(asyncio.get_event_loop()) vo = ValidationInputThing(expected_values_multiple_timeouts, self) drop.supply_event_when_timeout(EventWatcher(), scheduler, 1.1).output().connect(vo) scheduler.schedule_periodic(sensor, 1) sensor.print_downstream() scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed")
def test_supplying_event_on_timeout(self): """In this testcase, we drop every other event. We set the timeout to a bit longer than the event interval of one second. It then supplies the previous event. The resulting output stream will show every other value repeated twice. """ sensor = make_test_output_thing_from_vallist(1, sensor_values) drop = DropPeriodic(sensor) scheduler = Scheduler(asyncio.get_event_loop()) vo = ValidationInputThing(expected_values, self) drop.supply_event_when_timeout(EventWatcher(), scheduler, 1.1).output().connect(vo) scheduler.schedule_periodic(sensor, 1) sensor.print_downstream() scheduler.run_forever() self.assertTrue( vo.completed, "Schedule exited before validation observer completed")