From 5a5f2add28e54f3c3a822ae76be149116d3e625e Mon Sep 17 00:00:00 2001 From: Adam Collard Date: Fri, 28 Feb 2020 09:23:29 +0000 Subject: [PATCH 1/4] Fix machine details for a machine with tags Viscera layer produces a Tags.Managed object for machines with tags, this can't be str()ified. --- maas/client/flesh/tables.py | 10 ++++++- maas/client/flesh/tests/test_machines.py | 38 ++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/maas/client/flesh/tables.py b/maas/client/flesh/tables.py index 53acf3f..454f479 100644 --- a/maas/client/flesh/tables.py +++ b/maas/client/flesh/tables.py @@ -155,6 +155,14 @@ def render(self, target, data): return super().render(target, data.name) +class NodeTagsColumn(Column): + def render(self, target, data): + if data: + return super().render(target, ", ".join(tag.name for tag in data)) + else: + return "" + + class NodesTable(Table): def __init__(self): super().__init__( @@ -215,7 +223,7 @@ def __init__(self, with_type=False): NodeResourcePoolColumn("pool", "Resource pool"), NodeZoneColumn("zone", "Zone"), NodeOwnerColumn("owner", "Owner"), - Column("tags", "Tags"), + NodeTagsColumn("tags", "Tags"), ] if with_type: columns.insert(1, NodeTypeColumn("node_type", "Type")) diff --git a/maas/client/flesh/tests/test_machines.py b/maas/client/flesh/tests/test_machines.py index 22f946d..d9b77e8 100644 --- a/maas/client/flesh/tests/test_machines.py +++ b/maas/client/flesh/tests/test_machines.py @@ -10,13 +10,14 @@ from ...viscera.testing import bind from ...viscera.machines import Machine, Machines from ...viscera.resource_pools import ResourcePool +from ...viscera.tags import Tag, Tags from ...viscera.users import User from ...viscera.zones import Zone def make_origin(): """Make origin for machines.""" - return bind(Machines, Machine, User, ResourcePool, Zone) + return bind(Machines, Machine, User, ResourcePool, Zone, Tag, Tags) class TestMachines(TestCaseWithProfile): @@ -55,7 +56,7 @@ def test_returns_table_with_machines(self): cmd = machines.cmd_machines(parser) subparser = machines.cmd_machines.register(parser) options = subparser.parse_args([]) - output = yaml.load( + output = yaml.safe_load( cmd.execute(origin, options, target=tabular.RenderTarget.yaml) ) self.assertEquals( @@ -101,3 +102,36 @@ def test_calls_handler_with_hostnames(self): options = subparser.parse_args(hostnames) cmd.execute(origin, options, target=tabular.RenderTarget.yaml) origin.Machines._handler.read.assert_called_once_with(hostname=hostnames) + + +class TestMachine(TestCaseWithProfile): + """Tests for `cmd_machine`.""" + + def test_machine_details_with_tags(self): + origin = make_origin() + parser = ArgumentParser() + machine_objs = [ + { + "hostname": make_name_without_spaces(), + "architecture": "amd64/generic", + "status": NodeStatus.READY.value, + "status_name": NodeStatus.READY.name, + "owner": None, + "power_state": PowerState.OFF.value, + "cpu_count": 2, + "memory": 1024, + "pool": {"id": 1, "name": "pool1", "description": "pool1"}, + "zone": {"id": 1, "name": "zone1", "description": "zone1"}, + "tag_names": ["tag1", "tag2"], + "distro_series": "", + "power_type": "Manual", + }, + ] + origin.Machines._handler.read.return_value = machine_objs + cmd = machines.cmd_machine(parser) + subparser = machines.cmd_machine.register(parser) + options = subparser.parse_args([machine_objs[0]["hostname"]]) + output = yaml.safe_load( + cmd.execute(origin, options, target=tabular.RenderTarget.yaml) + ) + self.assertEqual(output.get("tags"), "tag1, tag2") From 21dfd8350e98c15bcb08f7c6f0455b2a14cce1f2 Mon Sep 17 00:00:00 2001 From: Adam Collard Date: Fri, 28 Feb 2020 09:37:23 +0000 Subject: [PATCH 2/4] Black --- maas/client/bones/testing/server.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/maas/client/bones/testing/server.py b/maas/client/bones/testing/server.py index 9fd8d63..15648e8 100644 --- a/maas/client/bones/testing/server.py +++ b/maas/client/bones/testing/server.py @@ -22,9 +22,11 @@ def __init__(self, description): super(ApplicationBuilder, self).__init__() self._description = desc.Description(description) self._application = aiohttp.web.Application() - self._rootpath, self._basepath, self._version = ( - self._discover_version_and_paths() - ) + ( + self._rootpath, + self._basepath, + self._version, + ) = self._discover_version_and_paths() self._wire_up_description() self._actions = {} self._views = {} From 39c95bc0f2e10e0073aae5b5c9db4a8d6cdd2fa3 Mon Sep 17 00:00:00 2001 From: Adam Collard Date: Fri, 28 Feb 2020 10:12:41 +0000 Subject: [PATCH 3/4] =?UTF-8?q?YAML=20rendition=20of=20tags=20should=20be?= =?UTF-8?q?=20a=20list=20(Bj=C3=B6rn's=20feedback)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- maas/client/flesh/tables.py | 2 +- maas/client/flesh/tests/test_machines.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/maas/client/flesh/tables.py b/maas/client/flesh/tables.py index 454f479..7004759 100644 --- a/maas/client/flesh/tables.py +++ b/maas/client/flesh/tables.py @@ -158,7 +158,7 @@ def render(self, target, data): class NodeTagsColumn(Column): def render(self, target, data): if data: - return super().render(target, ", ".join(tag.name for tag in data)) + return super().render(target, [tag.name for tag in data]) else: return "" diff --git a/maas/client/flesh/tests/test_machines.py b/maas/client/flesh/tests/test_machines.py index d9b77e8..dcc0562 100644 --- a/maas/client/flesh/tests/test_machines.py +++ b/maas/client/flesh/tests/test_machines.py @@ -131,7 +131,7 @@ def test_machine_details_with_tags(self): cmd = machines.cmd_machine(parser) subparser = machines.cmd_machine.register(parser) options = subparser.parse_args([machine_objs[0]["hostname"]]) - output = yaml.safe_load( + yaml_output = yaml.safe_load( cmd.execute(origin, options, target=tabular.RenderTarget.yaml) ) - self.assertEqual(output.get("tags"), "tag1, tag2") + self.assertEqual(yaml_output.get("tags"), ["tag1", "tag2"]) From e250f297e9c43b90ab1e1e421c837f40489677d4 Mon Sep 17 00:00:00 2001 From: Adam Collard Date: Fri, 28 Feb 2020 10:27:44 +0000 Subject: [PATCH 4/4] =?UTF-8?q?Add=20test=20for=20plain=20output=20too=20(?= =?UTF-8?q?Bj=C3=B6rn's=20feedback)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- maas/client/flesh/tests/test_machines.py | 38 ++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/maas/client/flesh/tests/test_machines.py b/maas/client/flesh/tests/test_machines.py index dcc0562..6e3c941 100644 --- a/maas/client/flesh/tests/test_machines.py +++ b/maas/client/flesh/tests/test_machines.py @@ -1,5 +1,6 @@ """Tests for `maas.client.flesh.machines`.""" +from functools import partial from operator import itemgetter import yaml @@ -107,12 +108,14 @@ def test_calls_handler_with_hostnames(self): class TestMachine(TestCaseWithProfile): """Tests for `cmd_machine`.""" - def test_machine_details_with_tags(self): + def setUp(self): + super().setUp() origin = make_origin() parser = ArgumentParser() + self.hostname = make_name_without_spaces() machine_objs = [ { - "hostname": make_name_without_spaces(), + "hostname": self.hostname, "architecture": "amd64/generic", "status": NodeStatus.READY.value, "status_name": NodeStatus.READY.name, @@ -131,7 +134,32 @@ def test_machine_details_with_tags(self): cmd = machines.cmd_machine(parser) subparser = machines.cmd_machine.register(parser) options = subparser.parse_args([machine_objs[0]["hostname"]]) - yaml_output = yaml.safe_load( - cmd.execute(origin, options, target=tabular.RenderTarget.yaml) - ) + self.cmd = partial(cmd.execute, origin, options) + + def test_yaml_machine_details_with_tags(self): + yaml_output = yaml.safe_load(self.cmd(target=tabular.RenderTarget.yaml)) self.assertEqual(yaml_output.get("tags"), ["tag1", "tag2"]) + + def test_plain_machine_details_with_tags(self): + plain_output = self.cmd(target=tabular.RenderTarget.plain) + self.assertEqual( + plain_output, + f"""\ ++---------------+-------------+ +| Hostname | {self.hostname} | +| Status | READY | +| Image | (none) | +| Power | Off | +| Power Type | Manual | +| Arch | amd64 | +| #CPUs | 2 | +| RAM | 1.0 GB | +| Interfaces | 0 physical | +| IP addresses | | +| Resource pool | pool1 | +| Zone | zone1 | +| Owner | (none) | +| Tags | tag1 | +| | tag2 | ++---------------+-------------+""", + )