...
Marvin - is a python testing framework for Apache CloudStack. Tests written using the framework use the unittest module under the hood. The unittest module is the Python version of the unit-testing framework originally developed by Kent Beck et al and will be familiar to the Java people in the form of JUnit. The following document will act as a tutorial introduction to those interested in testing CloudStack with python. This document does not cover the python language and we will be pointing the reader instead to explore some tutorials that are more thorough on the topic. In the following we will be assuming basic python scripting knowledge from the reader. The reader is encouraged to walk through the tutorial in full and explore the existing tests in the repository before beginning to write tests.
Table of Contents |
---|
Marvin requires Python 2.6 for installation but the tests written using marvin utilize Python 2.7 to the fullest. You should follow the test environment setup instructions here before proceeding further.
...
Code Block |
---|
json { "dbSvr": { "dbSvr": "marvin.testlab.com", "passwd": "cloud", "db": "cloud", "port": 3306, "user": "cloud" }, "logger": [ { "nameLogFolderPath": "TestClient/tmp/", }, "filemgtSvr": "/tmp/testclient.log" },[ { "namemgtSvrIp": "TestCasemarvin.testlab.com", "fileport": "/tmp/testcase.log" 8096, } ], "mgtSvruser": [ {"root", "mgtSvrIppasswd": "marvin.testlab.compassword", "porthypervisor": 8096"XenServer", } ] } |
- Note:
dbSvr
is the location where mysql server is running and passwd is the password for user cloud
...
In addition to the regular deploydb you will be deploying the simulator database where all the agent information is stored for the mockvms, mockvolumes etc.
Code Block |
---|
$ mvn -Pdeveloper -pl developer -Ddeploydb
$ mvn -Pdeveloper -pl developer -Ddeploydb-simulator
|
...
Check-In tests are the same as any other tests written using Marvin. The only additional step you need to do is ensure that your test is driven entirely by the API only. This makes it possible to run the test on a simulator. Once you have your test, you need to tag it to run on the simulator so the marvin test runner can pick it up during the checkin-test run. Then place your test module in the test/integration/smoke
folder and it will become part of the checkin test run.
For eg:
Code Block |
---|
|
Code Block |
---|
@attr(tags ="simulator", "advanced", "smoke")
def test_deploy_virtualmachine(self):
"""Tests deployment of VirtualMachine
"""
|
Code Block |
---|
|
The sample simulator configurations for advanced and basic zone is available in setup/dev/ directory. The default configuration setup/dev/advanced.cfg deploys an advanced zone with two simulator hypervisors in a single cluster in a single pod, two primary NFS storage pools and a secondary storage NFS store. If your test requires any extra hypervisors, storage pools, additional IP allocations, VLANs etc - you should adjust the configuration accordingly. Ensure that you have run all the checkin tests in the new configuration. For this you can directly edit the JSON file or generate a new configuration file. The setup/dev/advanced.cfg was generated as follows
Code Block |
---|
$ cd tools/marvin/marvin/sandbox/advanced
$ python advanced_env.py -i setup.properties -o advanced.cfgThese configurations are generated using the marvin configGenerator module. You can write your own configuration by following the examples shown in the configGenerator module:
|
...
Some tests have been tagged to run only for devcloud environment. In order to run these tests you can use the following command after you have setup your management server and the devcloud vm is running with tools/devcloud/devcloud.cfg
as its deployment configuration.
Code Block |
---|
tsp@cloud:~/cloudstack# nosetests with-marvin marvin-config=tools/devcloud/devcloud.cfg load -a tags='devcloud' test/integration/smoke
Test Deploy Virtual Machine ok
Test Stop Virtual Machine ok
Test Start Virtual Machine ok
Test Reboot Virtual Machine ok
Test destroy Virtual Machine ok
Test recover Virtual Machine ok
Test destroy(expunge) Virtual Machine ok
----
Ran 7 tests in 10.001s
OK
|
...
The above one host configuration was described as follows:
Code Block |
---|
import random
import marvin
from marvin.configGenerator import *
def describeResources():
zs = cloudstackConfiguration()
z = zone()
z.dns1 = '10.147.28.6'
z.internaldns1 = '10.147.28.6'
z.name = 'Sandbox-XenServer'
z.networktype = 'Advanced'
z.guestcidraddress = '10.1.1.0/24'
pn = physical_network()
pn.name = "test-network"
pn.traffictypes = [traffictype("Guest"), traffictype("Management"), traffictype("Public")]
z.physical_networks.append(pn)
p = pod()
p.name = 'POD0'
p.gateway = '10.147.29.1'
p.startip = '10.147.29.150'
p.endip = '10.147.29.159'
p.netmask = '255.255.255.0'
v = iprange()
v.gateway = '10.147.31.1'
v.startip = '10.147.31.150'
v.endip = '10.147.31.159'
v.netmask = '255.255.255.0'
v.vlan = '31'
z.ipranges.append(v)
c = cluster()
c.clustername = 'C0'
c.hypervisor = 'XenServer'
c.clustertype = 'CloudManaged'
h = host()
h.username = 'root'
h.password = 'password'
h.url = 'http://10.147.29.58'
c.hosts.append(h)
ps = primaryStorage()
ps.name = 'PS0'
ps.url = 'nfs://10.147.28.6:/export/home/sandbox/primary'
c.primaryStorages.append(ps)
p.clusters.append(c)
z.pods.append(p)
secondary = secondaryStorage()
secondary.url = 'nfs://10.147.28.6:/export/home/sandbox/secondary'
z.secondaryStorages.append(secondary)
'''Add zone'''
zs.zones.append(z)
'''Add mgt server'''
mgt = managementServer()
mgt.mgtSvrIp = '10.147.29.111'
zs.mgtSvr.append(mgt)
'''Add a database'''
db = dbServer()
db.dbSvr = '10.147.29.111'
db.user = 'cloud'
db.passwd = 'cloud'
zs.dbSvr = db
'''Add some configuration'''
[zs.globalConfig.append(cfg) for cfg in getGlobalSettings()]
''''add loggers'''
testClientLogger = logger()
testClientLogger.name = 'TestClient'
testClientLogger.file = '/var/log/testclient.log'
testCaseLogger = logger()
testCaseLogger.name = 'TestCase'
testCaseLogger.file = '/var/log/testcase.log'
zs.logger.append(testClientLogger)
zs.logger.append(testCaseLogger)
return zs
def getGlobalSettings():
globals = { "storage.cleanup.interval" : "300",
"account.cleanup.interval" : "60",
}
for k, v in globals.iteritems():
cfg = configuration()
cfg.name = k
cfg.value = v
yield cfg
if __name__ == '__main__':
config = describeResources()
generate_setup_config(config, 'advanced_cloud.cfg')
|
...
If you execute testing with marvin, add this parameter in cloud-marvin/pom.xml like this:
Code Block |
---|
<executable>nosetests</executable>
<arguments>
<argument>--with-marvin</argument>
<argument>--marvin-config</argument>
<argument>${resolved.user.dir}/${resolved.marvin.config}</argument>
<argument>--load</argument>
<argument>-a</argument>
<argument>tags=${tag}</argument>
<argument>${resolved.user.dir}/${test}</argument>
<argument>-v</argument>
<argument>--with-timer</argument>
</arguments>
|
...