def testLoadConfigWithDuplicate(self): c = Controller() try: c.loadConfig(os.path.join(os.path.dirname(__file__), 'testDuplicateDevice.json')) self.fail("Didn't throw an exception when adding a duplicated device ID") except DuplicateDeviceIDError as e: self.assertEqual("Device already exists: Duplicate", str(e))
def testUpDownStopArray(self, mock_logging): udsr1 = MagicMock() udsr1.deviceID = "udsr1" udsr2 = MagicMock() udsr2.deviceID = "udsr2" c = Controller() c.addDevice(udsr1) c.addDevice(udsr2) udsa = UpDownStopArray("Test", c, {1: 'udsr1'}) udsa.add(udsr2, 2) self.assertEqual(2, len(udsa.relays.items())) udsa.raiseUp(1) udsr1.raiseUp.assert_called_once_with() self.assertEqual(0, udsr2.raiseUp.call_count) udsa.lower(0) udsr1.lower.assert_called_once_with() udsr2.lower.assert_called_once_with() udsa.stop(2) udsr2.stop.assert_called_once_with() udsa.raiseUp(3) mock_logging.error.assert_called_once_with("Tried to raise relay channel 3 but no such device attached to Test") mock_logging.reset_mock() udsa.lower(-123) mock_logging.error.assert_called_once_with("Tried to lower relay channel -123 but no such device attached to Test") mock_logging.reset_mock() udsa.stop(42) mock_logging.error.assert_called_once_with("Tried to stop relay channel 42 but no such device attached to Test")
def testLoadConfigWithLogging(self, logging): mockLogger = MagicMock() logging.getLogger = MagicMock(return_value=mockLogger) c = Controller() c.loadConfig(os.path.join(os.path.dirname(__file__), 'testConfigWithLogging.json'), True) logging.config.dictConfig.assert_called_once_with({"key": "value", "key2": "value2"}) mockLogger.setLevel.assert_called_once_with(logging.DEBUG) logging.info.assert_called_once_with("-d specified, overriding any specified default logger level to DEBUG")
def testKramerVP88Listener(self): port = MockSerialPort() port.setDataForRead([chr(0x41), chr(0x82), chr(0x83), chr(0x81)]) # Notification that input 2 sent to output 3 k = KramerVP88("Test", port) c = Controller() c.addDevice(k) k.broadcast = MagicMock() k.initialise() sleep(1) k.deinitialise() k.broadcast.assert_called_with('avx.client.OutputMapping', {3: 2})
def testKramerVP88Listener(self): port = MockSerialPort() port.read = MagicMock(return_value=[chr(0x41), chr(0x82), chr(0x83), chr(0x81)]) # Notification that input 2 sent to output 3 k = KramerVP88("Test", port) c = Controller() c.addDevice(k) kl = KramerVP88Listener("TestListener", k.deviceID, c, machineNumber=1) dispatcher = NullDispatcher() dispatcher.updateOutputMappings = MagicMock() kl.registerDispatcher(dispatcher) kl.start() threading.Event().wait(0.1) kl.stop() dispatcher.updateOutputMappings.assert_called_with({'Test': {3: 2}})
def testLoadConfig(self): c = Controller() c.loadConfig(os.path.join(os.path.dirname(__file__), 'testConfig.json')) self.assertTrue(c.hasDevice("Main")) self.assertTrue(c.hasDevice("Main Listener")) self.assertTrue(isinstance(c.getDevice("Main"), KramerVP88)) self.assertTrue(isinstance(c.getDevice("Main Listener"), KramerVP88Listener)) self.assertEqual("testController", c.controllerID)
def main(): pid_file = 'av-control.pid' fp = open(pid_file, 'w') try: fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: # another instance is running print "av-control is already running." sys.exit(1) logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO) app = QApplication(sys.argv) parser = argparse.ArgumentParser() parser.add_argument("-f", "--fullscreen", help="Run in fullscreen mode and hide the mouse cursor", action="store_true") parser.add_argument("-c", help="Specify the controller ID to connect to", metavar="CONTROLLERID", default="") args = parser.parse_args() try: ssf = QFile(":/stylesheet") ssf.open(QFile.ReadOnly) styleSheet = str(ssf.readAll()) app.setStyleSheet(styleSheet) except IOError: # never mind logging.warn("Cannot find stylesheet, using default system styles.") try: controller = Controller.fromPyro(args.c) myapp = MainWindow(controller) client = AvControlClient(myapp) client.setDaemon(True) client.start() client.started.wait() atexit.register(lambda: controller.unregisterClient(client.uri)) controller.registerClient(client.uri) if args.fullscreen: QApplication.setOverrideCursor(Qt.BlankCursor) myapp.showFullScreen() else: myapp.show() sys.exit(app.exec_()) except VersionMismatchError as e: Dialogs.errorBox(str(e))
def testKramerVP88Listener(self): port = MockSerialPort() port.read = MagicMock(return_value=[ chr(0x41), chr(0x82), chr(0x83), chr(0x81) ]) # Notification that input 2 sent to output 3 k = KramerVP88("Test", port) c = Controller() c.addDevice(k) kl = KramerVP88Listener("TestListener", k.deviceID, c, machineNumber=1) dispatcher = NullDispatcher() dispatcher.updateOutputMappings = MagicMock() kl.registerDispatcher(dispatcher) kl.start() threading.Event().wait(0.1) kl.stop() dispatcher.updateOutputMappings.assert_called_with({'Test': {3: 2}})
def testKramer602Listener(self): port = MockSerialPort() port.setDataForRead([chr(0x28), chr(0x81)]) # Notification that input 1 sent to output 1 k = Kramer602("Test", port) c = Controller() c.addDevice(k) k.broadcast = MagicMock() k.initialise() sleep(1) k.deinitialise() k.broadcast.assert_called_with('avx.client.OutputMapping', {1: 1}) port = MockSerialPort() port.setDataForRead([chr(0x28), chr(0x8A)]) # Notification that input 5 sent to output 2 k = Kramer602("Test", port) c = Controller() c.addDevice(k) k.broadcast = MagicMock() k.initialise() sleep(1) k.deinitialise() k.broadcast.assert_called_with('avx.client.OutputMapping', {2: 5})
def testLoadConfigWithRemote(self, fromPyro, logging): c = Controller() fakeSlave = MagicMock() fakeSlave.getVersion = MagicMock(return_value=c.getVersion()) fakeSlave.hasDevice = MagicMock(return_value=True) incompatibleSlave = MagicMock() incompatibleSlave.getVersion = MagicMock(return_value="0.1.0") fromPyro.side_effect = [fakeSlave, incompatibleSlave, NamingError()] c.loadConfig(os.path.join(os.path.dirname(__file__), 'testConfigWithSlaves.json')) fromPyro.assert_has_calls([ call('slave1'), # Boba Fett? Boba Fett? Where? call('incompatible'), call('nonexistent') ]) logging.error.assert_has_calls([ call("This Controller is version {} but tried to add slave incompatible of version 0.1.0".format(c.getVersion())), call("Could not connect to slave with controller ID nonexistent") ]) self.assertEqual(1, len(c.slaves)) c.proxyDevice("fakeDevice") fakeSlave.proxyDevice.assert_called_once_with("fakeDevice")
def testSendControlSignalsToBlinds(self): c = Controller() cp = ControllerProxy(c) self.PyroThread(c.daemon).start() blinds = UpDownStopArray("Blinds", c) blinds.lower = MagicMock(return_value=0) blinds.raiseUp = MagicMock(return_value=0) blinds.stop = MagicMock(return_value=0) c.addDevice(blinds) cp["Blinds"].lower(1) blinds.lower.assert_called_once_with(1) cp["Blinds"].raiseUp(256) blinds.raiseUp.assert_called_once_with(256) cp["Blinds"].stop(1138) blinds.stop.assert_called_once_with(1138) c.daemon.shutdown()
def testBadClientDisconnect(self): c = Controller() c.registerClient("DOES_NOT_EXIST") self.assertEqual(["DOES_NOT_EXIST"], c.clients) c.callAllClients(lambda c: c.doesNotExist()) self.assertEqual([], c.clients)
def testInitAndDeinitDevices(self, atexit): c = Controller() d = MagicMock() d.deviceID = "Test" c.addDevice(d) c.initialise() d.initialise.assert_called_once_with() atexit.register.assert_called_once_with(c.deinitialise) c.deinitialise() d.deinitialise.assert_called_once_with()
def testUpDownStopRelay(self): card = MagicMock() directionRelay = MagicMock() startStopRelay = MagicMock() card.createDevice.side_effect = [directionRelay, startStopRelay] card.deviceID = "Test" c = Controller() c.addDevice(card) udsr = UpDownStopRelay("TestUDSR", c, ("Test", 1), ("Test", 2)) card.createDevice.assert_has_calls([ call("TestUDSR_direction", 1), call("TestUDSR_startStop", 2) ]) udsr.raiseUp() directionRelay.on.assert_called_once_with() startStopRelay.on.assert_called_once_with() startStopRelay.reset_mock() directionRelay.reset_mock() udsr.stop() startStopRelay.off.assert_called_once_with() self.assertEqual(0, directionRelay.call_count) startStopRelay.reset_mock() directionRelay.reset_mock() udsr.lower() directionRelay.off.assert_called_once_with() startStopRelay.on.assert_called_once_with()
def testCallsAllGoodClients(self, pyro4): c = Controller() c.registerClient("Bad") c.registerClient("Good") good = MagicMock() good.clientMethod = MagicMock() pyro4.Proxy = MagicMock() pyro4.Proxy.side_effect = [Exception("Foo"), good] c.callAllClients(lambda c: c.clientMethod("Bar")) pyro4.Proxy.assert_has_calls([ call("Bad"), call("Good") ]) good.clientMethod.assert_called_once_with("Bar")
def testCallRemoteController(self): master = Controller() slave = Controller() cp = ControllerProxy(master) self.PyroThread(master.daemon).start() self.PyroThread(slave.daemon).start() switcher = KramerVP88("Test", FakeSerialPort()) switcher.sendInputToOutput = MagicMock(return_value=1) slave.addDevice(switcher) self.assertFalse(master.hasDevice("Test")) self.assertTrue(slave.hasDevice("Test")) master.slaves.append(slave) cp["Test"].sendInputToOutput(1, 2) switcher.sendInputToOutput.assert_called_once_with(1, 2) master.daemon.shutdown() slave.daemon.shutdown()
def main(): pid_file = 'av-control.pid' fp = open(pid_file, 'w') try: fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: # another instance is running print "av-control is already running." sys.exit(1) logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO) app = QApplication(sys.argv) parser = argparse.ArgumentParser() parser.add_argument( "-f", "--fullscreen", help="Run in fullscreen mode and hide the mouse cursor", action="store_true") parser.add_argument("-c", help="Specify the controller ID to connect to", metavar="CONTROLLERID", default="") parser.add_argument( "-j", "--joystick", help="Path to joystick device to use for camera control") args = parser.parse_args() try: ssf = QFile(":/stylesheet") ssf.open(QFile.ReadOnly) styleSheet = str(ssf.readAll()) app.setStyleSheet(styleSheet) except IOError: # never mind logging.warn("Cannot find stylesheet, using default system styles.") try: controller = Controller.fromPyro(args.c) js = None joystickDevice = args.joystick print args try: if args.joystick: if os.path.exists(joystickDevice): logging.info( "Configuring joystick {}".format(joystickDevice)) js = Joystick(joystickDevice) js.start() else: logging.error( "Specified joystick device {} does not exist!".format( joystickDevice)) except IOError: logging.exception("Unable to configure joystick") pass jsa = SensitivityPrefsCameraJoystickAdapter(js) jsa.start() myapp = MainWindow(controller, jsa) client = AvControlClient(myapp) client.setDaemon(True) client.start() client.started.wait() atexit.register(lambda: controller.unregisterClient(client.uri)) controller.registerClient(client.uri) if args.fullscreen: QApplication.setOverrideCursor(Qt.BlankCursor) myapp.showFullScreen() else: myapp.show() sys.exit(app.exec_()) except VersionMismatchError as e: Dialogs.errorBox(str(e))
def setUp(self): self.controller = Controller() self.sequencer = Sequencer(self.controller)
class TestSequencer(unittest.TestCase): def setUp(self): self.controller = Controller() self.sequencer = Sequencer(self.controller) def performSequenceTest(self, *events): self.sequencer.sequence(*events) self.sequencer.start() sleep(len(events) + 1) def testSimpleEvent(self): m = MagicMock() m.deviceID = "Mock" e1 = Event(m.frobnicate, "badger") self.performSequenceTest(e1) m.frobnicate.assert_called_once_with("badger") def testControllerEvent(self): self.controller.frobnicate = MagicMock(return_value=True) e = ControllerEvent("frobnicate", "badger") self.performSequenceTest(e) self.controller.frobnicate.assert_called_once_with("badger") def testDeviceEvent(self): m = MagicMock() m.deviceID = "Mock" self.controller.addDevice(m) e = DeviceEvent("Mock", "frobnicate", "badger") self.performSequenceTest(e) m.frobnicate.assert_called_once_with("badger") def testCompositeEvent(self): m = MagicMock() e1 = Event(m, "one") e2 = Event(m, "two") ce = CompositeEvent(e1, e2) self.performSequenceTest(ce) m.assert_has_calls([call("one"), call("two")]) @patch("avx.Sequencer.time") def testSleepEvent(self, time): e = SleepEvent(5) self.performSequenceTest(e) # N.B. time.sleep is also called by the sequencer itself time.sleep.assert_has_calls([call(5)]) @patch("avx.Sequencer.logging") def testLogEvent(self, logging): e = LogEvent(logging.INFO, "This is informational") self.performSequenceTest(e) logging.log.assert_called_once_with(logging.INFO, "This is informational")
else: self._device.tallyOff() if __name__ == '__main__': parser = ArgumentParser() parser.add_argument("-c", '--controller', help="Specify the controller ID to connect to", metavar="CONTROLLERID", default="") parser.add_argument('-t', '--tally', help='Tally input number to monitor', type=int, required=True) parser.add_argument('-b', '--brightness', help='Brightness of LEDs, between 0 and 1', type=float, default=0.1) args = parser.parse_args() clear() set_pixel(NUM_PIXELS - 1, 0, 0, 255, 0.05) show() controller = Controller.fromPyro(args.controller) client = BlinktTallyClient(args.tally, args.brightness) client.run()
def main(): pid_file = 'av-control.pid' fp = open(pid_file, 'w') try: fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError: # another instance is running print "av-control is already running." sys.exit(1) logging.basicConfig(format='%(asctime)s %(levelname)s: %(message)s', level=logging.INFO) app = QApplication(sys.argv) parser = argparse.ArgumentParser() parser.add_argument("-f", "--fullscreen", help="Run in fullscreen mode and hide the mouse cursor", action="store_true") parser.add_argument("-c", help="Specify the controller ID to connect to", metavar="CONTROLLERID", default="") parser.add_argument("-j", "--joystick", help="Path to joystick device to use for camera control") args = parser.parse_args() try: ssf = QFile(":/stylesheet") ssf.open(QFile.ReadOnly) styleSheet = str(ssf.readAll()) app.setStyleSheet(styleSheet) except IOError: # never mind logging.warn("Cannot find stylesheet, using default system styles.") try: controller = Controller.fromPyro(args.c) js = None joystickDevice = args.joystick print args try: if args.joystick: if os.path.exists(joystickDevice): logging.info("Configuring joystick {}".format(joystickDevice)) js = Joystick(joystickDevice) js.start() else: logging.error("Specified joystick device {} does not exist!".format(joystickDevice)) except IOError: logging.exception("Unable to configure joystick") pass jsa = SensitivityPrefsCameraJoystickAdapter(js) jsa.start() myapp = MainWindow(controller, jsa) client = AvControlClient(myapp) client.setDaemon(True) client.start() client.started.wait() atexit.register(lambda: controller.unregisterClient(client.uri)) controller.registerClient(client.uri) if args.fullscreen: QApplication.setOverrideCursor(Qt.BlankCursor) myapp.showFullScreen() else: myapp.show() sys.exit(app.exec_()) except VersionMismatchError as e: Dialogs.errorBox(str(e))
def testMomentaryUpDownStopRelay(self): card = MagicMock() upRelay = MagicMock() downRelay = MagicMock() stopRelay = MagicMock() card.createDevice.side_effect = [upRelay, downRelay, stopRelay] card.deviceID = "Test" c = Controller() c.addDevice(card) mudsr = MomentaryUpDownStopRelay("TestUDSR", c, ("Test", 1), ("Test", 2), ("Test", 3)) card.createDevice.assert_has_calls([ call("TestUDSR_up", 1), call("TestUDSR_down", 2), call("TestUDSR_stop", 3) ]) mudsr.raiseUp() sleep(0.1) with mudsr.lock: # wait for sequence to complete upRelay.on.assert_called_once() upRelay.off.assert_called_once() downRelay.on.assert_not_called() downRelay.off.assert_not_called() stopRelay.on.assert_not_called() stopRelay.off.assert_not_called() upRelay.reset_mock() mudsr.lower() sleep(0.1) with mudsr.lock: upRelay.on.assert_not_called() upRelay.off.assert_not_called() downRelay.on.assert_called_once() downRelay.off.assert_called_once() stopRelay.on.assert_not_called() stopRelay.off.assert_not_called() downRelay.reset_mock() mudsr.stop() sleep(0.1) with mudsr.lock: upRelay.on.assert_not_called() upRelay.off.assert_not_called() downRelay.on.assert_not_called() downRelay.off.assert_not_called() stopRelay.on.assert_called_once() stopRelay.off.assert_called_once() stopRelay.reset_mock() synctest = MagicMock() relay = MagicMock() synctest.createDevice.side_effect = [relay, relay, relay] synctest.deviceID = "synctest" c2 = Controller() c2.addDevice(synctest) mudsr2 = MomentaryUpDownStopRelay("testsync", c2, ("synctest", 1), ("synctest", 2), ("synctest", 3)) mudsr2.raiseUp() mudsr2.lower() sleep(1) with mudsr2.lock: relay.assert_has_calls([ call.on(), call.off(), # Specifically: this off() is called before the second on() call.on(), call.off() ])
def testPersistClientList(self): with create_temporary_copy(os.path.join(os.path.dirname(__file__), 'testConfig.json')) as confFile: c = Controller() c.loadConfig(confFile.name) c.registerClient("DOES_NOT_EXIST") withClient = json.load(confFile) print withClient self.assertEqual(withClient["clients"], ["DOES_NOT_EXIST"]) del c c2 = Controller() c2.loadConfig(confFile.name) self.assertEqual(c2.clients, ["DOES_NOT_EXIST"]) c2.callAllClients(lambda c: c.notARealMethod()) with open(confFile.name, "r") as cf2: withClient2 = json.load(cf2) self.assertEqual(withClient2["clients"], [])
def testLoadInvalidConfig(self, logging): c = Controller() c.loadConfig(os.path.join(os.path.dirname(__file__), 'notJson')) logging.exception.assert_called_once_with("Cannot parse config.json!")