Unit tests and CI config
Change-Id: I2dfa889913caba8f6ac96ec4e9393c23fdda6100
This commit is contained in:
parent
9511b77a00
commit
744491d03b
5
charms/openstack-hypervisor/.gitreview
Normal file
5
charms/openstack-hypervisor/.gitreview
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[gerrit]
|
||||||
|
host=review.opendev.org
|
||||||
|
port=29418
|
||||||
|
project=openstack/charm-openstack-hypervisor.git
|
||||||
|
defaultbranch=main
|
10
charms/openstack-hypervisor/.zuul.yaml
Normal file
10
charms/openstack-hypervisor/.zuul.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
- project:
|
||||||
|
templates:
|
||||||
|
- openstack-python3-charm-yoga-jobs
|
||||||
|
- openstack-cover-jobs
|
||||||
|
vars:
|
||||||
|
charm_build_name: keystone-k8s
|
||||||
|
juju_channel: 3.1/stable
|
||||||
|
juju_classic_mode: false
|
||||||
|
microk8s_channel: 1.26-strict/stable
|
||||||
|
microk8s_classic_mode: false
|
@ -30,12 +30,12 @@ import string
|
|||||||
import subprocess
|
import subprocess
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
|
import ops.framework
|
||||||
import ops_sunbeam.charm as sunbeam_charm
|
import ops_sunbeam.charm as sunbeam_charm
|
||||||
import ops_sunbeam.guard as sunbeam_guard
|
import ops_sunbeam.guard as sunbeam_guard
|
||||||
import ops_sunbeam.ovn.relation_handlers as ovn_relation_handlers
|
import ops_sunbeam.ovn.relation_handlers as ovn_relation_handlers
|
||||||
import ops_sunbeam.relation_handlers as sunbeam_rhandlers
|
import ops_sunbeam.relation_handlers as sunbeam_rhandlers
|
||||||
from netifaces import AF_INET, gateways, ifaddresses
|
from netifaces import AF_INET, gateways, ifaddresses
|
||||||
import ops.framework
|
|
||||||
from ops.main import main
|
from ops.main import main
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -68,7 +68,7 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
|||||||
def __init__(self, framework: ops.framework.Framework) -> None:
|
def __init__(self, framework: ops.framework.Framework) -> None:
|
||||||
"""Run constructor."""
|
"""Run constructor."""
|
||||||
super().__init__(framework)
|
super().__init__(framework)
|
||||||
self._state.set_default(metadata_secret='')
|
self._state.set_default(metadata_secret="")
|
||||||
|
|
||||||
def get_relation_handlers(
|
def get_relation_handlers(
|
||||||
self, handlers: List[sunbeam_rhandlers.RelationHandler] = None
|
self, handlers: List[sunbeam_rhandlers.RelationHandler] = None
|
||||||
@ -90,12 +90,13 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
|||||||
"""Ensure systemd services running."""
|
"""Ensure systemd services running."""
|
||||||
# This should taken care of by the snap
|
# This should taken care of by the snap
|
||||||
svcs = [
|
svcs = [
|
||||||
'snap.openstack-hypervisor.neutron-ovn-metadata-agent.service',
|
"snap.openstack-hypervisor.neutron-ovn-metadata-agent.service",
|
||||||
'snap.openstack-hypervisor.nova-api-metadata.service',
|
"snap.openstack-hypervisor.nova-api-metadata.service",
|
||||||
'snap.openstack-hypervisor.nova-compute.service']
|
"snap.openstack-hypervisor.nova-compute.service",
|
||||||
|
]
|
||||||
for svc in svcs:
|
for svc in svcs:
|
||||||
if os.system(f'systemctl is-active --quiet {svc}') != 0:
|
if os.system(f"systemctl is-active --quiet {svc}") != 0:
|
||||||
os.system(f'systemctl start {svc}')
|
os.system(f"systemctl start {svc}")
|
||||||
|
|
||||||
def generate_metadata_secret(self) -> str:
|
def generate_metadata_secret(self) -> str:
|
||||||
"""Generate a secure secret.
|
"""Generate a secure secret.
|
||||||
@ -139,7 +140,7 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
|||||||
contexts = self.contexts()
|
contexts = self.contexts()
|
||||||
sb_connection_strs = list(contexts.ovsdb_cms.db_ingress_sb_connection_strs)
|
sb_connection_strs = list(contexts.ovsdb_cms.db_ingress_sb_connection_strs)
|
||||||
if not sb_connection_strs:
|
if not sb_connection_strs:
|
||||||
raise AttributeError(name='ovsdb southbound ingress string')
|
raise AttributeError(name="ovsdb southbound ingress string")
|
||||||
snap_data = {
|
snap_data = {
|
||||||
"compute.cpu-mode": "host-model",
|
"compute.cpu-mode": "host-model",
|
||||||
"compute.spice-proxy-address": config("ip-address") or local_ip,
|
"compute.spice-proxy-address": config("ip-address") or local_ip,
|
||||||
@ -157,14 +158,11 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
|||||||
"network.dns-servers": config("dns-servers"),
|
"network.dns-servers": config("dns-servers"),
|
||||||
"network.enable-gateway": json.dumps(config("enable-gateway")),
|
"network.enable-gateway": json.dumps(config("enable-gateway")),
|
||||||
"network.external-bridge": config("external-bridge"),
|
"network.external-bridge": config("external-bridge"),
|
||||||
"network.external-bridge-address": config("external-bridge-address") or "10.20.20.1/24",
|
"network.external-bridge-address": config("external-bridge-address")
|
||||||
|
or "10.20.20.1/24",
|
||||||
"network.ip-address": config("ip-address") or local_ip,
|
"network.ip-address": config("ip-address") or local_ip,
|
||||||
"network.ovn-key": base64.b64encode(
|
"network.ovn-key": base64.b64encode(contexts.certificates.key.encode()).decode(),
|
||||||
contexts.certificates.key.encode()
|
"network.ovn-cert": base64.b64encode(contexts.certificates.cert.encode()).decode(),
|
||||||
).decode(),
|
|
||||||
"network.ovn-cert": base64.b64encode(
|
|
||||||
contexts.certificates.cert.encode()
|
|
||||||
).decode(),
|
|
||||||
"network.ovn-cacert": base64.b64encode(
|
"network.ovn-cacert": base64.b64encode(
|
||||||
contexts.certificates.ca_cert.encode()
|
contexts.certificates.ca_cert.encode()
|
||||||
).decode(),
|
).decode(),
|
||||||
@ -174,12 +172,11 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
|
|||||||
"node.ip-address": config("ip-address") or local_ip,
|
"node.ip-address": config("ip-address") or local_ip,
|
||||||
"rabbitmq.url": contexts.amqp.transport_url,
|
"rabbitmq.url": contexts.amqp.transport_url,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = ["snap", "set", "openstack-hypervisor"] + [
|
|
||||||
f"{k}={v}" for k, v in snap_data.items()
|
|
||||||
]
|
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
raise sunbeam_guard.WaitingExceptionError("Data missing: {}".format(e.name))
|
raise sunbeam_guard.WaitingExceptionError("Data missing: {}".format(e.name))
|
||||||
|
cmd = ["snap", "set", "openstack-hypervisor"]
|
||||||
|
for k in sorted(snap_data.keys()):
|
||||||
|
cmd.append(f"{k}={snap_data[k]}")
|
||||||
subprocess.check_call(cmd)
|
subprocess.check_call(cmd)
|
||||||
self.ensure_services_running()
|
self.ensure_services_running()
|
||||||
self._state.unit_bootstrapped = True
|
self._state.unit_bootstrapped = True
|
||||||
|
@ -14,12 +14,10 @@
|
|||||||
|
|
||||||
"""Tests for Openstack hypervisor charm."""
|
"""Tests for Openstack hypervisor charm."""
|
||||||
|
|
||||||
import unittest
|
import base64
|
||||||
import mock
|
import json
|
||||||
import ops_sunbeam.test_utils as test_utils
|
|
||||||
|
|
||||||
import ops.testing
|
import ops_sunbeam.test_utils as test_utils
|
||||||
from ops.testing import Harness
|
|
||||||
|
|
||||||
import charm
|
import charm
|
||||||
|
|
||||||
@ -32,8 +30,10 @@ class _HypervisorOperatorCharm(charm.HypervisorOperatorCharm):
|
|||||||
self.seen_events = []
|
self.seen_events = []
|
||||||
super().__init__(framework)
|
super().__init__(framework)
|
||||||
|
|
||||||
|
|
||||||
class TestCharm(test_utils.CharmTestCase):
|
class TestCharm(test_utils.CharmTestCase):
|
||||||
PATCHES = ['subprocess']
|
PATCHES = ["subprocess", "socket"]
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
"""Setup OpenStack Hypervisor tests."""
|
"""Setup OpenStack Hypervisor tests."""
|
||||||
super().setUp(charm, self.PATCHES)
|
super().setUp(charm, self.PATCHES)
|
||||||
@ -42,15 +42,85 @@ class TestCharm(test_utils.CharmTestCase):
|
|||||||
self.harness = test_utils.get_harness(
|
self.harness = test_utils.get_harness(
|
||||||
_HypervisorOperatorCharm,
|
_HypervisorOperatorCharm,
|
||||||
container_calls=self.container_calls,
|
container_calls=self.container_calls,
|
||||||
charm_config=config_data
|
charm_config=config_data,
|
||||||
)
|
)
|
||||||
self.addCleanup(self.harness.cleanup)
|
self.addCleanup(self.harness.cleanup)
|
||||||
self.harness.begin()
|
|
||||||
|
def initial_setup(self):
|
||||||
|
rel_id = self.harness.add_relation("certificates", "vault")
|
||||||
|
self.harness.add_relation_unit(rel_id, "vault/0")
|
||||||
|
self.harness.update_config({"snap-channel": "essex/stable", "ip-address": "10.0.0.10"})
|
||||||
|
self.harness.begin_with_initial_hooks()
|
||||||
|
csr = {"certificate_signing_request": test_utils.TEST_CSR}
|
||||||
|
self.harness.update_relation_data(
|
||||||
|
rel_id,
|
||||||
|
self.harness.charm.unit.name,
|
||||||
|
{
|
||||||
|
"ingress-address": "10.0.0.34",
|
||||||
|
"certificate_signing_requests": json.dumps([csr]),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
test_utils.add_certificates_relation_certs(self.harness, rel_id)
|
||||||
|
ovs_rel_id = self.harness.add_relation("ovsdb-cms", "ovn-relay")
|
||||||
|
self.harness.add_relation_unit(ovs_rel_id, "ovn-relay/0")
|
||||||
|
self.harness.update_relation_data(
|
||||||
|
ovs_rel_id,
|
||||||
|
"ovn-relay/0",
|
||||||
|
{
|
||||||
|
"bound-address": "10.1.176.143",
|
||||||
|
"bound-hostname": "ovn-relay-0.ovn-relay-endpoints.openstack.svc.cluster.local",
|
||||||
|
"egress-subnets": "10.20.21.10/32",
|
||||||
|
"ingress-address": "10.20.21.10",
|
||||||
|
"ingress-bound-address": "10.20.21.10",
|
||||||
|
"private-address": "10.20.21.10",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def test_all_relations(self):
|
def test_all_relations(self):
|
||||||
"""Test all the charms relations."""
|
"""Test all the charms relations."""
|
||||||
|
self.socket.getfqdn.return_value = "test.local"
|
||||||
|
self.initial_setup()
|
||||||
self.harness.set_leader()
|
self.harness.set_leader()
|
||||||
self.harness.update_config({'snap-channel': 'essex/stable'})
|
|
||||||
test_utils.add_all_relations(self.harness)
|
|
||||||
self.subprocess.check_call.assert_any_call(
|
self.subprocess.check_call.assert_any_call(
|
||||||
['snap', 'install', 'openstack-hypervisor', '--channel', 'essex/stable'])
|
["snap", "install", "openstack-hypervisor", "--channel", "essex/stable"]
|
||||||
|
)
|
||||||
|
test_utils.add_complete_amqp_relation(self.harness)
|
||||||
|
test_utils.add_complete_identity_credentials_relation(self.harness)
|
||||||
|
metadata = self.harness.charm.metadata_secret()
|
||||||
|
ovn_cacert = test_utils.TEST_CA + "\n" + "\n".join(test_utils.TEST_CHAIN)
|
||||||
|
ovn_cacert = base64.b64encode(ovn_cacert.encode()).decode()
|
||||||
|
private_key = base64.b64encode(
|
||||||
|
self.harness.charm.contexts().certificates.key.encode()
|
||||||
|
).decode()
|
||||||
|
certificate = base64.b64encode(test_utils.TEST_SERVER_CERT.encode()).decode()
|
||||||
|
expect_settings = [
|
||||||
|
"compute.cpu-mode=host-model",
|
||||||
|
"compute.spice-proxy-address=10.0.0.10",
|
||||||
|
"compute.virt-type=kvm",
|
||||||
|
f"credentials.ovn-metadata-proxy-shared-secret={metadata}",
|
||||||
|
"identity.auth-url=None",
|
||||||
|
"identity.password=user-password",
|
||||||
|
"identity.project-domain-name=pdomain_-ame",
|
||||||
|
"identity.project-name=user-project",
|
||||||
|
"identity.region-name=region12",
|
||||||
|
"identity.user-domain-name=udomain-name",
|
||||||
|
"identity.username=username",
|
||||||
|
"logging.debug=false",
|
||||||
|
"network.dns-domain=openstack.local",
|
||||||
|
"network.dns-servers=8.8.8.8",
|
||||||
|
"network.enable-gateway=false",
|
||||||
|
"network.external-bridge=br-ex",
|
||||||
|
"network.external-bridge-address=10.20.20.1/24",
|
||||||
|
"network.ip-address=10.0.0.10",
|
||||||
|
f"network.ovn-cacert={ovn_cacert}",
|
||||||
|
f"network.ovn-cert={certificate}",
|
||||||
|
f"network.ovn-key={private_key}",
|
||||||
|
"network.ovn-sb-connection=ssl:10.20.21.10:6642",
|
||||||
|
"network.physnet-name=physnet1",
|
||||||
|
"node.fqdn=test.local",
|
||||||
|
"node.ip-address=10.0.0.10",
|
||||||
|
"rabbitmq.url=rabbit://hypervisor:rabbit.pass@10.0.0.13:5672/openstack",
|
||||||
|
]
|
||||||
|
expect_set_cmd = ["snap", "set", "openstack-hypervisor"]
|
||||||
|
expect_set_cmd.extend(expect_settings)
|
||||||
|
self.subprocess.check_call.assert_any_call(expect_set_cmd)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user