mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Previously the jsonHelper would incorrectly deserialize the json response if the object returned had an attribute of the same name resulting in an additional level of indirection to refer to the entity's attributes. eg: account.account.name instead of account.name This fixes the tests that have still the same indirection exposed. Signed-off-by: Prasanna Santhanam <tsp@apache.org>
1042 lines
40 KiB
Python
1042 lines
40 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
""" BVT tests for Virtual Machine Life Cycle
|
|
"""
|
|
#Import Local Modules
|
|
import marvin
|
|
from marvin.cloudstackTestCase import *
|
|
from marvin.cloudstackAPI import *
|
|
from marvin.integration.lib.utils import *
|
|
from marvin.integration.lib.base import *
|
|
from marvin.integration.lib.common import *
|
|
from nose.plugins.attrib import attr
|
|
#Import System modules
|
|
import time
|
|
|
|
_multiprocess_shared_ = True
|
|
class Services:
|
|
"""Test VM Life Cycle Services
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.services = {
|
|
"disk_offering":{
|
|
"displaytext": "Small",
|
|
"name": "Small",
|
|
"disksize": 1
|
|
},
|
|
"account": {
|
|
"email": "test@test.com",
|
|
"firstname": "Test",
|
|
"lastname": "User",
|
|
"username": "test",
|
|
# Random characters are appended in create account to
|
|
# ensure unique username generated each time
|
|
"password": "password",
|
|
},
|
|
"small":
|
|
# Create a small virtual machine instance with disk offering
|
|
{
|
|
"displayname": "testserver",
|
|
"username": "root", # VM creds for SSH
|
|
"password": "password",
|
|
"ssh_port": 22,
|
|
"hypervisor": 'XenServer',
|
|
"privateport": 22,
|
|
"publicport": 22,
|
|
"protocol": 'TCP',
|
|
},
|
|
"medium": # Create a medium virtual machine instance
|
|
{
|
|
"displayname": "testserver",
|
|
"username": "root",
|
|
"password": "password",
|
|
"ssh_port": 22,
|
|
"hypervisor": 'XenServer',
|
|
"privateport": 22,
|
|
"publicport": 22,
|
|
"protocol": 'TCP',
|
|
},
|
|
"service_offerings":
|
|
{
|
|
"tiny":
|
|
{
|
|
"name": "Tiny Instance",
|
|
"displaytext": "Tiny Instance",
|
|
"cpunumber": 1,
|
|
"cpuspeed": 100, # in MHz
|
|
"memory": 128, # In MBs
|
|
},
|
|
"small":
|
|
{
|
|
# Small service offering ID to for change VM
|
|
# service offering from medium to small
|
|
"name": "Small Instance",
|
|
"displaytext": "Small Instance",
|
|
"cpunumber": 1,
|
|
"cpuspeed": 100,
|
|
"memory": 256,
|
|
},
|
|
"medium":
|
|
{
|
|
# Medium service offering ID to for
|
|
# change VM service offering from small to medium
|
|
"name": "Medium Instance",
|
|
"displaytext": "Medium Instance",
|
|
"cpunumber": 1,
|
|
"cpuspeed": 100,
|
|
"memory": 256,
|
|
}
|
|
},
|
|
"iso": # ISO settings for Attach/Detach ISO tests
|
|
{
|
|
"displaytext": "Test ISO",
|
|
"name": "testISO",
|
|
"url": "http://people.apache.org/~tsp/dummy.iso",
|
|
# Source URL where ISO is located
|
|
"ostype": 'CentOS 5.3 (64-bit)',
|
|
"mode": 'HTTP_DOWNLOAD', # Downloading existing ISO
|
|
},
|
|
"template": {
|
|
"displaytext": "Cent OS Template",
|
|
"name": "Cent OS Template",
|
|
"passwordenabled": True,
|
|
},
|
|
"diskdevice": '/dev/xvdd',
|
|
# Disk device where ISO is attached to instance
|
|
"mount_dir": "/mnt/tmp",
|
|
"sleep": 60,
|
|
"timeout": 10,
|
|
#Migrate VM to hostid
|
|
"ostype": 'CentOS 5.3 (64-bit)',
|
|
# CentOS 5.3 (64-bit)
|
|
}
|
|
|
|
|
|
class TestDeployVM(cloudstackTestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.services = Services().services
|
|
cls.apiclient = super(TestDeployVM, cls).getClsTestClient().getApiClient()
|
|
# Get Zone, Domain and templates
|
|
domain = get_domain(cls.apiclient, cls.services)
|
|
zone = get_zone(cls.apiclient, cls.services)
|
|
cls.services['mode'] = zone.networktype
|
|
|
|
#If local storage is enabled, alter the offerings to use localstorage
|
|
#this step is needed for devcloud
|
|
if zone.localstorageenabled == True:
|
|
cls.services["service_offerings"]["tiny"]["storagetype"] = 'local'
|
|
cls.services["service_offerings"]["small"]["storagetype"] = 'local'
|
|
cls.services["service_offerings"]["medium"]["storagetype"] = 'local'
|
|
|
|
template = get_template(
|
|
cls.apiclient,
|
|
zone.id,
|
|
cls.services["ostype"]
|
|
)
|
|
# Set Zones and disk offerings
|
|
cls.services["small"]["zoneid"] = zone.id
|
|
cls.services["small"]["template"] = template.id
|
|
|
|
cls.services["medium"]["zoneid"] = zone.id
|
|
cls.services["medium"]["template"] = template.id
|
|
cls.services["iso"]["zoneid"] = zone.id
|
|
|
|
cls.account = Account.create(
|
|
cls.apiclient,
|
|
cls.services["account"],
|
|
domainid=domain.id
|
|
)
|
|
|
|
cls.service_offering = ServiceOffering.create(
|
|
cls.apiclient,
|
|
cls.services["service_offerings"]["tiny"]
|
|
)
|
|
|
|
cls.virtual_machine = VirtualMachine.create(
|
|
cls.apiclient,
|
|
cls.services["small"],
|
|
accountid=cls.account.name,
|
|
domainid=cls.account.domainid,
|
|
serviceofferingid=cls.service_offering.id,
|
|
mode=cls.services['mode']
|
|
)
|
|
|
|
cls.cleanup = [
|
|
cls.service_offering,
|
|
cls.account
|
|
]
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
try:
|
|
cleanup_resources(cls.apiclient, cls.cleanup)
|
|
except Exception as e:
|
|
cls.debug("Warning! Exception in tearDown: %s" % e)
|
|
|
|
def setUp(self):
|
|
self.apiclient = self.testClient.getApiClient()
|
|
self.dbclient = self.testClient.getDbConnection()
|
|
|
|
|
|
@attr(tags = ["simulator", "devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_deploy_vm(self):
|
|
"""Test Deploy Virtual Machine
|
|
"""
|
|
# Validate the following:
|
|
# 1. Virtual Machine is accessible via SSH
|
|
# 2. listVirtualMachines returns accurate information
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.virtual_machine.id
|
|
)
|
|
|
|
self.debug(
|
|
"Verify listVirtualMachines response for virtual machine: %s" \
|
|
% self.virtual_machine.id
|
|
)
|
|
self.assertEqual(
|
|
isinstance(list_vm_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
self.assertNotEqual(
|
|
len(list_vm_response),
|
|
0,
|
|
"Check VM available in List Virtual Machines"
|
|
)
|
|
vm_response = list_vm_response[0]
|
|
self.assertEqual(
|
|
|
|
vm_response.id,
|
|
self.virtual_machine.id,
|
|
"Check virtual machine id in listVirtualMachines"
|
|
)
|
|
self.assertEqual(
|
|
vm_response.name,
|
|
self.virtual_machine.name,
|
|
"Check virtual machine name in listVirtualMachines"
|
|
)
|
|
self.assertEqual(
|
|
vm_response.state,
|
|
'Running',
|
|
msg="VM is not in Running state"
|
|
)
|
|
return
|
|
|
|
|
|
@attr(tags = ["simulator", "advanced"])
|
|
def test_advZoneVirtualRouter(self):
|
|
"""
|
|
Test advanced zone virtual router
|
|
1. Is Running
|
|
2. is in the account the VM was deployed in
|
|
3. Has a linklocalip, publicip and a guestip
|
|
@return:
|
|
"""
|
|
routers = list_routers(self.apiclient, account=self.account.name)
|
|
self.assertTrue(len(routers) > 0, msg = "No virtual router found")
|
|
router = routers[0]
|
|
|
|
self.assertEqual(router.state, 'Running', msg="Router is not in running state")
|
|
self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account")
|
|
|
|
#Has linklocal, public and guest ips
|
|
self.assertIsNotNone(router.linklocalip, msg="Router has no linklocal ip")
|
|
self.assertIsNotNone(router.publicip, msg="Router has no public ip")
|
|
self.assertIsNotNone(router.guestipaddress, msg="Router has no guest ip")
|
|
|
|
@attr(hypervisor = ["simulator"])
|
|
@attr(mode = ["basic"])
|
|
def test_basicZoneVirtualRouter(self):
|
|
"""
|
|
Tests for basic zone virtual router
|
|
1. Is Running
|
|
2. is in the account the VM was deployed in
|
|
@return:
|
|
"""
|
|
routers = list_routers(self.apiclient, account=self.account.name)
|
|
self.assertTrue(len(routers) > 0, msg = "No virtual router found")
|
|
router = routers[0]
|
|
|
|
self.assertEqual(router.state, 'Running', msg="Router is not in running state")
|
|
self.assertEqual(router.account, self.account.name, msg="Router does not belong to the account")
|
|
|
|
def tearDown(self):
|
|
pass
|
|
|
|
|
|
class TestVMLifeCycle(cloudstackTestCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.api_client = super(TestVMLifeCycle, cls).getClsTestClient().getApiClient()
|
|
cls.services = Services().services
|
|
|
|
# Get Zone, Domain and templates
|
|
domain = get_domain(cls.api_client, cls.services)
|
|
zone = get_zone(cls.api_client, cls.services)
|
|
cls.services['mode'] = zone.networktype
|
|
|
|
#if local storage is enabled, alter the offerings to use localstorage
|
|
#this step is needed for devcloud
|
|
if zone.localstorageenabled == True:
|
|
cls.services["service_offerings"]["tiny"]["storagetype"] = 'local'
|
|
cls.services["service_offerings"]["small"]["storagetype"] = 'local'
|
|
cls.services["service_offerings"]["medium"]["storagetype"] = 'local'
|
|
|
|
template = get_template(
|
|
cls.api_client,
|
|
zone.id,
|
|
cls.services["ostype"]
|
|
)
|
|
# Set Zones and disk offerings
|
|
cls.services["small"]["zoneid"] = zone.id
|
|
cls.services["small"]["template"] = template.id
|
|
|
|
cls.services["medium"]["zoneid"] = zone.id
|
|
cls.services["medium"]["template"] = template.id
|
|
cls.services["iso"]["zoneid"] = zone.id
|
|
|
|
# Create VMs, NAT Rules etc
|
|
cls.account = Account.create(
|
|
cls.api_client,
|
|
cls.services["account"],
|
|
domainid=domain.id
|
|
)
|
|
|
|
cls.small_offering = ServiceOffering.create(
|
|
cls.api_client,
|
|
cls.services["service_offerings"]["small"]
|
|
)
|
|
|
|
cls.medium_offering = ServiceOffering.create(
|
|
cls.api_client,
|
|
cls.services["service_offerings"]["medium"]
|
|
)
|
|
#create small and large virtual machines
|
|
cls.small_virtual_machine = VirtualMachine.create(
|
|
cls.api_client,
|
|
cls.services["small"],
|
|
accountid=cls.account.name,
|
|
domainid=cls.account.domainid,
|
|
serviceofferingid=cls.small_offering.id,
|
|
mode=cls.services["mode"]
|
|
)
|
|
cls.medium_virtual_machine = VirtualMachine.create(
|
|
cls.api_client,
|
|
cls.services["medium"],
|
|
accountid=cls.account.name,
|
|
domainid=cls.account.domainid,
|
|
serviceofferingid=cls.medium_offering.id,
|
|
mode=cls.services["mode"]
|
|
)
|
|
cls.virtual_machine = VirtualMachine.create(
|
|
cls.api_client,
|
|
cls.services["small"],
|
|
accountid=cls.account.name,
|
|
domainid=cls.account.domainid,
|
|
serviceofferingid=cls.small_offering.id,
|
|
mode=cls.services["mode"]
|
|
)
|
|
cls._cleanup = [
|
|
cls.small_offering,
|
|
cls.medium_offering,
|
|
cls.account
|
|
]
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
cls.api_client = super(TestVMLifeCycle, cls).getClsTestClient().getApiClient()
|
|
cleanup_resources(cls.api_client, cls._cleanup)
|
|
return
|
|
|
|
def setUp(self):
|
|
self.apiclient = self.testClient.getApiClient()
|
|
self.dbclient = self.testClient.getDbConnection()
|
|
self.cleanup = []
|
|
|
|
def tearDown(self):
|
|
#Clean up, terminate the created ISOs
|
|
cleanup_resources(self.apiclient, self.cleanup)
|
|
return
|
|
|
|
|
|
@attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_01_stop_vm(self):
|
|
"""Test Stop Virtual Machine
|
|
"""
|
|
|
|
# Validate the following
|
|
# 1. Should Not be able to login to the VM.
|
|
# 2. listVM command should return
|
|
# this VM.State of this VM should be ""Stopped"".
|
|
|
|
self.debug("Stopping VM - ID: %s" % self.virtual_machine.id)
|
|
self.small_virtual_machine.stop(self.apiclient)
|
|
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
|
|
self.assertEqual(
|
|
isinstance(list_vm_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
self.assertNotEqual(
|
|
len(list_vm_response),
|
|
0,
|
|
"Check VM available in List Virtual Machines"
|
|
)
|
|
|
|
self.assertEqual(
|
|
list_vm_response[0].state,
|
|
"Stopped",
|
|
"Check virtual machine is in stopped state"
|
|
)
|
|
return
|
|
|
|
@attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_02_start_vm(self):
|
|
"""Test Start Virtual Machine
|
|
"""
|
|
# Validate the following
|
|
# 1. listVM command should return this VM.State
|
|
# of this VM should be Running".
|
|
|
|
self.debug("Starting VM - ID: %s" % self.virtual_machine.id)
|
|
self.small_virtual_machine.start(self.apiclient)
|
|
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
self.assertEqual(
|
|
isinstance(list_vm_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
|
|
self.assertNotEqual(
|
|
len(list_vm_response),
|
|
0,
|
|
"Check VM avaliable in List Virtual Machines"
|
|
)
|
|
|
|
self.debug(
|
|
"Verify listVirtualMachines response for virtual machine: %s" \
|
|
% self.small_virtual_machine.id
|
|
)
|
|
self.assertEqual(
|
|
list_vm_response[0].state,
|
|
"Running",
|
|
"Check virtual machine is in running state"
|
|
)
|
|
return
|
|
|
|
@attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_03_reboot_vm(self):
|
|
"""Test Reboot Virtual Machine
|
|
"""
|
|
|
|
# Validate the following
|
|
# 1. Should be able to login to the VM.
|
|
# 2. listVM command should return the deployed VM.
|
|
# State of this VM should be "Running"
|
|
|
|
self.debug("Rebooting VM - ID: %s" % self.virtual_machine.id)
|
|
self.small_virtual_machine.reboot(self.apiclient)
|
|
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
self.assertEqual(
|
|
isinstance(list_vm_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
|
|
self.assertNotEqual(
|
|
len(list_vm_response),
|
|
0,
|
|
"Check VM avaliable in List Virtual Machines"
|
|
)
|
|
|
|
self.assertEqual(
|
|
list_vm_response[0].state,
|
|
"Running",
|
|
"Check virtual machine is in running state"
|
|
)
|
|
return
|
|
|
|
@attr(tags = ["advanced", "advancedns", "smoke"])
|
|
def test_04_change_offering_small(self):
|
|
"""Change Offering to a small capacity
|
|
"""
|
|
|
|
# Validate the following
|
|
# 1. Log in to the Vm .We should see that the CPU and memory Info of
|
|
# this Vm matches the one specified for "Small" service offering.
|
|
# 2. Using listVM command verify that this Vm
|
|
# has Small service offering Id.
|
|
|
|
self.debug("Stopping VM - ID: %s" % self.medium_virtual_machine.id)
|
|
|
|
self.medium_virtual_machine.stop(self.apiclient)
|
|
|
|
# Poll listVM to ensure VM is stopped properly
|
|
timeout = self.services["timeout"]
|
|
|
|
while True:
|
|
time.sleep(self.services["sleep"])
|
|
|
|
# Ensure that VM is in stopped state
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.medium_virtual_machine.id
|
|
)
|
|
|
|
if isinstance(list_vm_response, list):
|
|
|
|
vm = list_vm_response[0]
|
|
if vm.state == 'Stopped':
|
|
self.debug("VM state: %s" % vm.state)
|
|
break
|
|
|
|
if timeout == 0:
|
|
raise Exception(
|
|
"Failed to stop VM (ID: %s) in change service offering" % vm.id)
|
|
|
|
timeout = timeout - 1
|
|
|
|
self.debug("Change Service offering VM - ID: %s" %
|
|
self.medium_virtual_machine.id)
|
|
|
|
cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd()
|
|
cmd.id = self.medium_virtual_machine.id
|
|
cmd.serviceofferingid = self.small_offering.id
|
|
self.apiclient.changeServiceForVirtualMachine(cmd)
|
|
|
|
self.debug("Starting VM - ID: %s" % self.medium_virtual_machine.id)
|
|
self.medium_virtual_machine.start(self.apiclient)
|
|
|
|
# Poll listVM to ensure VM is started properly
|
|
timeout = self.services["timeout"]
|
|
|
|
while True:
|
|
time.sleep(self.services["sleep"])
|
|
|
|
# Ensure that VM is in running state
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.medium_virtual_machine.id
|
|
)
|
|
|
|
if isinstance(list_vm_response, list):
|
|
|
|
vm = list_vm_response[0]
|
|
if vm.state == 'Running':
|
|
self.debug("VM state: %s" % vm.state)
|
|
break
|
|
|
|
if timeout == 0:
|
|
raise Exception(
|
|
"Failed to start VM (ID: %s) after changing service offering" % vm.id)
|
|
|
|
timeout = timeout - 1
|
|
|
|
try:
|
|
ssh = self.medium_virtual_machine.get_ssh_client()
|
|
except Exception as e:
|
|
self.fail(
|
|
"SSH Access failed for %s: %s" % \
|
|
(self.medium_virtual_machine.ipaddress, e)
|
|
)
|
|
|
|
cpuinfo = ssh.execute("cat /proc/cpuinfo")
|
|
|
|
cpu_cnt = len([i for i in cpuinfo if "processor" in i])
|
|
#'cpu MHz\t\t: 2660.499'
|
|
cpu_speed = [i for i in cpuinfo if "cpu MHz" in i ][0].split()[3]
|
|
|
|
meminfo = ssh.execute("cat /proc/meminfo")
|
|
#MemTotal: 1017464 kB
|
|
total_mem = [i for i in meminfo if "MemTotal" in i][0].split()[1]
|
|
|
|
self.debug(
|
|
"CPU count: %s, CPU Speed: %s, Mem Info: %s" % (
|
|
cpu_cnt,
|
|
cpu_speed,
|
|
total_mem
|
|
))
|
|
self.assertAlmostEqual(
|
|
int(cpu_cnt),
|
|
self.small_offering.cpunumber,
|
|
"Check CPU Count for small offering"
|
|
)
|
|
|
|
self.assertAlmostEqual(
|
|
list_vm_response[0].cpuspeed,
|
|
self.small_offering.cpuspeed,
|
|
"Check CPU Speed for small offering"
|
|
)
|
|
self.assertAlmostEqual(
|
|
int(total_mem) / 1024, # In MBs
|
|
self.small_offering.memory,
|
|
"Check Memory(kb) for small offering"
|
|
)
|
|
return
|
|
|
|
@attr(tags = ["advanced", "advancedns", "smoke"])
|
|
def test_05_change_offering_medium(self):
|
|
"""Change Offering to a medium capacity
|
|
"""
|
|
# Validate the following
|
|
# 1. Log in to the Vm .We should see that the CPU and memory Info of
|
|
# this Vm matches the one specified for "Medium" service offering.
|
|
# 2. Using listVM command verify that this Vm
|
|
# has Medium service offering Id.
|
|
|
|
self.debug("Stopping VM - ID: %s" % self.small_virtual_machine.id)
|
|
self.small_virtual_machine.stop(self.apiclient)
|
|
|
|
# Poll listVM to ensure VM is stopped properly
|
|
timeout = self.services["timeout"]
|
|
|
|
while True:
|
|
time.sleep(self.services["sleep"])
|
|
|
|
# Ensure that VM is in stopped state
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
|
|
if isinstance(list_vm_response, list):
|
|
|
|
vm = list_vm_response[0]
|
|
if vm.state == 'Stopped':
|
|
self.debug("VM state: %s" % vm.state)
|
|
break
|
|
|
|
if timeout == 0:
|
|
raise Exception(
|
|
"Failed to stop VM (ID: %s) in change service offering" % vm.id)
|
|
|
|
timeout = timeout - 1
|
|
|
|
self.debug("Change service offering VM - ID: %s" %
|
|
self.small_virtual_machine.id)
|
|
|
|
cmd = changeServiceForVirtualMachine.changeServiceForVirtualMachineCmd()
|
|
cmd.id = self.small_virtual_machine.id
|
|
cmd.serviceofferingid = self.medium_offering.id
|
|
self.apiclient.changeServiceForVirtualMachine(cmd)
|
|
|
|
self.debug("Starting VM - ID: %s" % self.small_virtual_machine.id)
|
|
self.small_virtual_machine.start(self.apiclient)
|
|
|
|
# Poll listVM to ensure VM is started properly
|
|
timeout = self.services["timeout"]
|
|
|
|
while True:
|
|
time.sleep(self.services["sleep"])
|
|
|
|
# Ensure that VM is in running state
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
|
|
if isinstance(list_vm_response, list):
|
|
|
|
vm = list_vm_response[0]
|
|
if vm.state == 'Running':
|
|
self.debug("VM state: %s" % vm.state)
|
|
break
|
|
|
|
if timeout == 0:
|
|
raise Exception(
|
|
"Failed to start VM (ID: %s) after changing service offering" % vm.id)
|
|
|
|
timeout = timeout - 1
|
|
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
|
|
try:
|
|
ssh_client = self.small_virtual_machine.get_ssh_client()
|
|
except Exception as e:
|
|
self.fail(
|
|
"SSH Access failed for %s: %s" % \
|
|
(self.small_virtual_machine.ipaddress, e)
|
|
)
|
|
|
|
cpuinfo = ssh_client.execute("cat /proc/cpuinfo")
|
|
|
|
cpu_cnt = len([i for i in cpuinfo if "processor" in i])
|
|
#'cpu MHz\t\t: 2660.499'
|
|
cpu_speed = [i for i in cpuinfo if "cpu MHz" in i][0].split()[3]
|
|
|
|
meminfo = ssh_client.execute("cat /proc/meminfo")
|
|
#MemTotal: 1017464 kB
|
|
total_mem = [i for i in meminfo if "MemTotal" in i][0].split()[1]
|
|
|
|
self.debug(
|
|
"CPU count: %s, CPU Speed: %s, Mem Info: %s" % (
|
|
cpu_cnt,
|
|
cpu_speed,
|
|
total_mem
|
|
))
|
|
self.assertAlmostEqual(
|
|
int(cpu_cnt),
|
|
self.medium_offering.cpunumber,
|
|
"Check CPU Count for medium offering"
|
|
)
|
|
|
|
self.assertAlmostEqual(
|
|
list_vm_response[0].cpuspeed,
|
|
self.medium_offering.cpuspeed,
|
|
"Check CPU Speed for medium offering"
|
|
)
|
|
|
|
self.assertAlmostEqual(
|
|
int(total_mem) / 1024, # In MBs
|
|
self.medium_offering.memory,
|
|
"Check Memory(kb) for medium offering"
|
|
)
|
|
return
|
|
|
|
@attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_06_destroy_vm(self):
|
|
"""Test destroy Virtual Machine
|
|
"""
|
|
|
|
# Validate the following
|
|
# 1. Should not be able to login to the VM.
|
|
# 2. listVM command should return this VM.State
|
|
# of this VM should be "Destroyed".
|
|
|
|
self.debug("Destroy VM - ID: %s" % self.small_virtual_machine.id)
|
|
self.small_virtual_machine.delete(self.apiclient)
|
|
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
self.assertEqual(
|
|
isinstance(list_vm_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
|
|
self.assertNotEqual(
|
|
len(list_vm_response),
|
|
0,
|
|
"Check VM avaliable in List Virtual Machines"
|
|
)
|
|
|
|
self.assertEqual(
|
|
list_vm_response[0].state,
|
|
"Destroyed",
|
|
"Check virtual machine is in destroyed state"
|
|
)
|
|
return
|
|
|
|
@attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_07_restore_vm(self):
|
|
"""Test recover Virtual Machine
|
|
"""
|
|
|
|
# Validate the following
|
|
# 1. listVM command should return this VM.
|
|
# State of this VM should be "Stopped".
|
|
# 2. We should be able to Start this VM successfully.
|
|
|
|
self.debug("Recovering VM - ID: %s" % self.small_virtual_machine.id)
|
|
|
|
cmd = recoverVirtualMachine.recoverVirtualMachineCmd()
|
|
cmd.id = self.small_virtual_machine.id
|
|
self.apiclient.recoverVirtualMachine(cmd)
|
|
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
self.assertEqual(
|
|
isinstance(list_vm_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
|
|
self.assertNotEqual(
|
|
len(list_vm_response),
|
|
0,
|
|
"Check VM avaliable in List Virtual Machines"
|
|
)
|
|
|
|
self.assertEqual(
|
|
list_vm_response[0].state,
|
|
"Stopped",
|
|
"Check virtual machine is in Stopped state"
|
|
)
|
|
|
|
return
|
|
|
|
@attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg", "multihost"])
|
|
def test_08_migrate_vm(self):
|
|
"""Test migrate VM
|
|
"""
|
|
# Validate the following
|
|
# 1. Should be able to login to the VM.
|
|
# 2. listVM command should return this VM.State of this VM
|
|
# should be "Running" and the host should be the host
|
|
# to which the VM was migrated to
|
|
|
|
hosts = Host.list(
|
|
self.apiclient,
|
|
zoneid=self.medium_virtual_machine.zoneid,
|
|
type='Routing'
|
|
)
|
|
|
|
self.assertEqual(
|
|
isinstance(hosts, list),
|
|
True,
|
|
"Check the number of hosts in the zone"
|
|
)
|
|
self.assertGreaterEqual(
|
|
len(hosts),
|
|
2,
|
|
"Atleast 2 hosts should be present in a zone for VM migration"
|
|
)
|
|
# Remove the host of current VM from the hosts list
|
|
hosts[:] = [host for host in hosts if host.id != self.medium_virtual_machine.hostid]
|
|
|
|
host = hosts[0]
|
|
self.debug("Migrating VM-ID: %s to Host: %s" % (
|
|
self.medium_virtual_machine.id,
|
|
host.id
|
|
))
|
|
|
|
cmd = migrateVirtualMachine.migrateVirtualMachineCmd()
|
|
cmd.hostid = host.id
|
|
cmd.virtualmachineid = self.medium_virtual_machine.id
|
|
self.apiclient.migrateVirtualMachine(cmd)
|
|
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.medium_virtual_machine.id
|
|
)
|
|
self.assertEqual(
|
|
isinstance(list_vm_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
|
|
self.assertNotEqual(
|
|
list_vm_response,
|
|
None,
|
|
"Check virtual machine is listVirtualMachines"
|
|
)
|
|
|
|
vm_response = list_vm_response[0]
|
|
|
|
self.assertEqual(
|
|
vm_response.id,
|
|
self.medium_virtual_machine.id,
|
|
"Check virtual machine ID of migrated VM"
|
|
)
|
|
|
|
self.assertEqual(
|
|
vm_response.hostid,
|
|
host.id,
|
|
"Check destination hostID of migrated VM"
|
|
)
|
|
return
|
|
|
|
@attr(configuration = "expunge.interval")
|
|
@attr(configuration = "expunge.delay")
|
|
@attr(tags = ["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_09_expunge_vm(self):
|
|
"""Test destroy(expunge) Virtual Machine
|
|
"""
|
|
# Validate the following
|
|
# 1. listVM command should NOT return this VM any more.
|
|
|
|
self.debug("Expunge VM-ID: %s" % self.small_virtual_machine.id)
|
|
|
|
cmd = destroyVirtualMachine.destroyVirtualMachineCmd()
|
|
cmd.id = self.small_virtual_machine.id
|
|
self.apiclient.destroyVirtualMachine(cmd)
|
|
|
|
config = list_configurations(
|
|
self.apiclient,
|
|
name='expunge.delay'
|
|
)
|
|
|
|
expunge_delay = int(config[0].value)
|
|
time.sleep(expunge_delay * 2)
|
|
|
|
#VM should be destroyed unless expunge thread hasn't run
|
|
#Wait for two cycles of the expunge thread
|
|
config = list_configurations(
|
|
self.apiclient,
|
|
name='expunge.interval'
|
|
)
|
|
expunge_cycle = int(config[0].value)
|
|
wait_time = expunge_cycle * 2
|
|
while wait_time >= 0:
|
|
list_vm_response = list_virtual_machines(
|
|
self.apiclient,
|
|
id=self.small_virtual_machine.id
|
|
)
|
|
if list_vm_response:
|
|
time.sleep(expunge_cycle)
|
|
wait_time = wait_time - expunge_cycle
|
|
else:
|
|
break
|
|
|
|
self.assertEqual(
|
|
list_vm_response,
|
|
None,
|
|
"Check Expunged virtual machine is listVirtualMachines"
|
|
)
|
|
return
|
|
|
|
@attr(tags = ["advanced", "advancedns", "smoke", "basic", "sg"])
|
|
def test_10_attachAndDetach_iso(self):
|
|
"""Test for detach ISO to virtual machine"""
|
|
|
|
# Validate the following
|
|
# 1. Create ISO
|
|
# 2. Attach ISO to VM
|
|
# 3. Log in to the VM.
|
|
# 4. The device should be available for use
|
|
# 5. Detach ISO
|
|
# 6. Check the device is properly detached by logging into VM
|
|
|
|
iso = Iso.create(
|
|
self.apiclient,
|
|
self.services["iso"],
|
|
account=self.account.name,
|
|
domainid=self.account.domainid
|
|
)
|
|
|
|
self.debug("Successfully created ISO with ID: %s" % iso.id)
|
|
try:
|
|
iso.download(self.apiclient)
|
|
except Exception as e:
|
|
self.fail("Exception while downloading ISO %s: %s"\
|
|
% (iso.id, e))
|
|
|
|
self.debug("Attach ISO with ID: %s to VM ID: %s" % (
|
|
iso.id,
|
|
self.virtual_machine.id
|
|
))
|
|
#Attach ISO to virtual machine
|
|
cmd = attachIso.attachIsoCmd()
|
|
cmd.id = iso.id
|
|
cmd.virtualmachineid = self.virtual_machine.id
|
|
self.apiclient.attachIso(cmd)
|
|
|
|
try:
|
|
ssh_client = self.virtual_machine.get_ssh_client()
|
|
|
|
cmds = [
|
|
"mkdir -p %s" % self.services["mount_dir"],
|
|
"mount -rt iso9660 %s %s" \
|
|
% (
|
|
self.services["diskdevice"],
|
|
self.services["mount_dir"]
|
|
),
|
|
]
|
|
|
|
for c in cmds:
|
|
res = ssh_client.execute(c)
|
|
|
|
self.assertEqual(res, [], "Check mount is successful or not")
|
|
|
|
c = "fdisk -l|grep %s|head -1" % self.services["diskdevice"]
|
|
res = ssh_client.execute(c)
|
|
#Disk /dev/xvdd: 4393 MB, 4393723904 bytes
|
|
|
|
except Exception as e:
|
|
self.fail("SSH failed for virtual machine: %s - %s" %
|
|
(self.virtual_machine.ipaddress, e))
|
|
|
|
# Res may contain more than one strings depending on environment
|
|
# Split strings to form new list which is used for assertion on ISO size
|
|
result = []
|
|
for i in res:
|
|
for k in i.split():
|
|
result.append(k)
|
|
|
|
# Get ISO size
|
|
iso_response = list_isos(
|
|
self.apiclient,
|
|
id=iso.id
|
|
)
|
|
self.assertEqual(
|
|
isinstance(iso_response, list),
|
|
True,
|
|
"Check list response returns a valid list"
|
|
)
|
|
iso_size = iso_response[0].size
|
|
|
|
self.assertEqual(
|
|
str(iso_size) in result,
|
|
True,
|
|
"Check size of the attached ISO"
|
|
)
|
|
try:
|
|
#Unmount ISO
|
|
command = "umount %s" % self.services["mount_dir"]
|
|
ssh_client.execute(command)
|
|
|
|
except Exception as e:
|
|
self.fail("SSH failed for virtual machine: %s - %s" %
|
|
(self.virtual_machine.ipaddress, e))
|
|
|
|
#Detach from VM
|
|
cmd = detachIso.detachIsoCmd()
|
|
cmd.virtualmachineid = self.virtual_machine.id
|
|
self.apiclient.detachIso(cmd)
|
|
|
|
try:
|
|
res = ssh_client.execute(c)
|
|
|
|
except Exception as e:
|
|
self.fail("SSH failed for virtual machine: %s - %s" %
|
|
(self.virtual_machine.ipaddress, e))
|
|
|
|
# Check if ISO is properly detached from VM (using fdisk)
|
|
result = self.services["diskdevice"] in str(res)
|
|
|
|
self.assertEqual(
|
|
result,
|
|
False,
|
|
"Check if ISO is detached from virtual machine"
|
|
)
|
|
return
|