Repository: cloudstack Updated Branches: refs/heads/pytest 2b45f67bc -> 468b9860f
add more pytest Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/468b9860 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/468b9860 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/468b9860 Branch: refs/heads/pytest Commit: 468b9860f573b836cdb8f9c250c2d7736742cb21 Parents: 2b45f67 Author: Edison Su <sudi...@gmail.com> Authored: Fri Sep 12 17:42:59 2014 -0700 Committer: Edison Su <sudi...@gmail.com> Committed: Fri Sep 12 17:42:59 2014 -0700 ---------------------------------------------------------------------- test/integration/smoke/conftest.py | 2 +- tools/marvin/marvin/cloudstackTestCase.py | 6 ++ tools/marvin/marvin/cloudstackTestClient.py | 13 +++ tools/marvin/marvin/lib/base.py | 11 ++ tools/marvin/marvin/marvinInit.py | 5 +- tools/marvin/marvin/marvinPlugin.py | 4 +- tools/marvin/marvin/pytest/VM.py | 104 +++++++++++++++++++ tools/marvin/marvin/pytest/__init__.py | 1 + .../marvin/pytest/pytest_marvin_plugin.py | 55 ++++++++++ tools/marvin/marvin/pytest_marvin_plugin.py | 60 ----------- tools/marvin/marvin/utils.py | 51 +++++++++ 11 files changed, 245 insertions(+), 67 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/test/integration/smoke/conftest.py ---------------------------------------------------------------------- diff --git a/test/integration/smoke/conftest.py b/test/integration/smoke/conftest.py index 5d359f5..33eed64 100644 --- a/test/integration/smoke/conftest.py +++ b/test/integration/smoke/conftest.py @@ -14,4 +14,4 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -pytest_plugins = "marvin.pytest_marvin_plugin" \ No newline at end of file +pytest_plugins = "marvin.pytest.pytest_marvin_plugin" \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/cloudstackTestCase.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/cloudstackTestCase.py b/tools/marvin/marvin/cloudstackTestCase.py index 5cb4a10..f5da5b2 100644 --- a/tools/marvin/marvin/cloudstackTestCase.py +++ b/tools/marvin/marvin/cloudstackTestCase.py @@ -16,8 +16,10 @@ # under the License. import unittest + from marvin.lib.utils import verifyElementInList from marvin.codes import PASS +from marvin.utils import initTestClass def user(Name, DomainName, AcctType): @@ -51,4 +53,8 @@ class cloudstackTestCase(unittest.case.TestCase): @classmethod def getClsTestClient(cls): + if cls.clstestclient is not None: + return cls.clstestclient + + initTestClass(cls, cls.__name__) return cls.clstestclient http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/cloudstackTestClient.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/cloudstackTestClient.py b/tools/marvin/marvin/cloudstackTestClient.py index ce7ffc9..8d505fa 100644 --- a/tools/marvin/marvin/cloudstackTestClient.py +++ b/tools/marvin/marvin/cloudstackTestClient.py @@ -27,6 +27,7 @@ from marvin.lib.utils import (random_gen, validateList) from marvin.cloudstackAPI.cloudstackAPIClient import CloudStackAPIClient import copy + class CSTestClient(object): ''' @@ -68,6 +69,7 @@ class CSTestClient(object): self.__zone = zone self.__setHypervisorInfo() + @property def identifier(self): return self.__id @@ -76,6 +78,17 @@ class CSTestClient(object): def identifier(self, id): self.__id = id + + def initConfig(self): + self.createTestClient() + + ''' + self._testConfig = CSConfig.createConfig(self) + ''' + + def getCSConfig(self): + return self._testConfig + def getParsedTestDataConfig(self): ''' @Name : getParsedTestDataConfig http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/lib/base.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 2a763ce..38a04db 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -500,6 +500,17 @@ class VirtualMachine: return VirtualMachine(virtual_machine.__dict__, services) + @classmethod + def createSmallVm(cls, testClient, ): + virtual_machine = VirtualMachine.create( + testClient.getApiclient(), + testClient.getCSConfig.getDefaultSmallDiskOffering(), + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id, + mode=cls.services['mode'] + ) + def start(self, apiclient): """Start the instance""" cmd = startVirtualMachine.startVirtualMachineCmd() http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/marvinInit.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/marvinInit.py b/tools/marvin/marvin/marvinInit.py index c6ee1a2..dd71211 100644 --- a/tools/marvin/marvin/marvinInit.py +++ b/tools/marvin/marvin/marvinInit.py @@ -206,9 +206,8 @@ class MarvinInit: test_data_filepath=self.__testDataFilePath, zone=self.__zoneForTests, hypervisor_type=self.__hypervisorType) - if self.__testClient: - return self.__testClient.createTestClient() - return FAILED + self.__testClient.initConfig() + return SUCCESS except Exception as e: print "\n Exception Occurred Under __createTestClient : %s" % \ GetDetailExceptionInfo(e) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/marvinPlugin.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/marvinPlugin.py b/tools/marvin/marvin/marvinPlugin.py index dfba4c1..435346c 100644 --- a/tools/marvin/marvin/marvinPlugin.py +++ b/tools/marvin/marvin/marvinPlugin.py @@ -20,7 +20,6 @@ import logging import time import os import nose.core -from marvin.cloudstackTestCase import cloudstackTestCase from marvin.marvinInit import MarvinInit from nose.plugins.base import Plugin from marvin.codes import (SUCCESS, @@ -128,8 +127,7 @@ class MarvinPlugin(Plugin): def wantClass(self, cls): if cls.__name__ == 'cloudstackTestCase': return False - if issubclass(cls, cloudstackTestCase): - return True + return None def __checkImport(self, filename): http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/pytest/VM.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/pytest/VM.py b/tools/marvin/marvin/pytest/VM.py new file mode 100644 index 0000000..ae80518 --- /dev/null +++ b/tools/marvin/marvin/pytest/VM.py @@ -0,0 +1,104 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import pytest + +from marvin.lib.common import get_zone,get_domain,get_template +from marvin.lib.base import ServiceOffering,Account,VirtualMachine + + +@pytest.fixture() +def test_client(request): + if request.cls is not None: + return request.node.cls.testClient + else: + return request.node.testClient + +@pytest.fixture() +def zone(test_client): + apiClient = test_client.getApiClient() + zone = get_zone(apiClient, test_client.getZoneForTests()) + return zone + +@pytest.fixture() +def tiny_service_offering(test_client, zone): + apiClient = test_client.getApiClient() + + params = { + "name": "Tiny Instance", + "displaytext": "Tiny Instance", + "cpunumber": 1, + "cpuspeed": 100, + "memory": 128, + } + + if zone.localstorageenabled: + params["storagetype"] = "local" + + return ServiceOffering.create(apiClient, params) + +@pytest.fixture() +def domain(test_client): + apiClient = test_client.getApiClient() + return get_domain(apiClient) + +@pytest.fixture() +def account(test_client, domain): + params = { + "email": "test-acco...@test.com", + "firstname": "test", + "lastname": "test", + "username": "test-account", + "password": "password" + } + + apiclient = test_client.getApiClient() + + return Account.create(apiclient, params, domainid=domain.id) + +@pytest.fixture() +def template(test_client, zone): + return get_template( + test_client.getApiClient(), + zone.id, + "CentOS 5.6 (64-bit)" + ) + +@pytest.fixture() +def vm(test_client, account, template, tiny_service_offering, zone): + params = { + "displayname": "testserver", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": "XenServer", + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + } + virtual_machine = VirtualMachine.create( + test_client.getApiClient(), + params, + zoneid=zone.id, + templateid=template.id, + accountid=account.name, + domainid=account.domainid, + serviceofferingid=tiny_service_offering.id, + mode=zone.networktype + ) + + return virtual_machine http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/pytest/__init__.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/pytest/__init__.py b/tools/marvin/marvin/pytest/__init__.py new file mode 100644 index 0000000..0871bc1 --- /dev/null +++ b/tools/marvin/marvin/pytest/__init__.py @@ -0,0 +1 @@ +__author__ = 'edison' http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/pytest/pytest_marvin_plugin.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/pytest/pytest_marvin_plugin.py b/tools/marvin/marvin/pytest/pytest_marvin_plugin.py new file mode 100644 index 0000000..90c7ed1 --- /dev/null +++ b/tools/marvin/marvin/pytest/pytest_marvin_plugin.py @@ -0,0 +1,55 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +import pytest + +from marvin.utils import initTestClass,getMarvin +from .VM import (vm,tiny_service_offering,template,test_client,account,domain,zone) + +def pytest_configure(config): + config.addinivalue_line("markers", + "attr(name): tag tests") + + result = getMarvin() + if result is None: + pytest.fail("failed to init marvin plugin") + + + +def pytest_runtest_setup(item): + attrmarker = item.get_marker("attr") + if attrmarker.kwargs["required_hardware"]: + pytest.skip("doesnt have hardware") + +@pytest.fixture(scope="class", autouse=True) +def marvin_inject_testclass(request): + if request.cls is None: + return + + test = request.cls + initTestClass(test, request.node.nodeid) + + +@pytest.fixture(scope="function", autouse=True) +def marvin_init_function(request): + if request.cls is not None: + return + marvinObj = getMarvin() + setattr(request.node, "testClient", marvinObj.getTestClient()) + + marvinObj.getTestClient().identifier = request.node.name + + http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/pytest_marvin_plugin.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/pytest_marvin_plugin.py b/tools/marvin/marvin/pytest_marvin_plugin.py deleted file mode 100644 index 5b66cc2..0000000 --- a/tools/marvin/marvin/pytest_marvin_plugin.py +++ /dev/null @@ -1,60 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -import pytest -import os -from marvin.marvinPlugin import MarvinInit -from marvin.codes import FAILED - -global_marvin_obj = None -def pytest_configure(): - configFile = os.environ.get("MARVIN_CONFIG", os.path.join(os.path.dirname(os.path.realpath(__file__)),"..", "..", "..", "setup", "dev", "advanced.cfg")) - deployDcb = False - deployDc = os.environ.get("MARVIN_DEPLOY_DC", "false") - if deployDc in ["True", "true"]: - deployDcb = True - zoneName = os.environ.get("MARVIN_ZONE_NAME", "Sandbox-simulator") - hypervisor_type = os.environ.get("MARVIN_HYPERVISOR_TYPE", "simulator") - logFolder = os.environ.get("MARVIN_LOG_FOLDER", os.path.expanduser(os.path.join("~","marvin"))) - - global global_marvin_obj - global_marvin_obj = MarvinInit(configFile, - deployDcb, - None, - zoneName, - hypervisor_type, - logFolder) - - result = global_marvin_obj.init() - if result == FAILED: - pytest.fail("failed to init marvin plugin") - -@pytest.fixture(scope="class", autouse=True) -def marvin_inject_testclass(request): - global global_marvin_obj - test = request.cls - setattr(test, "debug", global_marvin_obj.getLogger().debug) - setattr(test, "info", global_marvin_obj.getLogger().info) - setattr(test, "warn", global_marvin_obj.getLogger().warning) - setattr(test, "error",global_marvin_obj.getLogger().error) - setattr(test, "testClient", global_marvin_obj.getTestClient()) - setattr(test, "config", global_marvin_obj.getParsedConfig()) - setattr(test, "clstestclient", global_marvin_obj.getTestClient()) - if hasattr(test, "user"): - # when the class-level attr applied. all test runs as 'user' - request.testClient.getUserApiClient(test.UserName, - test.DomainName, - test.AcctType) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/468b9860/tools/marvin/marvin/utils.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/utils.py b/tools/marvin/marvin/utils.py new file mode 100644 index 0000000..e25b4c7 --- /dev/null +++ b/tools/marvin/marvin/utils.py @@ -0,0 +1,51 @@ +__author__ = 'edison' +import os +from marvin.marvinPlugin import MarvinInit +from marvin.codes import FAILED + +def getMarvin(): + configFile = os.environ.get("MARVIN_CONFIG", os.path.join(os.path.dirname(os.path.realpath(__file__)),"..", "..", "..", "setup", "dev", "advanced.cfg")) + deployDcb = False + deployDc = os.environ.get("MARVIN_DEPLOY_DC", "false") + if deployDc in ["True", "true"]: + deployDcb = True + zoneName = os.environ.get("MARVIN_ZONE_NAME", "Sandbox-simulator") + hypervisor_type = os.environ.get("MARVIN_HYPERVISOR_TYPE", "simulator") + logFolder = os.environ.get("MARVIN_LOG_FOLDER", os.path.expanduser(os.path.join("~","marvin"))) + + marvinObj = MarvinInit(configFile, + deployDcb, + None, + zoneName, + hypervisor_type, + logFolder) + + result = marvinObj.init() + if result == FAILED: + return None + else: + return marvinObj + +def initTestClass(cls, idenifier): + marvinObj = None + if hasattr(cls, "marvinObj"): + marvinObj = cls.marvinObj + else: + marvinObj = getMarvin() + setattr(cls, "debug", marvinObj.getLogger().debug) + setattr(cls, "info", marvinObj.getLogger().info) + setattr(cls, "warn", marvinObj.getLogger().warning) + setattr(cls, "error",marvinObj.getLogger().error) + setattr(cls, "testClient", marvinObj.getTestClient()) + setattr(cls, "config", marvinObj.getParsedConfig()) + if hasattr(cls, "clstestclient") is not True: + setattr(cls, "clstestclient", marvinObj.getTestClient()) + if cls.clstestclient is None: + cls.clstestclient = marvinObj.getTestClient() + + marvinObj.getTestClient().identifier = idenifier + if hasattr(cls, "user"): + # when the class-level attr applied. all test runs as 'user' + cls.testClient.getUserApiClient(cls.UserName, + cls.DomainName, + cls.AcctType) \ No newline at end of file