Merge ~rgildein/juju-verify:bug/1920131 into ~canonical-solutions-engineering/juju-verify:master

Proposed by Robert Gildein
Status: Merged
Approved by: Robert Gildein
Approved revision: 0439acdff2bd73afcbf2c5761b29ed95e902957d
Merged at revision: d61340b5e2f6db760e387ffb1d6e256373ffab9a
Proposed branch: ~rgildein/juju-verify:bug/1920131
Merge into: ~canonical-solutions-engineering/juju-verify:master
Diff against target: 160 lines (+63/-28)
3 files modified
juju_verify/verifiers/ceph.py (+31/-20)
tests/unit/conftest.py (+1/-1)
tests/unit/verifiers/test_ceph.py (+31/-7)
Reviewer Review Type Date Requested Status
🤖 prod-jenkaas-bootstack (community) continuous-integration Approve
Alvaro Uria (community) Approve
Canonical Solutions Engineering Team Pending
Review via email: mp+399911@code.launchpad.net

Commit message

CephOsd.get_ceph_mon_units refactor

Change the output of the CephOsd.get_ceph_mon_units function to provide a map between the verified and ceph-mon units.

Closes-bug: LP#1920131

---
[LP#1920131]: https://bugs.launchpad.net/juju-verify/+bug/1920131

To post a comment you must log in.
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :

A CI job is currently in progress. A follow up comment will be added when it completes.

Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alvaro Uria (aluria) wrote :

Please find some comments inline.

review: Needs Fixing
Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :

A CI job is currently in progress. A follow up comment will be added when it completes.

Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alvaro Uria (aluria) wrote :

I have a few comments - but this solution is perfect.

review: Needs Fixing
Revision history for this message
Robert Gildein (rgildein) :
Revision history for this message
Alvaro Uria (aluria) wrote :

+1 Thank you!

review: Approve
Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :

A CI job is currently in progress. A follow up comment will be added when it completes.

Revision history for this message
🤖 prod-jenkaas-bootstack (prod-jenkaas-bootstack) wrote :
review: Approve (continuous-integration)
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision d61340b5e2f6db760e387ffb1d6e256373ffab9a

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/juju_verify/verifiers/ceph.py b/juju_verify/verifiers/ceph.py
2index 28bca0a..32556cc 100644
3--- a/juju_verify/verifiers/ceph.py
4+++ b/juju_verify/verifiers/ceph.py
5@@ -16,7 +16,7 @@
6 # this program. If not, see https://www.gnu.org/licenses/.
7 """ceph-osd verification."""
8 import logging
9-from typing import Set
10+from typing import Dict, Optional
11
12 from juju.unit import Unit
13
14@@ -62,34 +62,45 @@ class CephOsd(CephCommon):
15
16 NAME = 'ceph-osd'
17
18- def get_ceph_mon_units(self) -> Set[Unit]:
19- """Get Ceph-mon units related to verified units.
20-
21- 1. get all distinct ceph-osd applications from provides units
22- 2. get all relationships based on found apps or ceph-mon
23- 3. get the first unit from the application providing the relation
24+ def _get_ceph_mon_unit(self, app_name: str) -> Optional[Unit]:
25+ """Get first ceph-mon unit from relation."""
26+ try:
27+ for relation in self.model.applications[app_name].relations:
28+ if relation.matches(f"{app_name}:mon"):
29+ # selecting the first unit from the application provided by relation
30+ return relation.provides.application.units[0]
31+ except (IndexError, KeyError) as error:
32+ logger.debug("Error to get ceph-mon unit from relations: %s", error)
33+
34+ return None
35+
36+ def get_ceph_mon_units(self) -> Dict[str, Unit]:
37+ """Get first ceph-mon units related to verified units.
38+
39+ This function groups by distinct application names for verified units, and then
40+ finds the relation ("<application>:mon") between the application and ceph-mon.
41+ The first unit of ceph-mon will be obtained from this relation.
42+ :returns: Map between verified and ceph-mon units
43 """
44- # get all affected ceph-osd applications
45 applications = {unit.application for unit in self.units}
46 logger.debug("affected applications %s", map(str, applications))
47- applications.add("ceph-osd")
48
49- # get all relation between ceph-osd and ceph-mon
50- relations = {relation for relation in self.model.relations
51- if any(relation.matches(f"{application}:mon")
52- for application in applications)}
53- logger.debug("found relations %s", map(str, relations))
54+ ceph_mon_app_map = {}
55+ for app_name in applications:
56+ unit = self._get_ceph_mon_unit(app_name)
57+ if unit is not None:
58+ ceph_mon_app_map[app_name] = unit
59
60- # get first ceph-mon unit from relation
61- ceph_mon_units = {relation.provides.application.units[0]
62- for relation in relations}
63- logger.debug("found units %s", map(str, ceph_mon_units))
64+ logger.debug("found units %s", map(str, ceph_mon_app_map.values()))
65
66- return ceph_mon_units
67+ return ceph_mon_app_map
68
69 def verify_reboot(self) -> Result:
70 """Verify that it's safe to reboot selected ceph-osd units."""
71- return aggregate_results(self.check_cluster_health(*self.get_ceph_mon_units()))
72+ ceph_mon_app_map = self.get_ceph_mon_units()
73+ # get unique ceph-mon units
74+ unique_ceph_mon_units = set(ceph_mon_app_map.values())
75+ return aggregate_results(self.check_cluster_health(*unique_ceph_mon_units))
76
77 def verify_shutdown(self) -> Result:
78 """Verify that it's safe to shutdown selected ceph-osd units."""
79diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py
80index 42b4426..8a7b55a 100644
81--- a/tests/unit/conftest.py
82+++ b/tests/unit/conftest.py
83@@ -56,7 +56,7 @@ def model(session_mocker, all_units):
84 mock_model = Model()
85 session_mocker.patch.object(Model, 'connect_current')
86 session_mocker.patch.object(Model, 'connect_model')
87- session_mocker.patch.object(Model, 'relations')
88+ session_mocker.patch.object(Model, 'applications')
89 session_mocker.patch.object(Unit, 'data')
90 session_mocker.patch.object(Unit, 'machine')
91 session_mocker.patch.object(Unit, 'run_action', new_callable=MagicMock)
92diff --git a/tests/unit/verifiers/test_ceph.py b/tests/unit/verifiers/test_ceph.py
93index 728a4cb..f5d16ad 100644
94--- a/tests/unit/verifiers/test_ceph.py
95+++ b/tests/unit/verifiers/test_ceph.py
96@@ -74,25 +74,49 @@ def test_check_cluster_health_unknown_state(mock_run_action_on_units, model):
97 assert result == Result(False, "Ceph cluster is in an unknown state")
98
99
100-def test_get_ceph_mon_units(model):
101- """Test function to get ceph-mon units related to verified units."""
102- ceph_osd_units = [model.units["ceph-osd/0"], model.units["ceph-osd/1"]]
103+def test_get_ceph_mon_unit(model):
104+ """Test get ceph-mon unit related to application."""
105 ceph_mon_units = [model.units["ceph-mon/0"], model.units["ceph-mon/1"],
106 model.units["ceph-mon/2"]]
107 mock_relation = MagicMock()
108 mock_relation.matches = {"ceph-osd:mon": True}.get
109 mock_relation.provides.application.units = ceph_mon_units
110- model.relations = [mock_relation]
111+ mock_relations = MagicMock()
112+ mock_relations.relations = [mock_relation]
113+ model.applications = {"ceph-osd": mock_relations}
114+
115+ # return first ceph-mon unit in "ceph-osd:mon" relations
116+ unit = CephOsd([model.units["ceph-osd/0"]])._get_ceph_mon_unit("ceph-osd")
117+ assert unit == ceph_mon_units[0]
118+
119+ # return none for non-existent application name
120+ model.applications = {"ceph-osd-cluster": mock_relations}
121+ unit = CephOsd([model.units["ceph-osd/0"]])._get_ceph_mon_unit("ceph-osd")
122+ assert unit is None
123+
124+ # return none for application with no units
125+ mock_relation.provides.application.units = []
126+ model.applications = {"ceph-osd": mock_relations}
127+ unit = CephOsd([model.units["ceph-osd/0"]])._get_ceph_mon_unit("ceph-osd")
128+ assert unit is None
129+
130+
131+@mock.patch("juju_verify.verifiers.ceph.CephOsd._get_ceph_mon_unit")
132+def test_get_ceph_mon_units(mock_get_ceph_mon_unit, model):
133+ """Test function to get ceph-mon units related to verified units."""
134+ ceph_osd_units = [model.units["ceph-osd/0"], model.units["ceph-osd/1"]]
135+ mock_get_ceph_mon_unit.return_value = model.units["ceph-mon/0"]
136
137 units = CephOsd(ceph_osd_units).get_ceph_mon_units()
138- assert {ceph_mon_units[0]} == units
139+
140+ assert units == {"ceph-osd": model.units["ceph-mon/0"]}
141
142
143 @mock.patch("juju_verify.verifiers.ceph.CephOsd.get_ceph_mon_units")
144 @mock.patch("juju_verify.verifiers.ceph.CephCommon.check_cluster_health")
145 def test_verify_reboot(mock_check_cluster_health, mock_get_ceph_mon_units, model):
146 """Test reboot verification on CephOsd."""
147- mock_get_ceph_mon_units.return_value = [model.units["ceph-mon/0"]]
148+ mock_get_ceph_mon_units.return_value = {"ceph-osd": model.units["ceph-mon/0"]}
149 mock_check_cluster_health.return_value = Result(True, "Ceph cluster is healthy")
150
151 result = CephOsd([model.units["ceph-osd/0"]]).verify_reboot()
152@@ -104,7 +128,7 @@ def test_verify_reboot(mock_check_cluster_health, mock_get_ceph_mon_units, model
153 @mock.patch("juju_verify.verifiers.ceph.CephCommon.check_cluster_health")
154 def test_verify_shutdown(mock_check_cluster_health, mock_get_ceph_mon_units, model):
155 """Test shutdown verification on CephOsd."""
156- mock_get_ceph_mon_units.return_value = [model.units["ceph-mon/0"]]
157+ mock_get_ceph_mon_units.return_value = {"ceph-osd": model.units["ceph-mon/0"]}
158 mock_check_cluster_health.return_value = Result(True, "Ceph cluster is healthy")
159
160 result = CephOsd([model.units["ceph-osd/0"]]).verify_shutdown()

Subscribers

People subscribed via source and target branches