From c6f0876fe9f2ff065b2449280a91e9030d4a4f17 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Fri, 19 Apr 2013 16:49:16 +0530 Subject: [PATCH] marvin_refactor: one shot creation of factories Build phase will init the bare minimum object required to make the web request to the mgmt server Create phase will make the actual request and fill the attributes of the entity after recieving the response This allows for one shot creation of the entity using: EntityFactory.create(apiclient) over two steps: factory = EntityFactory() entity = Entity.create(apiclient, factory) TODO: Figure out howto perform related factory creation. eg: UserFactory.create() inits AccountFactory.create() Signed-off-by: Prasanna Santhanam --- .../integration/lib/factory/AccountFactory.py | 1 + .../lib/factory/CloudStackBaseFactory.py | 24 +++++- .../integration/lib/factory/UserFactory.py | 4 +- .../lib/factory/test/testFactories.py | 81 ++++++++++--------- 4 files changed, 70 insertions(+), 40 deletions(-) diff --git a/tools/marvin/marvin/integration/lib/factory/AccountFactory.py b/tools/marvin/marvin/integration/lib/factory/AccountFactory.py index 7306073ccfa..00399e415c3 100644 --- a/tools/marvin/marvin/integration/lib/factory/AccountFactory.py +++ b/tools/marvin/marvin/integration/lib/factory/AccountFactory.py @@ -20,6 +20,7 @@ from marvin.integration.lib.factory.CloudStackBaseFactory import * from marvin.integration.lib.base import Account from marvin.integration.lib.utils import random_gen +@factory.use_strategy(new_strategy=factory.BUILD_STRATEGY) class AccountFactory(CloudStackBaseFactory): FACTORY_FOR = Account.Account diff --git a/tools/marvin/marvin/integration/lib/factory/CloudStackBaseFactory.py b/tools/marvin/marvin/integration/lib/factory/CloudStackBaseFactory.py index 57d77792e2d..ff107546ca8 100644 --- a/tools/marvin/marvin/integration/lib/factory/CloudStackBaseFactory.py +++ b/tools/marvin/marvin/integration/lib/factory/CloudStackBaseFactory.py @@ -16,12 +16,34 @@ # under the License. import factory +import inspect + +CREATORS = ["create", "deploy"] + class CloudStackBaseFactory(factory.Factory): ABSTRACT_FACTORY = True @classmethod - def _create(cls, target_class, *args, **kwargs): + def _build(cls, target_class, *args, **kwargs): if len(args) == 0: return target_class(kwargs) return target_class(*args, **kwargs) + + @classmethod + def _create(cls, target_class, *args, **kwargs): + if "apiclient" in kwargs: + members = inspect.getmembers(target_class, + predicate=inspect.ismethod) + creators = filter(lambda x: x[0] in CREATORS, members) + assert creators, "How do I bring this guy into existence?" + assert inspect.ismethod(creators[0][1]) + creator = creators[0][1] + apiclient = kwargs["apiclient"] + clean_kwargs = dict((k, v) for k, v in kwargs.iteritems() + if k != "apiclient") + return creator(apiclient, factory=cls._build(target_class, + *args, **clean_kwargs) + ) + else: + cls._build(target_class, *args, **kwargs) \ No newline at end of file diff --git a/tools/marvin/marvin/integration/lib/factory/UserFactory.py b/tools/marvin/marvin/integration/lib/factory/UserFactory.py index 1b13b8bcbec..84218c1542d 100644 --- a/tools/marvin/marvin/integration/lib/factory/UserFactory.py +++ b/tools/marvin/marvin/integration/lib/factory/UserFactory.py @@ -23,7 +23,7 @@ class UserFactory(CloudStackBaseFactory): FACTORY_FOR = User.User - account = factory.SubFactory(AccountFactory).factory() + account = factory.RelatedFactory(AccountFactory).factory() email = account.email firstname = account.firstname lastname = account.lastname @@ -31,4 +31,4 @@ class UserFactory(CloudStackBaseFactory): username = account.username class AdminUserFactory(UserFactory): - account = factory.SubFactory(AccountFactory, accounttype=1).factory() + account = factory.RelatedFactory(AccountFactory, accounttype=1).factory() diff --git a/tools/marvin/marvin/integration/lib/factory/test/testFactories.py b/tools/marvin/marvin/integration/lib/factory/test/testFactories.py index cb7165f825a..f338dcf0898 100644 --- a/tools/marvin/marvin/integration/lib/factory/test/testFactories.py +++ b/tools/marvin/marvin/integration/lib/factory/test/testFactories.py @@ -39,34 +39,46 @@ from marvin.integration.lib.base.VirtualMachine import VirtualMachine from marvin.integration.lib.factory.UserFactory import * from marvin.integration.lib.base.User import User + +class BuildVsCreateStrategyTest(unittest.TestCase): + def setUp(self): + self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient() + + def tearDown(self): + pass + + def test_buildAccountFactory(self): + af = AccountFactory() + self.assert_(af.username is not None, msg="Acount factory didn't initialize") + + def test_createAccountFactory(self): + af = AccountFactory.create(apiclient=self.apiClient) + self.assert_(isinstance(af, Account)) + self.assert_(af.account.id is not None, msg="Account creation failed") + self.assert_(af.account.domain is not None, msg="Account belongs to no domain") + + class AccountFactoryTest(unittest.TestCase): def setUp(self): self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient() - def test_userAccountFactory(self): - af = AccountFactory() - accnt = Account.create(apiclient=self.apiClient, AccountFactory=af) - self.assertTrue(accnt is not None, msg="no account created by factory") - self.assertEqual(accnt.name, af.username, msg="account names are not same") - def test_adminAccountFactory(self): - af = AdminAccountFactory() - accnt = Account.create(apiclient=self.apiClient, AccountFactory=af) - self.assertTrue(accnt is not None, msg="no account created by factory") - self.assertEqual(accnt.name, af.username, msg="account names are not same") + accnt = AdminAccountFactory.create(apiclient=self.apiClient) + self.assert_(accnt is not None, msg="no account created by factory") + self.assert_(accnt.account.name is not None) def test_userAccountFactoryCustomArgs(self): - af = AccountFactory(firstname='test', lastname='test') - accnt = Account.create(apiclient=self.apiClient, AccountFactory=af) - self.assertTrue(accnt is not None, msg="no account created by factory") - self.assertEqual(accnt.name, af.username, msg="account names are not same") + accnt = AccountFactory.create(apiclient=self.apiClient, firstname='test', lastname='test') + a = accnt.list(apiclient=self.apiClient, account=accnt.account.username, domainid=accnt.account.domainid) + self.assert_(accnt is not None, msg="no account created by factory") + self.assert_(accnt.account.name is not None) @unittest.skip("Job Queue gets stuck on this") def test_disableAccountPostFactoryGeneration(self): af = DomainAdminFactory() - domadmin = Account.create(apiclient=self.apiClient, AccountFactory=af) - self.assertTrue(domadmin is not None, msg="no account was created") - self.assertEqual(domadmin.name, af.username, msg = "account names don't match") + domadmin = DomainAdminFactory.create(apiclient=self.apiClient, factory=af) + self.assert_(domadmin is not None, msg="no account was created") + self.assert_(domadmin.account.name, af.username, msg = "account names don't match") domadmin.disable(self.apiClient, lock=True) def tearDown(self): @@ -78,10 +90,9 @@ class ServiceOfferingFactoryTest(unittest.TestCase): self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient() def test_serviceOfferingFactory(self): - sf = ServiceOfferingFactory() - soffering = ServiceOffering.create(apiclient=self.apiClient, ServiceOfferingFactory=sf) - self.assertTrue(soffering is not None, msg="no service offering was created") - self.assertEqual(soffering.name, sf.name, msg="error in service offering factory creation") + soffering = ServiceOfferingFactory.create(apiclient=self.apiClient) + self.assert_(soffering is not None, msg="no service offering was created") + self.assert_(soffering.name is not None, msg="error in service offering factory creation") def tearDown(self): @@ -93,19 +104,18 @@ class NetworkOfferingFactoryTest(unittest.TestCase): self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient() def test_defaultSourceNatOfferingFactory(self): - snatOfferingFactory = DefaultIsolatedNetworkOfferingWithSourceNatServiceFactory() - snatOffering = NetworkOffering.create(apiclient=self.apiClient, NetworkOfferingFactory=snatOfferingFactory) - self.assertTrue(snatOffering is not None, msg = "no network offering was created") - self.assertEqual(snatOffering.name, snatOfferingFactory.name, msg="error in network offering factory creation") + snatOffering = DefaultIsolatedNetworkOfferingWithSourceNatServiceFactory.create(apiclient=self.apiClient) + self.assert_(snatOffering is not None, msg = "no network offering was created") + self.assert_(snatOffering.name is not None, msg="error in network offering creation") def test_defaultSGOfferingEnable(self): - sgOfferingFactory = DefaultSharedNetworkOfferingWithSGServiceFactory() - sgOffering = NetworkOffering.create(apiclient=self.apiClient, NetworkOfferingFactory=sgOfferingFactory) + sgOffering = DefaultSharedNetworkOfferingWithSGServiceFactory.create(apiclient=self.apiClient) sgOffering.update(self.apiClient, state='Enabled') def tearDown(self): pass + class VirtualMachineFactoryTest(unittest.TestCase): def setUp(self): self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient() @@ -114,13 +124,14 @@ class VirtualMachineFactoryTest(unittest.TestCase): pass def test_virtualMachineDeploy(self): - sf = ServiceOfferingFactory() + sf = SmallServiceOfferingFactory() tf = DefaultBuiltInTemplateFactory() + service = ServiceOffering.create(apiclient=self.apiClient, factory=sf) zones = Zone.list(apiclient=self.apiClient) template = get_template(apiclient=self.apiClient, zoneid = zones[0].id, ostype=tf.ostype) - vmf = VirtualMachineFactory(serviceofferingid = sf.id, templateid = template.id, zoneid = zones[0].id) + vmf = VirtualMachineFactory(serviceofferingid = service.id, templateid = template.id, zoneid = zones[0].id) + vm = VirtualMachine.deploy(apiclient=self.apiClient, factory=vmf) - vm = VirtualMachine.create(apiclient=self.apiClient, VirtualMachineFactory=vmf) class UserFactorySubFactoryTest(unittest.TestCase): def setUp(self): @@ -130,10 +141,6 @@ class UserFactorySubFactoryTest(unittest.TestCase): pass def test_userSubFactory(self): - uf = UserFactory() - account = AccountFactory.create(apiclient=self.apiClient, AccountFactory=uf.account) - self.assertTrue(account is not None, msg="no account was created") - users = User.list(apiclient=self.apiClient, account=account.name) - self.assertTrue(users is not None, msg="no users were found in the account") - self.assertTrue(len(users) > 0, msg="user list is empty") - self.assertEqual(users[0].username, uf.username, msg="usernames are not same") + uf = UserFactory.create(apiclient=self.apiClient) + user = User.list(apiclient=self.apiClient, username=uf.username) + self.assert_(uf.username == user[0].username, msg="Usernames don't match")