Unit tests and CI config

Change-Id: I2dfa889913caba8f6ac96ec4e9393c23fdda6100
This commit is contained in:
Liam Young 2023-04-20 14:58:08 +00:00
parent ca373b4708
commit e52489b3eb
4 changed files with 112 additions and 30 deletions

5
.gitreview Normal file
View File

@ -0,0 +1,5 @@
[gerrit]
host=review.opendev.org
port=29418
project=openstack/charm-openstack-hypervisor.git
defaultbranch=main

10
.zuul.yaml Normal file
View 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

View File

@ -30,12 +30,12 @@ import string
import subprocess
from typing import List
import ops.framework
import ops_sunbeam.charm as sunbeam_charm
import ops_sunbeam.guard as sunbeam_guard
import ops_sunbeam.ovn.relation_handlers as ovn_relation_handlers
import ops_sunbeam.relation_handlers as sunbeam_rhandlers
from netifaces import AF_INET, gateways, ifaddresses
import ops.framework
from ops.main import main
logger = logging.getLogger(__name__)
@ -68,7 +68,7 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
def __init__(self, framework: ops.framework.Framework) -> None:
"""Run constructor."""
super().__init__(framework)
self._state.set_default(metadata_secret='')
self._state.set_default(metadata_secret="")
def get_relation_handlers(
self, handlers: List[sunbeam_rhandlers.RelationHandler] = None
@ -90,12 +90,13 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
"""Ensure systemd services running."""
# This should taken care of by the snap
svcs = [
'snap.openstack-hypervisor.neutron-ovn-metadata-agent.service',
'snap.openstack-hypervisor.nova-api-metadata.service',
'snap.openstack-hypervisor.nova-compute.service']
"snap.openstack-hypervisor.neutron-ovn-metadata-agent.service",
"snap.openstack-hypervisor.nova-api-metadata.service",
"snap.openstack-hypervisor.nova-compute.service",
]
for svc in svcs:
if os.system(f'systemctl is-active --quiet {svc}') != 0:
os.system(f'systemctl start {svc}')
if os.system(f"systemctl is-active --quiet {svc}") != 0:
os.system(f"systemctl start {svc}")
def generate_metadata_secret(self) -> str:
"""Generate a secure secret.
@ -139,7 +140,7 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
contexts = self.contexts()
sb_connection_strs = list(contexts.ovsdb_cms.db_ingress_sb_connection_strs)
if not sb_connection_strs:
raise AttributeError(name='ovsdb southbound ingress string')
raise AttributeError(name="ovsdb southbound ingress string")
snap_data = {
"compute.cpu-mode": "host-model",
"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.enable-gateway": json.dumps(config("enable-gateway")),
"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.ovn-key": base64.b64encode(
contexts.certificates.key.encode()
).decode(),
"network.ovn-cert": base64.b64encode(
contexts.certificates.cert.encode()
).decode(),
"network.ovn-key": base64.b64encode(contexts.certificates.key.encode()).decode(),
"network.ovn-cert": base64.b64encode(contexts.certificates.cert.encode()).decode(),
"network.ovn-cacert": base64.b64encode(
contexts.certificates.ca_cert.encode()
).decode(),
@ -174,12 +172,11 @@ class HypervisorOperatorCharm(sunbeam_charm.OSBaseOperatorCharm):
"node.ip-address": config("ip-address") or local_ip,
"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:
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)
self.ensure_services_running()
self._state.unit_bootstrapped = True

View File

@ -14,12 +14,10 @@
"""Tests for Openstack hypervisor charm."""
import unittest
import mock
import ops_sunbeam.test_utils as test_utils
import base64
import json
import ops.testing
from ops.testing import Harness
import ops_sunbeam.test_utils as test_utils
import charm
@ -32,8 +30,10 @@ class _HypervisorOperatorCharm(charm.HypervisorOperatorCharm):
self.seen_events = []
super().__init__(framework)
class TestCharm(test_utils.CharmTestCase):
PATCHES = ['subprocess']
PATCHES = ["subprocess", "socket"]
def setUp(self):
"""Setup OpenStack Hypervisor tests."""
super().setUp(charm, self.PATCHES)
@ -42,15 +42,85 @@ class TestCharm(test_utils.CharmTestCase):
self.harness = test_utils.get_harness(
_HypervisorOperatorCharm,
container_calls=self.container_calls,
charm_config=config_data
charm_config=config_data,
)
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):
"""Test all the charms relations."""
self.socket.getfqdn.return_value = "test.local"
self.initial_setup()
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(
['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)