Beispiel #1
0
class TestVmFunctions(unittest.TestCase):

    def mock_rabbitcli(self, exchange, exchange_type, process_message=None):
        class MockRabbitMQCommonClient(RabbitMQCommonClient):
            def publish_message(self, message, routing_key=None, reply_to=None, exchange=None, correlation_id=None, on_fail=None):
                return
        return MockRabbitMQCommonClient
    
    @mock.patch('imgstorage.imgstoragevm.RabbitMQCommonClient')
    def setUp(self, mock_rabbit):
        self.client = VmDaemon()
        mock_rabbit.publish_message = MagicMock()
        self.client.process_message = MagicMock()

        self.client.run()


    """ Testing mapping of zvol """
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_set_zvol_createnew_success(self, mockRunCommand):
        target = 'iqn.2001-04.com.nas-0-1-vol2'
        bdev = 'sdc'
        def my_side_effect(*args, **kwargs):
            if args[0][0] == 'iscsiadm':    return StringIO(iscsiadm_response%(target, bdev))

        mockRunCommand.side_effect = my_side_effect
        self.client.set_zvol(
            {'action': 'set_zvol', 'target':target, 'nas': 'nas-0-1'},
            BasicProperties(reply_to='reply_to', message_id='message_id'))
        self.client.queue_connector.publish_message.assert_called_with(
            {'action': 'zvol_attached', 'status': 'success', 'bdev': bdev, 'target': target}, 'reply_to', correlation_id='message_id')
Beispiel #2
0
    def setUp(self, mock_rabbit_vm):
        self.vm_client = VmDaemon()
        mock_rabbit_vm.publish_message = MagicMock()
        self.vm_client.process_message = MagicMock()

        self.vm_client.ZPOOL = 'tank'
        self.vm_client.SQLITE_DB = '/tmp/test_db_%s' % uuid.uuid4()
        self.vm_client.run()
Beispiel #3
0
    def setUp(self, mock_rabbit):
        self.client = VmDaemon()
        mock_rabbit.publish_message = MagicMock()
        self.client.process_message = MagicMock()

        self.client.run()

        self.client.SQLITE_DB = '/tmp/test_db_%s' % uuid.uuid4()
        self.client.run()

        with sqlite3.connect(self.client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',
                        ('vol1', 'iqn.2001-04.com.nas-0-1-vol1', 12345,
                         'reply_to', 'corr_id', 0, 1))
            con.commit()
 def setUp(self, mock_rabbit_vm):
     self.vm_client = VmDaemon()
     mock_rabbit_vm.publish_message = MagicMock()
     self.vm_client.process_message = MagicMock()
     
     self.vm_client.ZPOOL = 'tank'
     self.vm_client.SQLITE_DB = '/tmp/test_db_%s'%uuid.uuid4()
     self.vm_client.run()
    def setUp(self, mock_rabbit):
        self.client = VmDaemon()
        mock_rabbit.publish_message = MagicMock()
        self.client.process_message = MagicMock()

        self.client.run()

        self.client.SQLITE_DB = '/tmp/test_db_%s'%uuid.uuid4()
        self.client.run()

        with sqlite3.connect(self.client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',('vol1', 'iqn.2001-04.com.nas-0-1-vol1', 12345, 'reply_to', 'corr_id', 0, 1))
            con.commit()
Beispiel #6
0
class TestVmFunctions(unittest.TestCase):
    def mock_rabbitcli(self, exchange, exchange_type, process_message=None):
        class MockRabbitMQCommonClient(RabbitMQCommonClient):
            def publish_message(self,
                                message,
                                routing_key=None,
                                reply_to=None,
                                exchange=None,
                                correlation_id=None,
                                on_fail=None):
                return

        return MockRabbitMQCommonClient

    @mock.patch('imgstorage.imgstoragevm.RabbitMQCommonClient')
    def setUp(self, mock_rabbit):
        self.client = VmDaemon()
        mock_rabbit.publish_message = MagicMock()
        self.client.process_message = MagicMock()

        self.client.run()

        self.client.SQLITE_DB = '/tmp/test_db_%s' % uuid.uuid4()
        self.client.run()

        with sqlite3.connect(self.client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',
                        ('vol1', 'iqn.2001-04.com.nas-0-1-vol1', 12345,
                         'reply_to', 'corr_id', 0, 1))
            con.commit()

    """ Testing mapping of zvol """

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    @mock.patch('imgstorage.imgstoragevm.VmDaemon.is_sync_enabled',
                return_value=False)
    def test_map_zvol_createnew_success(self, mockSyncEnabled, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target, bdev)
        self.client.map_zvol(
            {
                'action': 'map_zvol',
                'target': target,
                'nas': 'nas-0-1',
                'size': '35',
                'zvol': zvol
            }, BasicProperties(reply_to='reply_to', message_id='message_id'))
        self.client.queue_connector.publish_message.assert_called_with(
            {
                'action': 'zvol_mapped',
                'status': 'success',
                'bdev': '/dev/%s' % bdev,
                'target': target
            },
            'reply_to',
            reply_to=self.client.NODE_NAME,
            correlation_id='message_id')
        mockRunCommand.assert_any_call([
            'iscsiadm', '-m', 'discovery', '-t', 'sendtargets', '-p', 'nas-0-1'
        ])
        mockRunCommand.assert_any_call(
            ['iscsiadm', '-m', 'node', '-T', target, '-p', 'nas-0-1', '-l'])
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'session', '-P3'])
        assert 3 == mockRunCommand.call_count

    """ Testing mapping of zvol for missing block device """

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    @mock.patch('imgstorage.imgstoragevm.VmDaemon.is_sync_enabled',
                return_value=False)
    def test_map_zvol_createnew_missing_blkdev_error(self, mockSyncEnabled,
                                                     mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target + "_missing_target", bdev)
        self.client.map_zvol(
            {
                'action': 'map_zvol',
                'target': target,
                'nas': 'nas-0-1',
                'size': '35',
                'zvol': zvol
            }, BasicProperties(reply_to='reply_to', message_id='message_id'))
        self.client.queue_connector.publish_message.assert_called_with(
            {
                'action': 'zvol_mapped',
                'status': 'error',
                'target': target,
                'error': 'Not found %s in targets' % target
            },
            'reply_to',
            reply_to=self.client.NODE_NAME,
            correlation_id='message_id')

    """ Testing unmapping of zvol """

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_unmap_zvol_success(self, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target, bdev)
        self.client.unmap_zvol(
            {
                'action': 'unmap_zvol',
                'target': target,
                'zvol': zvol
            }, BasicProperties(reply_to='reply_to', message_id='message_id'))
        print self.client.queue_connector.publish_message.mock_calls
        self.client.queue_connector.publish_message.assert_called_with(
            {
                'action': 'zvol_unmapped',
                'status': 'success',
                'target': target,
                'zvol': zvol
            },
            'reply_to',
            reply_to=self.client.NODE_NAME,
            correlation_id='message_id')
        mockRunCommand.assert_any_call(
            ['iscsiadm', '-m', 'node', '-T', target, '-u'])
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'session', '-P3'])

    """ Testing unmapping of zvol when not found - still returns success """

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_unmap_zvol_not_found(self, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target, bdev)
        self.client.unmap_zvol(
            {
                'action': 'unmap_zvol',
                'target': target + "not_found",
                'zvol': zvol
            }, BasicProperties(reply_to='reply_to', message_id='message_id'))
        print self.client.queue_connector.publish_message.mock_calls

        self.client.queue_connector.publish_message.assert_called_with(
            {
                'action': 'zvol_unmapped',
                'status': 'success',
                'target': target + "not_found",
                'zvol': zvol
            },
            'reply_to',
            reply_to=self.client.NODE_NAME,
            correlation_id='message_id')

    """ Testing unmapping of zvol with error from system call """

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_map_zvol_unmap_error(self, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'

        def my_side_effect(*args, **kwargs):
            if args[0][:3] == ['iscsiadm', '-m', 'session']:
                return StringIO(iscsiadm_session_response % (target, bdev))
            elif args[0][:3] == ['iscsiadm', '-m', 'discovery']:
                return StringIO(iscsiadm_discovery_response %
                                target)  # find remote targets
            elif args[0][:3] == ['iscsiadm', '-m', 'node']:
                raise ActionError('Some error happened')

        mockRunCommand.side_effect = my_side_effect
        self.client.unmap_zvol(
            {
                'action': 'unmap_zvol',
                'target': target,
                'zvol': zvol
            }, BasicProperties(reply_to='reply_to', message_id='message_id'))
        self.client.queue_connector.publish_message.assert_called_with(
            {
                'action': 'zvol_unmapped',
                'status': 'error',
                'target': target,
                'zvol': zvol,
                'error': 'Some error happened'
            },
            'reply_to',
            reply_to=self.client.NODE_NAME,
            correlation_id='message_id')
        mockRunCommand.assert_called_with(
            ['iscsiadm', '-m', 'node', '-T', target, '-u'])

    def create_iscsiadm_side_effect(self, target, bdev):
        def iscsiadm_side_effect(*args, **kwargs):
            if args[0][:3] == ['iscsiadm', '-m', 'session']:
                return (iscsiadm_session_response %
                        (target, bdev)).splitlines()  # list local devices
            elif args[0][:3] == ['iscsiadm', '-m', 'discovery']:
                return (iscsiadm_discovery_response %
                        target).splitlines()  # find remote targets
            elif args[0][:3] == ['iscsiadm', '-m', 'node']:
                return '\n'.splitlines()  # connect to iscsi target
            elif args[0][0] == 'blockdev':
                return '12345'.splitlines()

        return iscsiadm_side_effect
class TestVmSyncFunctions(unittest.TestCase):

    def mock_rabbitcli(self, exchange, exchange_type, process_message=None):
        class MockRabbitMQCommonClient(RabbitMQCommonClient):
            def publish_message(self, message, routing_key=None, reply_to=None, exchange=None, correlation_id=None, on_fail=None):
                return
        return MockRabbitMQCommonClient

    @mock.patch('imgstorage.imgstoragevm.RabbitMQCommonClient')
    def setUp(self, mock_rabbit_vm):
        self.vm_client = VmDaemon()
        mock_rabbit_vm.publish_message = MagicMock()
        self.vm_client.process_message = MagicMock()
        
        self.vm_client.ZPOOL = 'tank'
        self.vm_client.SQLITE_DB = '/tmp/test_db_%s'%uuid.uuid4()
        self.vm_client.run()

    def tearDown(self):
        os.remove(self.vm_client.SQLITE_DB)

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_run_sync_initial_synced(self, mockRunCommand):
        zvol = 'vm-hpcdev-pub03-1-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target, bdev, 1)
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',(zvol, 'iqn.2001-04.com.nas-0-1-%s'%zvol, 12345, 'reply_to', 'corr_id', 0, 1))
            con.commit()


        self.vm_client.run_sync()
        print mockRunCommand.mock_calls
        mockRunCommand.assert_any_call(['dmsetup', 'suspend', '/dev/mapper/%s-snap'%zvol])
        mockRunCommand.assert_any_call(['dmsetup', 'reload', '/dev/mapper/%s-snap'%zvol, '--table', '0 12345 snapshot-merge /dev/zvol/tank/%s /dev/zvol/tank/%s-temp-write P 16'%(zvol, zvol)])
        mockRunCommand.assert_any_call(['dmsetup', 'resume', '/dev/mapper/%s-snap'%zvol])
        mockRunCommand.assert_any_call(['dmsetup', 'reload', '/dev/mapper/%s-snap'%zvol, '--table', '0 12345 linear /dev/zvol/tank/%s 0'%(zvol)])
        mockRunCommand.assert_any_call(['zfs', 'destroy', 'tank/%s-temp-write'%zvol])
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'node', '-T', 'iqn.2001-04.com.nas-0-1-%s'%zvol, '-u'])

        print  mockRunCommand.call_count
        assert 10 == mockRunCommand.call_count
        self.vm_client.queue_connector.publish_message.assert_called_with({'action': 'zvol_synced', 'status': 'success', 'zvol': zvol}, u'reply_to', correlation_id=u'corr_id')


    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_run_sync_initial_not_synced(self, mockRunCommand):
        zvol = 'vm-hpcdev-pub03-2-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target, bdev, 2)
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',(zvol, 'iqn.2001-04.com.nas-0-1-%s'%zvol, 12345, 'reply_to', 'corr_id', 0, 1))
            con.commit()


        self.vm_client.run_sync()
        print mockRunCommand.mock_calls
        mockRunCommand.assert_any_call(['dmsetup', 'suspend', '/dev/mapper/%s-snap'%zvol])
        mockRunCommand.assert_any_call(['dmsetup', 'reload', '/dev/mapper/%s-snap'%zvol, '--table', '0 12345 snapshot-merge /dev/zvol/tank/%s /dev/zvol/tank/%s-temp-write P 16'%(zvol, zvol)])
        mockRunCommand.assert_any_call(['dmsetup', 'resume', '/dev/mapper/%s-snap'%zvol])

        print  mockRunCommand.call_count
        assert 4 == mockRunCommand.call_count
        assert not self.vm_client.queue_connector.publish_message.called, 'rabbotmq message was sent and should not have been'

    """ Testing zvol sync """
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    @mock.patch('imgstorage.imgstoragevm.time.time',return_value=111)
    def test_sync_zvol_success(self, mockTime, mockRunCommand):
        zvol= 'vm-hpcdev-pub03-1-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target, bdev)
        self.vm_client.sync_zvol(
            {'action': 'sync_zvol', 'zvol':zvol, 'target':target},
            BasicProperties(reply_to='reply_to', message_id='message_id'))
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('SELECT * FROM sync_queue')
            self.assertSequenceEqual(cur.fetchone(), [zvol, target, 12345, 'reply_to','message_id',0,111])

    
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_get_dev_list(self, mockRunCommand):
        zvol= 'vm-hpcdev-pub03-1-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target, bdev)
        dev_list = self.vm_client.get_dev_list()
        self.assertEqual(dev_list, {
            zvol: {'status': 'snapshot-merge', 'target': target, 'dev': '%s-snap'%zvol, 'synced': '32/73400320 32', 'bdev': bdev, 'size': 36}, 
            'vm-hpcdev-pub03-4-vol': {'status': 'linear', 'dev': 'vm-hpcdev-pub03-4-vol-snap', 'size': 36}, 
            'vm-hpcdev-pub03-2-vol': {'status': 'snapshot-merge', 'synced': '1321232/73400320 2592', 'dev': 'vm-hpcdev-pub03-2-vol-snap', 'size': 36}
        })
        print self.vm_client.get_dev_list()

    def create_iscsiadm_side_effect(self, target, bdev, dmsetup_return_line=None):
        def iscsiadm_side_effect(*args, **kwargs):
            if args[0][:3] == ['iscsiadm', '-m', 'session']:        return (iscsiadm_session_response%(target, bdev)).splitlines() # list local devices
            elif args[0][:3] == ['iscsiadm', '-m', 'discovery']:    return (iscsiadm_discovery_response%target).splitlines() # find remote targets
            elif args[0][:3] == ['iscsiadm', '-m', 'node']:         return '\n'.splitlines() # connect to iscsi target
            elif args[0][:2] == ['dmsetup', 'status']:
                if(not dmsetup_return_line):
                    return dmsetup_status_response.splitlines()
                else:
                    return [dmsetup_status_response.splitlines()[dmsetup_return_line][len('vm-hpcdev-pub03-1-vol-snap: '):]]
            elif args[0][0] == 'blockdev':                          return '12345'.splitlines()
        return iscsiadm_side_effect



    def check_zvol_busy(self, zvol):
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('SELECT count(*) from sync_queue where zvol = ?',[zvol])
            num_rows = cur.fetchone()[0]
            return num_rows > 0

    def assertSequenceEqual(self, it1, it2):
        self.assertEqual(tuple(it1), tuple(it2))
Beispiel #8
0
class TestVmSyncFunctions(unittest.TestCase):
    def mock_rabbitcli(self, exchange, exchange_type, process_message=None):
        class MockRabbitMQCommonClient(RabbitMQCommonClient):
            def publish_message(self,
                                message,
                                routing_key=None,
                                reply_to=None,
                                exchange=None,
                                correlation_id=None,
                                on_fail=None):
                return

        return MockRabbitMQCommonClient

    @mock.patch('imgstorage.imgstoragevm.RabbitMQCommonClient')
    def setUp(self, mock_rabbit_vm):
        self.vm_client = VmDaemon()
        mock_rabbit_vm.publish_message = MagicMock()
        self.vm_client.process_message = MagicMock()

        self.vm_client.ZPOOL = 'tank'
        self.vm_client.SQLITE_DB = '/tmp/test_db_%s' % uuid.uuid4()
        self.vm_client.run()

    def tearDown(self):
        os.remove(self.vm_client.SQLITE_DB)

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_run_sync_initial_synced(self, mockRunCommand):
        zvol = 'vm-hpcdev-pub03-1-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target, bdev, 1)
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',
                        (zvol, 'iqn.2001-04.com.nas-0-1-%s' % zvol, 12345,
                         'reply_to', 'corr_id', 0, 1))
            con.commit()

        self.vm_client.run_sync()
        print mockRunCommand.mock_calls
        mockRunCommand.assert_any_call(
            ['dmsetup', 'suspend',
             '/dev/mapper/%s-snap' % zvol])
        mockRunCommand.assert_any_call([
            'dmsetup', 'reload',
            '/dev/mapper/%s-snap' % zvol, '--table',
            '0 12345 snapshot-merge /dev/zvol/tank/%s /dev/zvol/tank/%s-temp-write P 16'
            % (zvol, zvol)
        ])
        mockRunCommand.assert_any_call(
            ['dmsetup', 'resume',
             '/dev/mapper/%s-snap' % zvol])
        mockRunCommand.assert_any_call([
            'dmsetup', 'reload',
            '/dev/mapper/%s-snap' % zvol, '--table',
            '0 12345 linear /dev/zvol/tank/%s 0' % (zvol)
        ])
        mockRunCommand.assert_any_call(
            ['zfs', 'destroy', 'tank/%s-temp-write' % zvol])
        mockRunCommand.assert_any_call([
            'iscsiadm', '-m', 'node', '-T',
            'iqn.2001-04.com.nas-0-1-%s' % zvol, '-u'
        ])

        print mockRunCommand.call_count
        assert 10 == mockRunCommand.call_count
        self.vm_client.queue_connector.publish_message.assert_called_with(
            {
                'action': 'zvol_synced',
                'status': 'success',
                'zvol': zvol
            },
            u'reply_to',
            correlation_id=u'corr_id')

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_run_sync_initial_not_synced(self, mockRunCommand):
        zvol = 'vm-hpcdev-pub03-2-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target, bdev, 2)
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',
                        (zvol, 'iqn.2001-04.com.nas-0-1-%s' % zvol, 12345,
                         'reply_to', 'corr_id', 0, 1))
            con.commit()

        self.vm_client.run_sync()
        print mockRunCommand.mock_calls
        mockRunCommand.assert_any_call(
            ['dmsetup', 'suspend',
             '/dev/mapper/%s-snap' % zvol])
        mockRunCommand.assert_any_call([
            'dmsetup', 'reload',
            '/dev/mapper/%s-snap' % zvol, '--table',
            '0 12345 snapshot-merge /dev/zvol/tank/%s /dev/zvol/tank/%s-temp-write P 16'
            % (zvol, zvol)
        ])
        mockRunCommand.assert_any_call(
            ['dmsetup', 'resume',
             '/dev/mapper/%s-snap' % zvol])

        print mockRunCommand.call_count
        assert 4 == mockRunCommand.call_count
        assert not self.vm_client.queue_connector.publish_message.called, 'rabbotmq message was sent and should not have been'

    """ Testing zvol sync """

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    @mock.patch('imgstorage.imgstoragevm.time.time', return_value=111)
    def test_sync_zvol_success(self, mockTime, mockRunCommand):
        zvol = 'vm-hpcdev-pub03-1-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target, bdev)
        self.vm_client.sync_zvol(
            {
                'action': 'sync_zvol',
                'zvol': zvol,
                'target': target
            }, BasicProperties(reply_to='reply_to', message_id='message_id'))
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('SELECT * FROM sync_queue')
            self.assertSequenceEqual(
                cur.fetchone(),
                [zvol, target, 12345, 'reply_to', 'message_id', 0, 111])

    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_get_dev_list(self, mockRunCommand):
        zvol = 'vm-hpcdev-pub03-1-vol'
        target = 'iqn.2001-04.com.nas-0-1-%s' % zvol
        bdev = 'sdc'
        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(
            target, bdev)
        dev_list = self.vm_client.get_dev_list()
        self.assertEqual(
            dev_list, {
                zvol: {
                    'status': 'snapshot-merge',
                    'target': target,
                    'dev': '%s-snap' % zvol,
                    'synced': '32/73400320 32',
                    'bdev': bdev,
                    'size': 36
                },
                'vm-hpcdev-pub03-4-vol': {
                    'status': 'linear',
                    'dev': 'vm-hpcdev-pub03-4-vol-snap',
                    'size': 36
                },
                'vm-hpcdev-pub03-2-vol': {
                    'status': 'snapshot-merge',
                    'synced': '1321232/73400320 2592',
                    'dev': 'vm-hpcdev-pub03-2-vol-snap',
                    'size': 36
                }
            })
        print self.vm_client.get_dev_list()

    def create_iscsiadm_side_effect(self,
                                    target,
                                    bdev,
                                    dmsetup_return_line=None):
        def iscsiadm_side_effect(*args, **kwargs):
            if args[0][:3] == ['iscsiadm', '-m', 'session']:
                return (iscsiadm_session_response %
                        (target, bdev)).splitlines()  # list local devices
            elif args[0][:3] == ['iscsiadm', '-m', 'discovery']:
                return (iscsiadm_discovery_response %
                        target).splitlines()  # find remote targets
            elif args[0][:3] == ['iscsiadm', '-m', 'node']:
                return '\n'.splitlines()  # connect to iscsi target
            elif args[0][:2] == ['dmsetup', 'status']:
                if (not dmsetup_return_line):
                    return dmsetup_status_response.splitlines()
                else:
                    return [
                        dmsetup_status_response.splitlines()
                        [dmsetup_return_line]
                        [len('vm-hpcdev-pub03-1-vol-snap: '):]
                    ]
            elif args[0][0] == 'blockdev':
                return '12345'.splitlines()

        return iscsiadm_side_effect

    def check_zvol_busy(self, zvol):
        with sqlite3.connect(self.vm_client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('SELECT count(*) from sync_queue where zvol = ?',
                        [zvol])
            num_rows = cur.fetchone()[0]
            return num_rows > 0

    def assertSequenceEqual(self, it1, it2):
        self.assertEqual(tuple(it1), tuple(it2))
class TestVmFunctions(unittest.TestCase):

    def mock_rabbitcli(self, exchange, exchange_type, process_message=None):
        class MockRabbitMQCommonClient(RabbitMQCommonClient):
            def publish_message(self, message, routing_key=None, reply_to=None, exchange=None, correlation_id=None, on_fail=None):
                return
        return MockRabbitMQCommonClient

    @mock.patch('imgstorage.imgstoragevm.RabbitMQCommonClient')
    def setUp(self, mock_rabbit):
        self.client = VmDaemon()
        mock_rabbit.publish_message = MagicMock()
        self.client.process_message = MagicMock()

        self.client.run()

        self.client.SQLITE_DB = '/tmp/test_db_%s'%uuid.uuid4()
        self.client.run()

        with sqlite3.connect(self.client.SQLITE_DB) as con:
            cur = con.cursor()
            cur.execute('INSERT INTO sync_queue VALUES (?,?,?,?,?,?,?)',('vol1', 'iqn.2001-04.com.nas-0-1-vol1', 12345, 'reply_to', 'corr_id', 0, 1))
            con.commit()


    """ Testing mapping of zvol """
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    @mock.patch('imgstorage.imgstoragevm.VmDaemon.is_sync_enabled', return_value=False)
    def test_map_zvol_createnew_success(self, mockSyncEnabled, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target, bdev)
        self.client.map_zvol(
            {'action': 'map_zvol', 'target':target, 'nas': 'nas-0-1', 'size':'35', 'zvol':zvol},
            BasicProperties(reply_to='reply_to', message_id='message_id'))
        self.client.queue_connector.publish_message.assert_called_with(
            {'action': 'zvol_mapped', 'status': 'success', 'bdev': '/dev/%s'%bdev, 'target': target}, 'reply_to', reply_to=self.client.NODE_NAME, correlation_id='message_id')
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'discovery', '-t', 'sendtargets', '-p', 'nas-0-1'])
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'node', '-T', target, '-p', 'nas-0-1', '-l'])
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'session', '-P3'])
        assert 3 == mockRunCommand.call_count

    """ Testing mapping of zvol for missing block device """
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    @mock.patch('imgstorage.imgstoragevm.VmDaemon.is_sync_enabled', return_value=False)
    def test_map_zvol_createnew_missing_blkdev_error(self, mockSyncEnabled, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target+"_missing_target", bdev)
        self.client.map_zvol(
            {'action': 'map_zvol', 'target':target, 'nas': 'nas-0-1', 'size':'35', 'zvol':zvol},
            BasicProperties(reply_to='reply_to', message_id='message_id'))
        self.client.queue_connector.publish_message.assert_called_with(
            {'action': 'zvol_mapped', 'status': 'error', 'target': target,
            'error': 'Not found %s in targets'%target},
            'reply_to', reply_to=self.client.NODE_NAME, correlation_id='message_id')

    """ Testing unmapping of zvol """
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_unmap_zvol_success(self, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target, bdev)
        self.client.unmap_zvol(
            {'action': 'unmap_zvol', 'target':target, 'zvol':zvol},
            BasicProperties(reply_to='reply_to', message_id='message_id'))
        print self.client.queue_connector.publish_message.mock_calls
        self.client.queue_connector.publish_message.assert_called_with(
            {'action': 'zvol_unmapped', 'status': 'success', 'target': target, 'zvol':zvol}, 'reply_to', reply_to=self.client.NODE_NAME, correlation_id='message_id')
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'node', '-T', target, '-u'])
        mockRunCommand.assert_any_call(['iscsiadm', '-m', 'session', '-P3'])

    """ Testing unmapping of zvol when not found - still returns success """
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_unmap_zvol_not_found(self, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'

        mockRunCommand.side_effect = self.create_iscsiadm_side_effect(target, bdev)
        self.client.unmap_zvol(
            {'action': 'unmap_zvol', 'target':target+"not_found", 'zvol':zvol},
            BasicProperties(reply_to='reply_to', message_id='message_id'))
        print self.client.queue_connector.publish_message.mock_calls

        self.client.queue_connector.publish_message.assert_called_with(
            {'action': 'zvol_unmapped', 'status': 'success', 'target': target+"not_found", 'zvol':zvol}, 'reply_to', reply_to=self.client.NODE_NAME, correlation_id='message_id')


    """ Testing unmapping of zvol with error from system call """
    @mock.patch('imgstorage.imgstoragevm.runCommand')
    def test_map_zvol_unmap_error(self, mockRunCommand):
        zvol = 'vol2'
        target = 'iqn.2001-04.com.nas-0-1-%s'%zvol
        bdev = 'sdc'
        def my_side_effect(*args, **kwargs):
            if args[0][:3] == ['iscsiadm', '-m', 'session']:    return StringIO(iscsiadm_session_response%(target, bdev))
            elif args[0][:3] == ['iscsiadm', '-m', 'discovery']:    return StringIO(iscsiadm_discovery_response%target) # find remote targets
            elif args[0][:3] == ['iscsiadm', '-m', 'node']:
                raise ActionError('Some error happened')

        mockRunCommand.side_effect = my_side_effect
        self.client.unmap_zvol(
            {'action': 'unmap_zvol', 'target':target, 'zvol':zvol},
            BasicProperties(reply_to='reply_to', message_id='message_id'))
        self.client.queue_connector.publish_message.assert_called_with(
            {'action': 'zvol_unmapped', 'status': 'error', 'target': target, 'zvol':zvol, 'error': 'Some error happened'},
            'reply_to', reply_to=self.client.NODE_NAME,  correlation_id='message_id')
        mockRunCommand.assert_called_with(['iscsiadm', '-m', 'node', '-T', target, '-u'])

    def create_iscsiadm_side_effect(self, target, bdev):
        def iscsiadm_side_effect(*args, **kwargs):
            if args[0][:3] == ['iscsiadm', '-m', 'session']:        return (iscsiadm_session_response%(target, bdev)).splitlines() # list local devices
            elif args[0][:3] == ['iscsiadm', '-m', 'discovery']:    return (iscsiadm_discovery_response%target).splitlines() # find remote targets
            elif args[0][:3] == ['iscsiadm', '-m', 'node']:         return '\n'.splitlines() # connect to iscsi target
            elif args[0][0] == 'blockdev':                          return '12345'.splitlines()
        return iscsiadm_side_effect
Beispiel #10
0
    def setUp(self, mock_rabbit):
        self.client = VmDaemon()
        mock_rabbit.publish_message = MagicMock()
        self.client.process_message = MagicMock()

        self.client.run()