Example #1
0
 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)
Example #2
0
    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()
Example #3
0
    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)
Example #4
0
    def test_sendMessage_LogsError_OnMissingProps(self):
        dev = self.make_and_start_a_test_device(
            1, "d1", {"handle": "fred@fred.com", "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)
Example #5
0
 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)
Example #6
0
    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)
Example #7
0
    def test_sendMessage_LogsError_OnUnconfiguredDevice(self):
        dev = self.make_and_start_a_test_device(
            1, "d1", {"handle": "fred@fred.com", "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)
Example #8
0
    def test_sendMessage_Succeeds_OnValidInput(self):
        dev = self.make_and_start_a_test_device(
            1, "d1", {"handle": "fred@fred.com", "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)
Example #9
0
    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("vos.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("vos.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)
Example #10
0
    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": "fred@fred.com", "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)
Example #11
0
    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": "barney@bedrock.com",
            "service": "E:fred@bedrock.com",
            "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], [])
Example #12
0
    def test_receiveMessage_Ignores_MessageWithNoMatchingDevice(self):
        self.mock_to_make_deviceStartComm_succeed()
        dev = self.make_and_start_a_test_device(
            1, "d1", {"handle": "fred@fred.com", "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": "george@george.com",
            "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], [])
Example #13
0
    def test_receiveMessageAndMarkAsRead_Succeed_WhenMatchingDeviceExists(self):
        self.mock_services_and_buddies()
        dev = self.make_and_start_a_test_device(
            1, "d1", {"handle": "barney@bedrock.com", "service": "E:fred@bedrock.com", "allSenders": False}
        )
        self.assertEqual(dev.states["status"], "No Message")

        action = Mock()
        test_message = "This is a test"
        action.props = {
            "message": test_message,
            "handle": "barney@bedrock.com",
            "service": "E:fred@bedrock.com",
            "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")
Example #14
0
    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["message"] = unicode(msg)
                self.plugin.getChatbotResponse(action)
                print("Bot> " + dev.states["response"])
                self.plugin.clearResponse(action)
Example #15
0
    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)