Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions checkbox-ng/checkbox_ng/launcher/subcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1237,13 +1237,16 @@
help=_(
(
"output format, as passed to print function. "
"Use '?' to list possible values"
"Use '?' to list possible values. "
"Use 'json' to print all objects as a json"
)
),
)

def invoked(self, ctx):
if ctx.args.GROUP == "all-jobs":
# print_objs supports json-printing all-jobs, so we can forward the
# query if json is requested
if ctx.args.GROUP == "all-jobs" and ctx.args.format != "json":
if ctx.args.attrs:
print_objs("job", ctx.sa, True)

Expand Down Expand Up @@ -1287,9 +1290,14 @@
end="",
)
return
elif ctx.args.format:
elif ctx.args.format and ctx.args.format != "json":
print(_("--format applies only to 'all-jobs' group. Ignoring..."))
print_objs(ctx.args.GROUP, ctx.sa, ctx.args.attrs)
print_objs(

Check warning on line 1295 in checkbox-ng/checkbox_ng/launcher/subcommands.py

View check run for this annotation

Codecov / codecov/patch

checkbox-ng/checkbox_ng/launcher/subcommands.py#L1295

Added line #L1295 was not covered by tests
ctx.args.GROUP,
ctx.sa,
ctx.args.attrs,
json_repr=ctx.args.format == "json",
)


class Expand:
Expand Down Expand Up @@ -1545,7 +1553,8 @@
return sorted(get_jobs(root), key=operator.itemgetter("full_id"))


def print_objs(group, sa, show_attrs=False, filter_fun=None):
def print_objs(group, sa, show_attrs=False, filter_fun=None, json_repr=False):
# note: group is unit type (including internal units like File)
providers = sa.get_selected_providers()
obj = Explorer(providers).get_object_tree()

Expand All @@ -1567,7 +1576,27 @@
for child in obj.children:
_show(child, indent)

_show(obj, "")
if not json_repr:
return _show(obj, "")

assert not filter_fun, "The json exporter doesn't support filtering"

# all-jobs is a meta-group that include all jobs + all templates
# note: if group is none, everything should be printed
groups = {group} if group != "all-jobs" else {"job", "template"}

to_print = []
childrens = obj.children
while childrens:
obj = childrens.pop()
childrens += obj.children or []
if group and obj.group not in groups:
continue
obj_repr = {"unit": obj.group, "name": obj.name}
if show_attrs:
obj_repr.update(obj.attrs)
to_print.append(obj_repr)
json.dump(to_print, sys.stdout)


class Show:
Expand Down
92 changes: 92 additions & 0 deletions checkbox-ng/checkbox_ng/launcher/test_subcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,108 @@

from checkbox_ng.launcher.subcommands import (
Expand,
List,
Launcher,
ListBootstrapped,
IncompatibleJobError,
ResumeInstead,
IJobResult,
request_comment,
generate_resume_candidate_description,
print_objs,
)


class TestSharedFunctions(TestCase):
def make_unit_mock(self, **kwargs):
to_r = MagicMock(**kwargs)
try:
# name is a kwarg of mock, so we need to set it manually
to_r.name = kwargs["name"]
except KeyError:
pass
return to_r

def get_test_tree(self):
# made this uniform as the function should be able to handle any valid
# unit tree
return self.make_unit_mock(
group="service",
children=[
self.make_unit_mock(
group="exporter",
children=None,
name="exporter name",
attrs={"id": "exporter id"},
),
self.make_unit_mock(
group="job",
name="job name",
children=None,
attrs={"id": "job id"},
),
self.make_unit_mock(
group="template",
name="template name",
children=None,
attrs={"id": "template id"},
),
],
)

@patch("sys.stdout", new_callable=StringIO)
@patch("checkbox_ng.launcher.subcommands.Explorer")
def test_print_objs_nojson(self, mock_explorer, stdout_mock):
mock_explorer().get_object_tree.return_value = self.get_test_tree()

print_objs(group="job", sa=MagicMock(), show_attrs=True)
printed = stdout_mock.getvalue()
self.assertIn("job name", printed)
self.assertIn("job id", printed)
self.assertNotIn("exporter id", printed)
self.assertNotIn("exporter id", printed)

@patch("sys.stdout", new_callable=StringIO)
@patch("checkbox_ng.launcher.subcommands.Explorer")
def test_print_objs_json(self, mock_explorer, stdout_mock):
mock_explorer().get_object_tree.return_value = self.get_test_tree()
print_objs(
group="job", sa=MagicMock(), show_attrs=True, json_repr=True
)
printed = stdout_mock.getvalue()
self.assertIn("job name", printed)
self.assertIn("job id", printed)
self.assertNotIn("exporter id", printed)
self.assertNotIn("exporter id", printed)

@patch("sys.stdout", new_callable=StringIO)
@patch("checkbox_ng.launcher.subcommands.Explorer")
def test_print_objs_json_print_all(self, mock_explorer, stdout_mock):
mock_explorer().get_object_tree.return_value = self.get_test_tree()
print_objs(
group=None, sa=MagicMock(), show_attrs=False, json_repr=True
)
printed = stdout_mock.getvalue()
self.assertIn("job name", printed)
self.assertNotIn(
"job id", printed
) # job id is an attr, so shouldnt be here
self.assertIn("exporter name", printed)
self.assertNotIn("exporter id", printed) # same for exporter id

@patch("sys.stdout", new_callable=StringIO)
@patch("checkbox_ng.launcher.subcommands.Explorer")
def test_print_objs_json_print_all_jobs(self, mock_explorer, stdout_mock):
mock_explorer().get_object_tree.return_value = self.get_test_tree()
print_objs(
group="all-jobs", sa=MagicMock(), show_attrs=False, json_repr=True
)
printed = stdout_mock.getvalue()
self.assertIn("job name", printed)
self.assertIn("template name", printed)
self.assertNotIn("exporter name", printed)


class TestLauncher(TestCase):
@patch(
"checkbox_ng.launcher.subcommands.open",
Expand Down
Loading