From 26db0d8b67f9dbade7102a6e1c8b9a0ad7f15cc3 Mon Sep 17 00:00:00 2001 From: Alex Kavanagh Date: Thu, 22 Jul 2021 19:53:11 +0100 Subject: [PATCH 1/7] Update requirements to remove distro-info / nail pip 20.2.3 Finally found a way to really pin pip to 20.2.3 in the tox. (cherry picked from commit 7c593fc8eaeb0367f6cf182464a500b8c0843c51) --- pip.sh | 3 +++ tox.ini | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100755 pip.sh diff --git a/pip.sh b/pip.sh new file mode 100755 index 000000000..1085da286 --- /dev/null +++ b/pip.sh @@ -0,0 +1,3 @@ +#!/bin/bash +pip install pip==20.2.3 +pip install "$@" diff --git a/tox.ini b/tox.ini index 62df7615c..55d1556d3 100644 --- a/tox.ini +++ b/tox.ini @@ -22,7 +22,7 @@ whitelist_external = juju passenv = HOME TERM CS_* OS_* TEST_* deps = -r{toxinidir}/requirements.txt install_command = - pip install {opts} {packages} + {toxinidir}/pip.sh install {opts} {packages} commands = nosetests --with-coverage --cover-package=zaza {posargs} {toxinidir}/unit_tests [testenv:py3] @@ -58,6 +58,13 @@ commands = {envdir}/bin/python3 setup.py install functest-run-suite --keep-model +[testenv:func-target] +basepython = python3 +deps = -r{toxinidir}/requirements.txt +commands = + {envdir}/bin/python3 setup.py install + functest-run-suite --keep-model --bundle {posargs} + [testenv:remove-placement] basepython = python3 deps = -r{toxinidir}/requirements.txt From fb515b3965cba653998398ead30c01678297ac91 Mon Sep 17 00:00:00 2001 From: Frode Nordahl Date: Fri, 18 Feb 2022 07:32:09 +0100 Subject: [PATCH 2/7] CI: fix juju crashdump collection The ``--keep-last-model`` literally only keeps the last model, so if the failure is in the middle model it will be destroyed. Use ``--keep-faulty-model`` instead. The `juju status` command is currently run after tox in the same job. In the event of non-zero return from tox the shell will stop execution and subsequently not issue the ``juju status``. Move to crashdump job instead. The ``juju crashdump`` command is currently not scoped to the Zaza model(s) and subsequently fails to collect data. (cherry picked from commit 208180cdd31ff698d9df3814ba50d9e267a84b49) --- .github/workflows/tox.yaml | 8 +++++--- tox.ini | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml index 0f8b395d3..cc0545a6b 100644 --- a/.github/workflows/tox.yaml +++ b/.github/workflows/tox.yaml @@ -57,12 +57,14 @@ jobs: set -euxo pipefail mkdir logs tox -e func | tee logs/tox-output.txt - juju status -m $(juju models --format yaml|grep "^- name:.*zaza"|cut -f2 -d/) | tee logs/juju-status.txt - name: crashdump on failure if: failure() run: | - set -euxo pipefail - juju crashdump -o logs/ + set -eux + juju models + model=$(juju models --format yaml|grep "^- name:.*zaza"|cut -f2 -d/) + juju status -m $model | tee logs/juju-status.txt + juju crashdump -m $model -o logs/ - name: upload logs on failure if: failure() uses: actions/upload-artifact@v2 diff --git a/tox.ini b/tox.ini index 55d1556d3..44328e376 100644 --- a/tox.ini +++ b/tox.ini @@ -56,7 +56,7 @@ basepython = python3 deps = -r{toxinidir}/requirements.txt commands = {envdir}/bin/python3 setup.py install - functest-run-suite --keep-model + functest-run-suite --keep-faulty-model [testenv:func-target] basepython = python3 From 30121b42bf2ef43bb23f5fdc72c71c741fed87c6 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Tue, 16 Aug 2022 18:57:37 -0400 Subject: [PATCH 3/7] Test get_subordinates() This patch adds the ntp charm and relates it the ubuntu application, then get_subordinates() is exercised in a test. (cherry picked from commit 8f0dcf4f4862ab786ebb61327e883caecc424f0e) --- tests/bundles/first.yaml | 6 ++++++ tests/bundles/second.yaml | 6 ++++++ tests/bundles/third.yaml | 7 ++++++- zaza/charm_tests/libjuju/tests.py | 12 ++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/bundles/first.yaml b/tests/bundles/first.yaml index 7595b3464..ef473c3cd 100644 --- a/tests/bundles/first.yaml +++ b/tests/bundles/first.yaml @@ -13,3 +13,9 @@ applications: ubuntu: charm: ch:ubuntu num_units: 3 + ntp: + charm: ch:ntp + num_units: 0 +relations: + - - ubuntu + - ntp diff --git a/tests/bundles/second.yaml b/tests/bundles/second.yaml index b4ead7f8f..362a15b02 100644 --- a/tests/bundles/second.yaml +++ b/tests/bundles/second.yaml @@ -8,3 +8,9 @@ applications: ubuntu: charm: ch:ubuntu num_units: 3 + ntp: + charm: ch:ntp + num_units: 0 +relations: + - - ubuntu + - ntp diff --git a/tests/bundles/third.yaml b/tests/bundles/third.yaml index c6294bbc7..5e6de776f 100644 --- a/tests/bundles/third.yaml +++ b/tests/bundles/third.yaml @@ -3,4 +3,9 @@ applications: ubuntu: charm: ch:ubuntu num_units: 10 - + ntp: + charm: ch:ntp + num_units: 0 +relations: + - - ubuntu + - ntp diff --git a/zaza/charm_tests/libjuju/tests.py b/zaza/charm_tests/libjuju/tests.py index ca266a127..67b66cf59 100644 --- a/zaza/charm_tests/libjuju/tests.py +++ b/zaza/charm_tests/libjuju/tests.py @@ -20,6 +20,7 @@ import unittest import zaza.model +import zaza.utilities.juju as juju_utils class RegressionTest(unittest.TestCase): @@ -50,3 +51,14 @@ def test_02_get_unit_public_address(self): for ip in ips: logging.info("Ip found %s", ip) self.assertIsNotNone(ip) + + def test_03_get_subordinates(self): + """Get the subordinates associated to a principal.""" + logging.info('Get the list of subordinates.') + units = [u.entity_id for u in zaza.model.get_units('ubuntu')] + logging.info('principal units found: %s', units) + subordinate = juju_utils.get_subordinate_units([units[0]], + charm_name='ntp') + logging.info('subordinate(s) found %s for principal %s', + subordinate, units[0]) + self.assertEqual(len(subordinate), 1) From 4c5edf78550e88d127ec506c30407214c4a14111 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Mon, 22 Aug 2022 15:25:30 -0400 Subject: [PATCH 4/7] Test using multiple versions of juju (cherry picked from commit 289479e74d42c6547e8c89b960ebffa3516f89a1) --- .github/workflows/tox.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml index cc0545a6b..aac3e3403 100644 --- a/.github/workflows/tox.yaml +++ b/.github/workflows/tox.yaml @@ -31,6 +31,13 @@ jobs: codecov --verbose --gcov-glob unit_tests/* func: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + juju_channel: + - latest/stable + - 2.9/stable + - 2.8/stable needs: build steps: - uses: actions/checkout@v1 @@ -39,7 +46,7 @@ jobs: set -euxo pipefail python -m pip install --upgrade pip pip install tox tox-gh-actions - sudo snap install --classic juju + sudo snap install --channel ${{ matrix.juju_channel }} --classic juju sudo snap install --classic juju-crashdump sudo lxd init --auto # This is a throw-away CI environment, do not do this at home From 55a0e4f4048eabeb3e54a918178818fe01d38423 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Mon, 22 Aug 2022 17:04:46 -0400 Subject: [PATCH 5/7] Use func-target (cherry picked from commit 3f01c96c8d95d94c847c16f17590a72841f4bac8) --- .github/workflows/tox.yaml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml index aac3e3403..c2f83a3ff 100644 --- a/.github/workflows/tox.yaml +++ b/.github/workflows/tox.yaml @@ -38,6 +38,18 @@ jobs: - latest/stable - 2.9/stable - 2.8/stable + bundle: + - first + - second + - third + exclude: + # disable 'first' and 'second' bundles for juju 2.8 since 'magpie' + # is not a promulgated charm in the charmstore, only on charmhub + # which 2.8 can't talk to. + - juju_channel: 2.8/stable + bundle: first + - juju_channel: 2.8/stable + bundle: second needs: build steps: - uses: actions/checkout@v1 @@ -63,7 +75,7 @@ jobs: run: | set -euxo pipefail mkdir logs - tox -e func | tee logs/tox-output.txt + tox -e func-target -- ${{ matrix.bundle }} | tee logs/tox-output.txt - name: crashdump on failure if: failure() run: | From 239209b0561fc0d7dba99d1eee8617ffc4349236 Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Mon, 22 Aug 2022 17:13:16 -0400 Subject: [PATCH 6/7] Drop ch: prefix from third.yaml This change makes it compatible with juju 2.8, the other 2 bundles have magpie which was not a promulgated charm in the charm store, so they will fail even if the prefix is dropped. (cherry picked from commit f16fa22f4e649d44ba8e2dbe4cd5a38b044109b1) --- tests/bundles/third.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bundles/third.yaml b/tests/bundles/third.yaml index 5e6de776f..1b2235d4a 100644 --- a/tests/bundles/third.yaml +++ b/tests/bundles/third.yaml @@ -1,10 +1,10 @@ series: focal applications: ubuntu: - charm: ch:ubuntu + charm: ubuntu num_units: 10 ntp: - charm: ch:ntp + charm: ntp num_units: 0 relations: - - ubuntu From 32a95268bcaabe776b28c2bed11b549dee6485fc Mon Sep 17 00:00:00 2001 From: Felipe Reyes Date: Mon, 22 Aug 2022 22:06:28 -0400 Subject: [PATCH 7/7] Find subordinates reading from top level tree. This patch changes the way subordinates are filtered, since juju-2.9 doesn't populate the 'charm' key within the 'subordinates' key in the principal, so instead this change uses the unit id to get the app name and read the 'charm' value from the 'applications' section. This functionality is behind a feature a flag, if the environment variable TEST_ZAZA_BUG_LP1987332 is set to anything that evaluates to true, then this new code path is executed. Related-Bug: #1987332 (cherry picked from commit fc268181e8da1cb4293328fa2e78082873d98697) --- .github/workflows/tox.yaml | 2 + .../utilities/test_zaza_utilities_juju.py | 46 +++++++++++++++++++ zaza/utilities/juju.py | 11 +++-- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tox.yaml b/.github/workflows/tox.yaml index c2f83a3ff..3bdd5dba2 100644 --- a/.github/workflows/tox.yaml +++ b/.github/workflows/tox.yaml @@ -50,6 +50,8 @@ jobs: bundle: first - juju_channel: 2.8/stable bundle: second + env: + TEST_ZAZA_BUG_LP1987332: "on" # http://pad.lv/1987332 needs: build steps: - uses: actions/checkout@v1 diff --git a/unit_tests/utilities/test_zaza_utilities_juju.py b/unit_tests/utilities/test_zaza_utilities_juju.py index f15b3e4f5..7fa5e2187 100644 --- a/unit_tests/utilities/test_zaza_utilities_juju.py +++ b/unit_tests/utilities/test_zaza_utilities_juju.py @@ -13,6 +13,7 @@ # limitations under the License. import mock +import os import unit_tests.utils as ut_utils from zaza.utilities import juju as juju_utils @@ -411,6 +412,51 @@ def test_get_subordinate_units(self): status=juju_status), ['cinder-ceph/3']) + def test_get_subordinate_units_lp1987332(self): + juju_status = mock.MagicMock() + juju_status.applications = { + 'nova-compute': { + 'charm': 'ch:amd64/focal/nova-compute-1', + 'units': { + 'nova-compute/0': { + 'subordinates': { + 'neutron-openvswitch/2': { + 'charm': ''}}}}}, + 'cinder': { + 'charm': 'ch:amd64/focal/cinder-2', + 'units': { + 'cinder/1': { + 'subordinates': { + 'cinder-hacluster/0': { + 'charm': ''}, + 'cinder-ceph/3': { + 'charm': ''}}}}}, + 'cinder-hacluster': { + 'charm': 'ch:amd64/focal/hacluster-3', + }, + 'cinder-ceph': { + 'charm': 'ch:amd64/focal/cinder-ceph-4', + }, + 'neutron-openvswitch': { + 'charm': 'ch:amd64/focal/neutron-openvswitch-5', + }, + } + self.model.get_status.return_Value = juju_status + with mock.patch.dict(os.environ, + {'TEST_ZAZA_BUG_LP1987332': '1'}): + self.assertEqual( + sorted(juju_utils.get_subordinate_units( + ['nova-compute/0', 'cinder/1'], + status=juju_status)), + sorted(['neutron-openvswitch/2', 'cinder-hacluster/0', + 'cinder-ceph/3'])) + self.assertEqual( + juju_utils.get_subordinate_units( + ['nova-compute/0', 'cinder/1'], + charm_name='ceph', + status=juju_status), + ['cinder-ceph/3']) + def test_get_application_ip(self): self.model.get_application_config.return_value = { 'vip': {'value': '10.0.0.10'}} diff --git a/zaza/utilities/juju.py b/zaza/utilities/juju.py index 95dd94671..de9b942e9 100644 --- a/zaza/utilities/juju.py +++ b/zaza/utilities/juju.py @@ -480,9 +480,14 @@ def get_subordinate_units(unit_list, charm_name=None, status=None, subs = status.applications[app_name]['units'][unit_name].get( 'subordinates') or {} if charm_name: - for unit_name, unit_data in subs.items(): - if charm_name in unit_data['charm']: - sub_units.append(unit_name) + for subordinate_name, unit_data in subs.items(): + if os.environ.get('TEST_ZAZA_BUG_LP1987332'): + sub_app = subordinate_name.split('/')[0] + charm = status.applications[sub_app]['charm'] + else: + charm = unit_data['charm'] + if charm_name in charm: + sub_units.append(subordinate_name) else: sub_units.extend([n for n in subs.keys()]) return sub_units