def test_fsync(self): file = "/dir1/dir2/file" testfs = vofs.VOFS(self.testMountPoint, self.testCacheDir, opt) testfs.client = Object() node = Mock(spec=vos.Node) node.isdir = Mock(return_value=False) node.props = Object node.props.get = Mock(side_effect=SideEffect({ ('islocked', False): False, ('length',): 10, ('MD5',): 12354, }, name="node.props.get")) node.type = "vos:DataNode" node.name = "testNode" testfs.client.get_node = Mock(return_value=node) with patch('vos.CadcCache.FileHandle') as mockFileHandle: mockFileHandle.return_value = MyFileHandle( file, testfs.cache, None) fh = testfs.open(file, os.O_RDWR | os.O_CREAT, None) HandleWrapper.file_handle(fh).cache_file_handle.fsync = \ Mock(wraps=HandleWrapper.file_handle( fh).cache_file_handle.fsync) testfs.fsync(file, False, fh) HandleWrapper.file_handle( fh).cache_file_handle.fsync.assert_called_once_with() HandleWrapper.file_handle( fh).cache_file_handle.fsync.assert_called_once_with()
def test_fsync(self): file = "/dir1/dir2/file" testfs = vofs.VOFS(self.testMountPoint, self.testCacheDir, opt) testfs.client = Object() node = Mock(spec=vos.Node) node.isdir = Mock(return_value=False) node.props = Object node.props.get = Mock(side_effect=SideEffect({ ('islocked', False): False, ('length',): 10, ('MD5',): 12354, }, name="node.props.get")) node.type = "vos:DataNode" node.name = "testNode" testfs.client.get_node = Mock(return_value=node) with patch('vofs.CadcCache.FileHandle') as mockFileHandle: mockFileHandle.return_value = MyFileHandle( file, testfs.cache, None) fh = testfs.open(file, os.O_RDWR | os.O_CREAT, None) HandleWrapper.file_handle(fh).cache_file_handle.fsync = \ Mock(wraps=HandleWrapper.file_handle( fh).cache_file_handle.fsync) testfs.fsync(file, False, fh) HandleWrapper.file_handle( fh).cache_file_handle.fsync.assert_called_once_with() HandleWrapper.file_handle( fh).cache_file_handle.fsync.assert_called_once_with()
def test_respondToMessageAndClearResponse_Succeed_OnValidInput(self): dev = self.make_and_start_a_test_device(1, "d1", {"deviceVersion": _VERSION}) self.assertEqual(dev.states["status"], "Idle") action = Mock() action.deviceId = dev.id test_message = "sensor wet" action.props = { "message": test_message, "name": "test", "actionVersion": _VERSION } for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): action.props[k] = "wet" + unicode(i) self.plugin.getChatbotResponse(action) self.assertEqual(dev.states["status"], "Ready") self.assertEqual(dev.states["message"], test_message) self.assertEqual(dev.states["name"], "test") self.assertEqual(dev.states["response"], "Now the leak sensor is wet.") for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): self.assertEqual(dev.states[k], "wet" + unicode(i)) # Because the setup is already done, test that getChatbotResponse adds to # the backlog when there is already a response waiting test_message2 = "sensor dry" action.props["message"] = test_message2 for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): action.props[k] = "dry" + unicode(i) self.plugin.getChatbotResponse(action) self.assertEqual(dev.states["status"], "Ready") self.assertEqual(dev.states["message"], test_message) self.assertEqual(dev.states["name"], "test") self.assertEqual(dev.states["response"], "Now the leak sensor is wet.") for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): self.assertEqual(dev.states[k], "wet" + unicode(i)) self.assertEqual(len(self.plugin.device_info[dev.id]), 1) # Now test that clearResponse fetches the backlog action = Mock() action.deviceId = dev.id self.plugin.clearResponse(action) self.assertEqual(dev.states["status"], "Ready") self.assertEqual(dev.states["message"], test_message2) self.assertEqual(dev.states["name"], "test") self.assertEqual(dev.states["response"], "Now the leak sensor is dry.") for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): self.assertEqual(dev.states[k], "dry" + unicode(i)) self.assertEqual(self.plugin.device_info[dev.id], []) # And clearResponse again should change state to Idle self.plugin.clearResponse(action) self.assertEqual(dev.states["status"], "Idle") self.assertFalse(PluginBaseForTest.errorLog.called)
def test_respond_LogsError_OnBadVersion(self): action = Mock() action.props = {"message": "status", "actionVersion": "0.1"} dev = self.make_and_start_a_test_device(1, "d1", {"deviceVersion": _VERSION}) action.deviceId = dev.id self.plugin.getChatbotResponse(action) self.assertTrue(PluginBaseForTest.errorLog.called)
def test_respond_LogsError_OnBadVersion(self): action = Mock() action.props = {"message":"status", "actionVersion":"0.1"} dev = self.make_and_start_a_test_device(1, "d1", {"deviceVersion":_VERSION}) action.deviceId = dev.id self.plugin.getChatbotResponse(action) self.assertTrue(PluginBaseForTest.errorLog.called)
def test_fsync2(self): file = "/dir1/dir2/file" testfs = vofs.VOFS(self.testMountPoint, self.testCacheDir, opt) testfs.client = Object() node = Mock(spec=vos.Node) node.isdir = Mock(return_value=False) node.props = Object node.props.get = Mock(side_effect=SideEffect({ ('islocked', False): False, ('length',): 10, ('MD5',): 12354, }, name="node.props.get")) node.type = "vos:DataNode" testfs.client.get_node = Mock(return_value=node) # Try flushing on a read-only file. with patch('vofs.CadcCache.FileHandle') as mockFileHandle: mockFileHandle.return_value = MyFileHandle( file, testfs.cache, None) fh = testfs.open(file, os.O_RDONLY, None) self.assertFalse(HandleWrapper.file_handle(fh).cache_file_handle. fileModified) HandleWrapper.file_handle(fh).cache_file_handle.fsync = \ Mock(wraps=HandleWrapper.file_handle(fh).cache_file_handle. fsync) with self.assertRaises(FuseOSError) as e: testfs.fsync(file, False, fh) self.assertEqual(e.exception.errno, EPERM) self.assertEqual(HandleWrapper.file_handle(fh).cache_file_handle. fsync.call_count, 0) self.assertFalse(HandleWrapper.file_handle(fh).cache_file_handle. fileModified) testfs.release(file, fh) # Try with an invalid file descriptor with self.assertRaises(FuseOSError) as e: testfs.fsync(file, False, -1) self.assertEqual(e.exception.errno, EIO) # Try flushing on a read-only file system. with patch('vofs.CadcCache.FileHandle') as mockFileHandle: myopt = copy.copy(opt) testfs = vofs.VOFS(self.testMountPoint, self.testCacheDir, myopt) mockFileHandle.return_value = MyFileHandle( file, testfs.cache, None) myopt.readonly = True testfs.client = Object() testfs.client.get_node = Mock(return_value=node) fh = testfs.open(file, os.O_RDONLY, None) HandleWrapper.file_handle(fh).cache_file_handle.fsync = \ Mock(wraps=HandleWrapper.file_handle(fh).cache_file_handle. fsync) testfs.fsync(file, False, fh) self.assertEqual( HandleWrapper.file_handle(fh).cache_file_handle.fsync. call_count, 0) testfs.release(file, fh)
def test_respondToMessageAndClearResponse_Succeed_OnValidInput(self): dev = self.make_and_start_a_test_device(1, "d1", {"deviceVersion":_VERSION}) self.assertEqual(dev.states["status"], "Idle") action = Mock() action.deviceId = dev.id test_message = "sensor wet" action.props = {"message":test_message, "name":"test", "actionVersion":_VERSION} for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): action.props[k] = "wet" + unicode(i) self.plugin.getChatbotResponse(action) self.assertEqual(dev.states["status"], "Ready") self.assertEqual(dev.states["message"], test_message) self.assertEqual(dev.states["name"], "test") self.assertEqual(dev.states["response"], "Now the leak sensor is wet.") for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): self.assertEqual(dev.states[k], "wet" + unicode(i)) # Because the setup is already done, test that getChatbotResponse adds to # the backlog when there is already a response waiting test_message2 = "sensor dry" action.props["message"] = test_message2 for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): action.props[k] = "dry" + unicode(i) self.plugin.getChatbotResponse(action) self.assertEqual(dev.states["status"], "Ready") self.assertEqual(dev.states["message"], test_message) self.assertEqual(dev.states["name"], "test") self.assertEqual(dev.states["response"], "Now the leak sensor is wet.") for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): self.assertEqual(dev.states[k], "wet" + unicode(i)) self.assertEqual(len(self.plugin.device_info[dev.id]), 1) # Now test that clearResponse fetches the backlog action = Mock() action.deviceId = dev.id self.plugin.clearResponse(action) self.assertEqual(dev.states["status"], "Ready") self.assertEqual(dev.states["message"], test_message2) self.assertEqual(dev.states["name"], "test") self.assertEqual(dev.states["response"], "Now the leak sensor is dry.") for i, k in enumerate(self.plugin_module._SENDER_INFO_FIELDS): self.assertEqual(dev.states[k], "dry" + unicode(i)) self.assertEqual(self.plugin.device_info[dev.id], []) # And clearResponse again should change state to Idle self.plugin.clearResponse(action) self.assertEqual(dev.states["status"], "Idle") self.assertFalse(PluginBaseForTest.errorLog.called)
def test_send_keypad_beep_error_checks_when_scripted( plugin, started_controller_device): action = Mock() action.deviceId = started_controller_device.id action.props = {"consoleNumber": "0", "beepCommand": "doTheHokeyPokey"} action.pluginTypeId = "sendBeepCommand" plugin.sendBeepCommand(action) assert plugin.errorLog.called plugin.errorLog.reset_mock()
def test_enable_disable_keypad_beeper_handles_unconfigured_action( plugin, started_controller_device): action = Mock() action.deviceId = started_controller_device.id action.props = {} action.pluginTypeId = "enableConsoleBeeper" plugin.enableConsoleBeeper(action) assert plugin.errorLog.called plugin.errorLog.reset_mock()
def test_send_keypad_beep_handles_unconfigured_action( plugin, started_controller_device): action = Mock() action.deviceId = started_controller_device.id action.props = {} action.pluginTypeId = "sendBeepCommand" plugin.sendBeepCommand(action) assert plugin.errorLog.called plugin.errorLog.reset_mock()
def test_enable_disable_keypad_handles_network_error( plugin, plugin_module, indigo, omni1, started_controller_device): action = Mock() action.deviceId = started_controller_device.id action.props = {"consoleNumber": "3"} action.pluginTypeId = "enableConsoleBeeper" omni1.connected.side_effect = plugin_module.ConnectionError plugin.enableConsoleBeeper(action) assert plugin.errorLog.called plugin.errorLog.reset_mock()
def test_receiveMessage_LogsError_WhenActionPropsMissingKeys(self): action = Mock() action.props = {"message":"", "handle":""} PluginBaseForTest.errorLog.side_effect = None self.plugin.receiveMessage(action) self.assertEqual(PluginBaseForTest.errorLog.call_count, 1) action.props.pop("handle") self.plugin.receiveMessage(action) self.assertEqual(PluginBaseForTest.errorLog.call_count, 2) action.props.pop("message") self.plugin.receiveMessage(action) self.assertEqual(PluginBaseForTest.errorLog.call_count, 3)
def test_sendMessage_LogsError_OnMissingProps(self): dev = self.make_and_start_a_test_device(1, "d1", {"handle":"*****@*****.**", "service":"fredserv", "allSenders":True}) action = Mock() action.deviceId = dev.id action.props ={"message":"test"} PluginBaseForTest.errorLog.side_effect = None self.plugin.sendMessage(action) self.assertTrue(PluginBaseForTest.errorLog.called)
def test_MarkAsRead_LogsError_UnconfiguredDevice(self): dev = DeviceForTest(1, "dev", {}) dev.configured = False self.indigo_mock.devices[1] = dev action = Mock() action.props = {"message":"", "handle":""} action.device_id = 1 PluginBaseForTest.errorLog.side_effect = None self.plugin.markAsRead(action) self.assertTrue(PluginBaseForTest.errorLog.called)
def test_send_keypad_beep_handles_network_error(plugin, py4j, omni1, started_controller_device): action = Mock() action.deviceId = started_controller_device.id action.props = {"consoleNumber": "0", "beepCommand": "beepOn"} action.pluginTypeId = "sendBeepCommand" omni1.controllerCommand.side_effect = py4j.protocol.Py4JError plugin.sendBeepCommand(action) assert plugin.errorLog.called plugin.errorLog.reset_mock()
def test_sendMessage_Succeeds_OnValidInput(self): dev = self.make_and_start_a_test_device(1, "d1", {"handle":"*****@*****.**", "service":"fredserv", "allSenders":False}) action = Mock() test_message = "This is a test" action.deviceId = dev.id action.props ={"message": test_message} self.plugin.sendMessage(action) self.assertTrue(self.mapp.send.called) self.assertEqual(dev.states["responseStatus"], "Sent") self.assertEqual(dev.states["response"], test_message)
def test_sendMessage_LogsError_OnUnconfiguredDevice(self): dev = self.make_and_start_a_test_device(1, "d1", {"handle":"*****@*****.**", "service":"fredserv", "allSenders":False}) dev.configured = False action = Mock() test_message = "This is a test" action.deviceId = dev.id action.props ={"message": test_message} PluginBaseForTest.errorLog.side_effect = None self.plugin.sendMessage(action) self.assertTrue(PluginBaseForTest.errorLog.called)
def test_sendMessage_SetsErrorState_OnMessagesAppException(self): # Turns out Messages.app doesn't throw exceptions no matter what # random non-handle string and service you give it self.mapp.send.side_effect=Exception("test") PluginBaseForTest.errorLog.side_effect = None dev = self.make_and_start_a_test_device(1, "d1", {"handle":"*****@*****.**", "service":"fredserv", "allSenders":False}) action = Mock() test_message = "This is a test" action.deviceId = dev.id action.props ={"message": test_message} self.plugin.sendMessage(action) self.assertEqual(dev.states["responseStatus"], "Error") self.assertEqual(dev.states["response"], test_message)
def test_receiveMessage_Succeeds_WhenAllSendersDeviceExists(self): self.mock_services_and_buddies() dev = self.make_and_start_a_test_device(1, "d1", {"handle":"", "service":"", "allSenders":True}) self.assertEqual(dev.states["status"], "No Message") action = Mock() test_message = "This is a test" action.props = {"message":test_message, "handle": "*****@*****.**", "service": "E:[email protected]", "service_type":"#####"} self.plugin.receiveMessage(action) self.assertEqual(dev.states["status"], "New") self.assertEqual(dev.states["message"], test_message) self.assertEqual(self.plugin.device_info[dev.id], [])
def test_check_security_code_updates_device_states_on_valid_code( plugin, started_controller_device, omni1, version): dev = started_controller_device mock_scv = jomni_mimic.SecurityCodeValidation(16, 2) omni1.reqSecurityCodeValidation = Mock(return_value=mock_scv) action = Mock() action.deviceId = dev.id action.props = {"code": "9876", "area": "1", "actionVersion": version} plugin.checkSecurityCode(action) omni1.reqSecurityCodeValidation.assert_called_with(1, 9, 8, 7, 6) assert dev.states["lastCheckedCode"] == action.props["code"] assert dev.states["lastCheckedCodeArea"] == action.props["area"] assert dev.states["lastCheckedCodeAuthority"] == "Manager" assert dev.states["lastCheckedCodeUser"] == 16 assert not dev.states["lastCheckedCodeDuress"]
def test_receiveMessage_Ignores_MessageWithNoMatchingDevice(self): self.mock_to_make_deviceStartComm_succeed() dev = self.make_and_start_a_test_device(1, "d1", {"handle":"*****@*****.**", "service":"fredserv", "allSenders":False}) self.assertTrue(dev.states["status"] == "No Message") action = Mock() test_message = "This is a test" action.props = {"message":test_message, "handle": "*****@*****.**", "service":dev.pluginProps["service"], "service_type":"#####"} self.plugin.receiveMessage(action) self.assertNotEqual(dev.states["status"], "New") self.assertEqual(dev.states["message"], "") self.assertEqual(self.plugin.device_info[dev.id], [])
def test_enable_disable_keypad_beeper_sends_command(plugin, indigo, omni1, started_controller_device, jomnilinkII): action = Mock() action.deviceId = started_controller_device.id action.props = {"consoleNumber": "3"} action.pluginTypeId = "enableConsoleBeeper" plugin.enableConsoleBeeper(action) CM = jomnilinkII.MessageTypes.CommandMessage assert omni1.controllerCommand.called_with( CM.CMD_CONSOLE_ENABLE_DISABLE_BEEPER, 1, 3) action.props["consoleNumber"] = "0" action.pluginTypeId = "disableConsoleBeeper" plugin.disableConsoleBeeper(action) assert omni1.controllerCommand.called_with( CM.CMD_CONSOLE_ENABLE_DISABLE_BEEPER, 0, 0)
def test_send_keypad_beep_sends_command(plugin, indigo, omni1, started_controller_device, jomnilinkII): action = Mock() action.deviceId = started_controller_device.id action.props = {"consoleNumber": "0", "beepCommand": "beepOff"} action.pluginTypeId = "sendBeepCommand" CM = jomnilinkII.MessageTypes.CommandMessage plugin.sendBeepCommand(action) assert omni1.controllerCommand.called_with(CM.CMD_CONSOLE_BEEP, 0, 0) action.props["consoleNumber"] = "4" action.props["beepCommand"] = "beep5" action.pluginTypeId = "sendBeepCommand" plugin.sendBeepCommand(action) assert omni1.controllerCommand.called_with( CM.CMD_CONSOLE_ENABLE_DISABLE_BEEPER, 6, 1)
def test_receiveMessageAndMarkAsRead_Succeed_WhenMatchingDeviceExists(self): self.mock_services_and_buddies() dev = self.make_and_start_a_test_device(1, "d1", {"handle":"*****@*****.**", "service":"E:[email protected]", "allSenders":False}) self.assertEqual(dev.states["status"], "No Message") action = Mock() test_message = "This is a test" action.props = {"message":test_message, "handle": "*****@*****.**", "service": "E:[email protected]", "service_type":"#####"} self.plugin.receiveMessage(action) self.assertEqual(dev.states["status"], "New") self.assertEqual(dev.states["message"], test_message) self.assertEqual(self.plugin.device_info[dev.id], []) # Because the setup is already done, test that receiveMessage adds to # the backlog when there is already a new message test_message2 = "This is a different test" action.props["message"] = test_message2 self.plugin.receiveMessage(action) self.assertEqual(dev.states["status"], "New") self.assertEqual(dev.states["message"], test_message) self.assertEqual(len(self.plugin.device_info[dev.id]), 1) # Now test that markAsRead fetches the backlog message action = Mock() action.deviceId = dev.id self.plugin.markAsRead(action) self.assertEqual(dev.states["status"], "New") self.assertEqual(dev.states["message"], test_message2) self.assertEqual(self.plugin.device_info[dev.id], []) # And markAsRead again should change state to Read self.plugin.markAsRead(action) self.assertEqual(dev.states["status"], "Read")
def test_check_security_code_handles_network_error(plugin, started_controller_device, omni1, py4j, version): dev = started_controller_device omni1.reqSecurityCodeValidation = Mock(side_effect=py4j.protocol.Py4JError) action = Mock() action.deviceId = dev.id action.props = {"code": "9876", "area": "1", "actionVersion": version} assert not plugin.errorLog.called plugin.checkSecurityCode(action) assert plugin.errorLog.called plugin.errorLog.reset_mock() assert dev.states["lastCheckedCode"] == action.props["code"] assert dev.states["lastCheckedCodeArea"] == action.props["area"] assert dev.states["lastCheckedCodeAuthority"] == "Error" assert dev.states["lastCheckedCodeUser"] == "N/A" assert not dev.states["lastCheckedCodeDuress"]
def messageLoop(self): action = Mock() action.props = { "send_method": None, "message_field": None, "name": "local" } dev = DeviceForTest(1, "dev", {}) action.deviceId = dev.id self.indigo_mock.devices[dev.id] = dev self.plugin.deviceStartComm(dev) print("Type /quit to quit, /debug to toggle debug output, " "/debugbot to toggle chatbot debug output, " "/botvars or /uservars to see values of variables, " "/reload to reload the scripts directory.") while True: msg = raw_input("You> ") if msg == "/quit": break elif msg == "/botvars": print(unicode(self.plugin.bot._botvars)) elif msg == "/uservars": if "local" in self.plugin.bot._users: print(unicode(self.plugin.bot._users["local"].vars)) else: print("No user variables have been defined.") elif msg == "/reload": self.plugin.bot.clear_rules() self.plugin.bot.load_script_directory(self.path) elif msg == "/debug": self.plugin.toggleDebugging() elif msg == "/debugbot": self.plugin.toggleEngineDebugging() else: action.props[u"message"] = unicode(msg) self.plugin.getChatbotResponse(action) print("Bot> " + dev.states["response"]) self.plugin.clearResponse(action)
def messageLoop(self): action = Mock() action.props = {"send_method":None, "message_field":None, "name":"local"} dev = DeviceForTest(1, "dev", {}) action.deviceId = dev.id self.indigo_mock.devices[dev.id] = dev self.plugin.deviceStartComm(dev) print ("Type /quit to quit, /debug to toggle debug output, " "/debugbot to toggle chatbot debug output, " "/botvars or /uservars to see values of variables, " "/reload to reload the scripts directory.") while True: msg = raw_input("You> ") if msg == "/quit": break elif msg == "/botvars": print(unicode(self.plugin.bot._botvars)) elif msg == "/uservars": if "local" in self.plugin.bot._users: print(unicode(self.plugin.bot._users["local"].vars)) else: print("No user variables have been defined.") elif msg == "/reload": self.plugin.bot.clear_rules() self.plugin.bot.load_script_directory(self.path) elif msg == "/debug": self.plugin.toggleDebugging() elif msg == "/debugbot": self.plugin.toggleEngineDebugging() else: action.props[u"message"] = unicode(msg) self.plugin.getChatbotResponse(action) print("Bot> " + dev.states["response"]) self.plugin.clearResponse(action)
def test_truncate(self): callCount = [0] def mock_read(block_size): callCount[0] += 1 if callCount[0] == 1: return "1234" else: return None file = "/dir1/dir2/file" testfs = vofs.VOFS(self.testMountPoint, self.testCacheDir, opt) node = Mock(spec=vos.Node) node.isdir = Mock(return_value=False) node.props = Object node.props.get = Mock(side_effect=SideEffect({ ('islocked', False): False, ('length',): 10, ('MD5',): 12354, }, name="node.props.get")) node.type = "vos:DataNode" node.uri = "vos:/dir1/dir2/file" node.name = "testNode" testfs.client = Object() testfs.client.get_node = Mock(return_value=node) testfs.client.close = Mock() testfs.client.read = Mock(side_effect=mock_read) testfs.client.copy = Mock() vos_VOFILE = Object() vos_VOFILE.close = Mock() vos_VOFILE.read = Mock(side_effect=mock_read) testfs.client.open = Mock(return_value=vos_VOFILE) testfs.client.nodeCache = Object() testfs.client.nodeCache = NodeCache() # Truncate a non-open file to 0 bytes testfs.cache.open = Mock(wraps=testfs.cache.open) origRelease = FileHandle.release origTruncate = FileHandle.truncate with patch('vofs.CadcCache.FileHandle.release') as mockRelease, \ patch('vofs.CadcCache.FileHandle') as mockFileHandle: mockFileHandle.return_value = MyFileHandle( file, testfs.cache, None) mockFileHandle.return_value.readData = \ Mock(wraps=mockFileHandle.return_value.readData) mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked testfs.truncate(file, 0) self.assertEqual(testfs.cache.open.call_count, 1) self.assertEqual(testfs.cache.open.call_args[0][0], file) self.assertFalse(testfs.cache.open.call_args[0][1]) self.assertTrue(testfs.cache.open.call_args[0][2]) mockRelease.assert_called_once_with() self.assertEqual( mockFileHandle.return_value.readData.call_count, 1) # Truncate a non-open file past the start of the file. testfs.cache.open.reset_mock() with patch('vofs.CadcCache.FileHandle.release') as mockRelease: mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked with patch('vofs.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.wraps = origTruncate # TODO Same issue as the # mockRelease TODO above. testfs.truncate(file, 5) self.assertEqual(testfs.cache.open.call_args[0][0], file) self.assertFalse(testfs.cache.open.call_args[0][1]) mockTruncate.assert_called_once_with(5) mockRelease.assert_called_once_with() # Truncate with an exception returned by the CadcCache truncate testfs.cache.open.reset_mock() with patch('vofs.CadcCache.FileHandle.release') as mockRelease, \ patch('vofs.CadcCache.FileHandle.readData'): mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked with patch('vofs.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.side_effect = NotImplementedError("an error") with self.assertRaises(NotImplementedError): testfs.truncate(file, 5) self.assertEqual(testfs.cache.open.call_args[0][0], file) self.assertFalse(testfs.cache.open.call_args[0][1]) mockRelease.assert_called_once_with() # Truncate an already opened file given the file handle. with patch('vofs.CadcCache.FileHandle.release') as mockRelease, \ patch('vofs.CadcCache.FileHandle.readData'): mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked try: fh = testfs.open(file, os.O_RDWR | os.O_CREAT, None) testfs.cache.open.reset_mock() with patch( 'vofs.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.wraps = origTruncate # TODO Same issue as the # mockRelease TODO above. testfs.truncate(file, 20, fh) # Open and release should not be called, truncate should be # called. self.assertEqual(testfs.cache.open.call_count, 0) mockTruncate.assert_called_once_with(20) self.assertEqual(mockRelease.call_count, 0) finally: testfs.release(file, fh) # Create a new file system for testing. This is required because of the # leaked file handles from the previous tests. testfs2 = vofs.VOFS(self.testMountPoint, self.testCacheDir, opt) testfs2.client = testfs.client testfs2.cache.open = Mock(wraps=testfs2.cache.open) # Truncate a read only file handle. with patch('vofs.CadcCache.FileHandle.release') as mockRelease, \ patch('vofs.CadcCache.FileHandle') as mockFileHandle: mockRelease.wraps = origRelease mockFileHandle.return_value = MyFileHandle(file, testfs2.cache, None) mockFileHandle.return_value.readData = \ Mock(wraps=mockFileHandle.return_value.readData) try: fh = testfs2.open(file, os.O_RDONLY, None) testfs2.cache.open.reset_mock() with patch( 'vofs.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.wraps = origTruncate with self.assertRaises(FuseOSError): testfs2.truncate(file, 20, fh) # Open, release and truncate should not be called. self.assertEqual(testfs2.cache.open.call_count, 0) self.assertEqual(mockTruncate.call_count, 0) self.assertEqual(mockRelease.call_count, 0) finally: testfs2.release(file, fh) # Truncate with an invalid file descriptor. with self.assertRaises(KeyError): testfs2.truncate(file, 20, -1)
def test_truncate(self): callCount = [0] def mock_read(block_size): callCount[0] += 1 if callCount[0] == 1: return "1234" else: return None file = "/dir1/dir2/file" testfs = vofs.VOFS(self.testMountPoint, self.testCacheDir, opt) node = Mock(spec=vos.Node) node.isdir = Mock(return_value=False) node.props = Object node.props.get = Mock(side_effect=SideEffect({ ('islocked', False): False, ('length',): 10, ('MD5',): 12354, }, name="node.props.get")) node.type = "vos:DataNode" node.uri = "vos:/dir1/dir2/file" node.name = "testNode" testfs.client = Object() testfs.client.get_node = Mock(return_value=node) testfs.client.close = Mock() testfs.client.read = Mock(side_effect=mock_read) testfs.client.copy = Mock() vos_VOFILE = Object() vos_VOFILE.close = Mock() vos_VOFILE.read = Mock(side_effect=mock_read) testfs.client.open = Mock(return_value=vos_VOFILE) testfs.client.nodeCache = Object() testfs.client.nodeCache = NodeCache() # Truncate a non-open file to 0 bytes testfs.cache.open = Mock(wraps=testfs.cache.open) origRelease = FileHandle.release origTruncate = FileHandle.truncate with nested(patch('vos.CadcCache.FileHandle.release'), patch('vos.CadcCache.FileHandle')) as (mockRelease, mockFileHandle): mockFileHandle.return_value = MyFileHandle( file, testfs.cache, None) mockFileHandle.return_value.readData = \ Mock(wraps=mockFileHandle.return_value.readData) mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked testfs.truncate(file, 0) self.assertEqual(testfs.cache.open.call_count, 1) self.assertEqual(testfs.cache.open.call_args[0][0], file) self.assertFalse(testfs.cache.open.call_args[0][1]) self.assertTrue(testfs.cache.open.call_args[0][2]) mockRelease.assert_called_once_with() self.assertEqual( mockFileHandle.return_value.readData.call_count, 1) # Truncate a non-open file past the start of the file. testfs.cache.open.reset_mock() with nested(patch('vos.CadcCache.FileHandle.release'), patch('vos.CadcCache.FileHandle.readData')) as mocks: mockRelease = mocks[0] mockReadData = mocks[1] mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked with patch('vos.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.wraps = origTruncate # TODO Same issue as the # mockRelease TODO above. testfs.truncate(file, 5) self.assertEqual(testfs.cache.open.call_args[0][0], file) self.assertFalse(testfs.cache.open.call_args[0][1]) mockTruncate.assert_called_once_with(5) mockRelease.assert_called_once_with() # Truncate with an exception returned by the CadcCache truncate testfs.cache.open.reset_mock() with nested(patch('vos.CadcCache.FileHandle.release'), patch('vos.CadcCache.FileHandle.readData')) as mocks: mockRelease = mocks[0] mockReadData = mocks[1] mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked with patch('vos.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.side_effect = NotImplementedError("an error") with self.assertRaises(NotImplementedError): testfs.truncate(file, 5) self.assertEqual(testfs.cache.open.call_args[0][0], file) self.assertFalse(testfs.cache.open.call_args[0][1]) mockRelease.assert_called_once_with() # Truncate an already opened file given the file handle. with nested(patch('vos.CadcCache.FileHandle.release'), patch('vos.CadcCache.FileHandle.readData')) as mocks: mockRelease = mocks[0] mockReadData = mocks[1] mockRelease.wraps = origRelease # TODO This doesn't really work, # release is not called and so open # files are being leaked try: fh = testfs.open(file, os.O_RDWR | os.O_CREAT, None) testfs.cache.open.reset_mock() with patch('vos.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.wraps = origTruncate # TODO Same issue as the # mockRelease TODO above. testfs.truncate(file, 20, fh) # Open and release should not be called, truncate should be # called. self.assertEqual(testfs.cache.open.call_count, 0) mockTruncate.assert_called_once_with(20) self.assertEqual(mockRelease.call_count, 0) finally: testfs.release(file, fh) # Create a new file system for testing. This is required because of the # leaked file handles from the previous tests. testfs2 = vofs.VOFS(self.testMountPoint, self.testCacheDir, opt) testfs2.client = testfs.client testfs = None testfs2.cache.open = Mock(wraps=testfs2.cache.open) # Truncate a read only file handle. with nested(patch('vos.CadcCache.FileHandle.release'), patch('vos.CadcCache.FileHandle')) as \ (mockRelease, mockFileHandle): mockRelease.wraps = origRelease mockFileHandle.return_value = MyFileHandle(file, testfs2.cache, None) mockFileHandle.return_value.readData = \ Mock(wraps=mockFileHandle.return_value.readData) try: fh = testfs2.open(file, os.O_RDONLY, None) testfs2.cache.open.reset_mock() with patch('vos.CadcCache.FileHandle.truncate') as mockTruncate: mockTruncate.wraps = origTruncate with self.assertRaises(FuseOSError): testfs2.truncate(file, 20, fh) # Open, release and truncate should not be called. self.assertEqual(testfs2.cache.open.call_count, 0) self.assertEqual(mockTruncate.call_count, 0) self.assertEqual(mockRelease.call_count, 0) finally: testfs2.release(file, fh) # Truncate with an invalid file descriptor. with self.assertRaises(KeyError) as e: testfs2.truncate(file, 20, -1)