From 8bd1ac6a414690be53451955afa9e25abaf66f05 Mon Sep 17 00:00:00 2001 From: Liam Young Date: Sat, 5 Feb 2022 07:58:00 +0000 Subject: [PATCH] Github workflow --- charms/neutron-k8s/.github/workflows/tox.yaml | 27 +++++++ charms/neutron-k8s/src/charm.py | 17 ----- charms/neutron-k8s/tests/test_charm.py | 66 ----------------- charms/neutron-k8s/tox.ini | 22 ++---- .../{tests => unit_tests}/__init__.py | 0 .../unit_tests/test_neutron_charm.py | 74 +++++++++++++++++++ 6 files changed, 107 insertions(+), 99 deletions(-) create mode 100644 charms/neutron-k8s/.github/workflows/tox.yaml delete mode 100644 charms/neutron-k8s/tests/test_charm.py rename charms/neutron-k8s/{tests => unit_tests}/__init__.py (100%) create mode 100644 charms/neutron-k8s/unit_tests/test_neutron_charm.py diff --git a/charms/neutron-k8s/.github/workflows/tox.yaml b/charms/neutron-k8s/.github/workflows/tox.yaml new file mode 100644 index 00000000..ddfeff1e --- /dev/null +++ b/charms/neutron-k8s/.github/workflows/tox.yaml @@ -0,0 +1,27 @@ +name: Python package + +on: + - push + - pull_request + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.8, 3.9] + + steps: + - uses: actions/checkout@v1 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions + - name: Lint with tox + run: tox -e pep8 + - name: Test with tox + run: tox -e py${{ matrix.python-version }} diff --git a/charms/neutron-k8s/src/charm.py b/charms/neutron-k8s/src/charm.py index a4786bae..dadf01ac 100755 --- a/charms/neutron-k8s/src/charm.py +++ b/charms/neutron-k8s/src/charm.py @@ -15,9 +15,6 @@ import advanced_sunbeam_openstack.core as sunbeam_core import advanced_sunbeam_openstack.container_handlers as sunbeam_chandlers import advanced_sunbeam_openstack.config_contexts as sunbeam_ctxts -from charms.observability_libs.v0.kubernetes_service_patch \ - import KubernetesServicePatch - logger = logging.getLogger(__name__) @@ -65,15 +62,6 @@ class NeutronOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm): '/etc/neutron/neutron.conf', '--config-file', '/etc/neutron/plugins/ml2/ml2_conf.ini', 'upgrade', 'head']] - def __init__(self, framework): - super().__init__(framework) - self.service_patcher = KubernetesServicePatch( - self, - [ - ('public', self.default_public_ingress_port), - ] - ) - def get_pebble_handlers(self) -> List[sunbeam_chandlers.PebbleHandler]: """Pebble handlers for the service.""" return [ @@ -159,27 +147,22 @@ class NeutronServerOVNPebbleHandler(sunbeam_chandlers.ServicePebbleHandler): def default_container_configs(self): return [ sunbeam_core.ContainerConfigFile( - [self.container_name], '/etc/neutron/neutron.conf', 'neutron', 'neutron'), sunbeam_core.ContainerConfigFile( - [self.container_name], '/etc/neutron/plugins/ml2/key_host', 'root', 'root'), sunbeam_core.ContainerConfigFile( - [self.container_name], '/etc/neutron/plugins/ml2/cert_host', 'root', 'root'), sunbeam_core.ContainerConfigFile( - [self.container_name], '/etc/neutron/plugins/ml2/neutron-ovn.crt', 'root', 'root'), sunbeam_core.ContainerConfigFile( - [self.container_name], '/etc/neutron/plugins/ml2/ml2_conf.ini', 'root', 'root')] diff --git a/charms/neutron-k8s/tests/test_charm.py b/charms/neutron-k8s/tests/test_charm.py deleted file mode 100644 index d0262094..00000000 --- a/charms/neutron-k8s/tests/test_charm.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2022 liam -# See LICENSE file for licensing details. -# -# Learn more about testing at: https://juju.is/docs/sdk/testing - -import unittest -from unittest.mock import Mock - -from charm import SunbeamNeutronOperatorCharm -from ops.model import ActiveStatus -from ops.testing import Harness - - -class TestCharm(unittest.TestCase): - def setUp(self): - self.harness = Harness(SunbeamNeutronOperatorCharm) - self.addCleanup(self.harness.cleanup) - self.harness.begin() - - def test_config_changed(self): - self.assertEqual(list(self.harness.charm._stored.things), []) - self.harness.update_config({"thing": "foo"}) - self.assertEqual(list(self.harness.charm._stored.things), ["foo"]) - - def test_action(self): - # the harness doesn't (yet!) help much with actions themselves - action_event = Mock(params={"fail": ""}) - self.harness.charm._on_fortune_action(action_event) - - self.assertTrue(action_event.set_results.called) - - def test_action_fail(self): - action_event = Mock(params={"fail": "fail this"}) - self.harness.charm._on_fortune_action(action_event) - - self.assertEqual(action_event.fail.call_args, [("fail this",)]) - - def test_httpbin_pebble_ready(self): - # Check the initial Pebble plan is empty - initial_plan = self.harness.get_container_pebble_plan("httpbin") - self.assertEqual(initial_plan.to_yaml(), "{}\n") - # Expected plan after Pebble ready with default config - expected_plan = { - "services": { - "httpbin": { - "override": "replace", - "summary": "httpbin", - "command": "gunicorn -b 0.0.0.0:80 httpbin:app -k gevent", - "startup": "enabled", - "environment": {"thing": "🎁"}, - } - }, - } - # Get the httpbin container from the model - container = self.harness.model.unit.get_container("httpbin") - # Emit the PebbleReadyEvent carrying the httpbin container - self.harness.charm.on.httpbin_pebble_ready.emit(container) - # Get the plan now we've run PebbleReady - updated_plan = self.harness.get_container_pebble_plan("httpbin").to_dict() - # Check we've got the plan we expected - self.assertEqual(expected_plan, updated_plan) - # Check the service was started - service = self.harness.model.unit.get_container("httpbin").get_service("httpbin") - self.assertTrue(service.is_running()) - # Ensure we set an ActiveStatus with no message - self.assertEqual(self.harness.model.unit.status, ActiveStatus()) diff --git a/charms/neutron-k8s/tox.ini b/charms/neutron-k8s/tox.ini index 31301b80..987807e9 100644 --- a/charms/neutron-k8s/tox.ini +++ b/charms/neutron-k8s/tox.ini @@ -35,26 +35,16 @@ whitelist_externals = passenv = HOME TERM CS_* OS_* TEST_* deps = -r{toxinidir}/test-requirements.txt -[testenv:py35] -basepython = python3.5 -# python3.5 is irrelevant on a focal+ charm. -commands = /bin/true - -[testenv:py36] -basepython = python3.6 -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt - -[testenv:py37] -basepython = python3.7 -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt - -[testenv:py38] +[testenv:py3.8] basepython = python3.8 deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt +[testenv:py3.9] +basepython = python3.9 +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + [testenv:py3] basepython = python3 deps = -r{toxinidir}/requirements.txt diff --git a/charms/neutron-k8s/tests/__init__.py b/charms/neutron-k8s/unit_tests/__init__.py similarity index 100% rename from charms/neutron-k8s/tests/__init__.py rename to charms/neutron-k8s/unit_tests/__init__.py diff --git a/charms/neutron-k8s/unit_tests/test_neutron_charm.py b/charms/neutron-k8s/unit_tests/test_neutron_charm.py new file mode 100644 index 00000000..22dc9ec1 --- /dev/null +++ b/charms/neutron-k8s/unit_tests/test_neutron_charm.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +# Copyright 2021 Canonical Ltd. +# +# Licensed 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 mock +import sys + +sys.path.append('lib') # noqa +sys.path.append('src') # noqa + +import charm +import advanced_sunbeam_openstack.test_utils as test_utils + + +class _NeutronOVNWallabyOperatorCharm(charm.NeutronOVNWallabyOperatorCharm): + + def __init__(self, framework): + self.seen_events = [] + self.render_calls = [] + super().__init__(framework) + + def _log_event(self, event): + self.seen_events.append(type(event).__name__) + + def renderer(self, containers, container_configs, template_dir, + openstack_release, adapters): + self.render_calls.append( + ( + containers, + container_configs, + template_dir, + openstack_release, + adapters)) + + def configure_charm(self, event): + super().configure_charm(event) + self._log_event(event) + + +class TestNeutronOperatorCharm(test_utils.CharmTestCase): + + PATCHES = [] + + @mock.patch( + 'charms.observability_libs.v0.kubernetes_service_patch.' + 'KubernetesServicePatch') + def setUp(self, mock_patch): + self.container_calls = { + 'push': {}, + 'pull': [], + 'remove_path': []} + super().setUp(charm, self.PATCHES) + self.harness = test_utils.get_harness( + _NeutronOVNWallabyOperatorCharm, + container_calls=self.container_calls) + self.addCleanup(self.harness.cleanup) + self.harness.begin() + + def test_pebble_ready_handler(self): + self.assertEqual(self.harness.charm.seen_events, []) + self.harness.container_pebble_ready('neutron-server') + self.assertEqual(len(self.harness.charm.seen_events), 1)