[test] ConvertedExtracted openstack recipe installation; added local http server for serving RPMs
This commit is contained in:
parent
237382e5c0
commit
ceb6c2b8e1
@ -4,7 +4,7 @@ import unittest
|
||||
from devops.model import Environment, Network, Node, Disk, Cdrom, Interface
|
||||
from devops.controller import Controller
|
||||
from devops.driver.libvirt import Libvirt
|
||||
from devops.helpers import tcp_ping, wait, TimeoutError, ssh
|
||||
from devops.helpers import tcp_ping, wait, TimeoutError, ssh, http_server
|
||||
import traceback
|
||||
|
||||
import simplejson as json
|
||||
@ -30,6 +30,8 @@ class Ci:
|
||||
|
||||
try:
|
||||
self.environment = devops.load(environment_id)
|
||||
self.node = self.environment.nodes[0]
|
||||
self.network = self.environment.networks[0]
|
||||
logger.info("Successfully loaded existing environment")
|
||||
except Exception, e:
|
||||
logger.error("Failed to load existing cookbooks environment: " + str(e) + "\n" + traceback.format_exc())
|
||||
@ -65,6 +67,8 @@ class Ci:
|
||||
return False
|
||||
|
||||
self.environment = environment
|
||||
self.node = node
|
||||
self.network = network
|
||||
|
||||
try:
|
||||
logger.info("Starting test node")
|
||||
@ -80,12 +84,14 @@ class Ci:
|
||||
repo.write("""
|
||||
[mirantis]
|
||||
name=Mirantis repository
|
||||
baseurl=http://twin0d.srt.mirantis.net/centos62
|
||||
baseurl=http://%s:8000
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
""")
|
||||
""" % network.ip_addresses[1])
|
||||
repo.close()
|
||||
|
||||
remote.execute('yum makecache')
|
||||
|
||||
logger.info("Disabling firewall")
|
||||
|
||||
remote.execute('service iptables save')
|
||||
@ -94,7 +100,7 @@ gpgcheck=0
|
||||
|
||||
logger.info("Creating snapshot 'blank'")
|
||||
|
||||
node.save_snapshot('blank')
|
||||
node.save_snapshot('empty')
|
||||
|
||||
logger.info("Test node is ready at %s" % node.ip_address)
|
||||
|
||||
@ -133,14 +139,53 @@ gpgcheck=0
|
||||
|
||||
return True
|
||||
|
||||
def setup_repository(self):
|
||||
remote = ssh(self.node.ip_address, username='root', password='r00tme')
|
||||
repo = remote.open('/etc/yum.repos.d/mirantis.repo', 'w')
|
||||
repo.write("""
|
||||
[mirantis]
|
||||
name=Mirantis repository
|
||||
baseurl=http://%s:%d
|
||||
enabled=1
|
||||
gpgcheck=0
|
||||
""" % (self.network.ip_addresses[1], self.repository_server.port))
|
||||
repo.close()
|
||||
|
||||
remote.execute('yum makecache')
|
||||
|
||||
|
||||
def start_environment(self):
|
||||
self.repository_server = http_server(
|
||||
os.path.abspath(
|
||||
os.path.join(
|
||||
os.path.dirname(__file__), "..", "..",
|
||||
"build", "packages", "centos", "Packages"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
self.setup_repository()
|
||||
|
||||
self.node.save_snapshot('blank', force=True)
|
||||
|
||||
return True
|
||||
|
||||
def shutdown_environment(self):
|
||||
if hasattr(self, 'repository_server'):
|
||||
self.repository_server.stop()
|
||||
|
||||
return True
|
||||
|
||||
ci = None
|
||||
|
||||
def setUp():
|
||||
if not ci.setup_environment():
|
||||
raise Exception, "Failed to setup cookbooks environment"
|
||||
if not ci.start_environment():
|
||||
raise Exception, "Failed to run cookboks environment"
|
||||
|
||||
def tearDown():
|
||||
ci.shutdown_environment()
|
||||
if not ci.environment_cache_file:
|
||||
ci.destroy_environment()
|
||||
|
||||
@ -164,23 +209,27 @@ class CookbookTestCase(unittest.TestCase):
|
||||
|
||||
klass.remote = ssh(klass.ip, username='root', password='r00tme')
|
||||
|
||||
snapshot = klass.__name__
|
||||
try:
|
||||
snapshot = klass.__name__
|
||||
|
||||
if not os.environ.get('DEVELOPMENT') or not snapshot in klass.node.snapshots:
|
||||
logger.info('Setting up state for %s' % klass.__name__)
|
||||
if not os.environ.get('DEVELOPMENT') or not snapshot in klass.node.snapshots:
|
||||
logger.info('Setting up state for %s' % klass.__name__)
|
||||
|
||||
if snapshot in klass.node.snapshots:
|
||||
klass.node.delete_snapshot(snapshot)
|
||||
if snapshot in klass.node.snapshots:
|
||||
klass.node.delete_snapshot(snapshot)
|
||||
|
||||
klass.node.restore_snapshot('blank')
|
||||
klass.remote.reconnect()
|
||||
klass.node.restore_snapshot('blank')
|
||||
klass.remote.reconnect()
|
||||
|
||||
klass.upload_cookbooks(klass.cookbooks)
|
||||
klass.setUpState()
|
||||
klass.upload_cookbooks(klass.cookbooks)
|
||||
klass.setUpState()
|
||||
|
||||
klass.node.save_snapshot(snapshot)
|
||||
klass.node.save_snapshot(snapshot)
|
||||
|
||||
logger.info('Finished state for %s' % klass.__name__)
|
||||
logger.info('Finished state for %s' % klass.__name__)
|
||||
except:
|
||||
# klass.http_server.stop()
|
||||
raise
|
||||
|
||||
@classmethod
|
||||
def upload_cookbooks(klass, cookbooks):
|
||||
@ -198,6 +247,8 @@ cookbook_path "/opt/os-cookbooks"
|
||||
|
||||
@classmethod
|
||||
def chef_solo(klass, attributes={}):
|
||||
ci.setup_repository()
|
||||
|
||||
recipes = attributes.get('recipes') or attributes.get('run_list')
|
||||
logger.info('Running Chef with recipes: %s' % (', '.join(recipes)))
|
||||
|
||||
|
122
test/cookbooks/openstack_common.py
Normal file
122
test/cookbooks/openstack_common.py
Normal file
@ -0,0 +1,122 @@
|
||||
|
||||
class OpenstackCommon(object):
|
||||
mysql_port = 3306
|
||||
|
||||
@classmethod
|
||||
def setUpMysql(klass, reuse_cached=True):
|
||||
if not klass.node.has_snapshot('openstack-mysql') or not reuse_cached:
|
||||
klass.upload_cookbooks(['mysql'])
|
||||
|
||||
klass.chef_solo({
|
||||
'recipes': ['mysql::server'],
|
||||
'mysql': {
|
||||
'port': klass.mysql_port,
|
||||
'db_maker_password': 'secret'
|
||||
},
|
||||
})
|
||||
|
||||
if not klass.node.has_snapshot('openstack-mysql'):
|
||||
klass.node.save_snapshot('openstack-mysql')
|
||||
else:
|
||||
klass.node.restore_snapshot('openstack-mysql')
|
||||
klass.remote.reconnect()
|
||||
|
||||
|
||||
keystone_admin_port = 37376
|
||||
keystone_public_port = 5000
|
||||
|
||||
@classmethod
|
||||
def setUpKeystone(klass, reuse_cached=True):
|
||||
if not klass.node.has_snapshot('openstack-keystone') or not reuse_cached:
|
||||
klass.setUpMysql()
|
||||
|
||||
klass.upload_cookbooks(['chef-resource-groups', 'database', 'keystone'])
|
||||
|
||||
klass.chef_solo({
|
||||
'recipes': ['keystone::server'],
|
||||
'mysql': {
|
||||
'admin': {
|
||||
'host': str(klass.ip),
|
||||
'port': klass.mysql_port,
|
||||
'username': 'db_maker',
|
||||
'password': 'test'
|
||||
}
|
||||
},
|
||||
'keystone': {
|
||||
'db': {
|
||||
'password': 'secret'
|
||||
},
|
||||
'admin_token': 'secret',
|
||||
'service_tenant': 'service',
|
||||
'admin_tenant': 'admin',
|
||||
'admin_user': 'admin',
|
||||
'admin_password': 'admin',
|
||||
'admin_role': 'admin',
|
||||
'admin_url': 'http://%s:%s/' % (klass.ip,
|
||||
klass.keystone_public_port),
|
||||
'public_url': 'http://%s:%s/' % (klass.ip,
|
||||
klass.keystone_public_port),
|
||||
'internal_url': 'http://%s:%s/' % (klass.ip,
|
||||
klass.keystone_public_port),
|
||||
'admin': {
|
||||
'host': klass.ip,
|
||||
'admin_port': klass.keystone_admin_port,
|
||||
'service_port': klass.keystone_public_port,
|
||||
},
|
||||
'public': {
|
||||
'host': klass.ip,
|
||||
'admin_port': klass.keystone_admin_port,
|
||||
'service_port': klass.keystone_public_port,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if not klass.node.has_snapshot('openstack-keystone'):
|
||||
klass.node.save_snapshot('openstack-keystone')
|
||||
else:
|
||||
klass.node.restore_snapshot('openstack-keystone')
|
||||
klass.remote.reconnect()
|
||||
|
||||
|
||||
glance_registry_port = 9191
|
||||
|
||||
@classmethod
|
||||
def setUpGlanceRegistry(klass, reuse_cached=True):
|
||||
if not klass.node.has_snapshot('openstack-glance-registry') or not reuse_cached:
|
||||
klass.setUpKeystone()
|
||||
|
||||
klass.upload_cookbooks(['chef-resource-groups', 'database', 'keystone', 'glance'])
|
||||
|
||||
klass.chef_solo({
|
||||
'recipes': ['glance::registry'],
|
||||
'glance': {
|
||||
'registry': {
|
||||
'port': klass.glance_registry_port,
|
||||
},
|
||||
},
|
||||
'services': {
|
||||
'glance_registry': {
|
||||
'endpoints': {
|
||||
'mysql': {
|
||||
'host': str(klass.ip),
|
||||
'port': klass.mysql_port,
|
||||
'username': 'db_maker',
|
||||
'password': 'secret',
|
||||
},
|
||||
'keystone_admin': {
|
||||
'host': str(klass.ip),
|
||||
'port': klass.keystone_admin_port,
|
||||
'username': 'admin',
|
||||
'token': 'keystone_secret',
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
if not klass.node.has_snapshot('openstack-glance-registry'):
|
||||
klass.node.save_snapshot('openstack-glance-registry')
|
||||
else:
|
||||
klass.node.restore_snapshot('openstack-glance-registry')
|
||||
klass.remote.reconnect()
|
||||
|
@ -1,82 +1,37 @@
|
||||
from . import CookbookTestCase
|
||||
from openstack_common import OpenstackCommon
|
||||
|
||||
from devops.helpers import tcp_ping
|
||||
from integration.helpers import HTTPClient
|
||||
import os
|
||||
import simplejson as json
|
||||
|
||||
class TestKeystone(CookbookTestCase):
|
||||
cookbooks = ['chef-resource-groups', 'mysql', 'database', 'keystone']
|
||||
def find(predicate, sequence):
|
||||
"Returns first element of sequence for which predicate is true or None"
|
||||
for item in sequence:
|
||||
if predicate(item):
|
||||
return item
|
||||
|
||||
mysql_port = 3306
|
||||
|
||||
keystone_admin_port = 37376
|
||||
keystone_public_port = 5000
|
||||
return None
|
||||
|
||||
class TestKeystone(CookbookTestCase, OpenstackCommon):
|
||||
cookbooks = ['chef-resource-groups', 'database', 'keystone']
|
||||
|
||||
@classmethod
|
||||
def setUpState(klass):
|
||||
klass.chef_solo({
|
||||
'recipes': ['mysql::server'],
|
||||
'mysql': {
|
||||
'port': klass.mysql_port,
|
||||
'db_maker_password': 'secret'
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
klass.chef_solo({
|
||||
'recipes': ['keystone::server'],
|
||||
'mysql': {
|
||||
'admin': {
|
||||
'host': str(klass.ip),
|
||||
'port': klass.mysql_port,
|
||||
'username': 'db_maker',
|
||||
'password': 'test'
|
||||
}
|
||||
},
|
||||
'keystone': {
|
||||
'db': {
|
||||
'password': 'secret'
|
||||
},
|
||||
'admin_token': 'secret',
|
||||
'service_tenant': 'service',
|
||||
'admin_tenant': 'admin',
|
||||
'admin_user': 'admin',
|
||||
'admin_password': 'admin',
|
||||
'admin_role': 'admin',
|
||||
'admin_url': 'http://%s:%s/' % (klass.ip,
|
||||
klass.keystone_public_port),
|
||||
'public_url': 'http://%s:%s/' % (klass.ip,
|
||||
klass.keystone_public_port),
|
||||
'internal_url': 'http://%s:%s/' % (klass.ip,
|
||||
klass.keystone_public_port),
|
||||
'admin': {
|
||||
'host': klass.ip,
|
||||
'admin_port': klass.keystone_admin_port,
|
||||
'service_port': klass.keystone_public_port,
|
||||
},
|
||||
'public': {
|
||||
'host': klass.ip,
|
||||
'admin_port': klass.keystone_admin_port,
|
||||
'service_port': klass.keystone_public_port,
|
||||
},
|
||||
},
|
||||
})
|
||||
klass.setUpMysql()
|
||||
klass.setUpKeystone(reuse_cached=False)
|
||||
|
||||
def test_public_port_open(self):
|
||||
assert tcp_ping(self.ip, self.keystone_public_port)
|
||||
|
||||
def test_keystone_identity_service_registered(self):
|
||||
http = HTTPClient()
|
||||
|
||||
keystone_url = "http://%s:%d" % (self.ip, self.keystone_admin_port)
|
||||
|
||||
http = HTTPClient()
|
||||
services = json.loads(http.get(keystone_url + "/v2.0/OS-KSADM/services"))['OS-KSADM:services']
|
||||
keystone_service = None
|
||||
for service in services:
|
||||
if service['name'] == 'keystone':
|
||||
keystone_service = service
|
||||
break
|
||||
|
||||
keystone_service = find(lambda service: service['name'] == 'keystone', services)
|
||||
|
||||
assert keystone_service, "Keystone service is not registered"
|
||||
assert keystone_service['type'] == 'identity', \
|
||||
|
@ -1,19 +1,13 @@
|
||||
from . import CookbookTestCase
|
||||
from openstack_common import OpenstackCommon
|
||||
from devops.helpers import tcp_ping
|
||||
|
||||
class TestMysql(CookbookTestCase):
|
||||
class TestMysql(CookbookTestCase, OpenstackCommon):
|
||||
cookbooks = ['mysql']
|
||||
|
||||
mysql_port = 3306
|
||||
|
||||
@classmethod
|
||||
def setUpState(klass):
|
||||
klass.chef_solo({
|
||||
'recipes': ['mysql::server'],
|
||||
'mysql': {
|
||||
'port': klass.mysql_port
|
||||
}
|
||||
})
|
||||
klass.setUpMysql(reuse_cached=False)
|
||||
|
||||
def test_mysql_deploy(self):
|
||||
assert tcp_ping(self.ip, self.mysql_port)
|
||||
|
@ -35,7 +35,7 @@ clean-integration-test:
|
||||
|
||||
|
||||
.PHONY: test-cookbooks
|
||||
test-cookbooks: $/environment-id-cookbooks
|
||||
test-cookbooks: $/environment-id-cookbooks $(centos.packages)/Packages/repodata/repomd.xml
|
||||
python test/integration_test.py -l $(LEVEL) --cache-file $(abspath $<) --iso $(image.centos.url) --suite cookbooks test $(NOSEARGS)
|
||||
|
||||
$/environment-id-cookbooks:
|
||||
|
Loading…
Reference in New Issue
Block a user