def test_scp_error(self):
     """
     If an SCP error occurs which is not a 'No space left on device' error, it must be raised.
     """
     file_name = 'dataset.nc.tar.gz'
     with mock.patch.object(utils.RemoteStorage, 'put') as mock_put:
         mock_put.side_effect = scp.SCPException()
         with mock.patch.object(utils.LocalStorage, 'get_file_size', return_value=1), \
                 mock.patch.object(utils.LocalStorage, 'get_block_size', return_value=4096), \
                 mock.patch.object(utils.RemoteStorage, 'free_space'), \
                 mock.patch.object(utils.RemoteStorage, '__init__', return_value=None), \
                 mock.patch.object(utils.RemoteStorage, '__del__', return_value=None):
             with self.assertRaises(scp.SCPException):
                 tasks.publish((1, [file_name]))  # pylint: disable=no-value-for-parameter
Exemplo n.º 2
0
 def generate():
     buff_size = buffer_size
     pos = 0
     while pos < size:
         # we have to make sure we don't read the final byte
         if size - pos <= buff_size:
             buff_size = size - pos
         buf = channel.recv(buff_size)
         pos += len(buf)
         yield buf
     msg = channel.recv(512)
     channel.close()
     if msg and msg[0:1] != b'\x00':
         self._closeSCPClient()
         raise scp.SCPException(scp.asunicode(msg[1:]))
Exemplo n.º 3
0
    def stream(self, remote_path, buffer_size=1024):
        client = self._connectSCPClient()
        channel = client._open()
        channel.settimeout(client.socket_timeout)
        channel.exec_command(
            b"scp -f " + client.sanitize(scp.asbytes(remote_path)))  # nosec
        while not channel.closed:
            # wait for command as long as we're open
            channel.sendall('\x00')
            msg = channel.recv(1024)
            if not msg:  # chan closed while recving
                break
            assert msg[-1:] == b'\n'
            msg = msg[:-1]
            code = msg[0:1]
            # recv file
            if code == b"C":
                cmd = msg[1:]
                parts = cmd.strip().split(b' ', 2)
                size = int(parts[1])

                channel.send(b'\x00')
                try:

                    def generate():
                        buff_size = buffer_size
                        pos = 0
                        while pos < size:
                            # we have to make sure we don't read the final byte
                            if size - pos <= buff_size:
                                buff_size = size - pos
                            buf = channel.recv(buff_size)
                            pos += len(buf)
                            yield buf
                        msg = channel.recv(512)
                        channel.close()
                        if msg and msg[0:1] != b'\x00':
                            self._closeSCPClient()
                            raise scp.SCPException(scp.asunicode(msg[1:]))

                    return generate()
                except SocketTimeout:
                    channel.close()
                    self._closeSCPClient()
                    raise scp.SCPException('Error receiving, socket.timeout')
    def test_no_space_left_error(self):
        """
        If a 'No space left on device error' occurs, the partially downloaded file must be removed
        and the task must be retried.
        """
        file_name = 'dataset.nc.tar.gz'

        with mock.patch.object(utils.RemoteStorage, 'put') as mock_put, \
                mock.patch.object(utils.RemoteStorage, 'remove') as mock_remove:
            mock_put.side_effect = scp.SCPException('No space left on device')
            with mock.patch.object(utils.LocalStorage, 'get_file_size', return_value=1), \
                    mock.patch.object(utils.LocalStorage, 'get_block_size', return_value=4096), \
                    mock.patch.object(utils.RemoteStorage, 'free_space'), \
                    mock.patch.object(utils.RemoteStorage, '__init__', return_value=None), \
                    mock.patch.object(utils.RemoteStorage, '__del__', return_value=None):
                with self.assertRaises(celery.exceptions.Retry):
                    tasks.publish((1, [file_name]))  # pylint: disable=no-value-for-parameter
            mock_remove.assert_called()