diff --git a/tests/virtual-device.py b/tests/virtual-device.py index 0e5ae942..f6e88ab8 100644 --- a/tests/virtual-device.py +++ b/tests/virtual-device.py @@ -60,6 +60,15 @@ class GLibErrorMessage: class VirtualDeviceBase(unittest.TestCase): DEFAULT_ENROLL_STEPS = 5 + USE_CLASS_DEVICE = True + + @classmethod + def get_device(cls, ctx): + for dev in ctx.get_devices(): + # We might have a USB device in the test system that needs skipping + if dev.get_driver() == cls._driver_name: + return dev + return None @classmethod def setUpClass(cls): @@ -75,26 +84,28 @@ class VirtualDeviceBase(unittest.TestCase): cls.sockaddr = os.path.join(cls.tmpdir, '{}.socket'.format(sock_name)) os.environ['FP_{}'.format(driver_name.upper())] = cls.sockaddr - cls.ctx = FPrint.Context() + cls._driver_name = driver_name - cls.dev = None - for dev in cls.ctx.get_devices(): - # We might have a USB device in the test system that needs skipping - if dev.get_driver() == driver_name: - cls.dev = dev - break - - assert cls.dev is not None, "You need to compile with {} for testing".format(driver_name) + if cls.USE_CLASS_DEVICE: + cls.ctx = FPrint.Context() + cls.dev = cls.get_device(cls.ctx) + assert cls.dev is not None, "You need to compile with {} for testing".format( + driver_name) @classmethod def tearDownClass(cls): shutil.rmtree(cls.tmpdir) - del cls.dev - del cls.ctx + if cls.USE_CLASS_DEVICE: + del cls.dev + del cls.ctx unittest.TestCase.tearDownClass() def setUp(self): super().setUp() + if not self.USE_CLASS_DEVICE: + self.ctx = FPrint.Context() + self.dev = self.get_device(self.ctx) + self.assertIsNotNone(self.dev) self._close_on_teardown = True self.assertFalse(self.dev.is_open()) self.dev.open_sync() @@ -107,6 +118,9 @@ class VirtualDeviceBase(unittest.TestCase): self.send_command('SET_ENROLL_STAGES', self.DEFAULT_ENROLL_STEPS) self.dev.close_sync() self.assertFalse(self.dev.is_open()) + if not self.USE_CLASS_DEVICE: + del self.dev + del self.ctx super().tearDown() def wait_timeout(self, interval): @@ -335,6 +349,79 @@ class VirtualDeviceBase(unittest.TestCase): self.assertEqual(self._verify_fp.props.fpi_data.get_string(), scan_nick) +class VirtualDeviceUnplugging(VirtualDeviceBase): + + driver_name = 'virtual_device' + USE_CLASS_DEVICE = False + + def test_device_unplug(self): + self._close_on_teardown = False + notified_spec = None + def on_removed_notify(dev, spec): + nonlocal notified_spec + notified_spec = spec + + removed = False + def on_removed(dev): + nonlocal removed + removed = dev.props.removed + + self.assertFalse(self.dev.props.removed) + + self.dev.connect('notify::removed', on_removed_notify) + self.dev.connect('removed', on_removed) + self.send_command('UNPLUG') + self.assertEqual(notified_spec.name, 'removed') + self.assertTrue(self.dev.props.removed) + self.assertIn(self.dev, self.ctx.get_devices()) + self.assertTrue(removed) + + with self.assertRaises(GLib.GError) as error: + self.dev.close_sync() + self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), + FPrint.DeviceError.REMOVED)) + + def test_device_unplug_during_verify(self): + self._close_on_teardown = False + self._destroy_on_teardown = True + + notified_spec = None + def on_removed_notify(dev, spec): + nonlocal notified_spec + notified_spec = spec + + removed = False + def on_removed(dev): + nonlocal removed + removed = dev.props.removed + + self.assertFalse(self.dev.props.removed) + self.dev.connect('notify::removed', on_removed_notify) + self.dev.connect('removed', on_removed) + + self.start_verify(FPrint.Print.new(self.dev), + identify=self.dev.supports_identify()) + + self.send_command('UNPLUG') + self.assertEqual(notified_spec.name, 'removed') + self.assertTrue(self.dev.props.removed) + self.assertIn(self.dev, self.ctx.get_devices()) + self.assertFalse(removed) + + with self.assertRaises(GLib.GError) as error: + self.complete_verify() + self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), + FPrint.DeviceError.REMOVED)) + + self.assertTrue(removed) + self.assertIn(self.dev, self.ctx.get_devices()) + + with self.assertRaises(GLib.GError) as error: + self.dev.close_sync() + self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), + FPrint.DeviceError.REMOVED)) + + class VirtualDevice(VirtualDeviceBase): def test_device_properties(self): @@ -705,69 +792,6 @@ class VirtualDevice(VirtualDeviceBase): self.assertEqual(self.dev.get_scan_type(), FPrint.ScanType.SWIPE) self.assertIsNone(notified_spec) - def test_device_unplug(self): - self._close_on_teardown = False - notified_spec = None - def on_removed_notify(dev, spec): - nonlocal notified_spec - notified_spec = spec - - removed = False - def on_removed(dev): - nonlocal removed - removed = True - - self.assertFalse(self.dev.props.removed) - - self.dev.connect('notify::removed', on_removed_notify) - self.dev.connect('removed', on_removed) - self.send_command('UNPLUG') - self.assertEqual(notified_spec.name, 'removed') - self.assertTrue(self.dev.props.removed) - self.assertTrue(removed) - - with self.assertRaises(GLib.GError) as error: - self.dev.close_sync() - self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), - FPrint.DeviceError.REMOVED)) - - def test_device_unplug_during_verify(self): - self._close_on_teardown = False - - notified_spec = None - def on_removed_notify(dev, spec): - nonlocal notified_spec - notified_spec = spec - - removed = False - def on_removed(dev): - nonlocal removed - removed = True - - self.assertFalse(self.dev.props.removed) - self.dev.connect('notify::removed', on_removed_notify) - self.dev.connect('removed', on_removed) - - self.start_verify(FPrint.Print.new(self.dev), - identify=self.dev.supports_identify()) - - self.send_command('UNPLUG') - self.assertEqual(notified_spec.name, 'removed') - self.assertTrue(self.dev.props.removed) - self.assertFalse(removed) - - with self.assertRaises(GLib.GError) as error: - self.complete_verify() - self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), - FPrint.DeviceError.REMOVED)) - - self.assertTrue(removed) - - with self.assertRaises(GLib.GError) as error: - self.dev.close_sync() - self.assertTrue(error.exception.matches(FPrint.DeviceError.quark(), - FPrint.DeviceError.REMOVED)) - def test_device_sleep(self): self.send_sleep(1500)