mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Moving smoke tests and component tests into the test folder
Reviewed-by: pychecker
This commit is contained in:
parent
a32f675875
commit
e29b0dafb6
0
test/integration/__init__.py
Normal file
0
test/integration/__init__.py
Normal file
41
test/integration/component/README
Normal file
41
test/integration/component/README
Normal file
@ -0,0 +1,41 @@
|
||||
P1 Cases
|
||||
--------------------------------------
|
||||
These test cases are the core functionality tests that ensure the application is stable and can be tested thoroughly.
|
||||
These P1 cases definitions are located at : https://docs.google.com/a/clogeny.com/spreadsheet/ccc?key=0Aq5M2ldK6eyedDJBa0EzM0RPNmdVNVZOWnFnOVJJcHc&hl=en_US
|
||||
|
||||
|
||||
Guidelines
|
||||
----------
|
||||
P1 test cases are being developed using Python's unittests2. Following are certain guidelines being followed
|
||||
1. Tests exercised for the same resource should ideally be present under a single suite or file.
|
||||
|
||||
2. Time-consuming operations that create new cloud resources like server creation, volume creation etc
|
||||
should not necessarily be exercised per unit test. The resources can be shared by creating them at
|
||||
the class-level using setUpClass and shared across all instances during a single run.
|
||||
|
||||
3. Certain tests pertaining to NAT, Firewall and Load Balancing warrant fresh resources per test. Hence a call should be
|
||||
taken by the stakeholders regarding sharing resources.
|
||||
|
||||
4. Ensure that the tearDown/tearDownClass functions clean up all the resources created during the test run.
|
||||
|
||||
For more information about unittests: http://docs.python.org/library/unittest.html
|
||||
|
||||
|
||||
P1 Tests
|
||||
----------
|
||||
The following files contain these P1 cases:
|
||||
|
||||
1. test_snapshots.py - Snapshots related tests
|
||||
2. test_routers.py - Router related tests
|
||||
3. test_usage.py - Usage realted tests
|
||||
4. test_account.py - Account related tests
|
||||
5. test_resource_limits.py - Resource limits tests
|
||||
6. test_security_groups.py - Security groups related tests
|
||||
7. test_templates.py - templates related tests
|
||||
8. test_volumes.py - Volumes related tests
|
||||
9. test_blocker_bugs.py - Blocker bugs tests
|
||||
10. test_project_configs.py - Project global configuration related tests
|
||||
11. test_project_limits.py - Project resource limits related tests
|
||||
12. test_project_resources.py - Project resource creation related tests
|
||||
13. test_project_usage.py - Project usage related tests
|
||||
14. test_projects - Projects functionality tests
|
||||
13
test/integration/component/__init__.py
Normal file
13
test/integration/component/__init__.py
Normal file
@ -0,0 +1,13 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
1091
test/integration/component/test_accounts.py
Normal file
1091
test/integration/component/test_accounts.py
Normal file
File diff suppressed because it is too large
Load Diff
1273
test/integration/component/test_blocker_bugs.py
Normal file
1273
test/integration/component/test_blocker_bugs.py
Normal file
File diff suppressed because it is too large
Load Diff
2336
test/integration/component/test_egress_rules.py
Normal file
2336
test/integration/component/test_egress_rules.py
Normal file
File diff suppressed because it is too large
Load Diff
969
test/integration/component/test_high_availability.py
Normal file
969
test/integration/component/test_high_availability.py
Normal file
@ -0,0 +1,969 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
|
||||
""" P1 tests for high availability
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
import datetime
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test network offering Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "HA",
|
||||
"lastname": "HA",
|
||||
"username": "HA",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "password",
|
||||
},
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # in MHz
|
||||
"memory": 64, # In MBs
|
||||
},
|
||||
"lbrule": {
|
||||
"name": "SSH",
|
||||
"alg": "roundrobin",
|
||||
# Algorithm used for load balancing
|
||||
"privateport": 22,
|
||||
"publicport": 2222,
|
||||
},
|
||||
"natrule": {
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": "TCP"
|
||||
},
|
||||
"fw_rule":{
|
||||
"startport": 1,
|
||||
"endport": 6000,
|
||||
"cidr": '55.55.0.0/11',
|
||||
# Any network (For creating FW rule)
|
||||
},
|
||||
"virtual_machine": {
|
||||
"displayname": "VM",
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
"hypervisor": 'XenServer',
|
||||
# Hypervisor type should be same as
|
||||
# hypervisor type of cluster
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"ostypeid": '9958b10f-9e5d-4ef1-908d-a047372d823b',
|
||||
# Cent OS 5.3 (64 bit)
|
||||
"sleep": 60,
|
||||
"timeout": 100,
|
||||
"mode":'advanced'
|
||||
}
|
||||
|
||||
|
||||
class TestHighAvailability(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
cls.api_client = super(
|
||||
TestHighAvailability,
|
||||
cls
|
||||
).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(
|
||||
cls.api_client,
|
||||
cls.services
|
||||
)
|
||||
cls.zone = get_zone(
|
||||
cls.api_client,
|
||||
cls.services
|
||||
)
|
||||
cls.pod = get_pod(
|
||||
cls.api_client,
|
||||
zoneid=cls.zone.id,
|
||||
services=cls.services
|
||||
)
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"],
|
||||
offerha=True
|
||||
)
|
||||
cls._cleanup = [
|
||||
cls.service_offering,
|
||||
]
|
||||
return
|
||||
|
||||
# @classmethod
|
||||
# def tearDownClass(cls):
|
||||
# try:
|
||||
# #Cleanup resources used
|
||||
# cleanup_resources(cls.api_client, cls._cleanup)
|
||||
# except Exception as e:
|
||||
# raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
# return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.account = Account.create(
|
||||
self.apiclient,
|
||||
self.services["account"],
|
||||
admin=True,
|
||||
domainid=self.domain.id
|
||||
)
|
||||
self.cleanup = [self.account]
|
||||
return
|
||||
|
||||
# def tearDown(self):
|
||||
# try:
|
||||
# #Clean up, terminate the created accounts, domains etc
|
||||
# cleanup_resources(self.apiclient, self.cleanup)
|
||||
# self.testClient.close()
|
||||
# except Exception as e:
|
||||
# raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
# return
|
||||
|
||||
def test_01_host_maintenance_mode(self):
|
||||
"""Test host maintenance mode
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. Create Vms. Acquire IP. Create port forwarding & load balancing
|
||||
# rules for Vms.
|
||||
# 2. Host 1: put to maintenance mode. All Vms should failover to Host
|
||||
# 2 in cluster. Vms should be in running state. All port forwarding
|
||||
# rules and load balancing Rules should work.
|
||||
# 3. After failover to Host 2 succeeds, deploy Vms. Deploy Vms on host
|
||||
# 2 should succeed.
|
||||
# 4. Host 1: cancel maintenance mode.
|
||||
# 5. Host 2 : put to maintenance mode. All Vms should failover to
|
||||
# Host 1 in cluster.
|
||||
# 6. After failover to Host 1 succeeds, deploy VMs. Deploy Vms on
|
||||
# host 1 should succeed.
|
||||
|
||||
hosts = Host.list(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
resourcestate='Enabled',
|
||||
type='Routing'
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"List hosts should return valid host response"
|
||||
)
|
||||
self.assertEqual(
|
||||
len(hosts),
|
||||
2,
|
||||
"There must be two hosts present in a cluster"
|
||||
)
|
||||
self.debug("Checking HA with hosts: %s, %s" % (
|
||||
hosts[0].name,
|
||||
hosts[1].name
|
||||
))
|
||||
self.debug("Deploying VM in account: %s" % self.account.account.name)
|
||||
# Spawn an instance in that network
|
||||
virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
self.debug("Deployed VM on host: %s" % vm.hostid)
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in RUnning state"
|
||||
)
|
||||
networks = Network.list(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(networks, list),
|
||||
True,
|
||||
"List networks should return valid list for the account"
|
||||
)
|
||||
network = networks[0]
|
||||
|
||||
self.debug("Associating public IP for account: %s" %
|
||||
self.account.account.name)
|
||||
public_ip = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.account.domainid,
|
||||
networkid=network.id
|
||||
)
|
||||
|
||||
self.debug("Associated %s with network %s" % (
|
||||
public_ip.ipaddress.ipaddress,
|
||||
network.id
|
||||
))
|
||||
self.debug("Creating PF rule for IP address: %s" %
|
||||
public_ip.ipaddress.ipaddress)
|
||||
nat_rule= NATRule.create(
|
||||
self.apiclient,
|
||||
virtual_machine,
|
||||
self.services["natrule"],
|
||||
ipaddressid=public_ip.ipaddress.id
|
||||
)
|
||||
|
||||
self.debug("Creating LB rule on IP with NAT: %s" %
|
||||
public_ip.ipaddress.ipaddress)
|
||||
|
||||
# Create Load Balancer rule on IP already having NAT rule
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=public_ip.ipaddress.id,
|
||||
accountid=self.account.account.name
|
||||
)
|
||||
self.debug("Created LB rule with ID: %s" % lb_rule.id)
|
||||
|
||||
# Should be able to SSH VM
|
||||
try:
|
||||
self.debug("SSH into VM: %s" % virtual_machine.id)
|
||||
ssh = virtual_machine.get_ssh_client(
|
||||
ipaddress=public_ip.ipaddress.ipaddress)
|
||||
except Exception as e:
|
||||
self.fail("SSH Access failed for %s: %s" % \
|
||||
(virtual_machine.ipaddress, e)
|
||||
)
|
||||
|
||||
first_host = vm.hostid
|
||||
self.debug("Enabling maintenance mode for host %s" % vm.hostid)
|
||||
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
|
||||
cmd.id = first_host
|
||||
self.apiclient.prepareHostForMaintenance(cmd)
|
||||
|
||||
self.debug("Waiting for SSVMs to come up")
|
||||
wait_for_ssvms(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
# Poll and check state of VM while it migrates from one host to another
|
||||
while True:
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
|
||||
self.debug("VM 1 state: %s" % vm.state)
|
||||
if vm.state in ["Stopping", "Stopped", "Running", "Starting"]:
|
||||
if vm.state == "Running":
|
||||
break
|
||||
else:
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
else:
|
||||
self.fail(
|
||||
"VM migration from one-host-to-other failed while enabling maintenance"
|
||||
)
|
||||
second_host = vm.hostid
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"VM should be in Running state after enabling host maintenance"
|
||||
)
|
||||
# Should be able to SSH VM
|
||||
try:
|
||||
self.debug("SSH into VM: %s" % virtual_machine.id)
|
||||
ssh = virtual_machine.get_ssh_client(
|
||||
ipaddress=public_ip.ipaddress.ipaddress)
|
||||
except Exception as e:
|
||||
self.fail("SSH Access failed for %s: %s" % \
|
||||
(virtual_machine.ipaddress, e)
|
||||
)
|
||||
self.debug("Deploying VM in account: %s" % self.account.account.name)
|
||||
# Spawn an instance on other host
|
||||
virtual_machine_2 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine_2.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
self.debug("Deployed VM on host: %s" % vm.hostid)
|
||||
self.debug("VM 2 state: %s" % vm.state)
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in Running state"
|
||||
)
|
||||
|
||||
self.debug("Canceling host maintenance for ID: %s" % first_host)
|
||||
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
|
||||
cmd.id = first_host
|
||||
self.apiclient.cancelHostMaintenance(cmd)
|
||||
self.debug("Maintenance mode canceled for host: %s" % first_host)
|
||||
|
||||
self.debug("Enabling maintenance mode for host %s" % second_host)
|
||||
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
|
||||
cmd.id = second_host
|
||||
self.apiclient.prepareHostForMaintenance(cmd)
|
||||
self.debug("Maintenance mode enabled for host: %s" % second_host)
|
||||
|
||||
self.debug("Waiting for SSVMs to come up")
|
||||
wait_for_ssvms(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
|
||||
# Poll and check the status of VMs
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
self.debug(
|
||||
"VM state after enabling maintenance on first host: %s" %
|
||||
vm.state)
|
||||
if vm.state in ["Stopping", "Stopped", "Running", "Starting"]:
|
||||
if vm.state == "Running":
|
||||
break
|
||||
else:
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
else:
|
||||
self.fail(
|
||||
"VM migration from one-host-to-other failed while enabling maintenance"
|
||||
)
|
||||
|
||||
for vm in vms:
|
||||
self.debug(
|
||||
"VM states after enabling maintenance mode on host: %s - %s" %
|
||||
(first_host, vm.state))
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in Running state"
|
||||
)
|
||||
# Spawn an instance on other host
|
||||
virtual_machine_3 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine_3.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
|
||||
self.debug("Deployed VM on host: %s" % vm.hostid)
|
||||
self.debug("VM 3 state: %s" % vm.state)
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in Running state"
|
||||
)
|
||||
|
||||
# Should be able to SSH VM
|
||||
try:
|
||||
self.debug("SSH into VM: %s" % virtual_machine.id)
|
||||
ssh = virtual_machine.get_ssh_client(
|
||||
ipaddress=public_ip.ipaddress.ipaddress)
|
||||
except Exception as e:
|
||||
self.fail("SSH Access failed for %s: %s" % \
|
||||
(virtual_machine.ipaddress, e)
|
||||
)
|
||||
|
||||
self.debug("Canceling host maintenance for ID: %s" % second_host)
|
||||
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
|
||||
cmd.id = second_host
|
||||
self.apiclient.cancelHostMaintenance(cmd)
|
||||
self.debug("Maintenance mode canceled for host: %s" % second_host)
|
||||
self.debug("Waiting for SSVMs to come up")
|
||||
wait_for_ssvms(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
return
|
||||
|
||||
def test_02_host_maintenance_mode_with_activities(self):
|
||||
"""Test host maintenance mode with activities
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. Create Vms. Acquire IP. Create port forwarding & load balancing
|
||||
# rules for Vms.
|
||||
# 2. While activities are ongoing: Create snapshots, recurring
|
||||
# snapshots, create templates, download volumes, Host 1: put to
|
||||
# maintenance mode. All Vms should failover to Host 2 in cluster
|
||||
# Vms should be in running state. All port forwarding rules and
|
||||
# load balancing Rules should work.
|
||||
# 3. After failover to Host 2 succeeds, deploy Vms. Deploy Vms on host
|
||||
# 2 should succeed. All ongoing activities in step 3 should succeed
|
||||
# 4. Host 1: cancel maintenance mode.
|
||||
# 5. While activities are ongoing: Create snapshots, recurring
|
||||
# snapshots, create templates, download volumes, Host 2: put to
|
||||
# maintenance mode. All Vms should failover to Host 1 in cluster.
|
||||
# 6. After failover to Host 1 succeeds, deploy VMs. Deploy Vms on
|
||||
# host 1 should succeed. All ongoing activities in step 6 should
|
||||
# succeed.
|
||||
|
||||
hosts = Host.list(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
resourcestate='Enabled',
|
||||
type='Routing'
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"List hosts should return valid host response"
|
||||
)
|
||||
self.assertEqual(
|
||||
len(hosts),
|
||||
2,
|
||||
"There must be two hosts present in a cluster"
|
||||
)
|
||||
self.debug("Checking HA with hosts: %s, %s" % (
|
||||
hosts[0].name,
|
||||
hosts[1].name
|
||||
))
|
||||
self.debug("Deploying VM in account: %s" % self.account.account.name)
|
||||
# Spawn an instance in that network
|
||||
virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
self.debug("Deployed VM on host: %s" % vm.hostid)
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in RUnning state"
|
||||
)
|
||||
networks = Network.list(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(networks, list),
|
||||
True,
|
||||
"List networks should return valid list for the account"
|
||||
)
|
||||
network = networks[0]
|
||||
|
||||
self.debug("Associating public IP for account: %s" %
|
||||
self.account.account.name)
|
||||
public_ip = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.account.domainid,
|
||||
networkid=network.id
|
||||
)
|
||||
|
||||
self.debug("Associated %s with network %s" % (
|
||||
public_ip.ipaddress.ipaddress,
|
||||
network.id
|
||||
))
|
||||
self.debug("Creating PF rule for IP address: %s" %
|
||||
public_ip.ipaddress.ipaddress)
|
||||
nat_rule= NATRule.create(
|
||||
self.apiclient,
|
||||
virtual_machine,
|
||||
self.services["natrule"],
|
||||
ipaddressid=public_ip.ipaddress.id
|
||||
)
|
||||
|
||||
self.debug("Creating LB rule on IP with NAT: %s" %
|
||||
public_ip.ipaddress.ipaddress)
|
||||
|
||||
# Create Load Balancer rule on IP already having NAT rule
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=public_ip.ipaddress.id,
|
||||
accountid=self.account.account.name
|
||||
)
|
||||
self.debug("Created LB rule with ID: %s" % lb_rule.id)
|
||||
|
||||
# Should be able to SSH VM
|
||||
try:
|
||||
self.debug("SSH into VM: %s" % virtual_machine.id)
|
||||
ssh = virtual_machine.get_ssh_client(
|
||||
ipaddress=public_ip.ipaddress.ipaddress)
|
||||
except Exception as e:
|
||||
self.fail("SSH Access failed for %s: %s" % \
|
||||
(virtual_machine.ipaddress, e)
|
||||
)
|
||||
# Get the Root disk of VM
|
||||
volumes = list_volumes(
|
||||
self.apiclient,
|
||||
virtualmachineid=virtual_machine.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
volume = volumes[0]
|
||||
self.debug(
|
||||
"Root volume of VM(%s): %s" % (
|
||||
virtual_machine.name,
|
||||
volume.name
|
||||
))
|
||||
# Create a snapshot from the ROOTDISK
|
||||
self.debug("Creating snapshot on ROOT volume: %s" % volume.name)
|
||||
snapshot = Snapshot.create(self.apiclient, volumes[0].id)
|
||||
self.debug("Snapshot created: ID - %s" % snapshot.id)
|
||||
|
||||
snapshots = list_snapshots(
|
||||
self.apiclient,
|
||||
id=snapshot.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(snapshots, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
snapshots,
|
||||
None,
|
||||
"Check if result exists in list snapshots call"
|
||||
)
|
||||
self.assertEqual(
|
||||
snapshots[0].id,
|
||||
snapshot.id,
|
||||
"Check snapshot id in list resources call"
|
||||
)
|
||||
# Generate template from the snapshot
|
||||
self.debug("Generating template from snapshot: %s" % snapshot.name)
|
||||
template = Template.create_from_snapshot(
|
||||
self.apiclient,
|
||||
snapshot,
|
||||
self.services["templates"]
|
||||
)
|
||||
self.cleanup.append(template)
|
||||
self.debug("Created template from snapshot: %s" % template.id)
|
||||
|
||||
templates = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templates"]["templatefilter"],
|
||||
id=template.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(templates, list),
|
||||
True,
|
||||
"List template call should return the newly created template"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
templates[0].isready,
|
||||
True,
|
||||
"The newly created template should be in ready state"
|
||||
)
|
||||
|
||||
first_host = vm.hostid
|
||||
self.debug("Enabling maintenance mode for host %s" % vm.hostid)
|
||||
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
|
||||
cmd.id = first_host
|
||||
self.apiclient.prepareHostForMaintenance(cmd)
|
||||
|
||||
self.debug("Waiting for SSVMs to come up")
|
||||
wait_for_ssvms(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
# Poll and check state of VM while it migrates from one host to another
|
||||
while True:
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
|
||||
self.debug("VM 1 state: %s" % vm.state)
|
||||
if vm.state in ["Stopping", "Stopped", "Running", "Starting"]:
|
||||
if vm.state == "Running":
|
||||
break
|
||||
else:
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
else:
|
||||
self.fail(
|
||||
"VM migration from one-host-to-other failed while enabling maintenance"
|
||||
)
|
||||
second_host = vm.hostid
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"VM should be in Running state after enabling host maintenance"
|
||||
)
|
||||
# Should be able to SSH VM
|
||||
try:
|
||||
self.debug("SSH into VM: %s" % virtual_machine.id)
|
||||
ssh = virtual_machine.get_ssh_client(
|
||||
ipaddress=public_ip.ipaddress.ipaddress)
|
||||
except Exception as e:
|
||||
self.fail("SSH Access failed for %s: %s" % \
|
||||
(virtual_machine.ipaddress, e)
|
||||
)
|
||||
self.debug("Deploying VM in account: %s" % self.account.account.name)
|
||||
# Spawn an instance on other host
|
||||
virtual_machine_2 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine_2.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
self.debug("Deployed VM on host: %s" % vm.hostid)
|
||||
self.debug("VM 2 state: %s" % vm.state)
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in Running state"
|
||||
)
|
||||
|
||||
self.debug("Canceling host maintenance for ID: %s" % first_host)
|
||||
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
|
||||
cmd.id = first_host
|
||||
self.apiclient.cancelHostMaintenance(cmd)
|
||||
self.debug("Maintenance mode canceled for host: %s" % first_host)
|
||||
|
||||
# Get the Root disk of VM
|
||||
volumes = list_volumes(
|
||||
self.apiclient,
|
||||
virtualmachineid=virtual_machine_2.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
volume = volumes[0]
|
||||
self.debug(
|
||||
"Root volume of VM(%s): %s" % (
|
||||
virtual_machine_2.name,
|
||||
volume.name
|
||||
))
|
||||
# Create a snapshot from the ROOTDISK
|
||||
self.debug("Creating snapshot on ROOT volume: %s" % volume.name)
|
||||
snapshot = Snapshot.create(self.apiclient, volumes[0].id)
|
||||
self.debug("Snapshot created: ID - %s" % snapshot.id)
|
||||
|
||||
snapshots = list_snapshots(
|
||||
self.apiclient,
|
||||
id=snapshot.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(snapshots, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
snapshots,
|
||||
None,
|
||||
"Check if result exists in list snapshots call"
|
||||
)
|
||||
self.assertEqual(
|
||||
snapshots[0].id,
|
||||
snapshot.id,
|
||||
"Check snapshot id in list resources call"
|
||||
)
|
||||
# Generate template from the snapshot
|
||||
self.debug("Generating template from snapshot: %s" % snapshot.name)
|
||||
template = Template.create_from_snapshot(
|
||||
self.apiclient,
|
||||
snapshot,
|
||||
self.services["templates"]
|
||||
)
|
||||
self.cleanup.append(template)
|
||||
self.debug("Created template from snapshot: %s" % template.id)
|
||||
|
||||
templates = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templates"]["templatefilter"],
|
||||
id=template.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(templates, list),
|
||||
True,
|
||||
"List template call should return the newly created template"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
templates[0].isready,
|
||||
True,
|
||||
"The newly created template should be in ready state"
|
||||
)
|
||||
|
||||
self.debug("Enabling maintenance mode for host %s" % second_host)
|
||||
cmd = prepareHostForMaintenance.prepareHostForMaintenanceCmd()
|
||||
cmd.id = second_host
|
||||
self.apiclient.prepareHostForMaintenance(cmd)
|
||||
self.debug("Maintenance mode enabled for host: %s" % second_host)
|
||||
|
||||
self.debug("Waiting for SSVMs to come up")
|
||||
wait_for_ssvms(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
|
||||
# Poll and check the status of VMs
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
self.debug(
|
||||
"VM state after enabling maintenance on first host: %s" %
|
||||
vm.state)
|
||||
if vm.state in ["Stopping", "Stopped", "Running", "Starting"]:
|
||||
if vm.state == "Running":
|
||||
break
|
||||
else:
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
else:
|
||||
self.fail(
|
||||
"VM migration from one-host-to-other failed while enabling maintenance"
|
||||
)
|
||||
|
||||
for vm in vms:
|
||||
self.debug(
|
||||
"VM states after enabling maintenance mode on host: %s - %s" %
|
||||
(first_host, vm.state))
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in Running state"
|
||||
)
|
||||
# Spawn an instance on other host
|
||||
virtual_machine_3 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
vms = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=virtual_machine_3.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vms, list),
|
||||
True,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(vms),
|
||||
0,
|
||||
"List VMs should return valid response for deployed VM"
|
||||
)
|
||||
vm = vms[0]
|
||||
|
||||
self.debug("Deployed VM on host: %s" % vm.hostid)
|
||||
self.debug("VM 3 state: %s" % vm.state)
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
"Running",
|
||||
"Deployed VM should be in Running state"
|
||||
)
|
||||
|
||||
# Should be able to SSH VM
|
||||
try:
|
||||
self.debug("SSH into VM: %s" % virtual_machine.id)
|
||||
ssh = virtual_machine.get_ssh_client(
|
||||
ipaddress=public_ip.ipaddress.ipaddress)
|
||||
except Exception as e:
|
||||
self.fail("SSH Access failed for %s: %s" % \
|
||||
(virtual_machine.ipaddress, e)
|
||||
)
|
||||
|
||||
self.debug("Canceling host maintenance for ID: %s" % second_host)
|
||||
cmd = cancelHostMaintenance.cancelHostMaintenanceCmd()
|
||||
cmd.id = second_host
|
||||
self.apiclient.cancelHostMaintenance(cmd)
|
||||
self.debug("Maintenance mode canceled for host: %s" % second_host)
|
||||
self.debug("Waiting for SSVMs to come up")
|
||||
wait_for_ssvms(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
return
|
||||
1783
test/integration/component/test_network_offering.py
Normal file
1783
test/integration/component/test_network_offering.py
Normal file
File diff suppressed because it is too large
Load Diff
1231
test/integration/component/test_project_configs.py
Normal file
1231
test/integration/component/test_project_configs.py
Normal file
File diff suppressed because it is too large
Load Diff
881
test/integration/component/test_project_limits.py
Normal file
881
test/integration/component/test_project_limits.py
Normal file
@ -0,0 +1,881 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" P1 tests for Resource limits
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
import datetime
|
||||
|
||||
class Services:
|
||||
"""Test Resource Limits Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"domain": {
|
||||
"name": "Domain",
|
||||
},
|
||||
"project": {
|
||||
"name": "Project",
|
||||
"displaytext": "Test project",
|
||||
},
|
||||
"account": {
|
||||
"email": "administrator@clogeny.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"user": {
|
||||
"email": "administrator@clogeny.com",
|
||||
"firstname": "User",
|
||||
"lastname": "User",
|
||||
"username": "User",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # in MHz
|
||||
"memory": 64, # In MBs
|
||||
},
|
||||
"disk_offering": {
|
||||
"displaytext": "Tiny Disk Offering",
|
||||
"name": "Tiny Disk Offering",
|
||||
"disksize": 1
|
||||
},
|
||||
"volume": {
|
||||
"diskname": "Test Volume",
|
||||
},
|
||||
"server": {
|
||||
"displayname": "TestVM",
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
"hypervisor": 'XenServer',
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"template": {
|
||||
"displaytext": "Cent OS Template",
|
||||
"name": "Cent OS Template",
|
||||
"ostypeid": '471a4b5b-5523-448f-9608-7d6218995733',
|
||||
"templatefilter": 'self',
|
||||
},
|
||||
"ostypeid": '471a4b5b-5523-448f-9608-7d6218995733',
|
||||
# Cent OS 5.3 (64 bit)
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
"mode": 'advanced',
|
||||
}
|
||||
|
||||
|
||||
class TestProjectLimits(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.api_client = super(
|
||||
TestProjectLimits,
|
||||
cls
|
||||
).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
# Get Zone
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
|
||||
# Create domains, account etc.
|
||||
cls.domain = Domain.create(
|
||||
cls.api_client,
|
||||
cls.services["domain"]
|
||||
)
|
||||
|
||||
cls.admin = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
admin=True,
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls.user = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["user"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls._cleanup = [
|
||||
cls.admin,
|
||||
cls.user,
|
||||
cls.domain
|
||||
]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
#Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
#Clean up, terminate the created accounts, domains etc
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_01_project_limits(self):
|
||||
""" Test project limits
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a Project. Verify once projects are created, they inherit
|
||||
# a default set of resource limits as configured by the Cloud Stack
|
||||
# ROOT admin.
|
||||
# 2. Reduce Project resources limits. Verify limits can be reduced by
|
||||
# the Project Owner of each project and project limit applies to
|
||||
# number of virtual instances, disk volumes, snapshots, IP address.
|
||||
# Also, verify resource limits for the project are independent of
|
||||
# account resource limits
|
||||
# 3. Increase Projects Resources limits above domains limit. Verify
|
||||
# project can’t have more resources than domain level limit allows.
|
||||
# 4. Create Resource more than its set limit for a project. Verify
|
||||
# resource allocation should fail giving proper message
|
||||
|
||||
# Create project as a domain admin
|
||||
project = Project.create(
|
||||
self.apiclient,
|
||||
self.services["project"],
|
||||
account=self.admin.account.name,
|
||||
domainid=self.admin.account.domainid
|
||||
)
|
||||
# Cleanup created project at end of test
|
||||
self.cleanup.append(project)
|
||||
self.debug("Created project with domain admin with ID: %s" %
|
||||
project.id)
|
||||
|
||||
list_projects_reponse = Project.list(
|
||||
self.apiclient,
|
||||
id=project.id,
|
||||
listall=True
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_projects_reponse, list),
|
||||
True,
|
||||
"Check for a valid list projects response"
|
||||
)
|
||||
list_project = list_projects_reponse[0]
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_projects_reponse),
|
||||
0,
|
||||
"Check list project response returns a valid project"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
project.name,
|
||||
list_project.name,
|
||||
"Check project name from list response"
|
||||
)
|
||||
# Get the resource limits for ROOT domain
|
||||
resource_limits = list_resource_limits(self.apiclient)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(resource_limits, list),
|
||||
True,
|
||||
"List resource API should return a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(resource_limits),
|
||||
0,
|
||||
"List resource API response should not be empty"
|
||||
)
|
||||
|
||||
# Reduce resource limits for project
|
||||
# Resource: 0 - Instance. Number of instances a user can create.
|
||||
# Resource: 1 - IP. Number of public IP addresses a user can own.
|
||||
# Resource: 2 - Volume. Number of disk volumes a user can create.
|
||||
# Resource: 3 - Snapshot. Number of snapshots a user can create.
|
||||
# Resource: 4 - Template. Number of templates that a user can
|
||||
# register/create
|
||||
for resource in resource_limits:
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
resource.resourcetype,
|
||||
max=1,
|
||||
projectid=project.id
|
||||
)
|
||||
self.debug(
|
||||
"Updating resource (ID: %s) limit for project: %s" % (
|
||||
resource,
|
||||
project.id
|
||||
))
|
||||
resource_limits = list_resource_limits(
|
||||
self.apiclient,
|
||||
projectid=project.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(resource_limits, list),
|
||||
True,
|
||||
"List resource API should return a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(resource_limits),
|
||||
0,
|
||||
"List resource API response should not be empty"
|
||||
)
|
||||
for resource in resource_limits:
|
||||
self.assertEqual(
|
||||
resource.max,
|
||||
1,
|
||||
"Resource limit should be updated to 1"
|
||||
)
|
||||
|
||||
# Get the resource limits for domain
|
||||
resource_limits = list_resource_limits(
|
||||
self.apiclient,
|
||||
domainid=self.domain.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(resource_limits, list),
|
||||
True,
|
||||
"List resource API should return a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(resource_limits),
|
||||
0,
|
||||
"List resource API response should not be empty"
|
||||
)
|
||||
|
||||
for resource in resource_limits:
|
||||
# Update domain resource limits to 2
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
resource.resourcetype,
|
||||
domainid=self.domain.id,
|
||||
max=2
|
||||
)
|
||||
with self.assertRaises(Exception):
|
||||
self.debug(
|
||||
"Attempting to update project: %s resource limit to: %s" % (
|
||||
project.id,
|
||||
max_value
|
||||
))
|
||||
# Update project resource limits to 3
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
resource.resourcetype,
|
||||
max=3,
|
||||
projectid=project.id
|
||||
)
|
||||
return
|
||||
@unittest.skip("No provision for updating resource limits from account through API")
|
||||
def test_02_project_limits_normal_user(self):
|
||||
""" Test project limits
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. Create a Project
|
||||
# 2. Reduce the projects limits as a domain admin. Verify resource
|
||||
# count is updated
|
||||
# 3. Reduce the projects limits as a project user owner who is not a
|
||||
# domain admin. Resource count should fail
|
||||
|
||||
# Create project as a domain admin
|
||||
project = Project.create(
|
||||
self.apiclient,
|
||||
self.services["project"],
|
||||
account=self.admin.account.name,
|
||||
domainid=self.admin.account.domainid
|
||||
)
|
||||
# Cleanup created project at end of test
|
||||
self.cleanup.append(project)
|
||||
self.debug("Created project with domain admin with ID: %s" %
|
||||
project.id)
|
||||
|
||||
list_projects_reponse = Project.list(
|
||||
self.apiclient,
|
||||
id=project.id,
|
||||
listall=True
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_projects_reponse, list),
|
||||
True,
|
||||
"Check for a valid list projects response"
|
||||
)
|
||||
list_project = list_projects_reponse[0]
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_projects_reponse),
|
||||
0,
|
||||
"Check list project response returns a valid project"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
project.name,
|
||||
list_project.name,
|
||||
"Check project name from list response"
|
||||
)
|
||||
# Get the resource limits for ROOT domain
|
||||
resource_limits = list_resource_limits(self.apiclient)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(resource_limits, list),
|
||||
True,
|
||||
"List resource API should return a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(resource_limits),
|
||||
0,
|
||||
"List resource API response should not be empty"
|
||||
)
|
||||
|
||||
# Reduce resource limits for project
|
||||
# Resource: 0 - Instance. Number of instances a user can create.
|
||||
# Resource: 1 - IP. Number of public IP addresses a user can own.
|
||||
# Resource: 2 - Volume. Number of disk volumes a user can create.
|
||||
# Resource: 3 - Snapshot. Number of snapshots a user can create.
|
||||
# Resource: 4 - Template. Number of templates that a user can
|
||||
# register/create
|
||||
for resource in resource_limits:
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
resource.resourcetype,
|
||||
max=1,
|
||||
projectid=project.id
|
||||
)
|
||||
self.debug(
|
||||
"Updating resource (ID: %s) limit for project: %s" % (
|
||||
resource,
|
||||
project.id
|
||||
))
|
||||
resource_limits = list_resource_limits(
|
||||
self.apiclient,
|
||||
projectid=project.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(resource_limits, list),
|
||||
True,
|
||||
"List resource API should return a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(resource_limits),
|
||||
0,
|
||||
"List resource API response should not be empty"
|
||||
)
|
||||
for resource in resource_limits:
|
||||
self.assertEqual(
|
||||
resource.max,
|
||||
1,
|
||||
"Resource limit should be updated to 1"
|
||||
)
|
||||
|
||||
self.debug("Adding %s user to project: %s" % (
|
||||
self.user.account.name,
|
||||
project.name
|
||||
))
|
||||
|
||||
# Add user to the project
|
||||
project.addAccount(
|
||||
self.apiclient,
|
||||
self.user.account.name,
|
||||
)
|
||||
|
||||
# Get the resource limits for domain
|
||||
resource_limits = list_resource_limits(
|
||||
self.apiclient,
|
||||
domainid=self.domain.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(resource_limits, list),
|
||||
True,
|
||||
"List resource API should return a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(resource_limits),
|
||||
0,
|
||||
"List resource API response should not be empty"
|
||||
)
|
||||
|
||||
for resource in resource_limits:
|
||||
#with self.assertRaises(Exception):
|
||||
self.debug(
|
||||
"Attempting to update resource limit by user: %s" % (
|
||||
self.user.account.name
|
||||
))
|
||||
# Update project resource limits to 3
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
resource.resourcetype,
|
||||
account=self.user.account.name,
|
||||
domainid=self.user.account.domainid,
|
||||
max=3,
|
||||
projectid=project.id
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class TestResourceLimitsProject(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.api_client = super(TestResourceLimitsProject, cls).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
# Get Zone, Domain and templates
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["server"]["zoneid"] = cls.zone.id
|
||||
|
||||
# Create Domains, Account etc
|
||||
cls.domain = Domain.create(
|
||||
cls.api_client,
|
||||
cls.services["domain"]
|
||||
)
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
# Create project as a domain admin
|
||||
cls.project = Project.create(
|
||||
cls.api_client,
|
||||
cls.services["project"],
|
||||
account=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid
|
||||
)
|
||||
cls.services["account"] = cls.account.account.name
|
||||
|
||||
# Create Service offering and disk offerings etc
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.disk_offering = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"]
|
||||
)
|
||||
cls._cleanup = [
|
||||
cls.project,
|
||||
cls.service_offering,
|
||||
cls.disk_offering,
|
||||
cls.account,
|
||||
cls.domain
|
||||
]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
#Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
#Clean up, terminate the created instance, volumes and snapshots
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_03_vm_per_project(self):
|
||||
"""Test VM limit per project
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. Set max VM per project to 2
|
||||
# 2. Create account and start 2 VMs. Verify VM state is Up and Running
|
||||
# 3. Try to create 3rd VM instance. The appropriate error or alert
|
||||
# should be raised
|
||||
|
||||
self.debug(
|
||||
"Updating instance resource limits for project: %s" %
|
||||
self.project.id)
|
||||
# Set usage_vm=1 for Account 1
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
0, # Instance
|
||||
max=2,
|
||||
projectid=self.project.id
|
||||
)
|
||||
|
||||
self.debug("Deploying VM for project: %s" % self.project.id)
|
||||
virtual_machine_1 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["server"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(virtual_machine_1)
|
||||
# Verify VM state
|
||||
self.assertEqual(
|
||||
virtual_machine_1.state,
|
||||
'Running',
|
||||
"Check VM state is Running or not"
|
||||
)
|
||||
self.debug("Deploying VM for project: %s" % self.project.id)
|
||||
virtual_machine_2 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["server"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(virtual_machine_2)
|
||||
# Verify VM state
|
||||
self.assertEqual(
|
||||
virtual_machine_2.state,
|
||||
'Running',
|
||||
"Check VM state is Running or not"
|
||||
)
|
||||
# Exception should be raised for second instance
|
||||
with self.assertRaises(Exception):
|
||||
VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["server"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
return
|
||||
|
||||
def test_04_publicip_per_project(self):
|
||||
"""Test Public IP limit per project
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. set max no of IPs per project to 2.
|
||||
# 2. Create an account in this domain
|
||||
# 3. Create 1 VM in this domain
|
||||
# 4. Acquire 1 IP in the domain. IP should be successfully acquired
|
||||
# 5. Try to acquire 3rd IP in this domain. It should give the user an
|
||||
# appropriate error and an alert should be generated.
|
||||
|
||||
self.debug(
|
||||
"Updating public IP resource limits for project: %s" %
|
||||
self.project.id)
|
||||
# Set usage_vm=1 for Account 1
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
1, # Public Ip
|
||||
max=2,
|
||||
projectid=self.project.id
|
||||
)
|
||||
|
||||
self.debug("Deploying VM for Project: %s" % self.project.id)
|
||||
virtual_machine_1 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["server"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(virtual_machine_1)
|
||||
# Verify VM state
|
||||
self.assertEqual(
|
||||
virtual_machine_1.state,
|
||||
'Running',
|
||||
"Check VM state is Running or not"
|
||||
)
|
||||
networks = Network.list(
|
||||
self.apiclient,
|
||||
projectid=self.project.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(networks, list),
|
||||
True,
|
||||
"Check list networks response returns a valid response"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(networks),
|
||||
0,
|
||||
"Check list networks response returns a valid network"
|
||||
)
|
||||
network = networks[0]
|
||||
self.debug("Associating public IP for project: %s" %
|
||||
self.project.id)
|
||||
public_ip_1 = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
zoneid=virtual_machine_1.zoneid,
|
||||
services=self.services["server"],
|
||||
networkid=network.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(public_ip_1)
|
||||
# Verify Public IP state
|
||||
self.assertEqual(
|
||||
public_ip_1.ipaddress.state in [
|
||||
'Allocated',
|
||||
'Allocating'
|
||||
],
|
||||
True,
|
||||
"Check Public IP state is allocated or not"
|
||||
)
|
||||
|
||||
# Exception should be raised for second Public IP
|
||||
with self.assertRaises(Exception):
|
||||
public_ip_2 = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
zoneid=virtual_machine_1.zoneid,
|
||||
services=self.services["server"],
|
||||
networkid=network.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
return
|
||||
|
||||
def test_05_snapshots_per_project(self):
|
||||
"""Test Snapshot limit per project
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. set max no of snapshots per project to 1.
|
||||
# 2. Create one snapshot in the project. Snapshot should be
|
||||
# successfully created
|
||||
# 5. Try to create another snapshot in this project. It should give
|
||||
# user an appropriate error and an alert should be generated.
|
||||
|
||||
self.debug(
|
||||
"Updating snapshot resource limits for project: %s" %
|
||||
self.project.id)
|
||||
# Set usage_vm=1 for Account 1
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
3, # Snapshot
|
||||
max=1,
|
||||
projectid=self.project.id
|
||||
)
|
||||
|
||||
self.debug("Deploying VM for account: %s" % self.account.account.name)
|
||||
virtual_machine_1 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["server"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(virtual_machine_1)
|
||||
# Verify VM state
|
||||
self.assertEqual(
|
||||
virtual_machine_1.state,
|
||||
'Running',
|
||||
"Check VM state is Running or not"
|
||||
)
|
||||
|
||||
# Get the Root disk of VM
|
||||
volumes = list_volumes(
|
||||
self.apiclient,
|
||||
projectid=self.project.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(volumes, list),
|
||||
True,
|
||||
"Check for list volume response return valid data"
|
||||
)
|
||||
volume = volumes[0]
|
||||
|
||||
self.debug("Creating snapshot from volume: %s" % volumes[0].id)
|
||||
# Create a snapshot from the ROOTDISK
|
||||
snapshot_1 = Snapshot.create(self.apiclient,
|
||||
volumes[0].id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(snapshot_1)
|
||||
# Verify Snapshot state
|
||||
self.assertEqual(
|
||||
snapshot_1.state in [
|
||||
'BackedUp',
|
||||
'CreatedOnPrimary'
|
||||
],
|
||||
True,
|
||||
"Check Snapshot state is Running or not"
|
||||
)
|
||||
|
||||
# Exception should be raised for second snapshot
|
||||
with self.assertRaises(Exception):
|
||||
Snapshot.create(self.apiclient,
|
||||
volumes[0].id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
return
|
||||
|
||||
def test_06_volumes_per_project(self):
|
||||
"""Test Volumes limit per project
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. set max no of volume per project to 1.
|
||||
# 2. Create 1 VM in this project
|
||||
# 4. Try to Create another VM in the project. It should give the user
|
||||
# an appropriate error that Volume limit is exhausted and an alert
|
||||
# should be generated.
|
||||
|
||||
self.debug(
|
||||
"Updating volume resource limits for project: %s" %
|
||||
self.project.id)
|
||||
# Set usage_vm=1 for Account 1
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
2, # Volume
|
||||
max=2,
|
||||
projectid=self.project.id
|
||||
)
|
||||
|
||||
self.debug("Deploying VM for project: %s" % self.project.id)
|
||||
virtual_machine_1 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["server"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(virtual_machine_1)
|
||||
# Verify VM state
|
||||
self.assertEqual(
|
||||
virtual_machine_1.state,
|
||||
'Running',
|
||||
"Check VM state is Running or not"
|
||||
)
|
||||
|
||||
# Exception should be raised for second volume
|
||||
with self.assertRaises(Exception):
|
||||
Volume.create(
|
||||
self.apiclient,
|
||||
self.services["volume"],
|
||||
zoneid=self.zone.id,
|
||||
diskofferingid=self.disk_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
return
|
||||
|
||||
def test_07_templates_per_project(self):
|
||||
"""Test Templates limit per project
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. set max no of templates per project to 1.
|
||||
# 2. Create a template in this project. Both template should be in
|
||||
# ready state
|
||||
# 3. Try create 2nd template in the project. It should give the user
|
||||
# appropriate error and an alert should be generated.
|
||||
|
||||
# Reset the volume limits
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
2, # Volume
|
||||
max=5,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.debug(
|
||||
"Updating template resource limits for domain: %s" %
|
||||
self.account.account.domainid)
|
||||
# Set usage_vm=1 for Account 1
|
||||
update_resource_limit(
|
||||
self.apiclient,
|
||||
4, # Template
|
||||
max=1,
|
||||
projectid=self.project.id
|
||||
)
|
||||
|
||||
self.debug("Deploying VM for account: %s" % self.account.account.name)
|
||||
virtual_machine_1 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["server"],
|
||||
templateid=self.template.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
self.cleanup.append(virtual_machine_1)
|
||||
# Verify VM state
|
||||
self.assertEqual(
|
||||
virtual_machine_1.state,
|
||||
'Running',
|
||||
"Check VM state is Running or not"
|
||||
)
|
||||
virtual_machine_1.stop(self.apiclient)
|
||||
# Get the Root disk of VM
|
||||
volumes = list_volumes(
|
||||
self.apiclient,
|
||||
projectid=self.project.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(volumes, list),
|
||||
True,
|
||||
"Check for list volume response return valid data"
|
||||
)
|
||||
volume = volumes[0]
|
||||
|
||||
self.debug("Creating template from volume: %s" % volume.id)
|
||||
# Create a template from the ROOTDISK
|
||||
template_1 = Template.create(
|
||||
self.apiclient,
|
||||
self.services["template"],
|
||||
volumeid=volume.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
|
||||
self.cleanup.append(template_1)
|
||||
# Verify Template state
|
||||
self.assertEqual(
|
||||
template_1.isready,
|
||||
True,
|
||||
"Check Template is in ready state or not"
|
||||
)
|
||||
|
||||
# Exception should be raised for second template
|
||||
with self.assertRaises(Exception):
|
||||
Template.create(
|
||||
self.apiclient,
|
||||
self.services["template"],
|
||||
volumeid=volume.id,
|
||||
projectid=self.project.id
|
||||
)
|
||||
return
|
||||
1314
test/integration/component/test_project_resources.py
Normal file
1314
test/integration/component/test_project_resources.py
Normal file
File diff suppressed because it is too large
Load Diff
1711
test/integration/component/test_project_usage.py
Normal file
1711
test/integration/component/test_project_usage.py
Normal file
File diff suppressed because it is too large
Load Diff
1809
test/integration/component/test_projects.py
Normal file
1809
test/integration/component/test_projects.py
Normal file
File diff suppressed because it is too large
Load Diff
1472
test/integration/component/test_resource_limits.py
Normal file
1472
test/integration/component/test_resource_limits.py
Normal file
File diff suppressed because it is too large
Load Diff
1201
test/integration/component/test_routers.py
Normal file
1201
test/integration/component/test_routers.py
Normal file
File diff suppressed because it is too large
Load Diff
1628
test/integration/component/test_security_groups.py
Normal file
1628
test/integration/component/test_security_groups.py
Normal file
File diff suppressed because it is too large
Load Diff
1396
test/integration/component/test_snapshots.py
Normal file
1396
test/integration/component/test_snapshots.py
Normal file
File diff suppressed because it is too large
Load Diff
612
test/integration/component/test_templates.py
Normal file
612
test/integration/component/test_templates.py
Normal file
@ -0,0 +1,612 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" P1 tests for Templates
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
import urllib
|
||||
from random import random
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test Templates Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # in MHz
|
||||
"memory": 64, # In MBs
|
||||
},
|
||||
"disk_offering": {
|
||||
"displaytext": "Small",
|
||||
"name": "Small",
|
||||
"disksize": 1
|
||||
},
|
||||
"virtual_machine": {
|
||||
"displayname": "testVM",
|
||||
"hypervisor": 'XenServer',
|
||||
"protocol": 'TCP',
|
||||
"ssh_port": 22,
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
},
|
||||
"volume": {
|
||||
"diskname": "Test Volume",
|
||||
},
|
||||
"templates": {
|
||||
# Configs for different Template formats
|
||||
# For Eg. raw image, zip etc
|
||||
0:{
|
||||
"displaytext": "Public Template",
|
||||
"name": "Public template",
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"url": "http://download.cloud.com/releases/2.0.0/UbuntuServer-10-04-64bit.vhd.bz2",
|
||||
"hypervisor": 'XenServer',
|
||||
"format" : 'VHD',
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"isextractable": True,
|
||||
},
|
||||
},
|
||||
"template": {
|
||||
"displaytext": "Cent OS Template",
|
||||
"name": "Cent OS Template",
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"templatefilter": 'self',
|
||||
},
|
||||
"templatefilter": 'self',
|
||||
"destzoneid": 2, # For Copy template (Destination zone)
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
"mode": 'advanced', # Networking mode: Advanced, basic
|
||||
}
|
||||
|
||||
|
||||
@unittest.skip("Open questions")
|
||||
class TestCreateTemplate(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.services = Services().services
|
||||
cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient()
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls.services["account"] = cls.account.account.name
|
||||
|
||||
cls._cleanup = [
|
||||
cls.account,
|
||||
cls.service_offering
|
||||
]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient()
|
||||
#Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def test_01_create_template(self):
|
||||
"""Test create public & private template
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. Upload a templates in raw img format. Create a Vm instances from
|
||||
# raw img template.
|
||||
# 2. Upload a templates in zip file format. Create a Vm instances from
|
||||
# zip template.
|
||||
# 3. Upload a templates in tar format.Create a Vm instances from tar
|
||||
# template.
|
||||
# 4. Upload a templates in tar gzip format.Create a Vm instances from
|
||||
# tar gzip template.
|
||||
# 5. Upload a templates in tar bzip format. Create a Vm instances from
|
||||
# tar bzip template.
|
||||
# 6. Verify VMs & Templates is up and in ready state
|
||||
|
||||
for k, v in self.services["templates"].items():
|
||||
|
||||
# Register new template
|
||||
template = Template.register(
|
||||
self.apiclient,
|
||||
v,
|
||||
zoneid=self.zone.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.debug(
|
||||
"Registered a template of format: %s with ID: %s" % (
|
||||
v["format"],
|
||||
template.id
|
||||
))
|
||||
# Wait for template to download
|
||||
template.download(self.apiclient)
|
||||
self.cleanup.append(template)
|
||||
|
||||
# Wait for template status to be changed across
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templatefilter"],
|
||||
id=template.id,
|
||||
zoneid=self.zone.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
if isinstance(list_template_response, list):
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List template failed!")
|
||||
|
||||
time.sleep(5)
|
||||
timeout = timeout - 1
|
||||
#Verify template response to check whether template added successfully
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check for list template response return valid data"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template available in List Templates"
|
||||
)
|
||||
|
||||
template_response = list_template_response[0]
|
||||
self.assertEqual(
|
||||
template_response.isready,
|
||||
True,
|
||||
"Check display text of newly created template"
|
||||
)
|
||||
|
||||
# Deploy new virtual machine using template
|
||||
virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
templateid=template.id,
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
mode=self.services["mode"]
|
||||
)
|
||||
self.debug("creating an instance with template ID: %s" % template.id)
|
||||
vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=virtual_machine.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vm_response, list),
|
||||
True,
|
||||
"Check for list VMs response after VM deployment"
|
||||
)
|
||||
#Verify VM response to check whether VM deployment was successful
|
||||
self.assertNotEqual(
|
||||
len(vm_response),
|
||||
0,
|
||||
"Check VMs available in List VMs response"
|
||||
)
|
||||
vm = vm_response[0]
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
'Running',
|
||||
"Check the state of VM created from Template"
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class TestTemplates(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
cls.services = Services().services
|
||||
cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient()
|
||||
|
||||
# Get Zone, templates etc
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
|
||||
cls.services["account"] = cls.account.account.name
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
|
||||
# create virtual machine
|
||||
cls.virtual_machine = VirtualMachine.create(
|
||||
cls.api_client,
|
||||
cls.services["virtual_machine"],
|
||||
templateid=template.id,
|
||||
accountid=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid,
|
||||
serviceofferingid=cls.service_offering.id,
|
||||
)
|
||||
#Stop virtual machine
|
||||
cls.virtual_machine.stop(cls.api_client)
|
||||
|
||||
timeout = cls.services["timeout"]
|
||||
#Wait before server has be successfully stopped
|
||||
time.sleep(cls.services["sleep"])
|
||||
|
||||
while True:
|
||||
list_volume = list_volumes(
|
||||
cls.api_client,
|
||||
virtualmachineid=cls.virtual_machine.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
if isinstance(list_volume, list):
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List volumes failed.")
|
||||
|
||||
time.sleep(5)
|
||||
timeout = timeout -1
|
||||
|
||||
cls.volume = list_volume[0]
|
||||
|
||||
#Create template from volume
|
||||
cls.template = Template.create(
|
||||
cls.api_client,
|
||||
cls.services["template"],
|
||||
cls.volume.id
|
||||
)
|
||||
cls._cleanup = [
|
||||
cls.service_offering,
|
||||
cls.account,
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient()
|
||||
#Cleanup created resources such as templates and VMs
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def test_01_create_template_volume(self):
|
||||
"""Test Create template from volume
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. Deploy new VM using the template created from Volume
|
||||
# 2. VM should be in Up and Running state
|
||||
|
||||
virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
templateid=self.template.id,
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
)
|
||||
|
||||
self.debug("creating an instance with template ID: %s" % self.template.id)
|
||||
self.cleanup.append(virtual_machine)
|
||||
vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=virtual_machine.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
#Verify VM response to check whether VM deployment was successful
|
||||
self.assertNotEqual(
|
||||
len(vm_response),
|
||||
0,
|
||||
"Check VMs available in List VMs response"
|
||||
)
|
||||
vm = vm_response[0]
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
'Running',
|
||||
"Check the state of VM created from Template"
|
||||
)
|
||||
return
|
||||
|
||||
def test_02_copy_template(self):
|
||||
"""Test for copy template from one zone to another"""
|
||||
|
||||
# Validate the following
|
||||
# 1. copy template should be successful and
|
||||
# secondary storage should contain new copied template.
|
||||
|
||||
self.debug(
|
||||
"Copying template from zone: %s to %s" % (
|
||||
self.template.id,
|
||||
self.services["destzoneid"]
|
||||
))
|
||||
cmd = copyTemplate.copyTemplateCmd()
|
||||
cmd.id = self.template.id
|
||||
cmd.destzoneid = self.services["destzoneid"]
|
||||
cmd.sourcezoneid = self.zone.id
|
||||
self.apiclient.copyTemplate(cmd)
|
||||
|
||||
# Verify template is copied to another zone using ListTemplates
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templatefilter"],
|
||||
id=self.template.id,
|
||||
zoneid=self.services["destzoneid"]
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check for list template response return valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template extracted in List Templates"
|
||||
)
|
||||
|
||||
template_response = list_template_response[0]
|
||||
self.assertEqual(
|
||||
template_response.id,
|
||||
self.template.id,
|
||||
"Check ID of the downloaded template"
|
||||
)
|
||||
self.assertEqual(
|
||||
template_response.zoneid,
|
||||
self.services["destzoneid"],
|
||||
"Check zone ID of the copied template"
|
||||
)
|
||||
|
||||
# Cleanup- Delete the copied template
|
||||
cmd = deleteTemplate.deleteTemplateCmd()
|
||||
cmd.id = self.template.id
|
||||
cmd.zoneid = self.services["destzoneid"]
|
||||
self.apiclient.deleteTemplate(cmd)
|
||||
return
|
||||
|
||||
def test_03_delete_template(self):
|
||||
"""Test Delete template
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. Create a template and verify it is shown in list templates response
|
||||
# 2. Delete the created template and again verify list template response
|
||||
|
||||
# Verify template response for updated attributes
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["template"]["templatefilter"],
|
||||
id=self.template.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check for list template response return valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template available in List Templates"
|
||||
)
|
||||
template_response = list_template_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
template_response.id,
|
||||
self.template.id,
|
||||
"Check display text of updated template"
|
||||
)
|
||||
|
||||
self.debug("Deleting template: %s" % self.template)
|
||||
# Delete the template
|
||||
self.template.delete(self.apiclient)
|
||||
self.debug("Delete template: %s successful" % self.template)
|
||||
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["template"]["templatefilter"],
|
||||
id=self.template.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
list_template_response,
|
||||
None,
|
||||
"Check template available in List Templates"
|
||||
)
|
||||
return
|
||||
|
||||
def test_04_template_from_snapshot(self):
|
||||
"""Create Template from snapshot
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 2. Snapshot the Root disk
|
||||
# 3. Create Template from snapshot
|
||||
# 4. Deploy Virtual machine using this template
|
||||
# 5. VM should be in running state
|
||||
|
||||
volumes = list_volumes(
|
||||
self.apiclient,
|
||||
virtualmachineid=self.virtual_machine.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
volume = volumes[0]
|
||||
|
||||
self.debug("Creating a snapshot from volume: %s" % volume.id)
|
||||
#Create a snapshot of volume
|
||||
snapshot = Snapshot.create(
|
||||
self.apiclient,
|
||||
volume.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.debug("Creating a template from snapshot: %s" % snapshot.id)
|
||||
# Generate template from the snapshot
|
||||
template = Template.create_from_snapshot(
|
||||
self.apiclient,
|
||||
snapshot,
|
||||
self.services["template"]
|
||||
)
|
||||
self.cleanup.append(template)
|
||||
# Verify created template
|
||||
templates = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["template"]["templatefilter"],
|
||||
id=template.id
|
||||
)
|
||||
self.assertNotEqual(
|
||||
templates,
|
||||
None,
|
||||
"Check if result exists in list item call"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
templates[0].id,
|
||||
template.id,
|
||||
"Check new template id in list resources call"
|
||||
)
|
||||
self.debug("Deploying a VM from template: %s" % template.id)
|
||||
# Deploy new virtual machine using template
|
||||
virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
templateid=template.id,
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
)
|
||||
self.cleanup.append(virtual_machine)
|
||||
|
||||
vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=virtual_machine.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(vm_response, list),
|
||||
True,
|
||||
"Check for list VM response return valid list"
|
||||
)
|
||||
|
||||
#Verify VM response to check whether VM deployment was successful
|
||||
self.assertNotEqual(
|
||||
len(vm_response),
|
||||
0,
|
||||
"Check VMs available in List VMs response"
|
||||
)
|
||||
vm = vm_response[0]
|
||||
self.assertEqual(
|
||||
vm.state,
|
||||
'Running',
|
||||
"Check the state of VM created from Template"
|
||||
)
|
||||
return
|
||||
1574
test/integration/component/test_usage.py
Normal file
1574
test/integration/component/test_usage.py
Normal file
File diff suppressed because it is too large
Load Diff
1019
test/integration/component/test_volumes.py
Normal file
1019
test/integration/component/test_volumes.py
Normal file
File diff suppressed because it is too large
Load Diff
13
test/integration/lib/__init__.py
Normal file
13
test/integration/lib/__init__.py
Normal file
@ -0,0 +1,13 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
1862
test/integration/lib/base.py
Normal file
1862
test/integration/lib/base.py
Normal file
File diff suppressed because it is too large
Load Diff
472
test/integration/lib/common.py
Normal file
472
test/integration/lib/common.py
Normal file
@ -0,0 +1,472 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
"""Common functions
|
||||
"""
|
||||
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
from utils import *
|
||||
from base import *
|
||||
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
def get_domain(apiclient, services=None):
|
||||
"Returns a default domain"
|
||||
|
||||
cmd = listDomains.listDomainsCmd()
|
||||
if services:
|
||||
if "domainid" in services:
|
||||
cmd.id = services["domainid"]
|
||||
|
||||
domains = apiclient.listDomains(cmd)
|
||||
|
||||
if isinstance(domains, list):
|
||||
return domains[0]
|
||||
else:
|
||||
raise Exception("Failed to find specified domain.")
|
||||
|
||||
def get_zone(apiclient, services=None):
|
||||
"Returns a default zone"
|
||||
|
||||
cmd = listZones.listZonesCmd()
|
||||
if services:
|
||||
if "zoneid" in services:
|
||||
cmd.id = services["zoneid"]
|
||||
|
||||
zones = apiclient.listZones(cmd)
|
||||
|
||||
if isinstance(zones, list):
|
||||
return zones[0]
|
||||
else:
|
||||
raise Exception("Failed to find specified zone.")
|
||||
|
||||
def get_pod(apiclient, zoneid, services=None):
|
||||
"Returns a default pod for specified zone"
|
||||
|
||||
cmd = listPods.listPodsCmd()
|
||||
cmd.zoneid = zoneid
|
||||
|
||||
if services:
|
||||
if "podid" in services:
|
||||
cmd.id = services["podid"]
|
||||
|
||||
pods = apiclient.listPods(cmd)
|
||||
|
||||
if isinstance(pods, list):
|
||||
return pods[0]
|
||||
else:
|
||||
raise Exception("Exception: Failed to find specified pod.")
|
||||
|
||||
def get_template(apiclient, zoneid, ostypeid=12, services=None):
|
||||
"Returns a template"
|
||||
|
||||
cmd = listTemplates.listTemplatesCmd()
|
||||
cmd.templatefilter = 'featured'
|
||||
cmd.zoneid = zoneid
|
||||
|
||||
if services:
|
||||
if "template" in services:
|
||||
cmd.id = services["template"]
|
||||
|
||||
list_templates = apiclient.listTemplates(cmd)
|
||||
|
||||
for template in list_templates:
|
||||
if template.ostypeid == ostypeid:
|
||||
return template
|
||||
|
||||
raise Exception("Exception: Failed to find template with OSTypeID: %s" %
|
||||
ostypeid)
|
||||
return
|
||||
|
||||
def download_systemplates_sec_storage(server, services):
|
||||
"""Download System templates on sec storage"""
|
||||
|
||||
try:
|
||||
# Login to management server
|
||||
ssh = remoteSSHClient.remoteSSHClient(
|
||||
server["ipaddress"],
|
||||
server["port"],
|
||||
server["username"],
|
||||
server["password"]
|
||||
)
|
||||
except Exception as e:
|
||||
raise Exception("SSH access failted for server with IP address: %s" %
|
||||
server["ipaddess"])
|
||||
# Mount Secondary Storage on Management Server
|
||||
cmds = [
|
||||
"mkdir -p %s" % services["mnt_dir"],
|
||||
"mount -t nfs %s:/%s %s" % (
|
||||
services["sec_storage"],
|
||||
services["path"],
|
||||
services["mnt_dir"]
|
||||
),
|
||||
"%s -m %s -u %s -h %s -F" % (
|
||||
services["command"],
|
||||
services["mnt_dir"],
|
||||
services["download_url"],
|
||||
services["hypervisor"]
|
||||
)
|
||||
]
|
||||
for c in cmds:
|
||||
result = ssh.execute(c)
|
||||
|
||||
res = str(result)
|
||||
|
||||
# Unmount the Secondary storage
|
||||
ssh.execute("umount %s" % (services["mnt_dir"]))
|
||||
|
||||
if res.count("Successfully installed system VM template") == 1:
|
||||
return
|
||||
else:
|
||||
raise Exception("Failed to download System Templates on Sec Storage")
|
||||
return
|
||||
|
||||
def wait_for_ssvms(apiclient, zoneid, podid, interval=60):
|
||||
"""After setup wait for SSVMs to come Up"""
|
||||
|
||||
time.sleep(interval)
|
||||
timeout = 40
|
||||
while True:
|
||||
list_ssvm_response = list_ssvms(
|
||||
apiclient,
|
||||
systemvmtype='secondarystoragevm',
|
||||
zoneid=zoneid,
|
||||
podid=podid
|
||||
)
|
||||
ssvm = list_ssvm_response[0]
|
||||
if ssvm.state != 'Running':
|
||||
# Sleep to ensure SSVMs are Up and Running
|
||||
time.sleep(interval)
|
||||
timeout = timeout - 1
|
||||
elif ssvm.state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("SSVM failed to come up")
|
||||
break
|
||||
|
||||
timeout = 40
|
||||
while True:
|
||||
list_ssvm_response = list_ssvms(
|
||||
apiclient,
|
||||
systemvmtype='consoleproxy',
|
||||
zoneid=zoneid,
|
||||
podid=podid
|
||||
)
|
||||
cpvm = list_ssvm_response[0]
|
||||
if cpvm.state != 'Running':
|
||||
# Sleep to ensure SSVMs are Up and Running
|
||||
time.sleep(interval)
|
||||
timeout = timeout - 1
|
||||
elif cpvm.state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("CPVM failed to come up")
|
||||
break
|
||||
return
|
||||
|
||||
def download_builtin_templates(apiclient, zoneid, hypervisor, host, linklocalip, interval=60):
|
||||
"""After setup wait till builtin templates are downloaded"""
|
||||
|
||||
# Change IPTABLES Rules
|
||||
result = get_process_status(
|
||||
host["ipaddress"],
|
||||
host["port"],
|
||||
host["username"],
|
||||
host["password"],
|
||||
linklocalip,
|
||||
"iptables -P INPUT ACCEPT"
|
||||
)
|
||||
time.sleep(interval)
|
||||
# Find the BUILTIN Templates for given Zone, Hypervisor
|
||||
list_template_response = list_templates(
|
||||
apiclient,
|
||||
hypervisor=hypervisor,
|
||||
zoneid=zoneid,
|
||||
templatefilter='self'
|
||||
)
|
||||
|
||||
if not isinstance(list_template_response, list):
|
||||
raise Exception("Failed to download BUILTIN templates")
|
||||
|
||||
# Ensure all BUILTIN templates are downloaded
|
||||
templateid = None
|
||||
for template in list_template_response:
|
||||
if template.templatetype == "BUILTIN":
|
||||
templateid = template.id
|
||||
|
||||
# Sleep to ensure that template is in downloading state after adding
|
||||
# Sec storage
|
||||
time.sleep(interval)
|
||||
while True:
|
||||
template_response = list_templates(
|
||||
apiclient,
|
||||
id=templateid,
|
||||
zoneid=zoneid,
|
||||
templatefilter='self'
|
||||
)
|
||||
template = template_response[0]
|
||||
# If template is ready,
|
||||
# template.status = Download Complete
|
||||
# Downloading - x% Downloaded
|
||||
# Error - Any other string
|
||||
if template.status == 'Download Complete':
|
||||
break
|
||||
|
||||
elif 'Downloaded' in template.status:
|
||||
time.sleep(interval)
|
||||
|
||||
elif 'Installing' not in template.status:
|
||||
raise Exception("ErrorInDownload")
|
||||
|
||||
return
|
||||
|
||||
def update_resource_limit(apiclient, resourcetype, account=None, domainid=None,
|
||||
max=None, projectid=None):
|
||||
"""Updates the resource limit to 'max' for given account"""
|
||||
|
||||
cmd = updateResourceLimit.updateResourceLimitCmd()
|
||||
cmd.resourcetype = resourcetype
|
||||
if account:
|
||||
cmd.account = account
|
||||
if domainid:
|
||||
cmd.domainid = domainid
|
||||
if max:
|
||||
cmd.max = max
|
||||
if projectid:
|
||||
cmd.projectid = projectid
|
||||
apiclient.updateResourceLimit(cmd)
|
||||
return
|
||||
|
||||
def list_routers(apiclient, **kwargs):
|
||||
"""List all Routers matching criteria"""
|
||||
|
||||
cmd = listRouters.listRoutersCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listRouters(cmd))
|
||||
|
||||
def list_zones(apiclient, **kwargs):
|
||||
"""List all Zones matching criteria"""
|
||||
|
||||
cmd = listZones.listZonesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listZones(cmd))
|
||||
|
||||
def list_networks(apiclient, **kwargs):
|
||||
"""List all Networks matching criteria"""
|
||||
|
||||
cmd = listNetworks.listNetworksCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listNetworks(cmd))
|
||||
|
||||
def list_clusters(apiclient, **kwargs):
|
||||
"""List all Clusters matching criteria"""
|
||||
|
||||
cmd = listClusters.listClustersCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listClusters(cmd))
|
||||
|
||||
def list_ssvms(apiclient, **kwargs):
|
||||
"""List all SSVMs matching criteria"""
|
||||
|
||||
cmd = listSystemVms.listSystemVmsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listSystemVms(cmd))
|
||||
|
||||
def list_storage_pools(apiclient, **kwargs):
|
||||
"""List all storage pools matching criteria"""
|
||||
|
||||
cmd = listStoragePools.listStoragePoolsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listStoragePools(cmd))
|
||||
|
||||
def list_virtual_machines(apiclient, **kwargs):
|
||||
"""List all VMs matching criteria"""
|
||||
|
||||
cmd = listVirtualMachines.listVirtualMachinesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listVirtualMachines(cmd))
|
||||
|
||||
def list_hosts(apiclient, **kwargs):
|
||||
"""List all Hosts matching criteria"""
|
||||
|
||||
cmd = listHosts.listHostsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listHosts(cmd))
|
||||
|
||||
def list_configurations(apiclient, **kwargs):
|
||||
"""List configuration with specified name"""
|
||||
|
||||
cmd = listConfigurations.listConfigurationsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listConfigurations(cmd))
|
||||
|
||||
def list_publicIP(apiclient, **kwargs):
|
||||
"""List all Public IPs matching criteria"""
|
||||
|
||||
cmd = listPublicIpAddresses.listPublicIpAddressesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listPublicIpAddresses(cmd))
|
||||
|
||||
def list_nat_rules(apiclient, **kwargs):
|
||||
"""List all NAT rules matching criteria"""
|
||||
|
||||
cmd = listPortForwardingRules.listPortForwardingRulesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listPortForwardingRules(cmd))
|
||||
|
||||
def list_lb_rules(apiclient, **kwargs):
|
||||
"""List all Load balancing rules matching criteria"""
|
||||
|
||||
cmd = listLoadBalancerRules.listLoadBalancerRulesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listLoadBalancerRules(cmd))
|
||||
|
||||
def list_lb_instances(apiclient, **kwargs):
|
||||
"""List all Load balancing instances matching criteria"""
|
||||
|
||||
cmd = listLoadBalancerRuleInstances.listLoadBalancerRuleInstancesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listLoadBalancerRuleInstances(cmd))
|
||||
|
||||
def list_firewall_rules(apiclient, **kwargs):
|
||||
"""List all Firewall Rules matching criteria"""
|
||||
|
||||
cmd = listFirewallRules.listFirewallRulesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listFirewallRules(cmd))
|
||||
|
||||
def list_volumes(apiclient, **kwargs):
|
||||
"""List all volumes matching criteria"""
|
||||
|
||||
cmd = listVolumes.listVolumesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listVolumes(cmd))
|
||||
|
||||
def list_isos(apiclient, **kwargs):
|
||||
"""Lists all available ISO files."""
|
||||
|
||||
cmd = listIsos.listIsosCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listIsos(cmd))
|
||||
|
||||
def list_snapshots(apiclient, **kwargs):
|
||||
"""List all snapshots matching criteria"""
|
||||
|
||||
cmd = listSnapshots.listSnapshotsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listSnapshots(cmd))
|
||||
|
||||
def list_templates(apiclient, **kwargs):
|
||||
"""List all templates matching criteria"""
|
||||
|
||||
cmd = listTemplates.listTemplatesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listTemplates(cmd))
|
||||
|
||||
def list_domains(apiclient, **kwargs):
|
||||
"""Lists domains"""
|
||||
|
||||
cmd = listDomains.listDomainsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listDomains(cmd))
|
||||
|
||||
def list_accounts(apiclient, **kwargs):
|
||||
"""Lists accounts and provides detailed account information for
|
||||
listed accounts"""
|
||||
|
||||
cmd = listAccounts.listAccountsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listAccounts(cmd))
|
||||
|
||||
def list_users(apiclient, **kwargs):
|
||||
"""Lists users and provides detailed account information for
|
||||
listed users"""
|
||||
|
||||
cmd = listUsers.listUsersCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listUsers(cmd))
|
||||
|
||||
def list_snapshot_policy(apiclient, **kwargs):
|
||||
"""Lists snapshot policies."""
|
||||
|
||||
cmd = listSnapshotPolicies.listSnapshotPoliciesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listSnapshotPolicies(cmd))
|
||||
|
||||
def list_events(apiclient, **kwargs):
|
||||
"""Lists events"""
|
||||
|
||||
cmd = listEvents.listEventsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listEvents(cmd))
|
||||
|
||||
def list_disk_offering(apiclient, **kwargs):
|
||||
"""Lists all available disk offerings."""
|
||||
|
||||
cmd = listDiskOfferings.listDiskOfferingsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listDiskOfferings(cmd))
|
||||
|
||||
def list_service_offering(apiclient, **kwargs):
|
||||
"""Lists all available service offerings."""
|
||||
|
||||
cmd = listServiceOfferings.listServiceOfferingsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listServiceOfferings(cmd))
|
||||
|
||||
def list_vlan_ipranges(apiclient, **kwargs):
|
||||
"""Lists all VLAN IP ranges."""
|
||||
|
||||
cmd = listVlanIpRanges.listVlanIpRangesCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listVlanIpRanges(cmd))
|
||||
|
||||
def list_usage_records(apiclient, **kwargs):
|
||||
"""Lists usage records for accounts"""
|
||||
|
||||
cmd = listUsageRecords.listUsageRecordsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listUsageRecords(cmd))
|
||||
|
||||
def list_nw_service_prividers(apiclient, **kwargs):
|
||||
"""Lists Network service providers"""
|
||||
|
||||
cmd = listNetworkServiceProviders.listNetworkServiceProvidersCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listNetworkServiceProviders(cmd))
|
||||
|
||||
def list_virtual_router_elements(apiclient, **kwargs):
|
||||
"""Lists Virtual Router elements"""
|
||||
|
||||
cmd = listVirtualRouterElements.listVirtualRouterElementsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listVirtualRouterElements(cmd))
|
||||
|
||||
def list_network_offerings(apiclient, **kwargs):
|
||||
"""Lists network offerings"""
|
||||
|
||||
cmd = listNetworkOfferings.listNetworkOfferingsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listNetworkOfferings(cmd))
|
||||
|
||||
def list_resource_limits(apiclient, **kwargs):
|
||||
"""Lists resource limits"""
|
||||
|
||||
cmd = listResourceLimits.listResourceLimitsCmd()
|
||||
[setattr(cmd, k, v) for k, v in kwargs.items()]
|
||||
return(apiclient.listResourceLimits(cmd))
|
||||
176
test/integration/lib/utils.py
Normal file
176
test/integration/lib/utils.py
Normal file
@ -0,0 +1,176 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
"""Utilities functions
|
||||
"""
|
||||
|
||||
import marvin
|
||||
import time
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin import cloudstackConnection
|
||||
#from cloudstackConnection import cloudConnection
|
||||
from marvin import configGenerator
|
||||
import logging
|
||||
import string
|
||||
import random
|
||||
import imaplib
|
||||
import email
|
||||
import datetime
|
||||
|
||||
def restart_mgmt_server(server):
|
||||
"""Restarts the management server"""
|
||||
|
||||
try:
|
||||
# Get the SSH client
|
||||
ssh = is_server_ssh_ready(
|
||||
server["ipaddress"],
|
||||
server["port"],
|
||||
server["username"],
|
||||
server["password"],
|
||||
)
|
||||
result = ssh.execute("/etc/init.d/cloud-management restart")
|
||||
res = str(result)
|
||||
# Server Stop - OK
|
||||
# Server Start - OK
|
||||
if res.count("OK") != 2:
|
||||
raise ("ErrorInReboot!")
|
||||
except Exception as e:
|
||||
raise e
|
||||
return
|
||||
|
||||
def fetch_latest_mail(services, from_mail):
|
||||
"""Fetch mail"""
|
||||
|
||||
# Login to mail server to verify email
|
||||
mail = imaplib.IMAP4_SSL(services["server"])
|
||||
mail.login(
|
||||
services["email"],
|
||||
services["password"]
|
||||
)
|
||||
mail.list()
|
||||
mail.select(services["folder"])
|
||||
date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y")
|
||||
|
||||
result, data = mail.uid(
|
||||
'search',
|
||||
None,
|
||||
'(SENTSINCE {date} HEADER FROM "{mail}")'.format(
|
||||
date=date,
|
||||
mail=from_mail
|
||||
)
|
||||
)
|
||||
# Return False if email is not present
|
||||
if data == []:
|
||||
return False
|
||||
|
||||
latest_email_uid = data[0].split()[-1]
|
||||
result, data = mail.uid('fetch', latest_email_uid, '(RFC822)')
|
||||
raw_email = data[0][1]
|
||||
email_message = email.message_from_string(raw_email)
|
||||
result = get_first_text_block(email_message)
|
||||
return result
|
||||
|
||||
def get_first_text_block(email_message_instance):
|
||||
"""fetches first text block from the mail"""
|
||||
maintype = email_message_instance.get_content_maintype()
|
||||
if maintype == 'multipart':
|
||||
for part in email_message_instance.get_payload():
|
||||
if part.get_content_maintype() == 'text':
|
||||
return part.get_payload()
|
||||
elif maintype == 'text':
|
||||
return email_message_instance.get_payload()
|
||||
|
||||
def random_gen(size=6, chars=string.ascii_uppercase + string.digits):
|
||||
"""Generate Random Strings of variable length"""
|
||||
return ''.join(random.choice(chars) for x in range(size))
|
||||
|
||||
def cleanup_resources(api_client, resources):
|
||||
"""Delete resources"""
|
||||
for obj in resources:
|
||||
obj.delete(api_client)
|
||||
|
||||
def is_server_ssh_ready(ipaddress, port, username, password, retries=50):
|
||||
"""Return ssh handle else wait till sshd is running"""
|
||||
loop_cnt = retries
|
||||
while True:
|
||||
try:
|
||||
ssh = remoteSSHClient.remoteSSHClient(
|
||||
ipaddress,
|
||||
port,
|
||||
username,
|
||||
password
|
||||
)
|
||||
except Exception as e:
|
||||
if loop_cnt == 0:
|
||||
raise e
|
||||
loop_cnt = loop_cnt - 1
|
||||
time.sleep(30)
|
||||
else:
|
||||
return ssh
|
||||
|
||||
|
||||
def format_volume_to_ext3(ssh_client, device="/dev/sda"):
|
||||
"""Format attached storage to ext3 fs"""
|
||||
cmds = [
|
||||
"echo -e 'n\np\n1\n\n\nw' | fdisk %s" % device,
|
||||
"mkfs.ext3 %s1" % device,
|
||||
]
|
||||
for c in cmds:
|
||||
ssh_client.execute(c)
|
||||
|
||||
def fetch_api_client(config_file='datacenterCfg'):
|
||||
"""Fetch the Cloudstack API Client"""
|
||||
config = configGenerator.get_setup_config(config_file)
|
||||
mgt = config.mgtSvr[0]
|
||||
testClientLogger = logging.getLogger("testClient")
|
||||
asyncTimeout = 3600
|
||||
return cloudstackAPIClient.CloudStackAPIClient(
|
||||
cloudstackConnection.cloudConnection(
|
||||
mgt.mgtSvrIp,
|
||||
mgt.port,
|
||||
mgt.apiKey,
|
||||
mgt.securityKey,
|
||||
asyncTimeout,
|
||||
testClientLogger
|
||||
)
|
||||
)
|
||||
|
||||
def get_process_status(hostip, port, username, password, linklocalip, process):
|
||||
"""Double hop and returns a process status"""
|
||||
|
||||
#SSH to the machine
|
||||
ssh = remoteSSHClient.remoteSSHClient(
|
||||
hostip,
|
||||
port,
|
||||
username,
|
||||
password
|
||||
)
|
||||
ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no "
|
||||
ssh_command = ssh_command + "-oUserKnownHostsFile=/dev/null -p 3922 %s %s" \
|
||||
% (linklocalip, process)
|
||||
|
||||
# Double hop into router
|
||||
timeout = 5
|
||||
# Ensure the SSH login is successful
|
||||
while True:
|
||||
res = ssh.execute(ssh_command)
|
||||
|
||||
if res[0] != "Host key verification failed.":
|
||||
break
|
||||
elif timeout == 0:
|
||||
break
|
||||
|
||||
time.sleep(5)
|
||||
timeout = timeout - 1
|
||||
return res
|
||||
41
test/integration/smoke/README
Normal file
41
test/integration/smoke/README
Normal file
@ -0,0 +1,41 @@
|
||||
Build Verification Testing (BVT) Cases
|
||||
--------------------------------------
|
||||
These test cases are the core functionality tests that ensure the application is stable and can be tested thoroughly.
|
||||
These BVT cases definitions are located at : https://docs.google.com/a/cloud.com/spreadsheet/ccc?key=0Ak8acbfxQG8ndEppOGZSLV9mUF9idjVkTkZkajhTZkE&invite=CPij0K0L
|
||||
|
||||
|
||||
Guidelines
|
||||
----------
|
||||
BVT test cases are being developed using Python's unittests2. Following are certain guidelines being followed
|
||||
1. Tests exercised for the same resource should ideally be present under a single suite or file.
|
||||
|
||||
2. Time-consuming operations that create new cloud resources like server creation, volume creation etc
|
||||
should not necessarily be exercised per unit test. The resources can be shared by creating them at
|
||||
the class-level using setUpClass and shared across all instances during a single run.
|
||||
|
||||
3. Certain tests pertaining to NAT, Firewall and Load Balancing warrant fresh resources per test. Hence a call should be
|
||||
taken by the stakeholders regarding sharing resources.
|
||||
|
||||
4. Ensure that the tearDown/tearDownClass functions clean up all the resources created during the test run.
|
||||
|
||||
For more information about unittests: http://docs.python.org/library/unittest.html
|
||||
|
||||
|
||||
BVT Tests
|
||||
----------
|
||||
The following files contain these BVT cases:
|
||||
|
||||
1. test_vm_life_cycle.py - VM Life Cycle tests
|
||||
2. test_volumes.py - Volumes related tests
|
||||
3. test_snapshots.py - Snapshots related tests
|
||||
4. test_disk_offerings.py - Disk Offerings related tests
|
||||
5. test_service_offerings.py - Service Offerings related tests
|
||||
6. test_hosts.py - Hosts and Clusters related tests
|
||||
7. test_iso.py - ISO related tests
|
||||
8. test_network.py - Network related tests
|
||||
9. test_primary_storage.py - Primary storage related tests
|
||||
10. test_secondary_storage.py - Secondary storage related tests
|
||||
11. test_ssvm.py - SSVM & CPVM related tests
|
||||
12. test_templates.py - Templates related tests
|
||||
13. test_routers.py - Router related tests
|
||||
|
||||
13
test/integration/smoke/__init__.py
Normal file
13
test/integration/smoke/__init__.py
Normal file
@ -0,0 +1,13 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
213
test/integration/smoke/test_disk_offerings.py
Normal file
213
test/integration/smoke/test_disk_offerings.py
Normal file
@ -0,0 +1,213 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Disk offerings"""
|
||||
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
|
||||
class Services:
|
||||
"""Test Disk offerings Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"off": {
|
||||
"name": "Disk offering",
|
||||
"displaytext": "Disk offering",
|
||||
"disksize": 1 # in GB
|
||||
},
|
||||
}
|
||||
|
||||
class TestCreateDiskOffering(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.services = Services().services
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_01_create_disk_offering(self):
|
||||
"""Test to create disk offering"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. createDiskOfferings should return valid info for new offering
|
||||
# 2. The Cloud Database contains the valid information
|
||||
|
||||
disk_offering = DiskOffering.create(
|
||||
self.apiclient,
|
||||
self.services["off"]
|
||||
)
|
||||
self.cleanup.append(disk_offering)
|
||||
|
||||
self.debug("Created Disk offering with ID: %s" % disk_offering.id)
|
||||
|
||||
list_disk_response = list_disk_offering(
|
||||
self.apiclient,
|
||||
id=disk_offering.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_disk_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_disk_response),
|
||||
0,
|
||||
"Check Disk offering is created"
|
||||
)
|
||||
disk_response = list_disk_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
disk_response.displaytext,
|
||||
self.services["off"]["displaytext"],
|
||||
"Check server id in createServiceOffering"
|
||||
)
|
||||
self.assertEqual(
|
||||
disk_response.name,
|
||||
self.services["off"]["name"],
|
||||
"Check name in createServiceOffering"
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class TestDiskOfferings(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
|
||||
def tearDown(self):
|
||||
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.services = Services().services
|
||||
cls.api_client = super(TestDiskOfferings, cls).getClsTestClient().getApiClient()
|
||||
cls.disk_offering_1 = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["off"]
|
||||
)
|
||||
cls.disk_offering_2 = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["off"]
|
||||
)
|
||||
cls._cleanup = [cls.disk_offering_1]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestDiskOfferings, cls).getClsTestClient().getApiClient()
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_02_edit_disk_offering(self):
|
||||
"""Test to update existing disk offering"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. updateDiskOffering should return
|
||||
# a valid information for newly created offering
|
||||
|
||||
#Generate new name & displaytext from random data
|
||||
random_displaytext = random_gen()
|
||||
random_name = random_gen()
|
||||
|
||||
self.debug("Updating Disk offering with ID: %s" %
|
||||
self.disk_offering_1.id)
|
||||
|
||||
cmd = updateDiskOffering.updateDiskOfferingCmd()
|
||||
cmd.id = self.disk_offering_1.id
|
||||
cmd.displaytext = random_displaytext
|
||||
cmd.name = random_name
|
||||
|
||||
self.apiclient.updateDiskOffering(cmd)
|
||||
|
||||
list_disk_response = list_disk_offering(
|
||||
self.apiclient,
|
||||
id=self.disk_offering_1.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_disk_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_disk_response),
|
||||
0,
|
||||
"Check disk offering is updated"
|
||||
)
|
||||
|
||||
disk_response = list_disk_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
disk_response.displaytext,
|
||||
random_displaytext,
|
||||
"Check service displaytext in updateServiceOffering"
|
||||
)
|
||||
self.assertEqual(
|
||||
disk_response.name,
|
||||
random_name,
|
||||
"Check service name in updateServiceOffering"
|
||||
)
|
||||
return
|
||||
|
||||
def test_03_delete_disk_offering(self):
|
||||
"""Test to delete disk offering"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. deleteDiskOffering should return
|
||||
# a valid information for newly created offering
|
||||
|
||||
self.disk_offering_2.delete(self.apiclient)
|
||||
|
||||
self.debug("Deleted Disk offering with ID: %s" %
|
||||
self.disk_offering_2.id)
|
||||
list_disk_response = list_disk_offering(
|
||||
self.apiclient,
|
||||
id=self.disk_offering_2.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
list_disk_response,
|
||||
None,
|
||||
"Check if disk offering exists in listDiskOfferings"
|
||||
)
|
||||
return
|
||||
224
test/integration/smoke/test_hosts.py
Normal file
224
test/integration/smoke/test_hosts.py
Normal file
@ -0,0 +1,224 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Hosts and Clusters
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
class Services:
|
||||
"""Test Hosts & Clusters Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"clusters": {
|
||||
0: {
|
||||
"clustername": "Xen Cluster",
|
||||
"clustertype": "CloudManaged",
|
||||
# CloudManaged or ExternalManaged"
|
||||
"hypervisor": "XenServer",
|
||||
# Hypervisor type
|
||||
},
|
||||
1: {
|
||||
"clustername": "KVM Cluster",
|
||||
"clustertype": "CloudManaged",
|
||||
# CloudManaged or ExternalManaged"
|
||||
"hypervisor": "KVM",
|
||||
# Hypervisor type
|
||||
},
|
||||
2: {
|
||||
"hypervisor": 'VMware',
|
||||
# Hypervisor type
|
||||
"clustertype": 'ExternalManaged',
|
||||
# CloudManaged or ExternalManaged"
|
||||
"username": 'administrator',
|
||||
"password": 'fr3sca',
|
||||
"url": 'http://192.168.100.17/CloudStack-Clogeny-Pune/Pune-1',
|
||||
# Format:http://vCenter Host/Datacenter/Cluster
|
||||
"clustername": 'VMWare Cluster',
|
||||
},
|
||||
},
|
||||
"hosts": {
|
||||
"xenserver": {
|
||||
# Must be name of corresponding Hypervisor type
|
||||
# in cluster in small letters
|
||||
"hypervisor": 'XenServer',
|
||||
# Hypervisor type
|
||||
"clustertype": 'CloudManaged',
|
||||
# CloudManaged or ExternalManaged"
|
||||
"url": 'http://192.168.100.211',
|
||||
"username": "root",
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"kvm": {
|
||||
"hypervisor": 'KVM',
|
||||
# Hypervisor type
|
||||
"clustertype": 'CloudManaged',
|
||||
# CloudManaged or ExternalManaged"
|
||||
"url": 'http://192.168.100.212',
|
||||
"username": "root",
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"vmware": {
|
||||
"hypervisor": 'VMware',
|
||||
# Hypervisor type
|
||||
"clustertype": 'ExternalManaged',
|
||||
# CloudManaged or ExternalManaged"
|
||||
"url": 'http://192.168.100.203',
|
||||
"username": "administrator",
|
||||
"password": "fr3sca",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
class TestHosts(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.services = Services().services
|
||||
self.zone = get_zone(self.apiclient, self.services)
|
||||
self.pod = get_pod(self.apiclient, self.zone.id, self.services)
|
||||
self.cleanup = []
|
||||
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_01_clusters(self):
|
||||
"""Test Add clusters & hosts - XEN, KVM, VWARE
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. Verify hypervisortype returned by API is Xen/KVM/VWare
|
||||
# 2. Verify that the cluster is in 'Enabled' allocation state
|
||||
# 3. Verify that the host is added successfully and in Up state
|
||||
# with listHosts API response
|
||||
|
||||
#Create clusters with Hypervisor type XEN/KVM/VWare
|
||||
for k, v in self.services["clusters"].items():
|
||||
cluster = Cluster.create(
|
||||
self.apiclient,
|
||||
v,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id
|
||||
)
|
||||
self.debug(
|
||||
"Created Cluster for hypervisor type %s & ID: %s" %(
|
||||
v["hypervisor"],
|
||||
cluster.id
|
||||
))
|
||||
self.assertEqual(
|
||||
cluster.hypervisortype,
|
||||
v["hypervisor"],
|
||||
"Check hypervisor type is " + v["hypervisor"] + " or not"
|
||||
)
|
||||
self.assertEqual(
|
||||
cluster.allocationstate,
|
||||
'Enabled',
|
||||
"Check whether allocation state of cluster is enabled"
|
||||
)
|
||||
|
||||
#If host is externally managed host is already added with cluster
|
||||
response = list_hosts(
|
||||
self.apiclient,
|
||||
clusterid=cluster.id
|
||||
)
|
||||
|
||||
if not response:
|
||||
hypervisor_type = str(cluster.hypervisortype.lower())
|
||||
host = Host.create(
|
||||
self.apiclient,
|
||||
cluster,
|
||||
self.services["hosts"][hypervisor_type],
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id
|
||||
)
|
||||
self.debug(
|
||||
"Created host (ID: %s) in cluster ID %s" %(
|
||||
host.id,
|
||||
cluster.id
|
||||
))
|
||||
|
||||
#Cleanup Host & Cluster
|
||||
self.cleanup.append(host)
|
||||
self.cleanup.append(cluster)
|
||||
|
||||
list_hosts_response = list_hosts(
|
||||
self.apiclient,
|
||||
clusterid=cluster.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_hosts_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_hosts_response),
|
||||
0,
|
||||
"Check list Hosts response"
|
||||
)
|
||||
|
||||
host_response = list_hosts_response[0]
|
||||
#Check if host is Up and running
|
||||
self.assertEqual(
|
||||
host_response.state,
|
||||
'Up',
|
||||
"Check if state of host is Up or not"
|
||||
)
|
||||
#Verify List Cluster Response has newly added cluster
|
||||
list_cluster_response = list_clusters(
|
||||
self.apiclient,
|
||||
id=cluster.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_cluster_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_cluster_response),
|
||||
0,
|
||||
"Check list Hosts response"
|
||||
)
|
||||
|
||||
cluster_response = list_cluster_response[0]
|
||||
self.assertEqual(
|
||||
cluster_response.id,
|
||||
cluster.id,
|
||||
"Check cluster ID with list clusters response"
|
||||
)
|
||||
self.assertEqual(
|
||||
cluster_response.hypervisortype,
|
||||
cluster.hypervisortype,
|
||||
"Check hypervisor type with is " + v["hypervisor"] + " or not"
|
||||
)
|
||||
return
|
||||
500
test/integration/smoke/test_iso.py
Normal file
500
test/integration/smoke/test_iso.py
Normal file
@ -0,0 +1,500 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Templates ISO
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
import urllib
|
||||
from random import random
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test ISO Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"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": "fr3sca",
|
||||
},
|
||||
"iso_1":
|
||||
{
|
||||
"displaytext": "Test ISO 1",
|
||||
"name": "ISO 1",
|
||||
"url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso",
|
||||
# Source URL where ISO is located
|
||||
"isextractable": True,
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
},
|
||||
"iso_2":
|
||||
{
|
||||
"displaytext": "Test ISO 2",
|
||||
"name": "ISO 2",
|
||||
"url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso",
|
||||
# Source URL where ISO is located
|
||||
"isextractable": True,
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"mode": 'HTTP_DOWNLOAD',
|
||||
# Used in Extract template, value must be HTTP_DOWNLOAD
|
||||
},
|
||||
"destzoneid": 5,
|
||||
# Copy ISO from one zone to another (Destination Zone)
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"isextractable": True,
|
||||
"bootable": True, # For edit template
|
||||
"passwordenabled": True,
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
# CentOS 5.3 (64 bit)
|
||||
"mode": 'advanced'
|
||||
# Networking mode: Basic or Advanced
|
||||
}
|
||||
|
||||
|
||||
class TestCreateIso(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.services = Services().services
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
# Get Zone, Domain and templates
|
||||
self.domain = get_domain(self.apiclient, self.services)
|
||||
self.zone = get_zone(self.apiclient, self.services)
|
||||
self.services["domainid"] = self.domain.id
|
||||
self.services["iso_2"]["zoneid"] = self.zone.id
|
||||
|
||||
self.account = Account.create(
|
||||
self.apiclient,
|
||||
self.services["account"],
|
||||
domainid=self.domain.id
|
||||
)
|
||||
|
||||
self.cleanup = [self.account]
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created ISOs
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def test_01_create_iso(self):
|
||||
"""Test create public & private ISO
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. database (vm_template table) should be
|
||||
# updated with newly created ISO
|
||||
# 2. UI should show the newly added ISO
|
||||
# 3. listIsos API should show the newly added ISO
|
||||
|
||||
iso = Iso.create(
|
||||
self.apiclient,
|
||||
self.services["iso_2"],
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.debug("ISO created 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))
|
||||
|
||||
list_iso_response = list_isos(
|
||||
self.apiclient,
|
||||
id=iso.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_iso_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_iso_response),
|
||||
0,
|
||||
"Check template available in List ISOs"
|
||||
)
|
||||
iso_response = list_iso_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
iso_response.displaytext,
|
||||
self.services["iso_2"]["displaytext"],
|
||||
"Check display text of newly created ISO"
|
||||
)
|
||||
self.assertEqual(
|
||||
iso_response.name,
|
||||
self.services["iso_2"]["name"],
|
||||
"Check name of newly created ISO"
|
||||
)
|
||||
self.assertEqual(
|
||||
iso_response.zoneid,
|
||||
self.services["iso_2"]["zoneid"],
|
||||
"Check zone ID of newly created ISO"
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class TestISO(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.services = Services().services
|
||||
cls.api_client = super(TestISO, cls).getClsTestClient().getApiClient()
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
|
||||
cls.services["domainid"] = cls.domain.id
|
||||
cls.services["iso_1"]["zoneid"] = cls.zone.id
|
||||
cls.services["iso_2"]["zoneid"] = cls.zone.id
|
||||
cls.services["sourcezoneid"] = cls.zone.id
|
||||
|
||||
#Create an account, ISOs etc.
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls.services["account"] = cls.account.account.name
|
||||
cls.iso_1 = Iso.create(
|
||||
cls.api_client,
|
||||
cls.services["iso_1"],
|
||||
account=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid
|
||||
)
|
||||
try:
|
||||
cls.iso_1.download(cls.api_client)
|
||||
except Exception as e:
|
||||
raise Exception("Exception while downloading ISO %s: %s"\
|
||||
% (cls.iso_1.id, e))
|
||||
|
||||
cls.iso_2 = Iso.create(
|
||||
cls.api_client,
|
||||
cls.services["iso_2"],
|
||||
account=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid
|
||||
)
|
||||
try:
|
||||
cls.iso_2.download(cls.api_client)
|
||||
except Exception as e:
|
||||
raise Exception("Exception while downloading ISO %s: %s"\
|
||||
% (cls.iso_2.id, e))
|
||||
|
||||
cls._cleanup = [cls.account]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestISO, cls).getClsTestClient().getApiClient()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created ISOs, VMs
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def test_02_edit_iso(self):
|
||||
"""Test Edit ISO
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. UI should show the edited values for ISO
|
||||
# 2. database (vm_template table) should have updated values
|
||||
|
||||
#Generate random values for updating ISO name and Display text
|
||||
new_displayText = random_gen()
|
||||
new_name = random_gen()
|
||||
|
||||
self.debug("Updating ISO permissions for ISO: %s" % self.iso_1.id)
|
||||
|
||||
cmd = updateIso.updateIsoCmd()
|
||||
#Assign new values to attributes
|
||||
cmd.id = self.iso_1.id
|
||||
cmd.displaytext = new_displayText
|
||||
cmd.name = new_name
|
||||
cmd.bootable = self.services["bootable"]
|
||||
cmd.passwordenabled = self.services["passwordenabled"]
|
||||
|
||||
self.apiclient.updateIso(cmd)
|
||||
|
||||
#Check whether attributes are updated in ISO using listIsos
|
||||
list_iso_response = list_isos(
|
||||
self.apiclient,
|
||||
id=self.iso_1.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_iso_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_iso_response),
|
||||
0,
|
||||
"Check template available in List ISOs"
|
||||
)
|
||||
|
||||
iso_response = list_iso_response[0]
|
||||
self.assertEqual(
|
||||
iso_response.displaytext,
|
||||
new_displayText,
|
||||
"Check display text of updated ISO"
|
||||
)
|
||||
self.assertEqual(
|
||||
iso_response.name,
|
||||
new_name,
|
||||
"Check name of updated ISO"
|
||||
)
|
||||
self.assertEqual(
|
||||
iso_response.bootable,
|
||||
self.services["bootable"],
|
||||
"Check if image is bootable of updated ISO"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
iso_response.ostypeid,
|
||||
self.services["ostypeid"],
|
||||
"Check OSTypeID of updated ISO"
|
||||
)
|
||||
return
|
||||
|
||||
def test_03_delete_iso(self):
|
||||
"""Test delete ISO
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. UI should not show the deleted ISP
|
||||
# 2. database (vm_template table) should not contain deleted ISO
|
||||
|
||||
self.debug("Deleting ISO with ID: %s" % self.iso_1.id)
|
||||
self.iso_1.delete(self.apiclient)
|
||||
|
||||
# Sleep to ensure that ISO state is reflected in other calls
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
#ListIsos to verify deleted ISO is properly deleted
|
||||
list_iso_response = list_isos(
|
||||
self.apiclient,
|
||||
id=self.iso_1.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
list_iso_response,
|
||||
None,
|
||||
"Check if ISO exists in ListIsos"
|
||||
)
|
||||
return
|
||||
|
||||
def test_04_extract_Iso(self):
|
||||
"Test for extract ISO"
|
||||
|
||||
# Validate the following
|
||||
# 1. Admin should able extract and download the ISO
|
||||
# 2. ListIsos should display all the public templates
|
||||
# for all kind of users
|
||||
# 3 .ListIsos should not display the system templates
|
||||
|
||||
self.debug("Extracting ISO with ID: %s" % self.iso_2.id)
|
||||
|
||||
cmd = extractIso.extractIsoCmd()
|
||||
cmd.id = self.iso_2.id
|
||||
cmd.mode = self.services["iso_2"]["mode"]
|
||||
cmd.zoneid = self.services["iso_2"]["zoneid"]
|
||||
list_extract_response = self.apiclient.extractIso(cmd)
|
||||
|
||||
try:
|
||||
#Format URL to ASCII to retrieve response code
|
||||
formatted_url = urllib.unquote_plus(list_extract_response.url)
|
||||
url_response = urllib.urlopen(formatted_url)
|
||||
response_code = url_response.getcode()
|
||||
except Exception:
|
||||
self.fail(
|
||||
"Extract ISO Failed with invalid URL %s (ISO id: %s)" \
|
||||
% (formatted_url, self.iso_2.id)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
list_extract_response.id,
|
||||
self.iso_2.id,
|
||||
"Check ID of the downloaded ISO"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_extract_response.extractMode,
|
||||
self.services["iso_2"]["mode"],
|
||||
"Check mode of extraction"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_extract_response.zoneid,
|
||||
self.services["iso_2"]["zoneid"],
|
||||
"Check zone ID of extraction"
|
||||
)
|
||||
self.assertEqual(
|
||||
response_code,
|
||||
200,
|
||||
"Check for a valid response of download URL"
|
||||
)
|
||||
return
|
||||
|
||||
def test_05_iso_permissions(self):
|
||||
"""Update & Test for ISO permissions"""
|
||||
|
||||
# validate the following
|
||||
# 1. listIsos returns valid permissions set for ISO
|
||||
# 2. permission changes should be reflected in vm_template
|
||||
# table in database
|
||||
|
||||
self.debug("Updating permissions for ISO: %s" % self.iso_2.id)
|
||||
|
||||
cmd = updateIsoPermissions.updateIsoPermissionsCmd()
|
||||
cmd.id = self.iso_2.id
|
||||
#Update ISO permissions
|
||||
cmd.isfeatured = self.services["isfeatured"]
|
||||
cmd.ispublic = self.services["ispublic"]
|
||||
cmd.isextractable = self.services["isextractable"]
|
||||
self.apiclient.updateIsoPermissions(cmd)
|
||||
|
||||
#Verify ListIsos have updated permissions for the ISO for normal user
|
||||
list_iso_response = list_isos(
|
||||
self.apiclient,
|
||||
id=self.iso_2.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_iso_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
iso_response = list_iso_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
iso_response.id,
|
||||
self.iso_2.id,
|
||||
"Check ISO ID"
|
||||
)
|
||||
self.assertEqual(
|
||||
iso_response.ispublic,
|
||||
self.services["ispublic"],
|
||||
"Check ispublic permission of ISO"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
iso_response.isfeatured,
|
||||
self.services["isfeatured"],
|
||||
"Check isfeatured permission of ISO"
|
||||
)
|
||||
return
|
||||
|
||||
def test_06_copy_iso(self):
|
||||
"""Test for copy ISO from one zone to another"""
|
||||
|
||||
#Validate the following
|
||||
#1. copy ISO should be successful and secondary storage
|
||||
# should contain new copied ISO.
|
||||
|
||||
self.debug("Copy ISO from %s to %s" % (
|
||||
self.zone.id,
|
||||
self.services["destzoneid"]
|
||||
))
|
||||
|
||||
cmd = copyIso.copyIsoCmd()
|
||||
cmd.id = self.iso_2.id
|
||||
cmd.destzoneid = self.services["destzoneid"]
|
||||
cmd.sourcezoneid = self.zone.id
|
||||
self.apiclient.copyIso(cmd)
|
||||
|
||||
#Verify ISO is copied to another zone using ListIsos
|
||||
list_iso_response = list_isos(
|
||||
self.apiclient,
|
||||
id=self.iso_2.id,
|
||||
zoneid=self.services["destzoneid"]
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_iso_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_iso_response),
|
||||
0,
|
||||
"Check template extracted in List ISO"
|
||||
)
|
||||
iso_response = list_iso_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
iso_response.id,
|
||||
self.iso_2.id,
|
||||
"Check ID of the downloaded ISO"
|
||||
)
|
||||
self.assertEqual(
|
||||
iso_response.zoneid,
|
||||
self.services["destzoneid"],
|
||||
"Check zone ID of the copied ISO"
|
||||
)
|
||||
|
||||
self.debug("Cleanup copied ISO: %s" % iso_response.id)
|
||||
# Cleanup- Delete the copied ISO
|
||||
cmd = deleteIso.deleteIsoCmd()
|
||||
cmd.id = iso_response.id
|
||||
cmd.zoneid = self.services["destzoneid"]
|
||||
self.apiclient.deleteIso(cmd)
|
||||
return
|
||||
1712
test/integration/smoke/test_network.py
Normal file
1712
test/integration/smoke/test_network.py
Normal file
File diff suppressed because it is too large
Load Diff
238
test/integration/smoke/test_primary_storage.py
Normal file
238
test/integration/smoke/test_primary_storage.py
Normal file
@ -0,0 +1,238 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Primary Storage
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
class Services:
|
||||
"""Test Primary storage Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"nfs": {
|
||||
0: {
|
||||
"url": "nfs://192.168.100.131/testprimary",
|
||||
# Format: File_System_Type/Location/Path
|
||||
"name": "Primary XEN",
|
||||
"hypervisor": 'XEN',
|
||||
},
|
||||
1: {
|
||||
"url": "nfs://192.168.100.131/Primary",
|
||||
"name": "Primary KVM",
|
||||
"hypervisor": 'KVM',
|
||||
},
|
||||
2: {
|
||||
"url": "nfs://192.168.100.131/Primary",
|
||||
"name": "Primary VMWare",
|
||||
"hypervisor": 'VMWare',
|
||||
},
|
||||
},
|
||||
"iscsi": {
|
||||
0: {
|
||||
"url": "iscsi://192.168.100.21/iqn.2012-01.localdomain.clo-cstack-cos6:iser/1",
|
||||
# Format : iscsi://IP Address/IQN number/LUN#
|
||||
"name": "Primary iSCSI",
|
||||
"hypervisor": 'XEN',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
class TestPrimaryStorageServices(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.services = Services().services
|
||||
self.cleanup = []
|
||||
# Get Zone and pod
|
||||
self.zone = get_zone(self.apiclient, self.services)
|
||||
self.pod = get_pod(self.apiclient, self.zone.id)
|
||||
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_01_primary_storage(self):
|
||||
"""Test primary storage pools - XEN, KVM, VMWare
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. verify hypervisortype returned by api is Xen/KVM/VMWare
|
||||
# 2. verify that the cluster is in 'Enabled' allocation state
|
||||
# 3. verify that the host is added successfully and
|
||||
# in Up state with listHosts api response
|
||||
|
||||
#Create NFS storage pools with on XEN/KVM/VMWare clusters
|
||||
for k, v in self.services["nfs"].items():
|
||||
|
||||
clusters = list_clusters(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
hypervisortype=v["hypervisor"]
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(clusters, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
cluster = clusters[0]
|
||||
#Host should be present before adding primary storage
|
||||
list_hosts_response = list_hosts(
|
||||
self.apiclient,
|
||||
clusterid=cluster.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_hosts_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_hosts_response),
|
||||
0,
|
||||
"Check list Hosts for hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
|
||||
storage = StoragePool.create(self.apiclient,
|
||||
v,
|
||||
clusterid=cluster.id,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id
|
||||
)
|
||||
self.cleanup.append(storage)
|
||||
|
||||
self.debug("Created storage pool in cluster: %s" % cluster.id)
|
||||
|
||||
self.assertEqual(
|
||||
storage.state,
|
||||
'Up',
|
||||
"Check primary storage state for hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
storage.type,
|
||||
'NetworkFilesystem',
|
||||
"Check storage pool type for hypervisor : " + v["hypervisor"]
|
||||
)
|
||||
|
||||
#Verify List Storage pool Response has newly added storage pool
|
||||
storage_pools_response = list_storage_pools(
|
||||
self.apiclient,
|
||||
id=storage.id,
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(storage_pools_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(storage_pools_response),
|
||||
0,
|
||||
"Check list Hosts response"
|
||||
)
|
||||
|
||||
storage_response = storage_pools_response[0]
|
||||
self.assertEqual(
|
||||
storage_response.id,
|
||||
storage.id,
|
||||
"Check storage pool ID for hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
self.assertEqual(
|
||||
storage.type,
|
||||
storage_response.type,
|
||||
"Check storage pool type for hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
# Call cleanup for reusing primary storage
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
self.cleanup = []
|
||||
|
||||
# Create iSCSI storage pools with on XEN/KVM clusters
|
||||
for k, v in self.services["iscsi"].items():
|
||||
clusters = list_clusters(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
hypervisortype=v["hypervisor"]
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(clusters, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
cluster = clusters[0]
|
||||
|
||||
storage = StoragePool.create(self.apiclient,
|
||||
v,
|
||||
clusterid=cluster.id,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id
|
||||
)
|
||||
self.cleanup.append(storage)
|
||||
|
||||
self.debug("Created iSCSI storage pool in cluster: %s" % cluster.id)
|
||||
|
||||
self.assertEqual(
|
||||
storage.state,
|
||||
'Up',
|
||||
"Check primary storage state for hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
|
||||
#Verify List Storage pool Response has newly added storage pool
|
||||
storage_pools_response = list_storage_pools(
|
||||
self.apiclient,
|
||||
id=storage.id,
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(storage_pools_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(storage_pools_response),
|
||||
0,
|
||||
"Check Hosts response for hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
|
||||
storage_response = storage_pools_response[0]
|
||||
self.assertEqual(
|
||||
storage_response.id,
|
||||
storage.id,
|
||||
"Check storage pool ID for hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
self.assertEqual(
|
||||
storage.type,
|
||||
storage_response.type,
|
||||
"Check storage pool type hypervisor: " + v["hypervisor"]
|
||||
)
|
||||
|
||||
# Call cleanup for reusing primary storage
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
self.cleanup = []
|
||||
return
|
||||
820
test/integration/smoke/test_routers.py
Normal file
820
test/integration/smoke/test_routers.py
Normal file
@ -0,0 +1,820 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for routers
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test router Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # in MHz
|
||||
"memory": 64, # In MBs
|
||||
},
|
||||
"virtual_machine":
|
||||
{
|
||||
"displayname": "Test VM",
|
||||
"username": "root",
|
||||
"password": "fr3sca",
|
||||
"ssh_port": 22,
|
||||
"hypervisor": 'XenServer',
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "testuser",
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"ostypeid":'5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
"mode": 'advanced', #Networking mode: Basic, Advanced
|
||||
}
|
||||
|
||||
|
||||
class TestRouterServices(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
cls.api_client = super(
|
||||
TestRouterServices,
|
||||
cls
|
||||
).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
|
||||
#Create an account, network, VM and IP addresses
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.vm_1 = VirtualMachine.create(
|
||||
cls.api_client,
|
||||
cls.services["virtual_machine"],
|
||||
templateid=template.id,
|
||||
accountid=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid,
|
||||
serviceofferingid=cls.service_offering.id
|
||||
)
|
||||
cls.cleanup = [
|
||||
cls.vm_1,
|
||||
cls.account,
|
||||
cls.service_offering
|
||||
]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(
|
||||
TestRouterServices,
|
||||
cls
|
||||
).getClsTestClient().getApiClient()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(cls.api_client, cls.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
return
|
||||
|
||||
def test_01_router_internal_basic(self):
|
||||
"""Test router internal basic zone
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. Router only does dhcp
|
||||
# 2. Verify that ports 67 (DHCP) and 53 (DNS) are open on UDP
|
||||
# by checking status of dnsmasq process
|
||||
|
||||
# Find router associated with user account
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
zoneid=router.zoneid,
|
||||
type='Routing',
|
||||
state='Up',
|
||||
virtualmachineid=self.vm_1.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list host returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Router ID: %s, state: %s" % (router.id, router.state))
|
||||
|
||||
self.assertEqual(
|
||||
router.state,
|
||||
'Running',
|
||||
"Check list router response for router state"
|
||||
)
|
||||
|
||||
result = get_process_status(
|
||||
host.ipaddress,
|
||||
self.services['virtual_machine']["publicport"],
|
||||
self.vm_1.username,
|
||||
self.vm_1.password,
|
||||
router.linklocalip,
|
||||
"service dnsmasq status"
|
||||
)
|
||||
res = str(result)
|
||||
self.debug("Dnsmasq process status: %s" % res)
|
||||
|
||||
self.assertEqual(
|
||||
res.count("running"),
|
||||
1,
|
||||
"Check dnsmasq service is running or not"
|
||||
)
|
||||
return
|
||||
|
||||
def test_02_router_internal_adv(self):
|
||||
"""Test router internal advanced zone
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. Router does dhcp, dns, gateway, LB, PF, FW
|
||||
# 2. verify that dhcp, dns ports are open on UDP
|
||||
# 3. dnsmasq, haproxy processes should be running
|
||||
|
||||
# Find router associated with user account
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
router = list_router_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
zoneid=router.zoneid,
|
||||
type='Routing',
|
||||
state='Up',
|
||||
virtualmachineid=self.vm_1.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Router ID: %s, state: %s" % (router.id, router.state))
|
||||
self.assertEqual(
|
||||
router.state,
|
||||
'Running',
|
||||
"Check list router response for router state"
|
||||
)
|
||||
|
||||
result = get_process_status(
|
||||
host.ipaddress,
|
||||
self.services['virtual_machine']["publicport"],
|
||||
self.vm_1.username,
|
||||
self.vm_1.password,
|
||||
router.linklocalip,
|
||||
"service dnsmasq status"
|
||||
)
|
||||
res = str(result)
|
||||
self.debug("Dnsmasq process status: %s" % res)
|
||||
|
||||
self.assertEqual(
|
||||
res.count("running"),
|
||||
1,
|
||||
"Check dnsmasq service is running or not"
|
||||
)
|
||||
|
||||
result = get_process_status(
|
||||
host.ipaddress,
|
||||
self.services['virtual_machine']["publicport"],
|
||||
self.vm_1.username,
|
||||
self.vm_1.password,
|
||||
router.linklocalip,
|
||||
"service haproxy status"
|
||||
)
|
||||
res = str(result)
|
||||
self.assertEqual(
|
||||
res.count("running"),
|
||||
1,
|
||||
"Check haproxy service is running or not"
|
||||
)
|
||||
self.debug("Haproxy process status: %s" % res)
|
||||
return
|
||||
|
||||
def test_03_restart_network_cleanup(self):
|
||||
"""Test restart network
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. When cleanup = true, router is destroyed and a new one created
|
||||
# 2. New router will have new publicIp and linkLocalIp and
|
||||
# all it's services should resume
|
||||
|
||||
# Find router associated with user account
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
#Store old values before restart
|
||||
old_linklocalip = router.linklocalip
|
||||
|
||||
timeout = 10
|
||||
# Network should be in Implemented or Setup stage before restart
|
||||
while True:
|
||||
networks = list_networks(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(networks, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
network = networks[0]
|
||||
if network.state in ["Implemented", "Setup"]:
|
||||
break
|
||||
elif timeout == 0:
|
||||
break
|
||||
else:
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
self.debug(
|
||||
"Restarting network with ID: %s, Network state: %s" % (
|
||||
network.id,
|
||||
network.state
|
||||
))
|
||||
cmd = restartNetwork.restartNetworkCmd()
|
||||
cmd.id = network.id
|
||||
cmd.cleanup = True
|
||||
self.apiclient.restartNetwork(cmd)
|
||||
|
||||
# Get router details after restart
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
self.assertNotEqual(
|
||||
router.linklocalip,
|
||||
old_linklocalip,
|
||||
"Check link-local IP after restart"
|
||||
)
|
||||
return
|
||||
|
||||
def test_04_restart_network_wo_cleanup(self):
|
||||
"""Test restart network without cleanup
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. When cleanup = false, router is restarted and
|
||||
# all services inside the router are restarted
|
||||
# 2. check 'uptime' to see if the actual restart happened
|
||||
|
||||
timeout = 10
|
||||
# Network should be in Implemented or Setup stage before restart
|
||||
while True:
|
||||
networks = list_networks(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(networks, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
network = networks[0]
|
||||
if network.state in ["Implemented", "Setup"]:
|
||||
break
|
||||
elif timeout == 0:
|
||||
break
|
||||
else:
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
self.debug(
|
||||
"Restarting network with ID: %s, Network state: %s" % (
|
||||
network.id,
|
||||
network.state
|
||||
))
|
||||
cmd = restartNetwork.restartNetworkCmd()
|
||||
cmd.id = network.id
|
||||
cmd.cleanup = False
|
||||
self.apiclient.restartNetwork(cmd)
|
||||
|
||||
# Get router details after restart
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
zoneid=router.zoneid,
|
||||
type='Routing',
|
||||
state='Up',
|
||||
virtualmachineid=self.vm_1.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
res = get_process_status(
|
||||
host.ipaddress,
|
||||
self.services['virtual_machine']["publicport"],
|
||||
self.vm_1.username,
|
||||
self.vm_1.password,
|
||||
router.linklocalip,
|
||||
"uptime"
|
||||
)
|
||||
|
||||
# res = 12:37:14 up 1 min, 0 users, load average: 0.61, 0.22, 0.08
|
||||
# Split result to check the uptime
|
||||
result = res[0].split()
|
||||
self.debug("Router Uptime: %s" % result)
|
||||
self.assertEqual(
|
||||
str(result[1]),
|
||||
'up',
|
||||
"Check router is running or not"
|
||||
)
|
||||
if str(result[3]) == "min,":
|
||||
self.assertEqual(
|
||||
(int(result[2]) < 3),
|
||||
True,
|
||||
"Check uptime is less than 3 mins or not"
|
||||
)
|
||||
else:
|
||||
self.assertEqual(
|
||||
str(result[3]),
|
||||
'sec,',
|
||||
"Check uptime is in seconds"
|
||||
)
|
||||
return
|
||||
|
||||
def test_05_router_basic(self):
|
||||
"""Test router basic setup
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. verify that listRouters returned a 'Running' router
|
||||
# 2. router will have dns same as that seen in listZones
|
||||
# 3. router will have a guestIP and a linkLocalIp"
|
||||
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_router_response),
|
||||
0,
|
||||
"Check list router response"
|
||||
)
|
||||
for router in list_router_response:
|
||||
self.assertEqual(
|
||||
router.state,
|
||||
'Running',
|
||||
"Check list router response for router state"
|
||||
)
|
||||
|
||||
zones = list_zones(
|
||||
self.apiclient,
|
||||
id=router.zoneid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(zones, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
zone = zones[0]
|
||||
|
||||
self.assertEqual(
|
||||
router.dns1,
|
||||
zone.dns1,
|
||||
"Compare DNS1 of router and zone"
|
||||
)
|
||||
self.assertEqual(
|
||||
router.dns2,
|
||||
zone.dns2,
|
||||
"Compare DNS2 of router and zone"
|
||||
)
|
||||
self.assertEqual(
|
||||
hasattr(router, 'guestipaddress'),
|
||||
True,
|
||||
"Check whether router has guest IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(router, 'linklocalip'),
|
||||
True,
|
||||
"Check whether router has link local IP field"
|
||||
)
|
||||
return
|
||||
|
||||
def test_06_router_advanced(self):
|
||||
"""Test router advanced setup
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. verify that listRouters returned a 'Running' router
|
||||
# 2. router will have dns and gateway as in listZones, listVlanIpRanges
|
||||
# 3. router will have guest,public and linklocal IPs
|
||||
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_router_response),
|
||||
0,
|
||||
"Check list router response"
|
||||
)
|
||||
for router in list_router_response:
|
||||
self.assertEqual(
|
||||
router.state,
|
||||
'Running',
|
||||
"Check list router response for router state"
|
||||
)
|
||||
|
||||
zones = list_zones(
|
||||
self.apiclient,
|
||||
id=router.zoneid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(zones, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
zone = zones[0]
|
||||
|
||||
self.assertEqual(
|
||||
router.dns1,
|
||||
zone.dns1,
|
||||
"Compare DNS1 of router and zone"
|
||||
)
|
||||
self.assertEqual(
|
||||
router.dns2,
|
||||
zone.dns2,
|
||||
"Compare DNS2 of router and zone"
|
||||
)
|
||||
self.assertEqual(
|
||||
hasattr(router, 'guestipaddress'),
|
||||
True,
|
||||
"Check whether router has guest IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(router, 'linklocalip'),
|
||||
True,
|
||||
"Check whether router has link local IP field"
|
||||
)
|
||||
|
||||
#Fetch corresponding ip ranges information from listVlanIpRanges
|
||||
ipranges_response = list_vlan_ipranges(
|
||||
self.apiclient,
|
||||
zoneid=router.zoneid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(ipranges_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
iprange = ipranges_response[0]
|
||||
self.assertEqual(
|
||||
router.gateway,
|
||||
iprange.gateway,
|
||||
"Check gateway with that of corresponding IP range"
|
||||
)
|
||||
return
|
||||
|
||||
def test_07_stop_router(self):
|
||||
"""Test stop router
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. listRouter should report the router for the account as stopped
|
||||
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
self.debug("Stopping the router with ID: %s" % router.id)
|
||||
#Stop the router
|
||||
cmd = stopRouter.stopRouterCmd()
|
||||
cmd.id = router.id
|
||||
self.apiclient.stopRouter(cmd)
|
||||
|
||||
#List routers to check state of router
|
||||
router_response = list_routers(
|
||||
self.apiclient,
|
||||
id=router.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
#List router should have router in stopped state
|
||||
self.assertEqual(
|
||||
router_response[0].state,
|
||||
'Stopped',
|
||||
"Check list router response for router state"
|
||||
)
|
||||
return
|
||||
|
||||
def test_08_start_router(self):
|
||||
"""Test start router
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. listRouter should report the router for the account as stopped
|
||||
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
self.debug("Starting the router with ID: %s" % router.id)
|
||||
|
||||
#Start the router
|
||||
cmd = startRouter.startRouterCmd()
|
||||
cmd.id = router.id
|
||||
self.apiclient.startRouter(cmd)
|
||||
|
||||
#List routers to check state of router
|
||||
router_response = list_routers(
|
||||
self.apiclient,
|
||||
id=router.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
#List router should have router in running state
|
||||
self.assertEqual(
|
||||
router_response[0].state,
|
||||
'Running',
|
||||
"Check list router response for router state"
|
||||
)
|
||||
return
|
||||
|
||||
def test_09_reboot_router(self):
|
||||
"""Test reboot router
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. listRouter should report the router for the account as stopped
|
||||
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
public_ip = router.publicip
|
||||
|
||||
self.debug("Rebooting the router with ID: %s" % router.id)
|
||||
|
||||
#Reboot the router
|
||||
cmd = rebootRouter.rebootRouterCmd()
|
||||
cmd.id = router.id
|
||||
self.apiclient.rebootRouter(cmd)
|
||||
|
||||
#List routers to check state of router
|
||||
router_response = list_routers(
|
||||
self.apiclient,
|
||||
id=router.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
#List router should have router in running state and same public IP
|
||||
self.assertEqual(
|
||||
router_response[0].state,
|
||||
'Running',
|
||||
"Check list router response for router state"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
router_response[0].publicip,
|
||||
public_ip,
|
||||
"Check list router response for router public IP"
|
||||
)
|
||||
return
|
||||
|
||||
def test_10_network_gc(self):
|
||||
"""Test network GC
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. stop All User VMs in the account
|
||||
# 2. wait for network.gc.interval time"
|
||||
# 3. After network.gc.interval, router should be stopped
|
||||
# 4. ListRouters should return the router in Stopped state
|
||||
|
||||
list_vms = list_virtual_machines(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_vms, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_vms),
|
||||
0,
|
||||
"Check length of list VM response"
|
||||
)
|
||||
|
||||
for vm in list_vms:
|
||||
self.debug("Stopping the VM with ID: %s" % vm.id)
|
||||
# Stop all virtual machines associated with that account
|
||||
cmd = stopVirtualMachine.stopVirtualMachineCmd()
|
||||
cmd.id = vm.id
|
||||
self.apiclient.stopVirtualMachine(cmd)
|
||||
|
||||
# Get network.gc.interval config value
|
||||
config = list_configurations(
|
||||
self.apiclient,
|
||||
name='network.gc.interval'
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(config, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
gcinterval = config[0]
|
||||
|
||||
# Get network.gc.wait config value
|
||||
config = list_configurations(
|
||||
self.apiclient,
|
||||
name='network.gc.wait'
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(config, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
gcwait = config[0]
|
||||
|
||||
total_wait = int(gcinterval.value) + int(gcwait.value)
|
||||
# Wait for wait_time * 2 time to cleanup all the resources
|
||||
time.sleep(total_wait * 2)
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
#Check status of network router
|
||||
list_router_response = list_routers(
|
||||
self.apiclient,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
if isinstance(list_router_response, list):
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List router call failed!")
|
||||
time.sleep(5)
|
||||
timeout = timeout -1
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_router_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
router = list_router_response[0]
|
||||
|
||||
self.debug("Router state after network.gc.interval: %s" % router.state)
|
||||
self.assertEqual(
|
||||
router.state,
|
||||
'Stopped',
|
||||
"Check state of the router after stopping all VMs associated"
|
||||
)
|
||||
return
|
||||
380
test/integration/smoke/test_secondary_storage.py
Normal file
380
test/integration/smoke/test_secondary_storage.py
Normal file
@ -0,0 +1,380 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Secondary Storage
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
class Services:
|
||||
"""Test secondary storage Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"storage": {
|
||||
"url": "nfs://192.168.100.131/SecStorage"
|
||||
# Format: File_System_Type/Location/Path
|
||||
},
|
||||
"hypervisors": {
|
||||
0: {
|
||||
"hypervisor": "XenServer",
|
||||
"templatefilter": "self",
|
||||
},
|
||||
1: {
|
||||
"hypervisor": "KVM",
|
||||
"templatefilter": "self",
|
||||
},
|
||||
2: {
|
||||
"hypervisor": "VMWare",
|
||||
"templatefilter": "self",
|
||||
},
|
||||
},
|
||||
"sleep": 60,
|
||||
"timeout": 5,
|
||||
}
|
||||
|
||||
class TestSecStorageServices(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.api_client = super(TestSecStorageServices, cls).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
cls._cleanup = []
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
#Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.cleanup = []
|
||||
self.services = Services().services
|
||||
# Get Zone and pod
|
||||
self.domain = get_domain(self.apiclient, self.services)
|
||||
self.zone = get_zone(self.apiclient, self.services)
|
||||
self.pod = get_pod(self.apiclient, self.zone.id)
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_01_add_sec_storage(self):
|
||||
"""Test secondary storage
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. secondary storage should be added to the zone.
|
||||
# 2. Verify with listHosts and type secondarystorage
|
||||
|
||||
cmd = addSecondaryStorage.addSecondaryStorageCmd()
|
||||
cmd.zoneid = self.zone.id
|
||||
cmd.url = self.services["storage"]["url"]
|
||||
sec_storage = self.apiclient.addSecondaryStorage(cmd)
|
||||
|
||||
self.debug("Added secondary storage to zone: %s" % self.zone.id)
|
||||
# Cleanup at the end
|
||||
self._cleanup.append(sec_storage)
|
||||
|
||||
self.assertEqual(
|
||||
sec_storage.zoneid,
|
||||
self.zone.id,
|
||||
"Check zoneid where sec storage is added"
|
||||
)
|
||||
|
||||
list_hosts_response = list_hosts(
|
||||
self.apiclient,
|
||||
type='SecondaryStorage',
|
||||
id=sec_storage.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_hosts_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_hosts_response),
|
||||
0,
|
||||
"Check list Hosts response"
|
||||
)
|
||||
|
||||
host_response = list_hosts_response[0]
|
||||
#Check if host is Up and running
|
||||
self.assertEqual(
|
||||
host_response.id,
|
||||
sec_storage.id,
|
||||
"Check ID of secondary storage"
|
||||
)
|
||||
self.assertEqual(
|
||||
sec_storage.type,
|
||||
host_response.type,
|
||||
"Check type of host from list hosts response"
|
||||
)
|
||||
return
|
||||
|
||||
def test_02_sys_vm_start(self):
|
||||
"""Test system VM start
|
||||
"""
|
||||
|
||||
# 1. verify listHosts has all 'routing' hosts in UP state
|
||||
# 2. verify listStoragePools shows all primary storage pools
|
||||
# in UP state
|
||||
# 3. verify that secondary storage was added successfully
|
||||
|
||||
list_hosts_response = list_hosts(
|
||||
self.apiclient,
|
||||
type='Routing',
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_hosts_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
# ListHosts has all 'routing' hosts in UP state
|
||||
self.assertNotEqual(
|
||||
len(list_hosts_response),
|
||||
0,
|
||||
"Check list host response"
|
||||
)
|
||||
for host in list_hosts_response:
|
||||
self.assertEqual(
|
||||
host.state,
|
||||
'Up',
|
||||
"Check state of routing hosts is Up or not"
|
||||
)
|
||||
|
||||
# ListStoragePools shows all primary storage pools in UP state
|
||||
list_storage_response = list_storage_pools(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_storage_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_storage_response),
|
||||
0,
|
||||
"Check list storage pools response"
|
||||
)
|
||||
|
||||
for primary_storage in list_hosts_response:
|
||||
self.assertEqual(
|
||||
primary_storage.state,
|
||||
'Up',
|
||||
"Check state of primary storage pools is Up or not"
|
||||
)
|
||||
|
||||
# Secondary storage is added successfully
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_hosts_response = list_hosts(
|
||||
self.apiclient,
|
||||
type='SecondaryStorage',
|
||||
zoneid=self.zone.id,
|
||||
)
|
||||
|
||||
if not isinstance(list_hosts_response, list):
|
||||
# Sleep to ensure Secondary storage is Up
|
||||
time.sleep(int(self.services["sleep"]))
|
||||
timeout = timeout - 1
|
||||
elif timeout == 0 or isinstance(list_hosts_response, list):
|
||||
break
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_hosts_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_hosts_response),
|
||||
0,
|
||||
"Check list Hosts response"
|
||||
)
|
||||
|
||||
host_response = list_hosts_response[0]
|
||||
#Check if host is Up and running
|
||||
self.assertEqual(
|
||||
host_response.state,
|
||||
'Up',
|
||||
"Check state of secondary storage"
|
||||
)
|
||||
self.debug("Checking SSVM status in zone: %s" % self.zone.id)
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
|
||||
while True:
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='secondarystoragevm',
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id
|
||||
)
|
||||
if not isinstance(list_ssvm_response, list):
|
||||
# Sleep to ensure SSVMs are Up and Running
|
||||
time.sleep(int(self.services["sleep"]))
|
||||
timeout = timeout - 1
|
||||
elif timeout == 0 or isinstance(list_ssvm_response, list):
|
||||
break
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_ssvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
#Verify SSVM response
|
||||
self.assertNotEqual(
|
||||
len(list_ssvm_response),
|
||||
0,
|
||||
"Check list System VMs response"
|
||||
)
|
||||
|
||||
for ssvm in list_ssvm_response:
|
||||
self.assertEqual(
|
||||
ssvm.state,
|
||||
'Running',
|
||||
"Check whether state of SSVM is running"
|
||||
)
|
||||
return
|
||||
|
||||
def test_03_sys_template_ready(self):
|
||||
"""Test system templates are ready
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# If SSVM is in UP state and running
|
||||
# 1. wait for listTemplates to show all builtin templates
|
||||
# downloaded for all added hypervisors and in “Ready” state"
|
||||
|
||||
for k, v in self.services["hypervisors"].items():
|
||||
|
||||
self.debug("Downloading BUILTIN templates in zone: %s" %
|
||||
self.zone.id)
|
||||
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
hypervisor=v["hypervisor"],
|
||||
zoneid=self.zone.id,
|
||||
templatefilter=v["templatefilter"],
|
||||
listall=True,
|
||||
account='system',
|
||||
domainid=self.domain.id
|
||||
)
|
||||
|
||||
# Ensure all BUILTIN templates are downloaded
|
||||
templateid = None
|
||||
for template in list_template_response:
|
||||
if template.templatetype == "BUILTIN":
|
||||
templateid = template.id
|
||||
|
||||
# Wait to start a downloading of template
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
while True and (templateid != None):
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
template_response = list_templates(
|
||||
self.apiclient,
|
||||
id=templateid,
|
||||
zoneid=self.zone.id,
|
||||
templatefilter=v["templatefilter"],
|
||||
listall=True,
|
||||
account='system',
|
||||
domainid=self.domain.id
|
||||
)
|
||||
|
||||
if isinstance(template_response, list):
|
||||
template = template_response[0]
|
||||
break
|
||||
|
||||
elif timeout == 0:
|
||||
raise Exception("List template API call failed.")
|
||||
|
||||
time.sleep(1)
|
||||
timeout = timeout - 1
|
||||
|
||||
# If template is ready,
|
||||
# template.status = Download Complete
|
||||
# Downloading - x% Downloaded
|
||||
# Error - Any other string
|
||||
if template.status == 'Download Complete' :
|
||||
break
|
||||
elif 'Downloaded' not in template.status.split():
|
||||
raise Exception
|
||||
elif 'Downloaded' in template.status.split():
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
#Ensuring the template is in ready state
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
template_response = list_templates(
|
||||
self.apiclient,
|
||||
id=templateid,
|
||||
zoneid=self.zone.id,
|
||||
templatefilter=v["templatefilter"],
|
||||
listall=True,
|
||||
account='system',
|
||||
domainid=self.domain.id
|
||||
)
|
||||
|
||||
if isinstance(template_response, list):
|
||||
template = template_response[0]
|
||||
break
|
||||
|
||||
elif timeout == 0:
|
||||
raise Exception("List template API call failed.")
|
||||
|
||||
time.sleep(1)
|
||||
timeout = timeout - 1
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(template_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
template = template_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
template.isready,
|
||||
True,
|
||||
"Check whether state of template is ready or not"
|
||||
)
|
||||
return
|
||||
238
test/integration/smoke/test_service_offerings.py
Normal file
238
test/integration/smoke/test_service_offerings.py
Normal file
@ -0,0 +1,238 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Service offerings"""
|
||||
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test Service offerings Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"off":
|
||||
{
|
||||
"name": "Service Offering",
|
||||
"displaytext": "Service Offering",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # MHz
|
||||
"memory": 64, # in MBs
|
||||
},
|
||||
}
|
||||
|
||||
class TestCreateServiceOffering(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
self.services = Services().services
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def test_01_create_service_offering(self):
|
||||
"""Test to create service offering"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. createServiceOfferings should return a valid information for newly created offering
|
||||
# 2. The Cloud Database contains the valid information
|
||||
|
||||
service_offering = ServiceOffering.create(
|
||||
self.apiclient,
|
||||
self.services["off"]
|
||||
)
|
||||
self.cleanup.append(service_offering)
|
||||
|
||||
self.debug("Created service offering with ID: %s" % service_offering.id)
|
||||
|
||||
list_service_response = list_service_offering(
|
||||
self.apiclient,
|
||||
id=service_offering.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_service_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_service_response),
|
||||
0,
|
||||
"Check Service offering is created"
|
||||
)
|
||||
service_response = list_service_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
list_service_response[0].cpunumber,
|
||||
self.services["off"]["cpunumber"],
|
||||
"Check server id in createServiceOffering"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_service_response[0].cpuspeed,
|
||||
self.services["off"]["cpuspeed"],
|
||||
"Check cpuspeed in createServiceOffering"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_service_response[0].displaytext,
|
||||
self.services["off"]["displaytext"],
|
||||
"Check server displaytext in createServiceOfferings"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_service_response[0].memory,
|
||||
self.services["off"]["memory"],
|
||||
"Check memory in createServiceOffering"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_service_response[0].name,
|
||||
self.services["off"]["name"],
|
||||
"Check name in createServiceOffering"
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class TestServiceOfferings(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
|
||||
def tearDown(self):
|
||||
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.services = Services().services
|
||||
cls.api_client = super(TestServiceOfferings, cls).getClsTestClient().getApiClient()
|
||||
cls.service_offering_1 = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["off"]
|
||||
)
|
||||
cls.service_offering_2 = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["off"]
|
||||
)
|
||||
cls._cleanup = [cls.service_offering_1]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestServiceOfferings, cls).getClsTestClient().getApiClient()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_02_edit_service_offering(self):
|
||||
"""Test to update existing service offering"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. updateServiceOffering should return
|
||||
# a valid information for newly created offering
|
||||
|
||||
#Generate new name & displaytext from random data
|
||||
random_displaytext = random_gen()
|
||||
random_name = random_gen()
|
||||
|
||||
self.debug("Updating service offering with ID: %s" %
|
||||
self.service_offering_1.id)
|
||||
|
||||
cmd = updateServiceOffering.updateServiceOfferingCmd()
|
||||
#Add parameters for API call
|
||||
cmd.id = self.service_offering_1.id
|
||||
cmd.displaytext = random_displaytext
|
||||
cmd.name = random_name
|
||||
self.apiclient.updateServiceOffering(cmd)
|
||||
|
||||
list_service_response = list_service_offering(
|
||||
self.apiclient,
|
||||
id=self.service_offering_1.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_service_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_service_response),
|
||||
0,
|
||||
"Check Service offering is updated"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
list_service_response[0].displaytext,
|
||||
random_displaytext,
|
||||
"Check server displaytext in updateServiceOffering"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_service_response[0].name,
|
||||
random_name,
|
||||
"Check server name in updateServiceOffering"
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
def test_03_delete_service_offering(self):
|
||||
"""Test to delete service offering"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. deleteServiceOffering should return
|
||||
# a valid information for newly created offering
|
||||
|
||||
self.debug("Deleting service offering with ID: %s" %
|
||||
self.service_offering_2.id)
|
||||
|
||||
self.service_offering_2.delete(self.apiclient)
|
||||
|
||||
list_service_response = list_service_offering(
|
||||
self.apiclient,
|
||||
id=self.service_offering_2.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
list_service_response,
|
||||
None,
|
||||
"Check if service offering exists in listDiskOfferings"
|
||||
)
|
||||
|
||||
return
|
||||
1159
test/integration/smoke/test_snapshots.py
Normal file
1159
test/integration/smoke/test_snapshots.py
Normal file
File diff suppressed because it is too large
Load Diff
916
test/integration/smoke/test_ssvm.py
Normal file
916
test/integration/smoke/test_ssvm.py
Normal file
@ -0,0 +1,916 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for SSVM
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
import telnetlib
|
||||
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
class Services:
|
||||
"""Test SSVM Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"host": {
|
||||
"username": 'root', # Credentials for SSH
|
||||
"password": 'fr3sca',
|
||||
"publicport": 22,
|
||||
},
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
}
|
||||
|
||||
class TestSSVMs(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.cleanup = []
|
||||
self.services = Services().services
|
||||
self.zone = get_zone(self.apiclient, self.services)
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_01_list_sec_storage_vm(self):
|
||||
"""Test List secondary storage VMs
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. listSystemVM (systemvmtype=secondarystoragevm)
|
||||
# should return only ONE SSVM per zone
|
||||
# 2. The returned SSVM should be in Running state
|
||||
# 3. listSystemVM for secondarystoragevm should list publicip,
|
||||
# privateip and link-localip
|
||||
# 4. The gateway programmed on the ssvm by listSystemVm should be
|
||||
# the same as the gateway returned by listVlanIpRanges
|
||||
# 5. DNS entries must match those given for the zone
|
||||
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='secondarystoragevm',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_ssvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
#Verify SSVM response
|
||||
self.assertNotEqual(
|
||||
len(list_ssvm_response),
|
||||
0,
|
||||
"Check list System VMs response"
|
||||
)
|
||||
|
||||
list_zones_response = list_zones(self.apiclient)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_zones_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.debug("Number of zones: %s" % len(list_zones_response))
|
||||
self.debug("Number of SSVMs: %s" % len(list_ssvm_response))
|
||||
# Number of Sec storage VMs = No of Zones
|
||||
self.assertEqual(
|
||||
len(list_ssvm_response),
|
||||
len(list_zones_response),
|
||||
"Check number of SSVMs with number of zones"
|
||||
)
|
||||
#For each secondary storage VM check private IP,
|
||||
#public IP, link local IP and DNS
|
||||
for ssvm in list_ssvm_response:
|
||||
|
||||
self.debug("SSVM state: %s" % ssvm.state)
|
||||
self.assertEqual(
|
||||
ssvm.state,
|
||||
'Running',
|
||||
"Check whether state of SSVM is running"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(ssvm, 'privateip'),
|
||||
True,
|
||||
"Check whether SSVM has private IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(ssvm, 'linklocalip'),
|
||||
True,
|
||||
"Check whether SSVM has link local IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(ssvm, 'publicip'),
|
||||
True,
|
||||
"Check whether SSVM has public IP field"
|
||||
)
|
||||
|
||||
#Fetch corresponding ip ranges information from listVlanIpRanges
|
||||
ipranges_response = list_vlan_ipranges(
|
||||
self.apiclient,
|
||||
zoneid=ssvm.zoneid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(ipranges_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
iprange = ipranges_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
ssvm.gateway,
|
||||
iprange.gateway,
|
||||
"Check gateway with that of corresponding ip range"
|
||||
)
|
||||
|
||||
#Fetch corresponding zone information from listZones
|
||||
zone_response = list_zones(
|
||||
self.apiclient,
|
||||
id=ssvm.zoneid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(zone_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertEqual(
|
||||
ssvm.dns1,
|
||||
zone_response[0].dns1,
|
||||
"Check DNS1 with that of corresponding zone"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
ssvm.dns2,
|
||||
zone_response[0].dns2,
|
||||
"Check DNS2 with that of corresponding zone"
|
||||
)
|
||||
return
|
||||
|
||||
def test_02_list_cpvm_vm(self):
|
||||
"""Test List console proxy VMs
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. listSystemVM (systemvmtype=consoleproxy) should return
|
||||
# at least ONE CPVM per zone
|
||||
# 2. The returned ConsoleProxyVM should be in Running state
|
||||
# 3. listSystemVM for console proxy should list publicip, privateip
|
||||
# and link-localip
|
||||
# 4. The gateway programmed on the console proxy should be the same
|
||||
# as the gateway returned by listZones
|
||||
# 5. DNS entries must match those given for the zone
|
||||
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='consoleproxy',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_cpvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
#Verify CPVM response
|
||||
self.assertNotEqual(
|
||||
len(list_cpvm_response),
|
||||
0,
|
||||
"Check list System VMs response"
|
||||
)
|
||||
list_zones_response = list_zones(self.apiclient)
|
||||
# Number of Console Proxy VMs = No of Zones
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_zones_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.debug("Number of zones: %s" % len(list_zones_response))
|
||||
self.debug("Number of CPVMs: %s" % len(list_cpvm_response))
|
||||
|
||||
self.assertEqual(
|
||||
len(list_cpvm_response),
|
||||
len(list_zones_response),
|
||||
"Check number of CPVMs with number of zones"
|
||||
)
|
||||
#For each CPVM check private IP, public IP, link local IP and DNS
|
||||
for cpvm in list_cpvm_response:
|
||||
|
||||
self.debug("CPVM state: %s" % cpvm.state)
|
||||
self.assertEqual(
|
||||
cpvm.state,
|
||||
'Running',
|
||||
"Check whether state of CPVM is running"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(cpvm, 'privateip'),
|
||||
True,
|
||||
"Check whether CPVM has private IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(cpvm, 'linklocalip'),
|
||||
True,
|
||||
"Check whether CPVM has link local IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(cpvm, 'publicip'),
|
||||
True,
|
||||
"Check whether CPVM has public IP field"
|
||||
)
|
||||
#Fetch corresponding ip ranges information from listVlanIpRanges
|
||||
ipranges_response = list_vlan_ipranges(
|
||||
self.apiclient,
|
||||
zoneid=cpvm.zoneid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(ipranges_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
iprange = ipranges_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
cpvm.gateway,
|
||||
iprange.gateway,
|
||||
"Check gateway with that of corresponding ip range"
|
||||
)
|
||||
|
||||
#Fetch corresponding zone information from listZones
|
||||
zone_response = list_zones(
|
||||
self.apiclient,
|
||||
id=cpvm.zoneid
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
cpvm.dns1,
|
||||
zone_response[0].dns1,
|
||||
"Check DNS1 with that of corresponding zone"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
cpvm.dns2,
|
||||
zone_response[0].dns2,
|
||||
"Check DNS2 with that of corresponding zone"
|
||||
)
|
||||
return
|
||||
|
||||
def test_03_ssvm_internals(self):
|
||||
"""Test SSVM Internals"""
|
||||
|
||||
# Validate the following
|
||||
# 1. The SSVM check script should not return any
|
||||
# WARN|ERROR|FAIL messages
|
||||
# 2. If you are unable to login to the SSVM with the signed key
|
||||
# then test is deemed a failure
|
||||
# 3. There should be only one ""cloud"" process running within the SSVM
|
||||
# 4. If no process is running/multiple process are running
|
||||
# then the test is a failure
|
||||
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='secondarystoragevm',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_ssvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
ssvm = list_ssvm_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=ssvm.hostid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Running SSVM check script")
|
||||
|
||||
result = get_process_status(
|
||||
host.ipaddress,
|
||||
self.services['host']["publicport"],
|
||||
self.services['host']["username"],
|
||||
self.services['host']["password"],
|
||||
ssvm.linklocalip,
|
||||
"/usr/local/cloud/systemvm/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL"
|
||||
)
|
||||
res = str(result)
|
||||
self.debug("SSVM script output: %s" % res)
|
||||
|
||||
self.assertEqual(
|
||||
res.count("ERROR"),
|
||||
1,
|
||||
"Check for Errors in tests"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
res.count("WARNING"),
|
||||
1,
|
||||
"Check for warnings in tests"
|
||||
)
|
||||
|
||||
#Check status of cloud service
|
||||
result = get_process_status(
|
||||
host.ipaddress,
|
||||
self.services['host']["publicport"],
|
||||
self.services['host']["username"],
|
||||
self.services['host']["password"],
|
||||
ssvm.linklocalip,
|
||||
"service cloud status"
|
||||
)
|
||||
res = str(result)
|
||||
self.debug("Cloud Process status: %s" % res)
|
||||
# cloud.com service (type=secstorage) is running: process id: 2346
|
||||
self.assertEqual(
|
||||
res.count("is running"),
|
||||
1,
|
||||
"Check cloud service is running or not"
|
||||
)
|
||||
return
|
||||
|
||||
def test_04_cpvm_internals(self):
|
||||
"""Test CPVM Internals"""
|
||||
|
||||
# Validate the following
|
||||
# 1. test that telnet access on 8250 is available to
|
||||
# the management server for the CPVM
|
||||
# 2. No telnet access, test FAIL
|
||||
# 3. Service cloud status should report cloud agent status to be
|
||||
# running
|
||||
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='consoleproxy',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_cpvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
cpvm = list_cpvm_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=cpvm.hostid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
try:
|
||||
telnet = telnetlib.Telnet(
|
||||
str(self.apiclient.connection.mgtSvr),
|
||||
'8250'
|
||||
)
|
||||
self.debug("Telnet management server (IP: %s)" %
|
||||
self.apiclient.connection.mgtSvr)
|
||||
except Exception as e:
|
||||
self.fail(
|
||||
"Telnet Access failed for %s: %s" % \
|
||||
(self.apiclient.connection.mgtSvr, e)
|
||||
)
|
||||
|
||||
self.debug("Checking cloud process status")
|
||||
|
||||
result = get_process_status(
|
||||
host.ipaddress,
|
||||
self.services['host']["publicport"],
|
||||
self.services['host']["username"],
|
||||
self.services['host']["password"],
|
||||
cpvm.linklocalip,
|
||||
"service cloud status"
|
||||
)
|
||||
res = str(result)
|
||||
self.debug("Cloud Process status: %s" % res)
|
||||
self.assertEqual(
|
||||
res.count("is running"),
|
||||
1,
|
||||
"Check cloud service is running or not"
|
||||
)
|
||||
return
|
||||
|
||||
def test_05_stop_ssvm(self):
|
||||
"""Test stop SSVM
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. The SSVM should go to stop state
|
||||
# 2. After a brief delay of say one minute, the SSVM should be
|
||||
# restarted once again and return to Running state with previous two
|
||||
# test cases still passing
|
||||
# 3. If either of the two above steps fail the test is a failure
|
||||
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='secondarystoragevm',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_ssvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
ssvm = list_ssvm_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=ssvm.hostid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Stopping SSVM: %s" % ssvm.id)
|
||||
cmd = stopSystemVm.stopSystemVmCmd()
|
||||
cmd.id = ssvm.id
|
||||
self.apiclient.stopSystemVm(cmd)
|
||||
|
||||
# Sleep to ensure that VM is in proper state
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
id=ssvm.id
|
||||
)
|
||||
if isinstance(list_ssvm_response, list):
|
||||
if list_ssvm_response[0].state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List SSVM call failed!")
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_ssvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
ssvm_response = list_ssvm_response[0]
|
||||
self.debug("SSVM state after debug: %s" % ssvm_response.state)
|
||||
self.assertEqual(
|
||||
ssvm_response.state,
|
||||
'Running',
|
||||
"Check whether SSVM is running or not"
|
||||
)
|
||||
# Call above tests to ensure SSVM is properly running
|
||||
self.test_01_list_sec_storage_vm()
|
||||
self.test_03_ssvm_internals()
|
||||
return
|
||||
|
||||
def test_06_stop_cpvm(self):
|
||||
"""Test stop CPVM
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. The CPVM should go to stop state
|
||||
# 2. After a brief delay of say one minute, the SSVM should be
|
||||
# restarted once again and return to Running state with previous
|
||||
# two test cases still passing
|
||||
# 3. If either of the two above steps fail the test is a failure
|
||||
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='consoleproxy',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_cpvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
cpvm = list_cpvm_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=cpvm.hostid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Stopping CPVM: %s" % cpvm.id)
|
||||
cmd = stopSystemVm.stopSystemVmCmd()
|
||||
cmd.id = cpvm.id
|
||||
self.apiclient.stopSystemVm(cmd)
|
||||
|
||||
# Sleep to ensure that VM is in proper state
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
id=cpvm.id
|
||||
)
|
||||
if isinstance(list_cpvm_response, list):
|
||||
if list_cpvm_response[0].state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List CPVM call failed!")
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
cpvm_response = list_cpvm_response[0]
|
||||
|
||||
self.debug("CPVM state after debug: %s" % cpvm_response.state)
|
||||
|
||||
self.assertEqual(
|
||||
cpvm_response.state,
|
||||
'Running',
|
||||
"Check whether CPVM is running or not"
|
||||
)
|
||||
# Call above tests to ensure CPVM is properly running
|
||||
self.test_02_list_cpvm_vm()
|
||||
self.test_04_cpvm_internals()
|
||||
return
|
||||
|
||||
def test_07_reboot_ssvm(self):
|
||||
"""Test reboot SSVM
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. The SSVM should go to stop and return to Running state
|
||||
# 2. SSVM's public-ip and private-ip must remain the same
|
||||
# before and after reboot
|
||||
# 3. The cloud process should still be running within the SSVM
|
||||
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='secondarystoragevm',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_ssvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
ssvm_response = list_ssvm_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=ssvm_response.hostid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
#Store the public & private IP values before reboot
|
||||
old_public_ip = ssvm_response.publicip
|
||||
old_private_ip = ssvm_response.privateip
|
||||
|
||||
self.debug("Rebooting SSVM: %s" % ssvm_response.id)
|
||||
cmd = rebootSystemVm.rebootSystemVmCmd()
|
||||
cmd.id = ssvm_response.id
|
||||
self.apiclient.rebootSystemVm(cmd)
|
||||
|
||||
# Sleep to ensure that VM is in proper state
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
id=ssvm_response.id
|
||||
)
|
||||
if isinstance(list_ssvm_response, list):
|
||||
if list_ssvm_response[0].state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List SSVM call failed!")
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
ssvm_response = list_ssvm_response[0]
|
||||
self.debug("SSVM State: %s" % ssvm_response.state)
|
||||
self.assertEqual(
|
||||
'Running',
|
||||
str(ssvm_response.state),
|
||||
"Check whether CPVM is running or not"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
ssvm_response.publicip,
|
||||
old_public_ip,
|
||||
"Check Public IP after reboot with that of before reboot"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
ssvm_response.privateip,
|
||||
old_private_ip,
|
||||
"Check Private IP after reboot with that of before reboot"
|
||||
)
|
||||
#Call to verify cloud process is running
|
||||
self.test_03_ssvm_internals()
|
||||
return
|
||||
|
||||
def test_08_reboot_cpvm(self):
|
||||
"""Test reboot CPVM
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. The CPVM should go to stop and return to Running state
|
||||
# 2. CPVM's public-ip and private-ip must remain
|
||||
# the same before and after reboot
|
||||
# 3. the cloud process should still be running within the CPVM
|
||||
|
||||
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='consoleproxy',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_cpvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
cpvm_response = list_cpvm_response[0]
|
||||
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=cpvm_response.hostid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
host = hosts[0]
|
||||
|
||||
#Store the public & private IP values before reboot
|
||||
old_public_ip = cpvm_response.publicip
|
||||
old_private_ip = cpvm_response.privateip
|
||||
|
||||
self.debug("Rebooting CPVM: %s" % cpvm_response.id)
|
||||
|
||||
cmd = rebootSystemVm.rebootSystemVmCmd()
|
||||
cmd.id = cpvm_response.id
|
||||
self.apiclient.rebootSystemVm(cmd)
|
||||
|
||||
# Sleep to ensure that VM is in proper state
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
id=cpvm_response.id
|
||||
)
|
||||
if isinstance(list_cpvm_response, list):
|
||||
if list_cpvm_response[0].state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List CPVM call failed!")
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
cpvm_response = list_cpvm_response[0]
|
||||
|
||||
self.debug("CPVM state: %s" % cpvm_response.state)
|
||||
self.assertEqual(
|
||||
'Running',
|
||||
str(cpvm_response.state),
|
||||
"Check whether CPVM is running or not"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
cpvm_response.publicip,
|
||||
old_public_ip,
|
||||
"Check Public IP after reboot with that of before reboot"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
cpvm_response.privateip,
|
||||
old_private_ip,
|
||||
"Check Private IP after reboot with that of before reboot"
|
||||
)
|
||||
#Call to verify cloud process is running
|
||||
self.test_04_cpvm_internals()
|
||||
return
|
||||
|
||||
def test_09_destroy_ssvm(self):
|
||||
"""Test destroy SSVM
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. SSVM should be completely destroyed and a new one will spin up
|
||||
# 2. listSystemVMs will show a different name for the
|
||||
# systemVM from what it was before
|
||||
# 3. new SSVM will have a public/private and link-local-ip
|
||||
# 4. cloud process within SSVM must be up and running
|
||||
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='secondarystoragevm',
|
||||
state='Running',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_ssvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
ssvm_response = list_ssvm_response[0]
|
||||
|
||||
old_name = ssvm_response.name
|
||||
|
||||
self.debug("Destroying SSVM: %s" % ssvm_response.id)
|
||||
cmd = destroySystemVm.destroySystemVmCmd()
|
||||
cmd.id = ssvm_response.id
|
||||
self.apiclient.destroySystemVm(cmd)
|
||||
|
||||
# Sleep to ensure that VM is in proper state
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_ssvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
systemvmtype='secondarystoragevm'
|
||||
)
|
||||
if isinstance(list_ssvm_response, list):
|
||||
if list_ssvm_response[0].state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List SSVM call failed!")
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
ssvm_response = list_ssvm_response[0]
|
||||
|
||||
# Verify Name, Public IP, Private IP and Link local IP
|
||||
# for newly created SSVM
|
||||
self.assertNotEqual(
|
||||
ssvm_response.name,
|
||||
old_name,
|
||||
"Check SSVM new name with name of destroyed SSVM"
|
||||
)
|
||||
self.assertEqual(
|
||||
hasattr(ssvm_response, 'privateip'),
|
||||
True,
|
||||
"Check whether SSVM has private IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(ssvm_response, 'linklocalip'),
|
||||
True,
|
||||
"Check whether SSVM has link local IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(ssvm_response, 'publicip'),
|
||||
True,
|
||||
"Check whether SSVM has public IP field"
|
||||
)
|
||||
|
||||
#Call to verify cloud process is running
|
||||
self.test_03_ssvm_internals()
|
||||
return
|
||||
|
||||
def test_10_destroy_cpvm(self):
|
||||
"""Test destroy CPVM
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. CPVM should be completely destroyed and a new one will spin up
|
||||
# 2. listSystemVMs will show a different name for the systemVM from
|
||||
# what it was before
|
||||
# 3. new CPVM will have a public/private and link-local-ip
|
||||
# 4. cloud process within CPVM must be up and running
|
||||
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='consoleproxy',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_cpvm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
cpvm_response = list_cpvm_response[0]
|
||||
|
||||
old_name = cpvm_response.name
|
||||
|
||||
self.debug("Destroying CPVM: %s" % cpvm_response.id)
|
||||
cmd = destroySystemVm.destroySystemVmCmd()
|
||||
cmd.id = cpvm_response.id
|
||||
self.apiclient.destroySystemVm(cmd)
|
||||
|
||||
# Sleep to ensure that VM is in proper state
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
list_cpvm_response = list_ssvms(
|
||||
self.apiclient,
|
||||
systemvmtype='consoleproxy',
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
if isinstance(list_cpvm_response, list):
|
||||
if list_cpvm_response[0].state == 'Running':
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List CPVM call failed!")
|
||||
|
||||
time.sleep(self.services["sleep"])
|
||||
timeout = timeout - 1
|
||||
|
||||
cpvm_response = list_cpvm_response[0]
|
||||
|
||||
# Verify Name, Public IP, Private IP and Link local IP
|
||||
# for newly created CPVM
|
||||
self.assertNotEqual(
|
||||
cpvm_response.name,
|
||||
old_name,
|
||||
"Check SSVM new name with name of destroyed CPVM"
|
||||
)
|
||||
self.assertEqual(
|
||||
hasattr(cpvm_response, 'privateip'),
|
||||
True,
|
||||
"Check whether CPVM has private IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(cpvm_response, 'linklocalip'),
|
||||
True,
|
||||
"Check whether CPVM has link local IP field"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
hasattr(cpvm_response, 'publicip'),
|
||||
True,
|
||||
"Check whether CPVM has public IP field"
|
||||
)
|
||||
|
||||
#Call to verify cloud process is running
|
||||
self.test_04_cpvm_internals()
|
||||
return
|
||||
753
test/integration/smoke/test_templates.py
Normal file
753
test/integration/smoke/test_templates.py
Normal file
@ -0,0 +1,753 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Templates ISO
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
import urllib
|
||||
from random import random
|
||||
#Import System modules
|
||||
import datetime
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test Templates Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # in MHz
|
||||
"memory": 64, # In MBs
|
||||
},
|
||||
"disk_offering": {
|
||||
"displaytext": "Small",
|
||||
"name": "Small",
|
||||
"disksize": 1
|
||||
},
|
||||
"virtual_machine": {
|
||||
"displayname": "testVM",
|
||||
"hypervisor": 'XenServer',
|
||||
"protocol": 'TCP',
|
||||
"ssh_port": 22,
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
},
|
||||
"volume": {
|
||||
"diskname": "Test Volume",
|
||||
},
|
||||
"template_1": {
|
||||
"displaytext": "Cent OS Template",
|
||||
"name": "Cent OS Template",
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
},
|
||||
"template_2": {
|
||||
"displaytext": "Public Template",
|
||||
"name": "Public template",
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"isextractable": True,
|
||||
"mode": "HTTP_DOWNLOAD",
|
||||
},
|
||||
"templatefilter": 'self',
|
||||
"destzoneid": 5,
|
||||
# For Copy template (Destination zone)
|
||||
"isfeatured": True,
|
||||
"ispublic": True,
|
||||
"isextractable": False,
|
||||
"bootable": True,
|
||||
"passwordenabled": True,
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"mode": 'advanced',
|
||||
# Networking mode: Advanced, basic
|
||||
"sleep": 30,
|
||||
"timeout": 10,
|
||||
}
|
||||
|
||||
|
||||
class TestCreateTemplate(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.services = Services().services
|
||||
cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient()
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
cls.disk_offering = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"]
|
||||
)
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["volume"]["diskoffering"] = cls.disk_offering.id
|
||||
cls.services["volume"]["zoneid"] = cls.zone.id
|
||||
cls.services["sourcezoneid"] = cls.zone.id
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
cls.services["account"] = cls.account.account.name
|
||||
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
#create virtual machine
|
||||
cls.virtual_machine = VirtualMachine.create(
|
||||
cls.api_client,
|
||||
cls.services["virtual_machine"],
|
||||
templateid=template.id,
|
||||
accountid=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid,
|
||||
serviceofferingid=cls.service_offering.id,
|
||||
mode=cls.services["mode"]
|
||||
)
|
||||
|
||||
#Stop virtual machine
|
||||
cls.virtual_machine.stop(cls.api_client)
|
||||
|
||||
# Poll listVM to ensure VM is stopped properly
|
||||
timeout = cls.services["timeout"]
|
||||
while True:
|
||||
time.sleep(cls.services["sleep"])
|
||||
|
||||
# Ensure that VM is in stopped state
|
||||
list_vm_response = list_virtual_machines(
|
||||
cls.api_client,
|
||||
id=cls.virtual_machine.id
|
||||
)
|
||||
|
||||
if isinstance(list_vm_response, list):
|
||||
|
||||
vm = list_vm_response[0]
|
||||
if vm.state == 'Stopped':
|
||||
break
|
||||
|
||||
if timeout == 0:
|
||||
raise Exception(
|
||||
"Failed to stop VM (ID: %s) in change service offering" %
|
||||
vm.id)
|
||||
|
||||
timeout = timeout - 1
|
||||
|
||||
list_volume = list_volumes(
|
||||
cls.api_client,
|
||||
virtualmachineid=cls.virtual_machine.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
|
||||
cls.volume = list_volume[0]
|
||||
cls._cleanup = [
|
||||
cls.account,
|
||||
cls.service_offering,
|
||||
cls.disk_offering,
|
||||
]
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestCreateTemplate, cls).getClsTestClient().getApiClient()
|
||||
#Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def test_01_create_template(self):
|
||||
"""Test create public & private template
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. database (vm_template table) should be updated
|
||||
# with newly created template
|
||||
# 2. UI should show the newly added template
|
||||
# 3. ListTemplates API should show the newly added template
|
||||
|
||||
#Create template from Virtual machine and Volume ID
|
||||
template = Template.create(
|
||||
self.apiclient,
|
||||
self.services["template_1"],
|
||||
self.volume.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.cleanup.append(template)
|
||||
|
||||
self.debug("Created template with ID: %s" % template.id)
|
||||
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templatefilter"],
|
||||
id=template.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
#Verify template response to check whether template added successfully
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template available in List Templates"
|
||||
)
|
||||
template_response = list_template_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
template_response.displaytext,
|
||||
self.services["template_1"]["displaytext"],
|
||||
"Check display text of newly created template"
|
||||
)
|
||||
name = template_response.name
|
||||
self.assertEqual(
|
||||
name.count(self.services["template_1"]["name"]),
|
||||
1,
|
||||
"Check name of newly created template"
|
||||
)
|
||||
self.assertEqual(
|
||||
template_response.ostypeid,
|
||||
self.services["template_1"]["ostypeid"],
|
||||
"Check osTypeID of newly created template"
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
class TestTemplates(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
|
||||
cls.services = Services().services
|
||||
cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient()
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
cls.disk_offering = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"]
|
||||
)
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["volume"]["diskoffering"] = cls.disk_offering.id
|
||||
cls.services["volume"]["zoneid"] = cls.zone.id
|
||||
cls.services["template_2"]["zoneid"] = cls.zone.id
|
||||
cls.services["sourcezoneid"] = cls.zone.id
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
admin=True,
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
|
||||
cls.user = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
|
||||
cls.services["account"] = cls.account.account.name
|
||||
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
#create virtual machine
|
||||
cls.virtual_machine = VirtualMachine.create(
|
||||
cls.api_client,
|
||||
cls.services["virtual_machine"],
|
||||
templateid=template.id,
|
||||
accountid=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid,
|
||||
serviceofferingid=cls.service_offering.id,
|
||||
mode=cls.services["mode"]
|
||||
)
|
||||
#Stop virtual machine
|
||||
cls.virtual_machine.stop(cls.api_client)
|
||||
|
||||
# Poll listVM to ensure VM is stopped properly
|
||||
timeout = cls.services["timeout"]
|
||||
while True:
|
||||
time.sleep(cls.services["sleep"])
|
||||
|
||||
# Ensure that VM is in stopped state
|
||||
list_vm_response = list_virtual_machines(
|
||||
cls.api_client,
|
||||
id=cls.virtual_machine.id
|
||||
)
|
||||
|
||||
if isinstance(list_vm_response, list):
|
||||
|
||||
vm = list_vm_response[0]
|
||||
if vm.state == 'Stopped':
|
||||
break
|
||||
|
||||
if timeout == 0:
|
||||
raise Exception(
|
||||
"Failed to stop VM (ID: %s) in change service offering" %
|
||||
vm.id)
|
||||
|
||||
timeout = timeout - 1
|
||||
|
||||
list_volume = list_volumes(
|
||||
cls.api_client,
|
||||
virtualmachineid=cls.virtual_machine.id,
|
||||
type='ROOT',
|
||||
listall=True
|
||||
)
|
||||
try:
|
||||
cls.volume = list_volume[0]
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
"Exception: Unable to find root volume foe VM: %s" %
|
||||
cls.virtual_machine.id)
|
||||
|
||||
#Create templates for Edit, Delete & update permissions testcases
|
||||
cls.template_1 = Template.create(
|
||||
cls.api_client,
|
||||
cls.services["template_1"],
|
||||
cls.volume.id,
|
||||
account=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid
|
||||
)
|
||||
cls.template_2 = Template.create(
|
||||
cls.api_client,
|
||||
cls.services["template_2"],
|
||||
cls.volume.id,
|
||||
account=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid
|
||||
)
|
||||
cls._cleanup = [
|
||||
cls.service_offering,
|
||||
cls.disk_offering,
|
||||
cls.account,
|
||||
cls.user
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestTemplates, cls).getClsTestClient().getApiClient()
|
||||
#Cleanup created resources such as templates and VMs
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
|
||||
self.dbclient.close()
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def test_02_edit_template(self):
|
||||
"""Test Edit template
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. UI should show the edited values for template
|
||||
# 2. database (vm_template table) should have updated values
|
||||
|
||||
new_displayText = random_gen()
|
||||
new_name = random_gen()
|
||||
|
||||
cmd = updateTemplate.updateTemplateCmd()
|
||||
# Update template attributes
|
||||
cmd.id = self.template_1.id
|
||||
cmd.displaytext = new_displayText
|
||||
cmd.name = new_name
|
||||
cmd.bootable = self.services["bootable"]
|
||||
cmd.passwordenabled = self.services["passwordenabled"]
|
||||
|
||||
self.apiclient.updateTemplate(cmd)
|
||||
|
||||
self.debug("Edited template with new name: %s" % new_name)
|
||||
|
||||
# Sleep to ensure update reflected across all the calls
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
timeout = self.services["timeout"]
|
||||
while True:
|
||||
# Verify template response for updated attributes
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templatefilter"],
|
||||
id=self.template_1.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
if isinstance(list_template_response, list):
|
||||
break
|
||||
elif timeout == 0:
|
||||
raise Exception("List Template failed!")
|
||||
|
||||
time.sleep(10)
|
||||
timeout = timeout -1
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template available in List Templates"
|
||||
)
|
||||
template_response = list_template_response[0]
|
||||
|
||||
self.debug("New Name: %s" % new_displayText)
|
||||
self.debug("Name in Template response: %s"
|
||||
% template_response.displaytext)
|
||||
self.assertEqual(
|
||||
template_response.displaytext,
|
||||
new_displayText,
|
||||
"Check display text of updated template"
|
||||
)
|
||||
self.assertEqual(
|
||||
template_response.name,
|
||||
new_name,
|
||||
"Check name of updated template"
|
||||
)
|
||||
self.assertEqual(
|
||||
str(template_response.passwordenabled).lower(),
|
||||
str(self.services["passwordenabled"]).lower(),
|
||||
"Check passwordenabled field of updated template"
|
||||
)
|
||||
self.assertEqual(
|
||||
template_response.ostypeid,
|
||||
self.services["ostypeid"],
|
||||
"Check OSTypeID of updated template"
|
||||
)
|
||||
return
|
||||
|
||||
def test_03_delete_template(self):
|
||||
"""Test delete template
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. UI should not show the deleted template
|
||||
# 2. database (vm_template table) should not contain deleted template
|
||||
|
||||
self.debug("Deleting Template ID: %s" % self.template_1.id)
|
||||
|
||||
self.template_1.delete(self.apiclient)
|
||||
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templatefilter"],
|
||||
id=self.template_1.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
# Verify template is deleted properly using ListTemplates
|
||||
self.assertEqual(
|
||||
list_template_response,
|
||||
None,
|
||||
"Check if template exists in List Templates"
|
||||
)
|
||||
return
|
||||
|
||||
def test_04_extract_template(self):
|
||||
"Test for extract template"
|
||||
|
||||
# Validate the following
|
||||
# 1. Admin should able extract and download the templates
|
||||
# 2. ListTemplates should display all the public templates
|
||||
# for all kind of users
|
||||
# 3 .ListTemplates should not display the system templates
|
||||
|
||||
self.debug("Extracting template with ID: %s" % self.template_2.id)
|
||||
|
||||
cmd = extractTemplate.extractTemplateCmd()
|
||||
cmd.id = self.template_2.id
|
||||
cmd.mode = self.services["template_2"]["mode"]
|
||||
cmd.zoneid = self.zone.id
|
||||
list_extract_response = self.apiclient.extractTemplate(cmd)
|
||||
|
||||
try:
|
||||
# Format URL to ASCII to retrieve response code
|
||||
formatted_url = urllib.unquote_plus(list_extract_response.url)
|
||||
url_response = urllib.urlopen(formatted_url)
|
||||
response_code = url_response.getcode()
|
||||
|
||||
except Exception:
|
||||
self.fail(
|
||||
"Extract Template Failed with invalid URL %s (template id: %s)" \
|
||||
% (formatted_url, self.template_2.id)
|
||||
)
|
||||
self.assertEqual(
|
||||
list_extract_response.id,
|
||||
self.template_2.id,
|
||||
"Check ID of the extracted template"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_extract_response.extractMode,
|
||||
self.services["template_2"]["mode"],
|
||||
"Check mode of extraction"
|
||||
)
|
||||
self.assertEqual(
|
||||
list_extract_response.zoneid,
|
||||
self.services["template_2"]["zoneid"],
|
||||
"Check zone ID of extraction"
|
||||
)
|
||||
self.assertEqual(
|
||||
response_code,
|
||||
200,
|
||||
"Check for a valid response download URL"
|
||||
)
|
||||
return
|
||||
|
||||
def test_05_template_permissions(self):
|
||||
"""Update & Test for template permissions"""
|
||||
|
||||
# Validate the following
|
||||
# 1. listTemplatePermissions returns valid
|
||||
# permissions set for template
|
||||
# 2. permission changes should be reflected in vm_template
|
||||
# table in database
|
||||
|
||||
self.debug("Updating Template permissions ID:%s" % self.template_2.id)
|
||||
|
||||
cmd = updateTemplatePermissions.updateTemplatePermissionsCmd()
|
||||
# Update template permissions
|
||||
cmd.id = self.template_2.id
|
||||
cmd.isfeatured = self.services["isfeatured"]
|
||||
cmd.ispublic = self.services["ispublic"]
|
||||
cmd.isextractable = self.services["isextractable"]
|
||||
self.apiclient.updateTemplatePermissions(cmd)
|
||||
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter='featured',
|
||||
id=self.template_2.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
# Verify template response for updated permissions for normal user
|
||||
template_response = list_template_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
template_response.id,
|
||||
self.template_2.id,
|
||||
"Check template ID"
|
||||
)
|
||||
self.assertEqual(
|
||||
template_response.ispublic,
|
||||
int(True),
|
||||
"Check ispublic permission of template"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
template_response.templatetype,
|
||||
'SYSTEM',
|
||||
"ListTemplates should not list any system templates"
|
||||
)
|
||||
return
|
||||
|
||||
def test_06_copy_template(self):
|
||||
"""Test for copy template from one zone to another"""
|
||||
|
||||
# Validate the following
|
||||
# 1. copy template should be successful and
|
||||
# secondary storage should contain new copied template.
|
||||
|
||||
self.debug("Copy template from Zone: %s to %s" % (
|
||||
self.services["sourcezoneid"],
|
||||
self.services["destzoneid"]
|
||||
))
|
||||
cmd = copyTemplate.copyTemplateCmd()
|
||||
cmd.id = self.template_2.id
|
||||
cmd.destzoneid = self.services["destzoneid"]
|
||||
cmd.sourcezoneid = self.services["sourcezoneid"]
|
||||
self.apiclient.copyTemplate(cmd)
|
||||
|
||||
# Verify template is copied to another zone using ListTemplates
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter=\
|
||||
self.services["templatefilter"],
|
||||
id=self.template_2.id,
|
||||
zoneid=self.services["destzoneid"]
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template extracted in List Templates"
|
||||
)
|
||||
|
||||
template_response = list_template_response[0]
|
||||
self.assertEqual(
|
||||
template_response.id,
|
||||
self.template_2.id,
|
||||
"Check ID of the downloaded template"
|
||||
)
|
||||
self.assertEqual(
|
||||
template_response.zoneid,
|
||||
self.services["destzoneid"],
|
||||
"Check zone ID of the copied template"
|
||||
)
|
||||
|
||||
# Cleanup- Delete the copied template
|
||||
cmd = deleteTemplate.deleteTemplateCmd()
|
||||
cmd.id = template_response.id
|
||||
cmd.zoneid = self.services["destzoneid"]
|
||||
self.apiclient.deleteTemplate(cmd)
|
||||
return
|
||||
|
||||
def test_07_list_public_templates(self):
|
||||
"""Test only public templates are visible to normal user"""
|
||||
|
||||
# Validate the following
|
||||
# 1. ListTemplates should show only 'public' templates for normal user
|
||||
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter='featured',
|
||||
account=self.user.account.name,
|
||||
domainid=self.user.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template available in List Templates"
|
||||
)
|
||||
#Template response should list all 'public' templates
|
||||
for template in list_template_response:
|
||||
self.assertEqual(
|
||||
template.ispublic,
|
||||
True,
|
||||
"ListTemplates should list only public templates"
|
||||
)
|
||||
return
|
||||
|
||||
def test_08_list_system_templates(self):
|
||||
"""Test System templates are not visible to normal user"""
|
||||
|
||||
# Validate the following
|
||||
# 1. ListTemplates should not show 'SYSTEM' templates for normal user
|
||||
|
||||
list_template_response = list_templates(
|
||||
self.apiclient,
|
||||
templatefilter='featured',
|
||||
account=self.user.account.name,
|
||||
domainid=self.user.account.domainid
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_template_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
len(list_template_response),
|
||||
0,
|
||||
"Check template available in List Templates"
|
||||
)
|
||||
|
||||
for template in list_template_response:
|
||||
self.assertNotEqual(
|
||||
template.templatetype,
|
||||
'SYSTEM',
|
||||
"ListTemplates should not list any system templates"
|
||||
)
|
||||
return
|
||||
947
test/integration/smoke/test_vm_life_cycle.py
Normal file
947
test/integration/smoke/test_vm_life_cycle.py
Normal file
@ -0,0 +1,947 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Virtual Machine Life Cycle
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
#Import System modules
|
||||
import time
|
||||
|
||||
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": "fr3sca",
|
||||
},
|
||||
"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": 64, # 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": 500,
|
||||
"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": 1000,
|
||||
"memory": 1024
|
||||
}
|
||||
},
|
||||
"iso": # ISO settings for Attach/Detach ISO tests
|
||||
{
|
||||
"displaytext": "Test ISO",
|
||||
"name": "testISO",
|
||||
"url": "http://iso.linuxquestions.org/download/504/1819/http/gd4.tuwien.ac.at/dsl-4.4.10.iso",
|
||||
# Source URL where ISO is located
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"mode": 'HTTP_DOWNLOAD', # Downloading existing ISO
|
||||
},
|
||||
"diskdevice": '/dev/xvdd',
|
||||
# Disk device where ISO is attached to instance
|
||||
"mount_dir": "/mnt/tmp",
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
#Migrate VM to hostid
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
# CentOS 5.3 (64-bit)
|
||||
"mode":'advanced',
|
||||
}
|
||||
|
||||
|
||||
class TestDeployVM(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.services = Services().services
|
||||
# Get Zone, Domain and templates
|
||||
domain = get_domain(self.apiclient, self.services)
|
||||
zone = get_zone(self.apiclient, self.services)
|
||||
|
||||
template = get_template(
|
||||
self.apiclient,
|
||||
zone.id,
|
||||
self.services["ostypeid"]
|
||||
)
|
||||
# Set Zones and disk offerings
|
||||
self.services["small"]["zoneid"] = zone.id
|
||||
self.services["small"]["template"] = template.id
|
||||
|
||||
self.services["medium"]["zoneid"] = zone.id
|
||||
self.services["medium"]["template"] = template.id
|
||||
self.services["iso"]["zoneid"] = zone.id
|
||||
|
||||
# Create Account, VMs, NAT Rules etc
|
||||
self.account = Account.create(
|
||||
self.apiclient,
|
||||
self.services["account"],
|
||||
domainid=domain.id
|
||||
)
|
||||
|
||||
self.service_offering = ServiceOffering.create(
|
||||
self.apiclient,
|
||||
self.services["service_offerings"]["tiny"]
|
||||
)
|
||||
# Cleanup
|
||||
self.cleanup = [
|
||||
self.service_offering,
|
||||
self.account
|
||||
]
|
||||
|
||||
def test_deploy_vm(self):
|
||||
"""Test Deploy Virtual Machine
|
||||
"""
|
||||
|
||||
# Validate the following:
|
||||
# 1. Virtual Machine is accessible via SSH
|
||||
# 2. listVirtualMachines returns accurate information
|
||||
# 3. The Cloud Database contains the valid information
|
||||
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
|
||||
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.displayname,
|
||||
self.virtual_machine.displayname,
|
||||
"Check virtual machine displayname in listVirtualMachines"
|
||||
)
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
self.debug("Warning! Exception in tearDown: %s" % e)
|
||||
|
||||
|
||||
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)
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
# 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.account.name,
|
||||
domainid=cls.account.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.account.name,
|
||||
domainid=cls.account.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.account.name,
|
||||
domainid=cls.account.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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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.assertEqual(
|
||||
len(hosts),
|
||||
2,
|
||||
"Atleast 2 hosts should be present in a zone for VM migration"
|
||||
)
|
||||
|
||||
# Find the host of VM and also the new host to migrate VM.
|
||||
if self.medium_virtual_machine.hostid == hosts[0].id:
|
||||
host = hosts[1]
|
||||
else:
|
||||
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
|
||||
|
||||
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'
|
||||
)
|
||||
|
||||
response = config[0]
|
||||
# Wait for some time more than expunge.delay
|
||||
time.sleep(int(response.value) * 2)
|
||||
|
||||
list_vm_response = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=self.small_virtual_machine.id
|
||||
)
|
||||
self.assertEqual(
|
||||
list_vm_response,
|
||||
None,
|
||||
"Check Expunged virtual machine is listVirtualMachines"
|
||||
)
|
||||
return
|
||||
|
||||
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.account.name,
|
||||
domainid=self.account.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
|
||||
517
test/integration/smoke/test_volumes.py
Normal file
517
test/integration/smoke/test_volumes.py
Normal file
@ -0,0 +1,517 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Copyright 2012 Citrix Systems, Inc. Licensed under the
|
||||
# Apache License, Version 2.0 (the "License"); you may not use this
|
||||
# file except in compliance with the License. Citrix Systems, Inc.
|
||||
# reserves all rights not expressly granted by 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 04/03/2012
|
||||
""" BVT tests for Volumes
|
||||
"""
|
||||
#Import Local Modules
|
||||
import marvin
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from integration.lib.utils import *
|
||||
from integration.lib.base import *
|
||||
from integration.lib.common import *
|
||||
from marvin.remoteSSHClient import remoteSSHClient
|
||||
#Import System modules
|
||||
import os
|
||||
import urllib
|
||||
import time
|
||||
import tempfile
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test Volume Services
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "test@test.com",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"service_offering": {
|
||||
"name": "Tiny Instance",
|
||||
"displaytext": "Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100, # in MHz
|
||||
"memory": 64, # In MBs
|
||||
},
|
||||
"disk_offering": {
|
||||
"displaytext": "Small",
|
||||
"name": "Small",
|
||||
"disksize": 1
|
||||
},
|
||||
"volume_offerings": {
|
||||
0: {
|
||||
"diskname": "TestDiskServ",
|
||||
},
|
||||
},
|
||||
"customdisksize": 1, # GBs
|
||||
"username": "root", # Creds for SSH to VM
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
"diskname": "TestDiskServ",
|
||||
"hypervisor": 'XenServer',
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
"diskdevice": "/dev/xvdb",
|
||||
"ostypeid": '5776c0d2-f331-42db-ba3a-29f1f8319bc9',
|
||||
"mode": 'advanced',
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
}
|
||||
|
||||
|
||||
class TestCreateVolume(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.api_client = super(TestCreateVolume, cls).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
cls.disk_offering = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"]
|
||||
)
|
||||
cls.custom_disk_offering = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"],
|
||||
custom=True
|
||||
)
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["domainid"] = cls.domain.id
|
||||
cls.services["zoneid"] = cls.zone.id
|
||||
cls.services["template"] = template.id
|
||||
cls.services["customdiskofferingid"] = cls.custom_disk_offering.id
|
||||
|
||||
# Create VMs, NAT Rules etc
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
|
||||
cls.services["account"] = cls.account.account.name
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.virtual_machine = VirtualMachine.create(
|
||||
cls.api_client,
|
||||
cls.services,
|
||||
accountid=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid,
|
||||
serviceofferingid=cls.service_offering.id,
|
||||
mode=cls.services["mode"]
|
||||
)
|
||||
cls._cleanup = [
|
||||
cls.service_offering,
|
||||
cls.disk_offering,
|
||||
cls.custom_disk_offering,
|
||||
cls.account
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.apiClient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
|
||||
def test_01_create_volume(self):
|
||||
"""Test Volume creation for all Disk Offerings (incl. custom)
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. Create volumes from the different sizes
|
||||
# 2. Verify the size of volume with actual size allocated
|
||||
|
||||
self.volumes = []
|
||||
for k, v in self.services["volume_offerings"].items():
|
||||
volume = Volume.create(
|
||||
self.apiClient,
|
||||
v,
|
||||
zoneid=self.zone.id,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
diskofferingid=self.disk_offering.id
|
||||
)
|
||||
self.debug("Created a volume with ID: %s" % volume.id)
|
||||
self.volumes.append(volume)
|
||||
|
||||
volume = Volume.create_custom_disk(
|
||||
self.apiClient,
|
||||
self.services,
|
||||
account=self.account.account.name,
|
||||
domainid=self.account.account.domainid,
|
||||
)
|
||||
self.debug("Created a volume with custom offering: %s" % volume.id)
|
||||
self.volumes.append(volume)
|
||||
|
||||
#Attach a volume with different disk offerings
|
||||
#and check the memory allocated to each of them
|
||||
for volume in self.volumes:
|
||||
list_volume_response = list_volumes(
|
||||
self.apiClient,
|
||||
id=volume.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_volume_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
list_volume_response,
|
||||
None,
|
||||
"Check if volume exists in ListVolumes"
|
||||
)
|
||||
self.debug(
|
||||
"Attaching volume (ID: %s) to VM (ID: %s)" % (
|
||||
volume.id,
|
||||
self.virtual_machine.id
|
||||
))
|
||||
self.virtual_machine.attach_volume(
|
||||
self.apiClient,
|
||||
volume
|
||||
)
|
||||
try:
|
||||
ssh = self.virtual_machine.get_ssh_client()
|
||||
ssh.execute("reboot")
|
||||
|
||||
except Exception as e:
|
||||
self.fail("SSH access failed for VM %s - %s" %
|
||||
(self.virtual_machine.ipaddress, e))
|
||||
|
||||
# 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.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) " % vm.id)
|
||||
|
||||
timeout = timeout - 1
|
||||
|
||||
try:
|
||||
ssh = self.virtual_machine.get_ssh_client(
|
||||
reconnect=True
|
||||
)
|
||||
c = "fdisk -l"
|
||||
res = ssh.execute(c)
|
||||
|
||||
except Exception as e:
|
||||
self.fail("SSH access failed for VM: %s - %s" %
|
||||
(self.virtual_machine.ipaddress, e))
|
||||
|
||||
# Disk /dev/sda doesn't contain a valid partition table
|
||||
# Disk /dev/sda: 21.5 GB, 21474836480 bytes
|
||||
result = str(res)
|
||||
self.debug("fdisk result: %s" % result)
|
||||
|
||||
self.assertEqual(
|
||||
str(list_volume_response[0].size) in result,
|
||||
True,
|
||||
"Check if promised disk size actually available"
|
||||
)
|
||||
self.virtual_machine.detach_volume(self.apiClient, volume)
|
||||
|
||||
def tearDown(self):
|
||||
#Clean up, terminate the created volumes
|
||||
cleanup_resources(self.apiClient, self.cleanup)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cls.api_client = super(TestCreateVolume, cls).getClsTestClient().getApiClient()
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
|
||||
class TestVolumes(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.api_client = super(TestVolumes, cls).getClsTestClient().getApiClient()
|
||||
cls.services = Services().services
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
cls.disk_offering = DiskOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["disk_offering"]
|
||||
)
|
||||
template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostypeid"]
|
||||
)
|
||||
cls.services["domainid"] = cls.domain.id
|
||||
cls.services["zoneid"] = cls.zone.id
|
||||
cls.services["template"] = template.id
|
||||
cls.services["diskofferingid"] = cls.disk_offering.id
|
||||
|
||||
# Create VMs, VMs etc
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
|
||||
cls.services["account"] = cls.account.account.name
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.virtual_machine = VirtualMachine.create(
|
||||
cls.api_client,
|
||||
cls.services,
|
||||
accountid=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid,
|
||||
serviceofferingid=cls.service_offering.id,
|
||||
mode=cls.services["mode"]
|
||||
)
|
||||
|
||||
cls.volume = Volume.create(
|
||||
cls.api_client,
|
||||
cls.services,
|
||||
account=cls.account.account.name,
|
||||
domainid=cls.account.account.domainid
|
||||
)
|
||||
cls._cleanup = [
|
||||
cls.service_offering,
|
||||
cls.disk_offering,
|
||||
cls.account
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
def setUp(self):
|
||||
self.apiClient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
|
||||
def test_02_attach_volume(self):
|
||||
"""Attach a created Volume to a Running VM
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. shows list of volumes
|
||||
# 2. "Attach Disk" pop-up box will display with list of instances
|
||||
# 3. disk should be attached to instance successfully
|
||||
|
||||
self.debug(
|
||||
"Attaching volume (ID: %s) to VM (ID: %s)" % (
|
||||
self.volume.id,
|
||||
self.virtual_machine.id
|
||||
))
|
||||
self.virtual_machine.attach_volume(self.apiClient, self.volume)
|
||||
|
||||
list_volume_response = list_volumes(
|
||||
self.apiClient,
|
||||
id=self.volume.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_volume_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
list_volume_response,
|
||||
None,
|
||||
"Check if volume exists in ListVolumes"
|
||||
)
|
||||
volume = list_volume_response[0]
|
||||
self.assertNotEqual(
|
||||
volume.virtualmachineid,
|
||||
None,
|
||||
"Check if volume state (attached) is reflected"
|
||||
)
|
||||
try:
|
||||
#Format the attached volume to a known fs
|
||||
format_volume_to_ext3(self.virtual_machine.get_ssh_client())
|
||||
|
||||
except Exception as e:
|
||||
|
||||
self.fail("SSH failed for VM: %s - %s" %
|
||||
(self.virtual_machine.ipaddress, e))
|
||||
return
|
||||
|
||||
def test_03_download_attached_volume(self):
|
||||
"""Download a Volume attached to a VM
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. download volume will fail with proper error message
|
||||
# "Failed - Invalid state of the volume with ID:
|
||||
# It should be either detached or the VM should be in stopped state
|
||||
|
||||
self.debug("Extract attached Volume ID: %s" % self.volume.id)
|
||||
|
||||
cmd = extractVolume.extractVolumeCmd()
|
||||
cmd.id = self.volume.id
|
||||
cmd.mode = "HTTP_DOWNLOAD"
|
||||
cmd.zoneid = self.services["zoneid"]
|
||||
# A proper exception should be raised;
|
||||
# downloading attach VM is not allowed
|
||||
with self.assertRaises(Exception):
|
||||
self.apiClient.extractVolume(cmd)
|
||||
|
||||
def test_04_delete_attached_volume(self):
|
||||
"""Delete a Volume attached to a VM
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# 1. delete volume will fail with proper error message
|
||||
# "Failed - Invalid state of the volume with ID:
|
||||
# It should be either detached or the VM should be in stopped state
|
||||
|
||||
self.debug("Trying to delete attached Volume ID: %s" %
|
||||
self.volume.id)
|
||||
|
||||
cmd = deleteVolume.deleteVolumeCmd()
|
||||
cmd.id = self.volume.id
|
||||
#Proper exception should be raised; deleting attach VM is not allowed
|
||||
#with self.assertRaises(Exception):
|
||||
result = self.apiClient.deleteVolume(cmd)
|
||||
self.assertEqual(
|
||||
result,
|
||||
None,
|
||||
"Check for delete download error while volume is attached"
|
||||
)
|
||||
|
||||
def test_05_detach_volume(self):
|
||||
"""Detach a Volume attached to a VM
|
||||
"""
|
||||
|
||||
# Validate the following
|
||||
# Data disk should be detached from instance and detached data disk
|
||||
# details should be updated properly
|
||||
|
||||
self.debug(
|
||||
"Detaching volume (ID: %s) from VM (ID: %s)" % (
|
||||
self.volume.id,
|
||||
self.virtual_machine.id
|
||||
))
|
||||
|
||||
self.virtual_machine.detach_volume(self.apiClient, self.volume)
|
||||
#Sleep to ensure the current state will reflected in other calls
|
||||
time.sleep(self.services["sleep"])
|
||||
list_volume_response = list_volumes(
|
||||
self.apiClient,
|
||||
id=self.volume.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_volume_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
|
||||
self.assertNotEqual(
|
||||
list_volume_response,
|
||||
None,
|
||||
"Check if volume exists in ListVolumes"
|
||||
)
|
||||
volume = list_volume_response[0]
|
||||
self.assertEqual(
|
||||
volume.virtualmachineid,
|
||||
None,
|
||||
"Check if volume state (detached) is reflected"
|
||||
)
|
||||
return
|
||||
|
||||
def test_06_download_detached_volume(self):
|
||||
"""Download a Volume unattached to an VM
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. able to download the volume when its not attached to instance
|
||||
|
||||
self.debug("Extract detached Volume ID: %s" % self.volume.id)
|
||||
|
||||
cmd = extractVolume.extractVolumeCmd()
|
||||
cmd.id = self.volume.id
|
||||
cmd.mode = "HTTP_DOWNLOAD"
|
||||
cmd.zoneid = self.services["zoneid"]
|
||||
extract_vol = self.apiClient.extractVolume(cmd)
|
||||
|
||||
#Attempt to download the volume and save contents locally
|
||||
try:
|
||||
formatted_url = urllib.unquote_plus(extract_vol.url)
|
||||
response = urllib.urlopen(formatted_url)
|
||||
fd, path = tempfile.mkstemp()
|
||||
os.close(fd)
|
||||
fd = open(path, 'wb')
|
||||
fd.write(response.read())
|
||||
fd.close()
|
||||
|
||||
except Exception:
|
||||
self.fail(
|
||||
"Extract Volume Failed with invalid URL %s (vol id: %s)" \
|
||||
% (extract_vol.url, self.volume.id)
|
||||
)
|
||||
|
||||
def test_07_delete_detached_volume(self):
|
||||
"""Delete a Volume unattached to an VM
|
||||
"""
|
||||
# Validate the following
|
||||
# 1. volume should be deleted successfully and listVolume should not
|
||||
# contain the deleted volume details.
|
||||
# 2. "Delete Volume" menu item not shown under "Actions" menu.
|
||||
# (UI should not allow to delete the volume when it is attached
|
||||
# to instance by hiding the menu Item)
|
||||
|
||||
self.debug("Delete Volume ID: %s" % self.volume.id)
|
||||
|
||||
cmd = deleteVolume.deleteVolumeCmd()
|
||||
cmd.id = self.volume.id
|
||||
self.apiClient.deleteVolume(cmd)
|
||||
|
||||
list_volume_response = list_volumes(
|
||||
self.apiClient,
|
||||
id=self.volume.id,
|
||||
type='DATADISK'
|
||||
)
|
||||
self.assertEqual(
|
||||
list_volume_response,
|
||||
None,
|
||||
"Check if volume exists in ListVolumes"
|
||||
)
|
||||
return
|
||||
Loading…
x
Reference in New Issue
Block a user