You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ts...@apache.org on 2013/04/25 16:45:29 UTC
[03/51] [abbrv] git commit: updated refs/heads/marvin_refactor to
dbcfc66
Merge branch 'master' into marvin_refactor
Conflicts:
tools/marvin/marvin/cloudstackConnection.py
tools/marvin/marvin/cloudstackTestClient.py
tools/marvin/marvin/oldbase.py
ui/scripts/zoneWizard.js
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/5cea6012
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5cea6012
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5cea6012
Branch: refs/heads/marvin_refactor
Commit: 5cea60128fed0467d098c5e307fdd6e90ddc6caa
Parents: 0b5fe9a a1ef9d7
Author: Prasanna Santhanam <ts...@apache.org>
Authored: Wed Apr 24 22:10:48 2013 +0530
Committer: Prasanna Santhanam <ts...@apache.org>
Committed: Wed Apr 24 22:10:48 2013 +0530
----------------------------------------------------------------------
api/src/com/cloud/vm/UserVmService.java | 27 +-
.../org/apache/cloudstack/api/ApiConstants.java | 1 +
api/src/org/apache/cloudstack/api/BaseCmd.java | 24 +
.../command/admin/account/CreateAccountCmd.java | 14 +-
.../api/command/admin/vm/MigrateVMCmd.java | 2 +-
.../api/command/user/vm/DeployVMCmd.java | 12 +-
.../api/command/user/vm/UpdateVMCmd.java | 2 +-
.../cloudstack/api/response/ClusterResponse.java | 9 +-
.../api/response/DomainRouterResponse.java | 11 +
.../cloudstack/api/response/HostResponse.java | 9 +-
.../cloudstack/api/response/NetworkResponse.java | 7 +
.../cloudstack/api/response/PodResponse.java | 9 +-
.../cloudstack/api/response/SnapshotResponse.java | 16 +
.../api/response/StoragePoolResponse.java | 15 +-
.../cloudstack/api/response/SystemVmResponse.java | 11 +
.../cloudstack/api/response/TemplateResponse.java | 7 +
.../cloudstack/api/response/UserVmResponse.java | 7 +
.../cloudstack/api/response/VolumeResponse.java | 8 +
.../WEB-INF/classes/resources/messages.properties | 1857 ++--
.../classes/resources/messages_fr_FR.properties | 216 +-
core/src/com/cloud/vm/UserVmVO.java | 6 +-
debian/rules | 5 +-
docs/en-US/Common_Content/feedback.xml | 24 +
docs/en-US/Preface.xml | 2 +-
docs/en-US/Release_Notes.xml |11164 ++++++++-------
docs/en-US/changed-API-commands-4.2.xml | 123 +
docs/en-US/feedback.xml | 24 +
docs/en-US/hypervisor-kvm-install-flow.xml | 2 +-
.../hypervisor-support-for-primarystorage.xml | 148 +-
docs/en-US/limit-accounts-domains.xml | 371 +
docs/en-US/vm-snapshots.xml | 10 +-
docs/en-US/work-with-usage.xml | 26 +-
.../cloudstack/storage/image/ImageServiceImpl.java | 85 +-
.../storage/motion/AncientDataMotionStrategy.java | 5 +-
packaging/centos63/package.sh | 1 +
server/src/com/cloud/api/ApiDispatcher.java | 9 -
server/src/com/cloud/api/ApiResponseHelper.java | 12 +
server/src/com/cloud/api/ApiServer.java | 155 +-
server/src/com/cloud/api/ApiServerService.java | 1 +
server/src/com/cloud/api/ApiServlet.java | 6 +-
.../api/query/dao/DomainRouterJoinDaoImpl.java | 1 +
.../com/cloud/api/query/dao/HostJoinDaoImpl.java | 1 +
.../api/query/dao/StoragePoolJoinDaoImpl.java | 1 +
.../com/cloud/api/query/dao/UserVmJoinDaoImpl.java | 1 +
.../com/cloud/api/query/dao/VolumeJoinDaoImpl.java | 3 +-
.../com/cloud/api/query/vo/DomainRouterJoinVO.java | 12 +
server/src/com/cloud/api/query/vo/HostJoinVO.java | 11 +
.../com/cloud/api/query/vo/StoragePoolJoinVO.java | 11 +
.../src/com/cloud/api/query/vo/UserVmJoinVO.java | 13 +
.../src/com/cloud/api/query/vo/VolumeJoinVO.java | 15 +
server/src/com/cloud/configuration/Config.java | 17 +-
.../configuration/ConfigurationManagerImpl.java | 13 +-
server/src/com/cloud/dc/dao/DataCenterDao.java | 2 +
server/src/com/cloud/dc/dao/DataCenterDaoImpl.java | 8 +
.../ExternalLoadBalancerDeviceManagerImpl.java | 4 +-
.../src/com/cloud/network/NetworkServiceImpl.java | 7 +-
.../src/com/cloud/network/vpc/VpcManagerImpl.java | 31 +-
.../com/cloud/template/TemplateManagerImpl.java | 17 +-
.../com/cloud/usage/UsageNetworkOfferingVO.java | 14 +-
.../usage/dao/UsageNetworkOfferingDaoImpl.java | 9 +-
server/src/com/cloud/vm/UserVmManagerImpl.java | 100 +-
server/src/com/cloud/vm/UserVmStateListener.java | 21 +-
.../com/cloud/vm/VirtualMachineManagerImpl.java | 13 +-
.../test/com/cloud/vm/MockUserVmManagerImpl.java | 48 +-
server/test/com/cloud/vm/UserVmManagerTest.java | 45 +-
.../test/com/cloud/vm/dao/UserVmDaoImplTest.java | 43 +-
.../cloud/vm/dao/UserVmDaoTestConfiguration.java | 50 +
server/test/resources/UserVMDaoTestContext.xml | 44 +
setup/db/db/schema-40to410.sql | 4 +-
setup/db/db/schema-410to420.sql | 337 +-
test/integration/smoke/test_affinity_groups.py | 10 +-
.../smoke/test_deploy_vm_with_userdata.py | 144 +
test/integration/smoke/test_global_settings.py | 33 +-
test/integration/smoke/test_non_contigiousvlan.py | 139 +-
test/integration/smoke/test_public_ip_range.py | 6 +-
test/integration/smoke/test_vm_life_cycle.py | 28 +-
tools/build/build_asf.sh | 79 +-
tools/build/setnextversion.sh | 75 +
tools/marvin/marvin/asyncJobMgr.py | 70 +-
tools/marvin/marvin/cloudstackConnection.py | 51 +-
tools/marvin/marvin/cloudstackTestClient.py | 55 +-
tools/marvin/marvin/codegenerator.py | 4 +-
tools/marvin/marvin/cs_entity_generator.py | 202 +
tools/marvin/marvin/dbConnection.py | 6 +-
tools/marvin/marvin/deployDataCenter.py | 7 +
.../factory/test/test_encapsulated_factory.py | 35 +
tools/marvin/marvin/factory/test/test_factories.py | 187 +
tools/marvin/marvin/oldbase.py | 597 +-
tools/marvin/marvin/remoteSSHClient.py | 18 +-
tools/marvin/marvin/utils.py | 17 +-
usage/src/com/cloud/usage/UsageManagerImpl.java | 10 +-
91 files changed, 10196 insertions(+), 6916 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5cea6012/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5cea6012/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5cea6012/tools/marvin/marvin/cloudstackConnection.py
----------------------------------------------------------------------
diff --cc tools/marvin/marvin/cloudstackConnection.py
index f6589bb,9a4c387..5266c75
--- a/tools/marvin/marvin/cloudstackConnection.py
+++ b/tools/marvin/marvin/cloudstackConnection.py
@@@ -30,10 -30,11 +30,11 @@@ from requests import Timeou
from requests import RequestException
-class cloudConnection(object):
+class CloudConnection(object):
""" Connections to make API calls to the cloudstack management server
"""
- def __init__(self, mgtSvr, port=8096, apiKey=None, securityKey=None,
+ def __init__(self, mgtSvr, port=8096, user=None, passwd=None,
+ apiKey=None, securityKey=None,
asyncTimeout=3600, logging=None, scheme='http',
path='client/api'):
self.apiKey = apiKey
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5cea6012/tools/marvin/marvin/cs_entity_generator.py
----------------------------------------------------------------------
diff --cc tools/marvin/marvin/cs_entity_generator.py
index 0000000,0000000..f6d94c0
new file mode 100644
--- /dev/null
+++ b/tools/marvin/marvin/cs_entity_generator.py
@@@ -1,0 -1,0 +1,202 @@@
++# 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 marvin
++from marvin.cloudstackAPI import *
++import os
++
++# Add verbs in grammar - same as cloudmonkey
++grammar = ['create', 'list', 'delete', 'update',
++ 'enable', 'activate', 'disable', 'add', 'remove',
++ 'attach', 'detach', 'associate', 'generate', 'ldap',
++ 'assign', 'authorize', 'change', 'register', 'configure',
++ 'start', 'restart', 'reboot', 'stop', 'reconnect',
++ 'cancel', 'destroy', 'revoke', 'mark', 'reset',
++ 'copy', 'extract', 'migrate', 'restore', 'suspend',
++ 'get', 'query', 'prepare', 'deploy', 'upload', 'lock',
++ 'disassociate', 'scale']
++
++LICENSE = """# 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.
++"""
++
++
++def get_api_cmds():
++ api_classes = __import__('marvin.cloudstackAPI')
++
++ cmdlist = map(
++ lambda f: getattr(api_classes.cloudstackAPI, f),
++ filter(
++ lambda t: t.startswith('__') == False,
++ dir(api_classes.cloudstackAPI)
++ )
++ )
++
++ cmdlist = filter(
++ lambda g: g is not None,
++ cmdlist
++ )
++
++ clslist = map(
++ lambda g: getattr(g, g.__name__.split('.')[-1] + 'Cmd'),
++ filter(
++ lambda h: h.__name__.split('.')[-1] not in ['baseCmd', 'baseResponse', 'cloudstackAPIClient'],
++ cmdlist
++ )
++ )
++
++ cmdlets = map(lambda t: t(), clslist)
++ return cmdlets
++
++def get_entity_from_api(api):
++ matching_verbs = filter(lambda v: api.__class__.__name__.startswith(v), grammar)
++ if len(matching_verbs) > 0:
++ verb = matching_verbs[0]
++ entity = api.__class__.__name__.replace(verb, '').replace('Cmd', '')
++ return entity
++
++def get_actionable_entities():
++ cmdlets = sorted(get_api_cmds(), key=lambda k: get_entity_from_api(k))
++ entities = {}
++ for cmd in cmdlets:
++ requireds = getattr(cmd, 'required')
++ optionals = filter(lambda x: '__' not in x and 'required' not in x and 'isAsync' not in x, dir(cmd))
++ matching_verbs = filter(lambda v: cmd.__class__.__name__.startswith(v), grammar)
++ if len(matching_verbs)> 0:
++ verb = matching_verbs[0]
++ entity = cmd.__class__.__name__.replace(verb, '').replace('Cmd', '')
++ if entity[:-1] in entities:
++ # Accounts and Account are the same entity
++ entity = entity[:-1]
++ if entity[:-2] in entities:
++ # IpAddresses and IpAddress are the same entity
++ entity = entity[:-2]
++ if entity not in entities:
++ entities[entity] = { }
++ entities[entity][verb] = {}
++ entities[entity][verb]['args'] = requireds
++ entities[entity][verb]['apimodule'] = cmd.__class__.__module__.split('.')[-1]
++ entities[entity][verb]['apicmd'] = cmd.__class__.__name__
++ return entities
++
++def write_entity_classes(entities):
++ tabspace = ' '
++ entitydict = {}
++ #TODO: Add license header for ASLv2
++ for entity, actions in entities.iteritems():
++ body = []
++ imports = []
++ imports.append('from marvin.integration.lib.base import CloudStackEntity')
++ body.append('class %s(CloudStackEntity.CloudStackEntity):'%entity)
++ body.append('\n')
++ body.append(tabspace + 'def __init__(self, items):')
++ body.append(tabspace*2 + 'self.__dict__.update(items)')
++ body.append('\n')
++ for action, details in actions.iteritems():
++ imports.append('from marvin.cloudstackAPI import %s'%details['apimodule'])
++ if action in ['create', 'list', 'deploy']:
++ body.append(tabspace + '@classmethod')
++ if action in ['create', 'deploy']:
++ body.append(tabspace + 'def %s(cls, apiclient, %sFactory, **kwargs):'%(action, entity))
++ body.append(tabspace*2 + 'cmd = %(module)s.%(command)s()'%{"module": details["apimodule"], "command": details["apicmd"]})
++ body.append(tabspace*2 + '[setattr(cmd, factoryKey, factoryValue) for factoryKey, factoryValue in %sFactory.__dict__.iteritems()]'%entity)
++ body.append(tabspace*2 + '[setattr(cmd, key, value) for key,value in kwargs.iteritems()]')
++ body.append(tabspace*2 + '%s = apiclient.%s(cmd)'%(entity.lower(), details['apimodule']))
++ body.append(tabspace*2 + 'return %s(%s.__dict__)'%(entity, entity.lower()))
++ else:
++ if len(details['args']) > 0:
++ body.append(tabspace + 'def %s(self, apiclient, %s, **kwargs):'%(action, ', '.join(list(set(details['args'])))))
++ else:
++ body.append(tabspace + 'def %s(self, apiclient, **kwargs):'%(action))
++ body.append(tabspace*2 + 'cmd = %(module)s.%(command)s()'%{"module": details["apimodule"], "command": details["apicmd"]})
++ if action not in ['create', 'list', 'deploy']:
++ body.append(tabspace*2 + 'cmd.id = self.id')
++ for arg in details['args']:
++ body.append(tabspace*2 + 'cmd.%s = %s'%(arg, arg))
++ body.append(tabspace*2 + '[setattr(cmd, key, value) for key,value in kwargs.iteritems()]')
++ body.append(tabspace*2 + '%s = apiclient.%s(cmd)'%(entity.lower(), details['apimodule']))
++ if action in ['list']:
++ body.append(tabspace*2 + 'return map(lambda e: %s(e.__dict__), %s)'%(entity, entity.lower()))
++ else:
++ body.append(tabspace*2 + 'return %s'%(entity.lower()))
++ body.append('\n')
++
++ imports = '\n'.join(imports)
++ body = '\n'.join(body)
++ code = imports + '\n\n' + body
++
++ entitydict[entity] = code
++ #write_entity_factory(entity, actions)
++ with open("./base/%s.py"%entity, "w") as writer:
++ writer.write(LICENSE)
++ writer.write(code)
++
++
++def write_entity_factory(entity, actions):
++ tabspace = ' '
++ #TODO: Add license header for ASLv2
++ code = ''
++ factory_defaults = []
++ if 'create' in actions:
++ factory_defaults.extend(actions['create']['args'])
++ elif 'deploy' in actions:
++ factory_defaults.extend(actions['deploy']['args'])
++ elif 'associate' in actions:
++ factory_defaults.extend(actions['associate']['args'])
++ elif 'register' in actions:
++ factory_defaults.extend(actions['register']['args'])
++ else:
++ return
++
++ if os.path.exists("./factory/%sFactory.py"%entity):
++ for arg in factory_defaults:
++ code += tabspace + '%s = None\n'%arg
++ with open("./factory/%sFactory.py"%entity, "r") as reader:
++ rcode = reader.read()
++ if rcode.find(code) > 0:
++ return
++ with open("./factory/%sFactory.py"%entity, "a") as writer:
++ writer.write(code)
++ else:
++ code += 'import factory\n'
++ code += 'from marvin.integration.lib.base import %s\n'%entity
++ code += 'class %sFactory(factory.Factory):'%entity
++ code += '\n\n'
++ code += tabspace + 'FACTORY_FOR = %s.%s\n\n'%(entity,entity)
++ for arg in factory_defaults:
++ code += tabspace + '%s = None\n'%arg
++ with open("./factory/%sFactory.py"%entity, "w") as writer:
++ writer.write(LICENSE)
++ writer.write(code)
++
++if __name__=='__main__':
++ entities = get_actionable_entities()
++ write_entity_classes(entities)
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5cea6012/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5cea6012/tools/marvin/marvin/factory/test/test_encapsulated_factory.py
----------------------------------------------------------------------
diff --cc tools/marvin/marvin/factory/test/test_encapsulated_factory.py
index 0000000,0000000..36c2c21
new file mode 100644
--- /dev/null
+++ b/tools/marvin/marvin/factory/test/test_encapsulated_factory.py
@@@ -1,0 -1,0 +1,35 @@@
++# 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 unittest
++import logging
++
++from marvin.cloudstackTestClient import cloudstackTestClient
++
++from marvin.base import Account
++
++class TestEncapsulatedFactory(unittest.TestCase):
++ def setUp(self):
++ self.apiClient = cloudstackTestClient(mgtSvr='localhost',
++ logging=logging.getLogger('factories.cloudstack')).getApiClient()
++
++ def test_accountEncapsulatedFactory(self):
++ account = Account.factory()
++ self.assert_(account is not None)
++
++ def tearDown(self):
++ pass
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5cea6012/tools/marvin/marvin/factory/test/test_factories.py
----------------------------------------------------------------------
diff --cc tools/marvin/marvin/factory/test/test_factories.py
index 0000000,0000000..31cdb40
new file mode 100644
--- /dev/null
+++ b/tools/marvin/marvin/factory/test/test_factories.py
@@@ -1,0 -1,0 +1,187 @@@
++# 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 unittest
++import logging
++
++from marvin.cloudstackTestClient import cloudstackTestClient
++
++from marvin.factory.AccountFactory import *
++from marvin.factory.ServiceOfferingFactory import *
++from marvin.factory.NetworkOfferingFactory import *
++from marvin.factory.TemplateFactory import *
++from marvin.factory.VirtualMachineFactory import *
++from marvin.factory.UserFactory import *
++
++from marvin.base.ServiceOffering import ServiceOffering
++from marvin.base.Zone import Zone
++from marvin.base.Account import Account
++from marvin.base.Template import Template
++from marvin.base.IpAddress import IpAddress
++from marvin.base.Network import Network
++
++class BuildVsCreateStrategyTest(unittest.TestCase):
++ def setUp(self):
++ self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient()
++
++ def tearDown(self):
++ pass
++
++ def test_buildUserAccountFactory(self):
++ af = UserAccountFactory()
++ self.assert_(af.name 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_adminAccountFactory(self):
++ 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):
++ accnt = UserAccountFactory.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("Account doesn't deserialize correctly")
++ def test_disableAccountPostFactoryGeneration(self):
++ domadmin = DomainAdminFactory.create(apiclient=self.apiClient)
++ self.assert_(domadmin is not None, msg="no account was created")
++ domadmin.disable(self.apiClient, lock=True)
++
++ def tearDown(self):
++ pass
++
++
++class ServiceOfferingFactoryTest(unittest.TestCase):
++ def setUp(self):
++ self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient()
++
++ def test_serviceOfferingFactory(self):
++ 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):
++ pass
++
++
++class NetworkOfferingFactoryTest(unittest.TestCase):
++ def setUp(self):
++ self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient()
++
++ def test_defaultSourceNatOfferingFactory(self):
++ 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):
++ 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()
++
++ def tearDown(self):
++ pass
++
++ def test_virtualMachineDeploy(self):
++ accnt = AccountFactory.create(apiclient=self.apiClient)
++ service = SmallServiceOfferingFactory.create(apiclient=self.apiClient)
++ tf = DefaultBuiltInTemplateFactory.build() #FIXME: Using build() strategy is confusing
++ zones = Zone.list(apiclient=self.apiClient)
++ template = Template.list(apiclient=self.apiClient,
++ templatefilter="featured",
++ ostype = tf.ostype,
++ zoneid = zones[0].id)
++ vm = VirtualMachineFactory.create(apiclient=self.apiClient,
++ serviceofferingid = service.id,
++ templateid = template[0].id,
++ zoneid = zones[0].id,
++ account = accnt.account.name,
++ domainid = accnt.account.domainid)
++ vm.destroy(apiclient=self.apiClient)
++
++
++
++class UserFactorySubFactoryTest(unittest.TestCase):
++ def setUp(self):
++ self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient()
++
++ def tearDown(self):
++ pass
++
++ def test_userSubFactory(self):
++ 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")
++
++
++class IpAddressFactoryTest(unittest.TestCase):
++ def setUp(self):
++ self.apiClient = cloudstackTestClient(mgtSvr='localhost', logging=logging.getLogger('factories.cloudstack')).getApiClient()
++
++ def tearDown(self):
++ pass
++
++ def test_associateIpAddress(self):
++ all_ips = IpAddress.list(apiclient=self.apiClient)
++ self.assert_(len(all_ips) > 0, msg="No free public IPs")
++ firstip = all_ips[0]
++ firstip.associate(apiclient=self.apiClient, zoneid=firstip.zoneid)
++
++ def test_vpcAssociateIpAddress(self):
++ #FIXME: To be written
++ self.assert_(1 == 1)
++
++ def test_associateIpAddressToNetwork(self):
++ accnt = AccountFactory.create(apiclient=self.apiClient)
++ self.assert_(accnt is not None)
++ self.assert_(isinstance(accnt, Account))
++ service = ServiceOffering.list(apiclient=self.apiClient, displaytext='Small')
++ self.assert_(len(service) > 0)
++ template = Template.list(apiclient=self.apiClient, templatefilter="featured")
++ self.assert_(len(template) > 0)
++ zones = Zone.list(apiclient=self.apiClient)
++ vm = VirtualMachineFactory.create(
++ apiclient=self.apiClient,
++ serviceofferingid = service[0].id,
++ templateid = template[0].id,
++ zoneid = zones[0].id,
++ account=accnt.account.name,
++ domainid=accnt.account.domainid)
++ all_ips = IpAddress.list(apiclient=self.apiClient)
++ firstip = all_ips[0]
++ networks = Network.list(apiclient=self.apiClient, account = accnt.account.name, domainid = accnt.account.domainid)
++ firstip.associate(apiclient=self.apiClient, networkid = networks[0].id)
++ vm.destroy(apiclient=self.apiClient)