Skip to content

Commit 0a46fcb

Browse files
committed
mgr/cephadm: unit test for staggered upgrade param validation
Signed-off-by: Adam King <[email protected]>
1 parent 791e1d2 commit 0a46fcb

File tree

1 file changed

+159
-1
lines changed

1 file changed

+159
-1
lines changed

src/pybind/mgr/cephadm/tests/test_upgrade.py

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
from cephadm.upgrade import CephadmUpgrade
99
from orchestrator import OrchestratorError, DaemonDescription
1010
from .fixtures import _run_cephadm, wait, with_host, with_service, \
11-
receive_agent_metadata
11+
receive_agent_metadata, async_side_effect
12+
13+
from typing import List, Tuple, Optional
1214

1315

1416
@mock.patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}'))
@@ -249,3 +251,159 @@ def test_upgrade_ls(current_version, use_tags, show_all_versions, tags, result,
249251
assert out['tags'] == result
250252
else:
251253
assert out['versions'] == result
254+
255+
256+
@pytest.mark.parametrize(
257+
"upgraded, not_upgraded, daemon_types, hosts, services, should_block",
258+
# [ ([(type, host, id), ... ], [...], [daemon types], [hosts], [services], True/False), ... ]
259+
[
260+
( # valid, upgrade mgr daemons
261+
[],
262+
[('mgr', 'a', 'a.x'), ('mon', 'a', 'a')],
263+
['mgr'],
264+
None,
265+
None,
266+
False
267+
),
268+
( # invalid, can't upgrade mons until mgr is upgraded
269+
[],
270+
[('mgr', 'a', 'a.x'), ('mon', 'a', 'a')],
271+
['mon'],
272+
None,
273+
None,
274+
True
275+
),
276+
( # invalid, can't upgrade mon service until all mgr daemons are upgraded
277+
[],
278+
[('mgr', 'a', 'a.x'), ('mon', 'a', 'a')],
279+
None,
280+
None,
281+
['mon'],
282+
True
283+
),
284+
( # valid, upgrade mgr service
285+
[],
286+
[('mgr', 'a', 'a.x'), ('mon', 'a', 'a')],
287+
None,
288+
None,
289+
['mgr'],
290+
False
291+
),
292+
( # valid, mgr is already upgraded so can upgrade mons
293+
[('mgr', 'a', 'a.x')],
294+
[('mon', 'a', 'a')],
295+
['mon'],
296+
None,
297+
None,
298+
False
299+
),
300+
( # invalid, can't upgrade all daemons on b b/c un-upgraded mgr on a
301+
[],
302+
[('mgr', 'b', 'b.y'), ('mon', 'a', 'a')],
303+
None,
304+
['a'],
305+
None,
306+
True
307+
),
308+
( # valid, only daemon on b is a mgr
309+
[],
310+
[('mgr', 'a', 'a.x'), ('mgr', 'b', 'b.y'), ('mon', 'a', 'a')],
311+
None,
312+
['b'],
313+
None,
314+
False
315+
),
316+
( # invalid, can't upgrade mon on a while mgr on b is un-upgraded
317+
[],
318+
[('mgr', 'a', 'a.x'), ('mgr', 'b', 'b.y'), ('mon', 'a', 'a')],
319+
None,
320+
['a'],
321+
None,
322+
True
323+
),
324+
( # valid, only upgrading the mgr on a
325+
[],
326+
[('mgr', 'a', 'a.x'), ('mgr', 'b', 'b.y'), ('mon', 'a', 'a')],
327+
['mgr'],
328+
['a'],
329+
None,
330+
False
331+
),
332+
( # valid, mgr daemon not on b are upgraded
333+
[('mgr', 'a', 'a.x')],
334+
[('mgr', 'b', 'b.y'), ('mon', 'a', 'a')],
335+
None,
336+
['b'],
337+
None,
338+
False
339+
),
340+
( # valid, all the necessary hosts are covered, mgr on c is already upgraded
341+
[('mgr', 'c', 'c.z')],
342+
[('mgr', 'a', 'a.x'), ('mgr', 'b', 'b.y'), ('mon', 'a', 'a'), ('osd', 'c', '0')],
343+
None,
344+
['a', 'b'],
345+
None,
346+
False
347+
),
348+
( # invalid, can't upgrade mon on a while mgr on b is un-upgraded
349+
[],
350+
[('mgr', 'a', 'a.x'), ('mgr', 'b', 'b.y'), ('mon', 'a', 'a')],
351+
['mgr', 'mon'],
352+
['a'],
353+
None,
354+
True
355+
),
356+
( # valid, only mon not on "b" is upgraded already. Case hit while making teuthology test
357+
[('mon', 'a', 'a')],
358+
[('mon', 'b', 'x'), ('mon', 'b', 'y'), ('osd', 'a', '1'), ('osd', 'b', '2')],
359+
['mon', 'osd'],
360+
['b'],
361+
None,
362+
False
363+
),
364+
]
365+
)
366+
@mock.patch("cephadm.module.HostCache.get_daemons")
367+
@mock.patch("cephadm.serve.CephadmServe._get_container_image_info")
368+
@mock.patch('cephadm.module.SpecStore.__getitem__')
369+
def test_staggered_upgrade_validation(
370+
get_spec,
371+
get_image_info,
372+
get_daemons,
373+
upgraded: List[Tuple[str, str, str]],
374+
not_upgraded: List[Tuple[str, str, str, str]],
375+
daemon_types: Optional[str],
376+
hosts: Optional[str],
377+
services: Optional[str],
378+
should_block: bool,
379+
cephadm_module: CephadmOrchestrator,
380+
):
381+
def to_dds(ts: List[Tuple[str, str]], upgraded: bool) -> List[DaemonDescription]:
382+
dds = []
383+
digest = 'new_image@repo_digest' if upgraded else 'old_image@repo_digest'
384+
for t in ts:
385+
dds.append(DaemonDescription(daemon_type=t[0],
386+
hostname=t[1],
387+
daemon_id=t[2],
388+
container_image_digests=[digest],
389+
deployed_by=[digest],))
390+
return dds
391+
get_daemons.return_value = to_dds(upgraded, True) + to_dds(not_upgraded, False)
392+
get_image_info.side_effect = async_side_effect(
393+
('new_id', 'ceph version 99.99.99 (hash)', ['new_image@repo_digest']))
394+
395+
class FakeSpecDesc():
396+
def __init__(self, spec):
397+
self.spec = spec
398+
399+
def _get_spec(s):
400+
return FakeSpecDesc(ServiceSpec(s))
401+
402+
get_spec.side_effect = _get_spec
403+
if should_block:
404+
with pytest.raises(OrchestratorError):
405+
cephadm_module.upgrade._validate_upgrade_filters(
406+
'new_image_name', daemon_types, hosts, services)
407+
else:
408+
cephadm_module.upgrade._validate_upgrade_filters(
409+
'new_image_name', daemon_types, hosts, services)

0 commit comments

Comments
 (0)