class TestStoragepoolsAPI(TestcasesBase):
    def setUp(self):
        super().setUp()
        self.storagepool_api = StoragepoolsAPI()
        self.nodeid = self.get_random_node()
        self.nodeip = [x['ip'] for x in self.nodes if x['id'] == self.nodeid]
        self.jwt = self.nodes_api.jwt
        self.pyclient = Client(self.nodeip[0], password=self.jwt)
        self.CLEANUP = []

    def tearDown(self):
        for storagepool in self.CLEANUP:
            self.storagepool_api.delete_storagepools_storagepoolname(self.nodeid, storagepool)
        super(TestStoragepoolsAPI, self).tearDown()

    def create_storagepool(self):
        freeDisks = self.pyclient.getFreeDisks()
        if freeDisks == []:
            self.skipTest('no free disks on node {}'.format(self.nodeid))

        self.lg.info('Create storagepool (SP0) on node (N0)')
        name = self.random_string()
        metadata = 'single'
        data = 'single'
        device = random.choice(freeDisks)
        body = {"name":name,
                "metadataProfile":metadata,
                "dataProfile":data,
                "devices":[device]}

        response = self.storagepool_api.post_storagepools(self.nodeid, body)
        self.assertEqual(response.status_code, 201)

        for _ in range(60):
            freeDisks = self.pyclient.getFreeDisks()
            if device not in freeDisks:
                self.CLEANUP.append(name)
                break
            else:
                time.sleep(3)
        else:
            self.lg.error('storagepool {} doesn\'t mount device {}'.format(name, device))
            
        return body

    def delete_storage_pool(self, storagepool):
        response = self.storagepool_api.delete_storagepools_storagepoolname(self.nodeid, storagepool)
        if response.status_code == 204:
            try:
                self.CLEANUP.remove(storagepool)
            except:
                pass
        
    def create_filesystem(self, storagepool):
        self.lg.info('Create filesystem (FS0) on storagepool {}'.format(storagepool))
        name = self.random_string()
        quota = random.randint(0, 10)
        body = {"name":name, "quota":quota}
        response = self.storagepool_api.post_storagepools_storagepoolname_filesystems(self.nodeid, storagepool, body)
        self.assertEqual(response.status_code, 201)
        for _ in range(60):
            try:
                data = self.pyclient.client.btrfs.subvol_list('/mnt/storagepools/{}'.format(storagepool))
                filesystems = [x for x in data if 'filesystems' in x['Path']]
                filesystems = [x['Path'][x['Path'].rfind('/')+1:] for x in filesystems]
                if name in filesystems:
                    break
                else:
                    time.sleep(3)
            except:
                pass
        else:
            self.lg.error('filesystem {} is not created {}'.format(name))
        return body
        
    def create_snapshot(self, storagepool, filesystem):
        self.lg.info('Create snapshot (SS0) of filesystem {}'.format(filesystem))
        name = self.rand_str()
        body = {"name":name}
        self.storagepool_api.post_filesystems_snapshots(self.nodeid, storagepool, filesystem, body)

        for _ in range(60):
            try:
                data = self.pyclient.client.btrfs.subvol_list('/mnt/storagepools/{}'.format(storagepool))
                snapshots = [x for x in data if 'snapshots/{}'.format(filesystem) in x['Path']]
                snapshots = [x['Path'][x['Path'].rfind('/')+1:] for x in snapshots]
                if name in snapshots:
                    break
                else:
                    time.sleep(3)
            except:
                pass
        else:
            self.lg.error('snapshot {} is not created {}'.format(name))

        return body
    

    def test001_get_storagepool(self):
        """ GAT-045
        **Test Scenario:**

        #. Create storagepool (SP0) on node (N0), should succeed.
        #. Get storagepool (SP0), should succeed with 200.
        #. Get storagepool (SP0) using python client, should be listed
        #. Get nonexisting storagepool, should fail with 404.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()
        
        self.lg.info('Get storagepool (SP0), should succeed with 200')
        response = self.storagepool_api.get_storagepools_storagepoolname(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        for key in storagepool.keys():
            if key == 'devices':
                continue
            self.assertEqual(response.json()[key], storagepool[key])

        self.lg.info('Get storagepool (SP0) using python client, should be listed')
        storagepools = self.pyclient.client.btrfs.list()
        storagepool_sp0 = [x for x in storagepools if x['label'] == 'sp_{}'.format(storagepool['name'])]
        self.assertNotEqual(storagepool_sp0, [])
        for device in storagepool['devices']: 
            self.assertIn(device, [x['path'][:-1] for x in storagepool_sp0[0]['devices']])

        self.lg.info('Get nonexisting storagepool, should fail with 404')
        response = self.storagepool_api.get_storagepools_storagepoolname(self.nodeid, 'fake_storagepool')
        self.assertEqual(response.status_code, 404)


    def test002_list_storagepool(self):
        """ GAT-046
        **Test Scenario:**

        #. Create Storagepool (SP0) on node (N0).
        #. list node (N0) storagepools, storagepool (SP0) should be listed.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('list node (N0) storagepools, storagepool (SP0) should be listed')
        response = self.storagepool_api.get_storagepools(self.nodeid)
        self.assertEqual(response.status_code, 200)
        self.assertIn(storagepool['name'], [x['name'] for x in response.json()])

    def test003_post_storagepool(self):
        """ GAT-047
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create storagepool (SP0) on node (N0).
        #. Get storagepool (SP0), should succeed with 200.
        #. Get storagepool (SP1) using python client, should be listed
        #. Delete Storagepool (SP0), should succeed with 204.
        #. Create invalid storagepool (missing required params), should fail with 400.
        """

        self.lg.info('Create Storagepool (SP1), should succeed with 201')
        name = self.random_string()
        free_devices = self.pyclient.getFreeDisks()

        levels = ['raid0', 'raid1', 'raid5', 'raid6', 'raid10', 'dup', 'single']

        if free_devices == []:
            self.skipTest('no free disks on node {}'.format(self.nodeid))

        if len(free_devices) < 6:
            metadata = 'single'
            data = 'single'
            devices = [random.choice(free_devices)]
        else:
            metadata = self.random_item(levels)
            data = self.random_item(levels)
            devices = free_devices[:4]

        body = {"name":name,
                "metadataProfile":metadata,
                "dataProfile":data,
                "devices":devices}

        response = self.storagepool_api.post_storagepools(self.nodeid, body)
        self.assertEqual(response.status_code, 201)
        time.sleep(30)

        self.lg.info('Get Storagepool (SP1), should succeed with 200')
        response = self.storagepool_api.get_storagepools_storagepoolname(self.nodeid, name)
        self.assertEqual(response.status_code, 200)
        for key in body.keys():
            if key == 'devices':
                continue
            self.assertEqual(response.json()[key], body[key])

        time.sleep(20)
        self.lg.info('Get storagepool (SP0) using python client, should be listed')
        storagepools = self.pyclient.client.btrfs.list()
        storagepool_sp1 = [x for x in storagepools if x['label'] == 'sp_{}'.format(name)]
        self.assertNotEqual(storagepool_sp1, [])
        
        for device in devices:
            self.assertIn(device, [x['path'][:-1] for x in storagepool_sp1[0]['devices']])

        self.lg.info('Delete Storagepool (SP0), should succeed with 204')
        response = self.storagepool_api.delete_storagepools_storagepoolname(self.nodeid, name)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Create invalid storagepool, should fail with 400')
        body = {"name":name, "metadataProfile":metadata}
        response = self.storagepool_api.post_storagepools(self.nodeid, body)
        self.assertEqual(response.status_code, 400)

    def test004_delete_storagepool(self):
        """ GAT-048
        **Test Scenario:**

        #. Create Storagepool (SP0) on node (N0).
        #. Delete Storagepool (SP0), should succeed with 204.
        #. list node (N0) storagepools, storagepool (SP0) should be gone.
        #. Delete nonexisting storagepool, should fail with 404.
        """

        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Delete storagepool (SP0), should succeed with 204')
        response = self.storagepool_api.delete_storagepools_storagepoolname(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 204)
        self.CLEANUP.remove(storagepool['name'])

        self.lg.info('list node (N0) storagepools, storagepool (SP0) should be gone')
        response = self.storagepool_api.get_storagepools(self.nodeid)
        self.assertEqual(response.status_code, 200)
        self.assertNotIn(storagepool['name'], [x['name'] for x in response.json()])

        self.lg.info('Delete nonexisting storagepool, should fail with 404')
        response = self.storagepool_api.delete_storagepools_storagepoolname(self.nodeid, 'fake_storagepool')
        self.assertEqual(response.status_code, 404)

    # @unittest.skip('https://github.com/zero-os/0-orchestrator/issues/209')
    def test005_get_storagepool_device(self):
        """ GAT-049
        **Test Scenario:**

        #. Create storagepool (SP0) with device (DV0) on node (N0).
        #. Get device (DV0), should succeed with 200.
        #. Get nonexisting device, should fail with 404.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()
        time.sleep(15)

        self.lg.info('Get device (DV0), should succeed with 200')
        response = self.storagepool_api.get_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(response.json(), [])
        device_uuid = response.json()[0]['uuid']

        response = self.storagepool_api.get_storagepools_storagepoolname_devices_deviceid(self.nodeid, storagepool['name'], device_uuid)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()['deviceName'][:-1], storagepool['devices'][0])
        self.assertEqual(response.json()['uuid'], device_uuid)
        self.assertEqual(response.json()['status'], 'healthy')

        self.lg.info('Get nonexisting device, should fail with 404')
        response = self.storagepool_api.get_storagepools_storagepoolname_devices_deviceid(self.nodeid, storagepool['name'], 'fake_device')
        self.assertEqual(response.status_code, 404)

    def test006_list_storagepool_devices(self):
        """ GAT-050
        **Test Scenario:**

        #. Create storagepool (SP0) with device (DV0) on node (N0).
        #. list storagepool (SP0) devices, should succeed with 200.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('list storagepool (SP0) devices, should succeed with 200')
        response = self.storagepool_api.get_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(response.json(), [])
        self.assertEqual(len(response.json()), len(storagepool['devices']))
        self.assertEqual(response.json()[0]['status'], 'healthy')

    def test007_post_storagepool_device(self):
        """ GAT-051
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create storagepool (SP0) with device (DV0) on node (N0).
        #. Create device (DV1) on storagepool (SP0), should succeed with 201.
        #. list storagepool (SP0) devices, device (DV1) should be listed.
        #. Create device with invalid body, should fail with 400.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create device (DV1) on storagepool (SP0), should succeed with 201')
        free_devices = self.pyclient.getFreeDisks()
        if free_devices == []:
            self.skipTest('no free disks on node {}'.format(self.nodeid))

        device = random.choice(free_devices)
        body = [device]
        response = self.storagepool_api.post_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'], body)
        self.assertEqual(response.status_code, 201)
        
        for _ in range(30):
            free_devices = self.pyclient.getFreeDisks()
            if device not in free_devices:
                break
            else:
                time.sleep(1)
            
        self.lg.info('list storagepool (SP0) devices, should succeed with 200')
        response = self.storagepool_api.get_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        self.assertIn(device, [x['deviceName'][:-1] for x in response.json()])

        #issue https://github.com/zero-os/0-orchestrator/issues/398
        # self.lg.info('Create device with invalid body, should fail with 400')
        # body = ""
        # response = self.storagepool_api.post_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'], body)
        # self.assertEqual(response.status_code, 400)
    
    # @unittest.skip('https://github.com/zero-os/0-orchestrator/issues/209')
    def test008_delete_storagepool_device(self):
        """ GAT-052
        **Test Scenario:**

        #. Create storagepool (SP0) with device (DV0) on node (N1), should succeed with 201.
        #. Delete device (DV0), should succeed with 204.
        #. list storagepool (SP0) devices, device (DV0) should be gone.
        #. Delete nonexisting device, should fail with 404.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create device (DV1) on storagepool (SP0), should succeed with 201')
        free_devices = self.pyclient.getFreeDisks()
        if free_devices == []:
            self.skipTest('no free disks on node {}'.format(self.nodeid))

        device = random.choice(free_devices)
        body = [device]
        response = self.storagepool_api.post_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'], body)
        self.assertEqual(response.status_code, 201)
        
        for _ in range(30):
            free_devices = self.pyclient.getFreeDisks()
            if device not in free_devices:
                break
            else:
                time.sleep(1)

        self.lg.info('list storagepool (SP0) devices, device (DV0) should be gone')
        response = self.storagepool_api.get_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        deviceuuid = [x['uuid'] for x in response.json() if x['deviceName'][:-1] == device]
        self.assertNotEqual(deviceuuid, [], 'device was not added to storagepool')

        self.lg.info('Delete device (DV1), should succeed with 204')
        response = self.storagepool_api.delete_storagepools_storagepoolname_devices_deviceid(self.nodeid, storagepool['name'], deviceuuid[0])
        self.assertEqual(response.status_code, 204)

        for _ in range(30):
            free_devices = self.pyclient.getFreeDisks()
            if device in free_devices:
                break
            else:
                time.sleep(1)

        self.lg.info('list storagepool (SP0) devices, device (DV0) should be gone')
        response = self.storagepool_api.get_storagepools_storagepoolname_devices(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        self.assertNotIn(device, [x['deviceName'][:-1] for x in response.json()])

        self.lg.info('Delete nonexisting device, should fail with 404')
        response = self.storagepool_api.delete_storagepools_storagepoolname_devices_deviceid(self.nodeid, storagepool['name'], 'fake_device')
        self.assertEqual(response.status_code, 404)

    def test009_get_storagepool_filessystem(self):
        """ GAT-053
        **Test Scenario:**

        #. Create storagepool (SP0) on node (N0), should succeed.
        #. Create filesystem (FS0) on storagepool (SP0).
        #. Get filesystem (FS0), should succeed with 200.
        #. Get nonexisting filesystem, should fail with 404.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create filesystem (FS0) on storagepool (SP0)')
        filesystem = self.create_filesystem(storagepool['name'])

        self.lg.info('Get filesystem (FS0), should succeed with 200')
        response = self.storagepool_api.get_storagepools_storagepoolname_filesystems_filesystemname(self.nodeid, storagepool['name'], filesystem['name'])
        self.assertEqual(response.status_code, 200)
        for key in filesystem.keys():
            self.assertEqual(response.json()[key], filesystem[key])

        self.lg.info('Get nonexisting filesystem, should fail with 404')
        response = self.storagepool_api.get_storagepools_storagepoolname_filesystems_filesystemname(self.nodeid, storagepool['name'], 'fake_filesystem')
        self.assertEqual(response.status_code, 404)

    def test010_list_storagepool_filesystems(self):
        """ GAT-054
        **Test Scenario:**

        #. Create Storagepool (SP0) on node (N0).
        #. Create filesystem (FS0) on storagepool (SP0).
        #. list storagepools (SP0) filesystems, filesystem (FS0) should be listed.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create filesystem (FS0) on storagepool (SP0)')
        filesystem = self.create_filesystem(storagepool['name'])

        self.lg.info('list storagepools (SP0) filesystems, filesystem (FS0) should be listed')
        response = self.storagepool_api.get_storagepools_storagepoolname_filesystems(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        self.assertIn(filesystem['name'], response.json())

    def test011_post_storagepool_filesystem(self):
        """ GAT-055
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create storagepool (SP0) on node (N0).
        #. Create filesystem (FS1) on storagepool (SP0), should succeed with 201.
        #. Get filesystem (FS1), should succeed with 200.
        #. Delete filesystem (FS1), should succeed with 204.
        #. Create invalid filesystem (missing required params), should fail with 400.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()
        
        self.lg.info('Create filesystem (FS1) on storagepool (SP0), should succeed with 201')
        name = self.random_string()
        quota = random.randint(0, 10)
        body = {"name":name, "quota":quota}
        response = self.storagepool_api.post_storagepools_storagepoolname_filesystems(self.nodeid, storagepool['name'], body)
        self.assertEqual(response.status_code, 201)
        time.sleep(5)

        self.lg.info('Get filesystem (FS1), should succeed with 200')
        response = self.storagepool_api.get_storagepools_storagepoolname_filesystems_filesystemname(self.nodeid, storagepool['name'], name)
        self.assertEqual(response.status_code, 200)
        for key in body.keys():
            self.assertEqual(response.json()[key], body[key])

        self.lg.info('Delete filesystem (FS1), should succeed with 204')
        response = self.storagepool_api.delete_storagepools_storagepoolname_filesystems_filesystemname(self.nodeid, storagepool['name'], name)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Create filesystem with invalid body, should fail with 400')
        body = {self.random_string() : self.random_string()}
        response = self.storagepool_api.post_storagepools_storagepoolname_filesystems(self.nodeid, storagepool['name'], body)
        self.assertEqual(response.status_code, 400)

    def test012_delete_storagepool_filesystem(self):
        """ GAT-056
        **Test Scenario:**

        #. Create Storagepool (SP0) on node (N0).
        #. Create filesystem (FS0) on storagepool (SP0).
        #. Delete filesystem (FS0), should succeed with 204.
        #. list storagepool (SP0) filesystems, filesystem (FS0) should be gone.
        #. Delete nonexisting filesystems, should fail with 404.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create filesystem (FS0) on storagepool (SP0)')
        filesystem = self.create_filesystem(storagepool['name'])

        self.lg.info('Delete filesystem (FS0), should succeed with 204')
        response = self.storagepool_api.delete_storagepools_storagepoolname_filesystems_filesystemname(self.nodeid, storagepool['name'], filesystem['name'])
        self.assertEqual(response.status_code, 204)

        self.lg.info('list storagepool (SP0) filesystems, filesystem (FS0) should be gone')
        response = self.storagepool_api.get_storagepools_storagepoolname_filesystems(self.nodeid, storagepool['name'])
        self.assertEqual(response.status_code, 200)
        self.assertNotIn(filesystem['name'], response.json())

        self.lg.info('Delete nonexisting filesystems, should fail with 404')
        response = self.storagepool_api.delete_storagepools_storagepoolname_filesystems_filesystemname(self.nodeid, storagepool['name'], 'fake_filesystem')
        self.assertEqual(response.status_code, 404)

    # @unittest.skip('https://github.com/zero-os/0-orchestrator/issues/687')
    def test013_get_storagepool_filessystem_snapshot(self):
        """ GAT-057
        **Test Scenario:**

        #. Create storagepool (SP0) on node (N0), should succeed.
        #. Create filesystem (FS0) on storagepool (SP0).
        #. Create snapshot (SS0) on filesystem (FS0).
        #. Get snapshot (SS0), should succeed with 200.
        #. Get nonexisting snapshot, should fail with 404.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create filesystem (FS0) on storagepool (SP0)')
        filesystem = self.create_filesystem(storagepool['name'])

        self.lg.info('Create snapshot (SS0) on filesystem (FS0)')
        snapshot = self.create_snapshot(storagepool['name'], filesystem['name'])


        self.lg.info('Get snapshot (SS0), should succeed with 200')
        response = self.storagepool_api.get_filesystem_snapshots_snapshotname(self.nodeid, storagepool['name'],
                                                                                           filesystem['name'],
                                                                                           snapshot['name'])
        self.assertEqual(response.status_code, 200)
        for key in snapshot.keys():
            self.assertEqual(response.json()[key], snapshot[key])

        self.lg.info('Get nonexisting snapshot, should fail with 404')
        response = self.storagepool_api.get_filesystem_snapshots_snapshotname(self.nodeid, storagepool['name'],
                                                                                           filesystem['name'],
                                                                                           'fake_snapshot')
        self.assertEqual(response.status_code, 404)

    # @unittest.skip('https://github.com/zero-os/0-orchestrator/issues/687')
    def test014_list_storagepool_filesystems_snapshots(self):
        """ GAT-058
        **Test Scenario:**

        #. Create storagepool (SP0) on node (N0), should succeed.
        #. Create filesystem (FS0) on storagepool (SP0).
        #. Create snapshot (SS0) on filesystem (FS0).
        #. list snapshots of filesystems (FS0), snapshot (SS0) should be listed.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create filesystem (FS0) on storagepool (SP0)')
        filesystem = self.create_filesystem(storagepool['name'])

        self.lg.info('Create snapshot (SS0) on filesystem (FS0)')
        snapshot = self.create_snapshot(storagepool['name'], filesystem['name'])
        
        self.lg.info('list snapshots of filesystems (FS0), snapshot (SS0) should be listed')
        response = self.storagepool_api.get_filesystem_snapshots(self.nodeid, storagepool['name'], filesystem['name'])
        self.assertEqual(response.status_code, 200)
        self.assertIn(snapshot['name'], response.json())

    # @unittest.skip('https://github.com/zero-os/0-orchestrator/issues/687')
    def test015_post_storagepool_filesystem_snapshot(self):
        """ GAT-059
        **Test Scenario:**

        #. Create storagepool (SP0) on node (N0), should succeed.
        #. Create filesystem (FS0) on storagepool (SP0).
        #. Create snapshot (SS1) on filesystem (FS0).
        #. Get snapshot (SS1), should succeed with 200.
        #. Delete snapshot (SS1), should succeed with 204.
        #. Create snapshot with missing required params, should fail with 400.
        """
        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create filesystem (FS0) on storagepool (SP0)')
        filesystem = self.create_filesystem(storagepool['name'])

        self.lg.info('Create snapshot (SS1) on filesystem (FS0)')
        name = self.random_string()
        body = {"name":name}
        response = self.storagepool_api.post_filesystems_snapshots(self.nodeid, storagepool['name'], filesystem['name'], body)
        self.assertEqual(response.status_code, 201)

        self.lg.info(' Get snapshot (SS1), should succeed with 200')
        response = self.storagepool_api.get_filesystem_snapshots_snapshotname(self.nodeid, storagepool['name'],
                                                                                           filesystem['name'],
                                                                                           name)
        self.assertEqual(response.status_code, 200)
        for key in body.keys():
            self.assertEqual(response.json()[key], body[key])

        self.lg.info('Delete snapshot (SS1), should succeed with 204')
        response = self.storagepool_api.delete_filesystem_snapshots_snapshotname(self.nodeid, storagepool['name'],
                                                                                              filesystem['name'],
                                                                                              name)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Create snapshot with missing required params, should fail with 400')
        body = {}
        response = self.storagepool_api.post_filesystems_snapshots(self.nodeid, storagepool['name'], filesystem['name'], body)
        self.assertEqual(response.status_code, 400)

    # @unittest.skip('https://github.com/zero-os/0-orchestrator/issues/687')
    def test016_delete_storagepool_filesystem_snapshot(self):
        """ GAT-060
        **Test Scenario:**

        #. Get random nodid (N0), should succeed.
        #. Create storagepool (SP0) on node (N0), should succeed.
        #. Create filesystem (FS0) on storagepool (SP0).
        #. Create snapshot (SS0) on filesystem (FS0).
        #. Delete  snapshot (SS0), should succeed with 204.
        #. list filesystem (FS0) snapshots, snapshot (SS0) should be gone.
        #. Delete nonexisting snapshot, should fail with 404.
        """

        self.lg.info('Create storagepool (SP0) on node (N0), should succeed')
        storagepool = self.create_storagepool()

        self.lg.info('Create filesystem (FS0) on storagepool (SP0)')
        filesystem = self.create_filesystem(storagepool['name'])

        self.lg.info('Create snapshot (SS0) on filesystem (FS0)')
        snapshot = self.create_snapshot(storagepool['name'], filesystem['name'])

        self.lg.info('Delete  snapshot (SS0), should succeed with 204')
        response = self.storagepool_api.delete_filesystem_snapshots_snapshotname(self.nodeid, storagepool['name'],
                                                                                              filesystem['name'],
                                                                                              snapshot['name'])
        self.assertEqual(response.status_code, 204)

        self.lg.info('list filesystem (FS0) snapshots, snapshot (SS0) should be gone')
        response = self.storagepool_api.get_filesystem_snapshots(self.nodeid, storagepool['name'], filesystem['name'])
        self.assertEqual(response.status_code, 200)
        self.assertNotIn(snapshot['name'], response.json())

        self.lg.info('Delete nonexisting snapshot, should fail with 404')
        response = self.storagepool_api.delete_filesystem_snapshots_snapshotname(self.nodeid, storagepool['name'], filesystem['name'], 'fake_filesystem')
        self.assertEqual(response.status_code, 404)
Exemple #2
0
class TestStorageclustersAPI(TestcasesBase):
    def setUp(self):
        super().setUp()
        self.storageclusters_api = Storageclusters()

        self.nodeid = self.get_random_node()
        pyclient_ip = [x['ip'] for x in self.nodes
                       if x['id'] == self.nodeid][0]
        self.jwt = self.nodes_api.jwt
        self.pyclient = Client(pyclient_ip, password=self.jwt)

        if self._testMethodName != 'test003_deploy_new_storagecluster':

            self.lg.info('Deploy new storage cluster (SC0)')
            free_disks = self.pyclient.getFreeDisks()
            if free_disks == []:
                self.skipTest('no free disks to create storagecluster')

            self.label = self.rand_str()
            self.servers = randint(1, len(free_disks))
            self.drivetype = 'ssd'

            self.body = {
                "label": self.label,
                "servers": self.servers,
                "driveType": self.drivetype,
                "clusterType": "storage",
                "nodes": [self.nodeid]
            }

            response = self.storageclusters_api.post_storageclusters(self.body)
            self.assertEqual(response.status_code, 201)

            for _ in range(60):
                response = self.storageclusters_api.get_storageclusters_label(
                    self.label)
                if response.status_code == 200:
                    if response.json()['status'] == 'ready':
                        break
                    else:
                        time.sleep(3)
                else:
                    time.sleep(10)
            else:
                self.lg.error(
                    'storagecluster status is not ready after 180 sec')

    def tearDown(self):
        self.lg.info('Kill storage cluster (SC0)')
        if self._testMethodName != 'test003_deploy_new_storagecluster':
            self.storageclusters_api.delete_storageclusters_label(self.label)
        super(TestStorageclustersAPI, self).tearDown()

    def test001_get_storageclusters_label(self):
        """ GAT-041
        **Test Scenario:**
        #. Deploy new storage cluster (SC0)
        #. Get storage cluster (SC0), should succeed with 200
        #. Get nonexisting storage cluster (SC0), should fail with 404
        """
        self.lg.info('Get storage cluster (SC0), should succeed with 200')
        response = self.storageclusters_api.get_storageclusters_label(
            self.label)
        self.assertEqual(response.status_code, 200)
        for key in ['label', 'driveType', 'nodes']:
            self.assertEqual(response.json()[key], self.body[key])
        self.assertNotEqual(response.json()['status'], 'error')

        self.lg.info(
            'Get nonexisting storage cluster (SC0), should fail with 404')
        response = self.storageclusters_api.get_storageclusters_label(
            'fake_label')
        self.assertEqual(response.status_code, 404)

    def test002_list_storageclusters(self):
        """ GAT-042
        **Test Scenario:**
        #. Deploy new storage cluster (SC0)
        #. List storage clusters, should succeed with 200
        """
        self.lg.info('Get storage cluster (SC0), should succeed with 200')
        response = self.storageclusters_api.get_storageclusters()
        self.assertEqual(response.status_code, 200)
        self.assertIn(self.label, response.json())

    def test003_deploy_new_storagecluster(self):
        """ GAT-043
        **Test Scenario:**
        #. Deploy new storage cluster (SC1), should succeed with 201
        #. List storage clusters, (SC1) should be listed
        #. Kill storage cluster (SC0), should succeed with 204
        """
        self.lg.info(
            'Deploy new storage cluster (SC1), should succeed with 201')

        free_disks = self.pyclient.getFreeDisks()
        if free_disks == []:
            self.skipTest('no free disks to create storagecluster')

        label = self.rand_str()
        servers = randint(1, len(free_disks))
        drivetype = 'ssd'
        body = {
            "label": label,
            "servers": servers,
            "driveType": drivetype,
            "clusterType": "storage",
            "nodes": [self.nodeid]
        }

        response = self.storageclusters_api.post_storageclusters(body)
        self.assertEqual(response.status_code, 201)

        for _ in range(60):
            response = self.storageclusters_api.get_storageclusters_label(
                label)
            if response.status_code == 200:
                if response.json()['status'] == 'ready':
                    break
                else:
                    time.sleep(3)
            else:
                time.sleep(10)
        else:
            self.lg.error('storagecluster status is not ready after 180 sec')

        self.lg.info('List storage clusters, (SC1) should be listed')
        response = self.storageclusters_api.get_storageclusters()
        self.assertEqual(response.status_code, 200)
        self.assertIn(label, response.json())

        self.lg.info('Kill storage cluster (SC1), should succeed with 204')
        response = self.storageclusters_api.delete_storageclusters_label(label)
        self.assertEqual(response.status_code, 204)

    def test004_kill_storagecluster_label(self):
        """ GAT-044
        **Test Scenario:**
        #. #. Deploy new storage cluster (SC0)
        #. Kill storage cluster (SC0), should succeed with 204
        #. List storage clusters, (SC0) should be gone
        #. Kill nonexisting storage cluster, should fail with 404
        """
        self.lg.info('Kill storage cluster (SC0), should succeed with 204')
        response = self.storageclusters_api.delete_storageclusters_label(
            self.label)
        self.assertEqual(response.status_code, 204)

        self.lg.info('List storage clusters, (SC0) should be gone')
        response = self.storageclusters_api.get_storageclusters()
        self.assertEqual(response.status_code, 200)
        self.assertNotIn(self.label, response.json())

        self.lg.info('Kill nonexisting storage cluster, should fail with 404')
        response = self.storageclusters_api.delete_storageclusters_label(
            'fake_label')
        self.assertEqual(response.status_code, 404)
Exemple #3
0
class TestVdisks(TestcasesBase):

    def setUp(self):
        super().setUp()
        self.vdisks_apis = VDisksAPIs()
        self.storageclusters_api = Storageclusters()

        node = self.get_random_node()
        pyclient_ip = [x['ip'] for x in self.nodes if x['id'] == node][0]
        self.jwt = self.nodes_api.jwt
        self.pyclient = Client(pyclient_ip, password=self.jwt)

        free_disks = self.pyclient.getFreeDisks()
        if free_disks == []:
            self.skipTest('no free disks to create storagecluster')

        storageclusters = self.storageclusters_api.get_storageclusters()
        if storageclusters.json() == []:
            self.lg.info('Deploy new storage cluster (SC0)')
            sc_label = self.rand_str()
            sc_servers = random.randint(1, len(free_disks))
            sc_drivetype = 'ssd'
            sc_nodes = [node]
            sc_body = {"label": sc_label,
                        "servers": sc_servers,
                        "driveType": sc_drivetype,
                        "clusterType": "storage",
                        "nodes":sc_nodes}

            response = self.storageclusters_api.post_storageclusters(sc_body)
            self.assertEqual(response.status_code, 201)

            for _ in range(60):
                response = self.storageclusters_api.get_storageclusters_label(sc_label)
                if response.status_code == 200:
                    if response.json()['status'] == 'ready':
                        break
                    else:
                        time.sleep(3)
                else:
                    time.sleep(10)
            else:
                self.lg.error('storagecluster status is not ready after 180 sec')

        else:
            sc_label = storageclusters.json()[0]

        self.lg.info('Create vdisk (VD0)')
        self.vd_creation_time = time.time()
        self.vdisk_id = self.rand_str()
        self.size = random.randint(1, 50)
        self.types = ['boot','db','cache','tmp']
        self.type = random.choice(self.types)
        self.block_size = random.randint(1, self.size)*512
        self.storagecluster = sc_label
        self.readOnly = random.choice([False, True])

        self.body = {"id": self.vdisk_id,
                     "size": self.size,
                     "blocksize": self.block_size,
                     "type": self.type,
                     "storagecluster": self.storagecluster,
                     "readOnly":self.readOnly}

        response = self.vdisks_apis.post_vdisks(self.body)
        self.assertEqual(response.status_code, 201) 

    def tearDown(self):
        self.lg.info('Delete vdisk (VD0)')
        self.vdisks_apis.delete_vdisks_vdiskid(self.vdisk_id)
        super(TestVdisks, self).tearDown()

    def test001_get_vdisk_details(self):
        """ GAT-061
        *GET:/vdisks/{vdiskid}*

        **Test Scenario:**

        #. Create vdisk (VD0).
        #. Get vdisk (VD0), should succeed with 200.
        #. Get nonexisting vdisk, should fail with 404.

        """
        self.lg.info('Get vdisk (VD0), should succeed with 200')
        response = self.vdisks_apis.get_vdisks_vdiskid(self.vdisk_id)
        self.assertEqual(response.status_code, 200)
        for key in self.body.keys():
            if not self.readOnly and key == "readOnly":
                continue
            self.assertEqual(self.body[key], response.json()[key])
        self.assertEqual(response.json()['status'], 'halted')

        self.lg.info('Get nonexisting vdisk, should fail with 404')
        response = self.vdisks_apis.get_vdisks_vdiskid('fake_vdisk')
        self.assertEqual(response.status_code, 404)

    def test002_list_vdisks(self):
        """ GAT-062
        *GET:/vdisks*

        **Test Scenario:**

        #. Create vdisk (VD0).
        #. List vdisks, should succeed with 200.

        """
        self.lg.info('List vdisks, should succeed with 200')
        response = self.vdisks_apis.get_vdisks()
        self.assertEqual(response.status_code, 200)
        vd0_data = {"id": self.vdisk_id,
                    "storageCluster": self.storagecluster,
                    "type": self.type}
        self.assertIn(vd0_data, response.json())

    def test003_create_vdisk(self):
        """ GAT-063
        *POST:/vdisks*

        **Test Scenario:**

        #. Create vdisk (VD1). should succeed with 201.
        #. List vdisks, (VD1) should be listed.
        #. Delete vdisk (VD0), should succeed with 204.
        #. Create vdisk with invalid body, should fail with 400.
        """
        self.lg.info('Create vdisk (VD1). should succeed with 201')
        vdisk_id = self.rand_str()
        size = random.randint(1, 50)
        vdisk_type = random.choice(self.types)
        block_size = random.randint(1, self.size)*512
        readOnly = random.choice([False, True])

        body = {"id": vdisk_id,
                "size": size,
                "blocksize": block_size,
                "type": vdisk_type,
                "storagecluster": self.storagecluster,
                "readOnly":readOnly}

        response = self.vdisks_apis.post_vdisks(body)
        self.assertEqual(response.status_code, 201)

        self.lg.info('List vdisks, (VD1) should be listed')
        response = self.vdisks_apis.get_vdisks()
        self.assertEqual(response.status_code, 200)
        self.assertIn(vdisk_id, [x['id'] for x in response.json()])

        self.lg.info('Delete vdisk (VD0), should succeed with 204')
        response = self.vdisks_apis.delete_vdisks_vdiskid(self.vdisk_id)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Create vdisk with invalid body, should fail with 400')
        body = {"id":self.rand_str()}
        response = self.vdisks_apis.post_vdisks(body)
        self.assertEqual(response.status_code, 400)


    def test004_delete_vdisk(self):
        """ GAT-064
        *Delete:/vdisks/{vdiskid}*

        **Test Scenario:**

        #. Create vdisk (VD0).
        #. Delete vdisk (VD0), should succeed with 204.
        #. List vdisks, (VD0) should be gone.
        #. Delete nonexisting vdisk, should fail with 404.
        """
        self.lg.info('Delete vdisk (VD0), should succeed with 204')
        response = self.vdisks_apis.delete_vdisks_vdiskid(self.vdisk_id)
        self.assertEqual(response.status_code, 204)

        self.lg.info('List vdisks, (VD0) should be gone')
        response = self.vdisks_apis.get_vdisks()
        self.assertEqual(response.status_code, 200)
        self.assertNotIn(self.vdisk_id, [x['id'] for x in response.json()])

        self.lg.info('Delete nonexisting vdisk, should fail with 404')
        response = self.vdisks_apis.delete_vdisks_vdiskid('fake_vdisk')
        self.assertEqual(response.status_code, 404)

    def test005_resize_vdisk(self):
        """ GAT-065
        *POST:/vdisks/{vdiskid}/resize*

        **Test Scenario:**

        #. Create vdisk (VD0).
        #. Resize vdisk (VD0), should succeed with 204.
        #. Check that size of volume changed, should succeed.
        #. Resize vdisk (VD0) with value less than the current vdisk size, should fail with 400.
        #. Check vdisk (VD0) size, shouldn't be changed.

        """
        self.lg.info('Resize vdisk (VD0), should succeed with 204')
        new_size = self.size + random.randint(1,10)
        body = {"newSize": new_size}
        response = self.vdisks_apis.post_vdisks_vdiskid_resize(self.vdisk_id, body)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Check that size of volume changed, should succeed')
        response = self.vdisks_apis.get_vdisks_vdiskid(self.vdisk_id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(new_size, response.json()['size'])
        self.size = new_size

        self.lg.info('Resize vdisk (VD0) with value less than the current vdisk size, should fail with 400')
        new_size = self.size - random.randint(1, self.size-1)
        body = {"newSize": new_size}
        response = self.vdisks_apis.post_vdisks_vdiskid_resize(self.vdisk_id, body)
        self.assertEqual(response.status_code, 400)

        self.lg.info('Check vdisk (VD0) size, shouldn\'t be changed')
        response = self.vdisks_apis.get_vdisks_vdiskid(self.vdisk_id)
        self.assertEqual(response.status_code, 200)
        self.assertNotEqual(new_size, response.json()['size'])


    @unittest.skip('Not implemented')
    def test006_Rollback_vdisk(self):
        """ GAT-066
        *POST:/vdisks/{vdiskid}/rollback*

        **Test Scenario:**

        #. Create vdisk (VD0), should succeed.
        #. Resize vdisk (VD0), should succeed.
        #. Check that size of vdisk (VD0) changed, should succeed.
        #. Rollback vdisk (VD0), should succeed.
        #. Check that vdisk (VD0) size is changed to the initial size, should succeed.
        """

        self.lg.info(' Resize  created volume.')
        new_size = self.size + random.randint(1, 10)
        body = {"newSize": new_size}
        response = self.vdisks_apis.post_volumes_volumeid_resize(self.vdisk_id, body)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Check that size of volume changed, should succeed')
        response = self.vdisks_apis.get_vdisks_vdiskid(self.vdisk_id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(new_size, response.json()['size'])

        self.lg.info('Rollback vdisk (VD0), should succeed')
        body = {"epoch": self.vd_creation_time}
        response = self.vdisks_apis.post_vdisks_vdiskid_rollback(self.vdisk_id, body)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Check that vdisk (VD0) size is changed to the initial size, should succeed')
        response = self.vdisks_apis.get_vdisks_vdiskid(self.vdisk_id)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(self.size, response.json()['size'])
Exemple #4
0
class TestVmsAPI(TestcasesBase):
    def setUp(self):
        super().setUp()
        self.vms_api = VmsAPI()
        self.storageclusters_api = Storageclusters()
        self.vdisks_apis = VDisksAPIs()
        self.lg.info('Get random nodid (N0)')
        self.nodeid = self.get_random_node()
        nodeip = [x['ip'] for x in self.nodes if x['id'] == self.nodeid][0]
        self.jwt = self.nodes_api.jwt
        self.pyclient = Client(nodeip, password=self.jwt)

        storageclusters = self.storageclusters_api.get_storageclusters()
        if storageclusters.json() == []:
            self.storagecluster = self.create_sotragecluster()['label']
        else:
            self.storagecluster = storageclusters.json()[0]

        vdisks = self.vdisks_apis.get_vdisks()
        vdisks = [
            x for x in vdisks.json()
            if (x['id'] == 'ubuntu-test-vdisk'
                and x['storageCluster'] == self.storagecluster)
        ]
        if vdisks == []:
            self.vdisk = self.create_boot_vdisk(self.storagecluster)
        else:
            self.vdisk = vdisks[0]

    def tearDown(self):
        self.lg.info('Delete virtual machine (VM0)')
        response = self.vms_api.get_nodes_vms(self.nodeid)
        if response.status_code == 200:
            vms = response.json()
            for vm in vms:
                self.vms_api.delete_nodes_vms_vmid(self.nodeid, vm['id'])

        super(TestVmsAPI, self).tearDown()

    def create_sotragecluster(self):
        free_disks = self.pyclient.getFreeDisks()
        if free_disks == []:
            self.skipTest('no free disks to create storagecluster')

        self.lg.info('Deploy new storage cluster (SC0)')
        label = self.rand_str()
        servers = random.randint(1, len(free_disks))
        drivetype = 'ssd'
        nodes = [self.nodeid]
        body = {
            "label": label,
            "servers": servers,
            "driveType": drivetype,
            "clusterType": "storage",
            "nodes": nodes
        }

        response = self.storageclusters_api.post_storageclusters(body)
        self.assertEqual(response.status_code, 201)

        for _ in range(60):
            response = self.storageclusters_api.get_storageclusters_label(
                label)
            if response.status_code == 200:
                if response.json()['status'] == 'ready':
                    break
                else:
                    time.sleep(3)
            else:
                time.sleep(10)
        else:
            self.lg.error('storagecluster status is not ready after 180 sec')

        return body

    def create_boot_vdisk(self, storagecluster):
        body = {
            "id": 'ubuntu-test-vdisk',
            "size": 15,
            "blocksize": 4096,
            "type": 'boot',
            "storagecluster": storagecluster,
            "templatevdisk": "ardb://hub.gig.tech:16379/template:ubuntu-1604"
        }

        response = self.vdisks_apis.post_vdisks(body)
        self.assertEqual(response.status_code, 201)
        return body

    def create_vm(self):
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vmid = self.random_string()
        mem = 1024
        cpu = 1
        nics = []
        disks = [{"vdiskid": "ubuntu-test-vdisk", "maxIOps": 2000}]
        userCloudInit = {}
        systemCloudInit = {}

        body = {
            "id": vmid,
            "memory": mem,
            "cpu": cpu,
            "nics": nics,
            "disks": disks,
            "userCloudInit": userCloudInit,
            "systemCloudInit": systemCloudInit
        }

        response = self.vms_api.post_nodes_vms(self.nodeid, body)
        self.assertEqual(response.status_code, 201)

        for _ in range(60):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vmid)
            if response.status_code == 200:
                if response.json()['status'] == 'running':
                    break
                else:
                    time.sleep(3)
            else:
                time.sleep(10)
        else:
            self.lg.error('vm status is not running after 180 sec')

        return body

    def test001_get_nodes_vms_vmid(self):
        """ GAT-067
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Get virtual machine (VM0), should succeed with 200.
        #. Get nonexisting virtual machine, should fail with 404.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Get virtual machine (VM0), should succeed with 200')
        response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 200)
        keys_to_check = ['id', 'memory', 'cpu', 'nics', 'disks']
        for key in keys_to_check:
            self.assertEqual(vm[key], response.json()[key])
        self.assertEqual(response.json()['status'], 'running')

        vms_list = self.pyclient.client.kvm.list()
        self.assertIn(vm['id'], [x['name'] for x in vms_list])

        self.lg.info('Get nonexisting virtual machine, should fail with 404')
        response = self.vms_api.get_nodes_vms_vmid(self.nodeid, 'fake_vm')
        self.assertEqual(response.status_code, 404)

    def test002_get_node_vms(self):
        """ GAT-068
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. List node (N0) virtual machines, virtual machine (VM0) should be listed, should succeed with 200.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info(
            'List node (N0) virtual machines, virtual machine (VM0) should be listed, should succeed with 200'
        )
        response = self.vms_api.get_nodes_vms(self.nodeid)
        self.assertEqual(response.status_code, 200)
        self.assertIn(vm['id'], [x['id'] for x in response.json()])

    def test003_post_node_vms(self):
        """ GAT-069
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM1) on node (N0).
        #. Get virtual machine (VM1), should succeed with 200.
        #. List kvms in python client, (VM1) should be listed.
        #. Delete virtual machine (VM1), should succeed with 204.
        #. Create virtual machine with missing parameters, should fail with 400.
        """
        self.lg.info('Create virtual machine (VM1) on node (N0)')
        vm_id = self.random_string()
        vm_mem = random.randint(1, 16) * 1024
        vm_cpu = random.randint(1, 16)
        vm_nics = []
        vm_disks = [{"vdiskid": "ubuntu-test-vdisk", "maxIOps": 2000}]
        vm_userCloudInit = {}
        vm_systemCloudInit = {}

        body = {
            "id": vm_id,
            "memory": vm_mem,
            "cpu": vm_cpu,
            "nics": vm_nics,
            "disks": vm_disks,
            "userCloudInit": vm_userCloudInit,
            "systemCloudInit": vm_systemCloudInit
        }

        response = self.vms_api.post_nodes_vms(self.nodeid, body)
        self.assertEqual(response.status_code, 201)
        time.sleep(20)

        response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm_id)
        self.assertEqual(response.status_code, 200)

        if response.json()['status'] == 'error':
            vm_id = self.rand_str()
            body['id'] = vm_id
            body['memory'] = 1024
            body['cpu'] = 1
            response = self.vms_api.post_nodes_vms(self.nodeid, body)
            self.assertEqual(response.status_code, 201)

        self.lg.info('Get virtual machine (VM1), should succeed with 200')
        response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm_id)
        self.assertEqual(response.status_code, 200)
        keys_to_check = ['id', 'memory', 'cpu', 'nics', 'disks']
        for key in keys_to_check:
            self.assertEqual(body[key], response.json()[key])
        self.assertEqual(response.json()['status'], 'deploying')

        for _ in range(60):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm_id)
            if response.status_code == 200:
                if response.json()['status'] == 'running':
                    break
                else:
                    time.sleep(3)
            else:
                time.sleep(10)
        else:
            raise AssertionError('{} != {}'.format(response.json()['status'],
                                                   'running'))

        self.lg.info('List kvms in python client, (VM1) should be listed')
        vms = self.pyclient.client.kvm.list()
        self.assertIn(vm_id, [x['name'] for x in vms])

        self.lg.info('Delete virtual machine (VM1), should succeed with 204')
        response = self.vms_api.delete_nodes_vms_vmid(self.nodeid, vm_id)
        self.assertEqual(response.status_code, 204)

        self.lg.info(
            'Create virtual machine with missing parameters, should fail with 400'
        )
        body = {"id": self.random_string()}
        response = self.vms_api.post_nodes_vms(self.nodeid, body)
        self.assertEqual(response.status_code, 400)

    # @unittest.skip('https://github.com/g8os/resourcepool/issues/126')
    def test004_put_nodes_vms_vmid(self):
        """ GAT-070
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Update virtual machine (VM1), should succeed with 201.
        #. Get virtual machine (VM1), should succeed with 200.
        #. Update virtual machine with missing parameters, should fail with 400.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm_mem = 2 * 1024
        vm_cpu = 2
        vm_nics = []
        vm_disks = [{"vdiskid": "ubuntu-test-vdisk", "maxIOps": 2000}]
        body = {
            "memory": vm_mem,
            "cpu": vm_cpu,
            "nics": vm_nics,
            "disks": vm_disks
        }

        self.lg.info('Stop virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_stop(self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)

        self.lg.info(
            'Get virtual machine (VM0), virtual machine (VM0) status should be halting'
        )
        for _ in range(20):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status == 'halted':
                break
            else:
                time.sleep(3)
        else:
            self.lg.error('can\'t stop vm')

        response = self.vms_api.put_nodes_vms_vmid(self.nodeid, vm['id'], body)
        self.assertEqual(response.status_code, 204)

        self.lg.info('Start virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_start(
            self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)
        for _ in range(20):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status == 'running':
                break
            else:
                time.sleep(3)
        else:
            self.lg.error('can\'t start vm')

        self.lg.info('Get virtual machine (VM0), should succeed with 200')
        response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 200)

        keys_to_check = ['memory', 'cpu', 'nics', 'disks']
        for key in keys_to_check:
            self.assertEqual(body[key], response.json()[key])
        self.assertEqual(response.json()['status'], 'running')

        self.lg.info(
            'Update virtual machine with missing parameters, should fail with 400'
        )
        body = {"id": self.random_string()}
        response = self.vms_api.put_nodes_vms_vmid(self.nodeid, vm['id'], body)
        self.assertEqual(response.status_code, 400)

    def test005_get_nodes_vms_vmid_info(self):
        """ GAT-071
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Get virtual machine (VM0) info, should succeed with 200.
        #. Get nonexisting virtual machine info, should fail with 404.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Get virtual machine (VM0) info, should succeed with 200')
        response = self.vms_api.get_nodes_vms_vmid_info(self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 200)

        self.lg.info(
            'Get nonexisting virtual machine info, should fail with 404')
        response = self.vms_api.get_nodes_vms_vmid_info(self.nodeid, 'fake_vm')

    def test006_delete_nodes_vms_vmid(self):
        """ GAT-072
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Delete virtual machine (VM0), should succeed with 204.
        #. List kvms in python client, (VM0) should be gone.
        #. Delete nonexisting virtual machine, should fail with 404.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Delete virtual machine (VM0), should succeed with 204')
        response = self.vms_api.delete_nodes_vms_vmid(self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)

        self.lg.info('List kvms in python client, (VM0) should be gone')
        vms = self.pyclient.client.kvm.list()
        self.assertNotIn(vm['id'], [x['name'] for x in vms])

        self.lg.info(
            'Delete nonexisting virtual machine, should fail with 404')
        response = self.vms_api.delete_nodes_vms_vmid(self.nodeid,
                                                      'fake_vm_id')
        self.assertEqual(response.status_code, 404)

    def test007_post_nodes_vms_vmid_start(self):
        """ GAT-073
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Stop virtual machine (VM0), should succeed with 204.
        #. Start virtual machine (VM0), should succeed with 204.
        #. Get virtual machine (VM0), virtual machine (VM0) status should be running.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Stop virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_stop(self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)
        for _ in range(20):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status == 'halted':
                break
            else:
                time.sleep(3)
        else:
            raise AssertionError('{} is not {}'.format(status, 'halted'))

        vms = self.pyclient.client.kvm.list()
        vm0 = [x for x in vms if x['name'] == vm['id']]
        self.assertEqual(vm0, [])

        self.lg.info('Start virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_start(
            self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)
        for _ in range(20):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status == 'running':
                break
            else:
                time.sleep(3)
        else:
            raise AssertionError('{} is not {}'.format(status, 'running'))

        vms = self.pyclient.client.kvm.list()
        vm0 = [x for x in vms if x['name'] == vm['id']]
        self.assertNotEqual(vm0, [])
        self.assertEquals(vm0[0]['state'], 'running')

    def test008_post_nodes_vms_vmid_stop(self):
        """ GAT-074
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Stop virtual machine (VM0), should succeed with 204.
        #. Get virtual machine (VM0), virtual machine (VM0) status should be halting.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Stop virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_stop(self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)

        self.lg.info(
            'Get virtual machine (VM0), virtual machine (VM0) status should be halting'
        )
        for _ in range(20):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status == 'halted':
                break
            else:
                time.sleep(3)
        else:
            raise AssertionError('{} != {}'.format(status, 'halted'))

        vms = self.pyclient.client.kvm.list()
        vm0 = [x for x in vms if x['name'] == vm['id']]
        self.assertEqual(vm0, [])

    def test009_post_nodes_vms_vmid_pause_resume(self):
        """ GAT-075
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Pause virtual machine (VM0), should succeed with 204.
        #. Get virtual machine (VM0), virtual machine (VM0) status should be paused.
        #. Resume virtual machine (VM0), should succeed with 204.
        #. Get virtual machine (VM0), virtual machine (VM0) status should be running
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Pause virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_pause(
            self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)

        self.lg.info(
            'Get virtual machine (VM0), virtual machine (VM0) status should be halting'
        )
        for _ in range(15):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status == 'paused':
                break
            else:
                time.sleep(1)
        else:
            raise AssertionError('{} != {}'.format(status, 'paused'))

        vms = self.pyclient.client.kvm.list()
        vm0 = [x for x in vms if x['name'] == vm['id']]
        self.assertNotEqual(vm0, [])
        self.assertEquals(vm0[0]['state'], 'paused')

        self.lg.info('Resume virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_resume(
            self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)

        self.lg.info(
            'Get virtual machine (VM0), virtual machine (VM0) status should be running'
        )
        for _ in range(15):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status == 'running':
                break
            else:
                time.sleep(1)
        else:
            raise AssertionError('{} != {}'.format(status, 'paused'))

        vms = self.pyclient.client.kvm.list()
        vm0 = [x for x in vms if x['name'] == vm['id']]
        self.assertNotEqual(vm0, [])
        self.assertEquals(vm0[0]['state'], 'running')

    @unittest.skip('https://github.com/g8os/resourcepool/issues/128')
    def test010_post_nodes_vms_vmid_shutdown(self):
        """ GAT-076
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Shutdown virtual machine (VM0), should succeed with 204.
        #. Get virtual machine (VM0), virtual machine (VM0) status should be halted.
        """
        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info('Shutdown virtual machine (VM0), should succeed with 204')
        response = self.vms_api.post_nodes_vms_vmid_shutdown(
            self.nodeid, vm['id'])
        self.assertEqual(response.status_code, 204)
        for _ in range(15):
            response = self.vms_api.get_nodes_vms_vmid(self.nodeid, vm['id'])
            self.assertEqual(response.status_code, 200)
            status = response.json()['status']
            if status in ['halting', 'halted']:
                break
            else:
                time.sleep(1)
        else:
            raise AssertionError('{} not {}'.format(status,
                                                    'halting or halted'))

        vms = self.pyclient.client.kvm.list()
        vm0 = [x for x in vms if x['name'] == vm['id']]
        self.assertEqual(vm0, [])

    @unittest.skip('https://github.com/g8os/resourcepool/issues/215')
    def test011_post_nodes_vms_vmid_migrate(self):
        """ GAT-077
        **Test Scenario:**

        #. Get random nodid (N0).
        #. Create virtual machine (VM0) on node (N0).
        #. Migrate virtual machine (VM0) to another node, should succeed with 204.
        #. Get virtual machine (VM0), virtual machine (VM0) status should be migrating.
        """
        if len(self.nodes) < 2:
            self.skipTest('need at least 2 nodes')

        self.lg.info('Create virtual machine (VM0) on node (N0)')
        vm = self.create_vm()

        self.lg.info(
            'Migrate virtual machine (VM0) to another node, should succeed with 204'
        )
        node_2 = self.get_random_node(except_node=self.nodeid)
        body = {"nodeid": node_2}
        response = self.vms_api.post_nodes_vms_vmid_migrate(
            self.nodeid, vm['id'], body)
        self.assertEqual(response.status_code, 204)

        time.sleep(30)

        response = self.vms_api.get_nodes_vms_vmid(node_2, vm['id'])
        self.assertEqual(response.status_code, 200)

        pyclient_ip = [x['ip'] for x in self.nodes if x['id'] == node_2]
        self.assertNotEqual(pyclient_ip, [])
        pyclient = Client(pyclient_ip)
        vms = pyclient.client.kvm.list()
        self.assertIn(vm['id'], [x['name'] for x in vms])