Browse Source

tests: rework unified OpenStack & Libvirt fixtures

keep-around/68a3c3746a6b9a97ade4ac05826340644ed27ed2
Loïc Dachary 6 months ago
committed by some
parent
commit
68a3c3746a
Signed by: dachary GPG Key ID: 992D23B392F9E4F2
  1. 14
      enough/common/__init__.py
  2. 17
      enough/common/dotenough.py
  3. 26
      enough/common/host.py
  4. 11
      enough/common/libvirt.py
  5. 5
      inventory/group_vars/all/libvirt.yml
  6. 134
      tests/conftest.py
  7. 2
      tests/enough/common/conftest.py
  8. 17
      tests/enough/common/test_init.py
  9. 95
      tests/enough/common/test_libvirt.py
  10. 5
      tests/enough/common/test_libvirt/networks_create/inventory/group_vars/all/libvirt.yml

14
enough/common/__init__.py

@ -6,10 +6,11 @@ import shutil
import textwrap
import yaml
from enough.common.dotenough import DotEnoughOpenStack, DotEnough, Hosts
from enough.common.dotenough import DotEnoughOpenStack, DotEnoughLibvirt, Hosts
from enough.common.host import host_factory
from enough.common.service import service_factory
from enough.common.openstack import OpenStack, Heat
from enough.common.libvirt import Libvirt
from enough.common import retry
from enough.common import ansible_utils
@ -37,20 +38,25 @@ class Enough(object):
self.args['cloud'] = cloud
self.dotenough.populate_provider(self.ansible, cloud)
else:
self.dotenough = DotEnough(self.config_dir, self.args['domain'])
self.dotenough = DotEnoughLibvirt(self.config_dir, self.args['domain'])
self.hosts = Hosts(self.config_dir)
self.host = host_factory(self.config_dir, self.share_dir, **self.args)
self.service = service_factory(self.config_dir, self.share_dir, **self.args)
if self.args.get('driver') == 'openstack':
self.openstack = OpenStack(self.config_dir, **self.args)
self.heat = Heat(self.config_dir, **self.args)
elif self.args.get('driver') == 'libvirt':
self.libvirt = Libvirt(self.config_dir, self.share_dir, **self.args)
self.playbook = ansible_utils.Playbook(self.config_dir, self.share_dir,
self.args.get('inventory'))
def create_missings(self, hosts):
public_key = f'{self.config_dir}/infrastructure_key.pub'
r = self.heat.create_missings(hosts, public_key)
self.update_internal_subnet_dns()
if self.args.get('driver') == 'openstack':
r = self.heat.create_missings(hosts, public_key)
self.update_internal_subnet_dns()
elif self.args.get('driver') == 'libvirt':
r = self.libvirt.create_or_update(Hosts(self.config_dir).missings(hosts), public_key)
return r
def update_internal_subnet_dns(self):

17
enough/common/dotenough.py

@ -137,6 +137,16 @@ class DotEnough(object):
"""))
class DotEnoughLibvirt(DotEnough):
def __init__(self, config_dir, domain):
super().__init__(config_dir, domain)
def ensure(self):
super().ensure()
self.populate_config('ownca')
class DotEnoughOpenStackUnknownProvider(Exception):
pass
@ -183,10 +193,3 @@ class DotEnoughOpenStack(DotEnough):
openstack_provider: {provider}
"""))
return f
class DotEnoughDocker(DotEnough):
def ensure(self):
super().ensure()
self.populate_config('ownca')

26
enough/common/host.py

@ -2,6 +2,7 @@ from abc import ABC, abstractmethod
from enough import settings
from enough.common import openstack
from enough.common import libvirt
from enough.common import dotenough
@ -51,6 +52,31 @@ class HostOpenStack(Host):
s.delete_wait()
class HostLibvirt(Host):
def __init__(self, config_dir, share_dir, **kwargs):
super().__init__(config_dir, share_dir, **kwargs)
self.args = kwargs
self.dotenough = dotenough.DotEnoughLibvirt(config_dir, self.args['domain'])
self.dotenough.ensure()
def create_or_update(self):
name = self.args['name']
dotenough.Hosts(self.config_dir).ensure(name)
lv = libvirt.Libvirt(self.config_dir, self.share_dir, **self.args)
return lv.create_or_update([name])[name]
def delete(self):
self.delete_hosts(self.args['name'])
def delete_hosts(self, names):
lv = libvirt.Libvirt(self.config_dir, self.share_dir, **self.args)
for name in names:
lv.delete(name)
def host_factory(config_dir=settings.CONFIG_DIR, share_dir=settings.SHARE_DIR, **kwargs):
if kwargs['driver'] == 'openstack':
return HostOpenStack(config_dir, share_dir, **kwargs)
elif kwargs['driver'] == 'libvirt':
return HostLibvirt(config_dir, share_dir, **kwargs)

11
enough/common/libvirt.py

@ -17,11 +17,11 @@ class Libvirt(object):
NETWORK = {
'external': {
'prefix': '10.23.10',
'name': 'enough-external',
'name': 'enough-ext',
},
'internal': {
'prefix': '10.23.90',
'name': 'enough-internal',
'name': 'enough-int',
},
}
@ -59,7 +59,7 @@ class Libvirt(object):
return None
log.info(f"{name}: building image")
self.image_builder()
sh.cp('-a', '--sparse=always', self.image_name(), self.host_image_name(name))
sh.cp('--sparse=always', self.image_name(), self.host_image_name(name))
log.info(f"{name}: preparing image")
self.sysprep(name, definition)
log.info(f"{name}: creating host")
@ -155,11 +155,14 @@ class Libvirt(object):
sh.chgrp('libvirt', image)
return True
def image_builder(self):
def image_dir_ensure(self):
if not os.path.exists(self.images_dir):
os.makedirs(self.images_dir)
sh.chmod('0771', self.images_dir)
sh.chgrp('libvirt', self.images_dir)
def image_builder(self):
self.image_dir_ensure()
return self._image_builder(self.image_name())
def networks_create(self):

5
inventory/group_vars/all/libvirt.yml

@ -0,0 +1,5 @@
---
libvirt_network_external_name: enough-ext
libvirt_network_external_prefix: 10.23.10
libvirt_network_internal_name: enough-int
libvirt_network_internal_prefix: 10.23.90

134
tests/conftest.py

@ -4,12 +4,14 @@ import pytest
import sh
import shutil
import tempfile
import textwrap
import time
from enough import settings
from enough.common import tcp
from enough.common.retry import retry
from enough.common.openstack import OpenStack
from enough.common.dotenough import DotEnoughLibvirt
from enough.common import libvirt
from tests import prepare_config_dir
@ -66,12 +68,134 @@ def openstack_name():
o.destroy_everything(prefix)
class Infrastructure(object):
def init(self, mocker, monkeypatch, tmpdir):
enough_dot_dir = str(tmpdir)
self.prefix_set()
self.mocker = mocker
self.domain = self.prefix
monkeypatch.setenv('ENOUGH_DOT', enough_dot_dir)
monkeypatch.setenv('ENOUGH_DOMAIN', self.domain)
self.prepare_config_dir(enough_dot_dir)
monkeypatch.setattr(settings, 'CONFIG_DIR', self.config_dir)
def prepare_config_dir(self, enough_dot_dir):
os.environ['ENOUGH_DOMAIN'] = self.domain
os.environ['ENOUGH_DOT'] = str(enough_dot_dir)
self.config_dir = f'{enough_dot_dir}/{self.domain}'
self.all_dir = f'{self.config_dir}/inventory/group_vars/all'
if not os.path.exists(self.all_dir):
os.makedirs(self.all_dir)
return enough_dot_dir
def fixture(self):
return self
class InfrastructureOpenStack(Infrastructure):
driver = 'openstack'
def prepare_config_dir(self, enough_dot_dir):
config_dir = super().prepare_config_dir(enough_dot_dir)
shutil.copyfile('tests/clouds.yml', f'{self.all_dir}/clouds.yml')
shutil.copyfile('inventory/group_vars/all/provision.yml', f'{self.all_dir}/provision.yml')
open(f'{self.all_dir}/certificate.yml', 'w').write(textwrap.dedent(f"""\
---
certificate_authority: letsencrypt_staging
"""))
return config_dir
def prefix_set(self):
self.prefix = 'enough_test_' + str(int(time.time()))
def destroy(self):
for cloud in ('production', 'clone'):
o = OpenStack(settings.CONFIG_DIR, cloud=cloud)
o.destroy_everything(None)
class InfrastructureLibvirt(Infrastructure):
driver = 'libvirt'
def prepare_config_dir(self, enough_dot_dir):
config_dir = super().prepare_config_dir(enough_dot_dir)
lv = libvirt.Libvirt(config_dir, '.', domain=self.domain)
self.images_dir = lv.images_dir
cached_images_dir = os.path.dirname(lv.images_dir)
filename = lv._image_name()
cached_image = f'{cached_images_dir}/{filename}'
if not os.path.exists(cached_image):
lv.image_builder()
os.rename(lv.image_name(), cached_image)
else:
lv.image_dir_ensure()
os.symlink(cached_image, lv.image_name())
dotenough = DotEnoughLibvirt(f'{config_dir}/{self.domain}', self.domain)
dotenough.ensure()
open(f'{self.all_dir}/certificate.yml', 'w').write(textwrap.dedent(f"""\
---
certificate_authority: ownca
"""))
port = '22'
global_variables = {
'libvirt_network_external_name': f'{self.prefix}e',
'libvirt_network_internal_name': f'{self.prefix}i',
}
self.mocker.patch('enough.common.ansible_utils.Ansible.get_global_variable',
return_value=global_variables)
definitions = {
self.prefix: {
'name': self.prefix,
'ansible_port': port,
'libvirt_ram': '1024',
},
}
definitions[self.prefix].update(global_variables)
self.mocker.patch('enough.common.libvirt.Libvirt.get_definitions',
return_value=definitions)
return config_dir
def prefix_set(self):
self.prefix = 'et' + str(int(time.time()))[5:]
def destroy(self):
lv = libvirt.Libvirt('.', '.')
lv.destroy_everything(self.prefix)
shutil.rmtree(self.images_dir)
@pytest.fixture(params=['openstack', 'libvirt'])
def dotenough_fixture(request, mocker, monkeypatch, tmpdir):
if request.param == 'openstack':
infrastructure = InfrastructureOpenStack()
elif request.param == 'libvirt':
infrastructure = InfrastructureLibvirt()
infrastructure.init(mocker, monkeypatch, tmpdir)
yield infrastructure.fixture()
infrastructure.destroy()
@pytest.fixture
def libvirt_name():
prefix = 'et' + str(int(time.time()))[5:]
yield prefix
lv = libvirt.Libvirt('.', '.')
lv.destroy_everything(prefix)
def dotenough_openstack_fixture(mocker, monkeypatch, tmpdir):
infrastructure = InfrastructureOpenStack()
infrastructure.init(mocker, monkeypatch, tmpdir)
yield infrastructure.fixture()
infrastructure.destroy()
@pytest.fixture
def dotenough_libvirt_fixture(mocker, monkeypatch, tmpdir):
infrastructure = InfrastructureLibvirt()
infrastructure.init(mocker, monkeypatch, tmpdir)
yield infrastructure.fixture()
infrastructure.destroy()
@pytest.fixture

2
tests/enough/common/conftest.py

@ -23,7 +23,7 @@ def openstack_variables(request):
@pytest.fixture
def dot_openstack(tmp_config_dir, request):
def dot_openstack(tmp_config_dir):
domain = settings.CONFIG_DIR.split('/')[-1]
dot_openstack = dotenough.DotEnoughOpenStack(settings.CONFIG_DIR, domain)
dot_openstack.ensure()

17
tests/enough/common/test_init.py

@ -463,13 +463,10 @@ def test_info_general(tmpdir):
# Host
#
@pytest.mark.openstack_integration
def test_host_create_or_update(request, tmpdir, openstack_name):
try:
enough = create_enough(tmpdir, 'host')
enough.set_args(name='new-host')
info = enough.host.create_or_update()
assert 'ipv4' in info
finally:
o = OpenStack(settings.CONFIG_DIR)
# comment out the following line to re-use the content of the regions and save time
o.destroy_everything(None)
def test_host_create_or_update(tmpdir, dotenough_fixture):
enough = Enough(dotenough_fixture.config_dir, settings.SHARE_DIR,
domain=dotenough_fixture.domain,
driver=dotenough_fixture.driver)
enough.set_args(name=dotenough_fixture.prefix)
info = enough.host.create_or_update()
assert 'ipv4' in info

95
tests/enough/common/test_libvirt.py

@ -1,86 +1,39 @@
import os
import shutil
from enough.common import libvirt
from enough.common.dotenough import DotEnoughLibvirt
from tests import make_config_dir
def libvirt_prepare_config_dir(domain, enough_dot_dir):
config_dir = make_config_dir(domain, enough_dot_dir)
dotenough = DotEnoughLibvirt(config_dir, domain)
dotenough.ensure()
return config_dir
def libvirt_image_cache(tmpimagesdir):
cachedimagesdir = os.path.dirname(tmpimagesdir)
filename = libvirt.Libvirt._image_name()
cachedimage = f'{cachedimagesdir}/{filename}'
libvirt.Libvirt._image_builder(cachedimage)
os.symlink(cachedimage, f'{tmpimagesdir}/{filename}')
def test_libvirt_network(libvirt_name):
lv = libvirt.Libvirt('.', '.')
def test_libvirt_network_all(dotenough_libvirt_fixture):
lv = libvirt.Libvirt(dotenough_libvirt_fixture.config_dir, '.')
prefix = '10.2.3'
network = lv.network_create(libvirt_name, prefix)
assert network.name() == libvirt_name
assert network.name() == lv.network_create(libvirt_name, prefix).name()
name = dotenough_libvirt_fixture.prefix
network = lv.network_create(name, prefix)
assert network.name() == name
assert network.name() == lv.network_create(name, prefix).name()
n = '10'
ip = f'{prefix}.{n}'
mac = f'52:54:00:00:00:{n}'
host = 'sample-host'
assert lv.network_host_set(libvirt_name, host, mac, ip) is True
assert lv.network_host_set(libvirt_name, host, mac, ip) is False
assert lv.network_host_unset(libvirt_name, host, mac, ip) is True
assert lv.network_host_unset(libvirt_name, host, mac, ip) is False
assert lv.network_destroy(libvirt_name) is True
assert lv.network_destroy(libvirt_name) is False
assert lv.network_host_set(name, host, mac, ip) is True
assert lv.network_host_set(name, host, mac, ip) is False
assert lv.network_host_unset(name, host, mac, ip) is True
assert lv.network_host_unset(name, host, mac, ip) is False
assert lv.network_destroy(name) is True
assert lv.network_destroy(name) is False
def test_libvirt_create_or_udpate(tmpdir, mocker, libvirt_cachedimagesdir, libvirt_name):
port = '22'
global_variables = {
'libvirt_network_external_name': f'{libvirt_name}e',
'libvirt_network_internal_name': f'{libvirt_name}i',
}
mocker.patch('enough.common.ansible_utils.Ansible.get_global_variable',
return_value=global_variables)
definitions = {
libvirt_name: {
'name': libvirt_name,
'ansible_port': port,
'libvirt_ram': '1024',
},
}
definitions[libvirt_name].update(global_variables)
mocker.patch('enough.common.libvirt.Libvirt.get_definitions',
return_value=definitions)
enough_domain = 'enough.com'
config_dir = libvirt_prepare_config_dir(enough_domain, tmpdir)
libvirt_image_cache(libvirt_cachedimagesdir)
lv = libvirt.Libvirt(config_dir, '.')
lv.images_dir = libvirt_cachedimagesdir
info = lv.create_or_update([libvirt_name])
assert info[libvirt_name]['port'] == port
def test_libvirt_create_or_udpate(dotenough_libvirt_fixture):
lv = libvirt.Libvirt(dotenough_libvirt_fixture.config_dir, '.',
domain=dotenough_libvirt_fixture.domain)
info = lv.create_or_update([dotenough_libvirt_fixture.prefix])
assert info[dotenough_libvirt_fixture.prefix]['port'] == '22'
def test_libvirt_networks_create(mocker, tmpdir, libvirt_name):
enough_domain = 'enough.com'
shutil.copytree(f'tests/enough/common/test_libvirt/networks_create',
f'{tmpdir}/{enough_domain}')
config_dir = libvirt_prepare_config_dir(enough_domain, tmpdir)
lv = libvirt.Libvirt(config_dir, '.')
mocker.patch('enough.common.libvirt.Libvirt.network_create', side_effect=lambda *args: args)
assert lv.networks_create() == [('test-external', '1.2.3'), ('test-internal', '10.20.30')]
def test_libvirt_networks_create(dotenough_libvirt_fixture):
lv = libvirt.Libvirt(dotenough_libvirt_fixture.config_dir, '.')
for network in lv.networks_create():
assert network.name().startswith(dotenough_libvirt_fixture.prefix)
def test_libvirt_image_builder(tmpdir, libvirt_cachedimagesdir, libvirt_name):
enough_domain = 'enough.com'
config_dir = libvirt_prepare_config_dir(enough_domain, tmpdir)
libvirt_image_cache(libvirt_cachedimagesdir)
lv = libvirt.Libvirt(config_dir, '.')
lv.images_dir = libvirt_cachedimagesdir
def test_libvirt_image_builder(dotenough_libvirt_fixture):
lv = libvirt.Libvirt(dotenough_libvirt_fixture.config_dir, '.',
domain=dotenough_libvirt_fixture.domain)
assert lv.image_builder() is False

5
tests/enough/common/test_libvirt/networks_create/inventory/group_vars/all/libvirt.yml

@ -1,5 +0,0 @@
---
libvirt_network_external_name: test-external
libvirt_network_external_prefix: 1.2.3
libvirt_network_internal_name: test-internal
libvirt_network_internal_prefix: 10.20.30
Loading…
Cancel
Save