Merge ~troyanov/maas:fix-2003940-3.3 into maas:3.3

Proposed by Anton Troyanov
Status: Merged
Approved by: Anton Troyanov
Approved revision: 478dc737be6a05c10c31e55fff5370b82d93cb2e
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~troyanov/maas:fix-2003940-3.3
Merge into: maas:3.3
Diff against target: 73 lines (+33/-3)
2 files modified
src/maasserver/websockets/handlers/machine.py (+15/-3)
src/maasserver/websockets/handlers/tests/test_machine.py (+18/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Anton Troyanov Approve
Review via email: mp+442024@code.launchpad.net

Commit message

fix(ws): incorrect storage amount

Combining multiple aggregations with annotate() will yield the wrong results
because joins are used instead of subqueries.

See related Django bug: https://code.djangoproject.com/ticket/10060

Resolves LP:2003940

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b fix-2003940-3.3 lp:~troyanov/maas/+git/maas into -b 3.3 lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 68957d1035d803a2b9dbeb3f4000d4a5375f3469

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b fix-2003940-3.3 lp:~troyanov/maas/+git/maas into -b 3.3 lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/2418/console
COMMIT: 478dc737be6a05c10c31e55fff5370b82d93cb2e

review: Needs Fixing
Revision history for this message
Anton Troyanov (troyanov) wrote :

jenkins: !test

Revision history for this message
Anton Troyanov (troyanov) wrote :

Self approving, since this backport is almost identical (but not a cherry-pick tho)
https://git.launchpad.net/maas/commit/?id=66663a3f3a99523aab3720697f9f0859def16b61

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b fix-2003940-3.3 lp:~troyanov/maas/+git/maas into -b 3.3 lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 478dc737be6a05c10c31e55fff5370b82d93cb2e

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/websockets/handlers/machine.py b/src/maasserver/websockets/handlers/machine.py
2index d5ae491..9365a64 100644
3--- a/src/maasserver/websockets/handlers/machine.py
4+++ b/src/maasserver/websockets/handlers/machine.py
5@@ -15,6 +15,7 @@ from django.db.models import (
6 Count,
7 Exists,
8 F,
9+ IntegerField,
10 OuterRef,
11 Subquery,
12 Sum,
13@@ -127,6 +128,15 @@ class MachineHandler(NodeHandler):
14 "partitiontable_set__partitions"
15 )
16 )
17+ node_storage_query_set = (
18+ Machine.objects.select_related("current_config")
19+ .annotate(
20+ storage=Sum(
21+ "current_config__blockdevice__physicalblockdevice__size"
22+ )
23+ )
24+ .filter(pk=OuterRef("pk"))
25+ )
26 list_queryset = (
27 Machine.objects.all()
28 .select_related("owner", "zone", "domain", "bmc", "current_config")
29@@ -157,10 +167,12 @@ class MachineHandler(NodeHandler):
30 .prefetch_related("ownerdata_set")
31 .alias(
32 physical_disk_count=Count(
33- "current_config__blockdevice__physicalblockdevice"
34+ "current_config__blockdevice__physicalblockdevice",
35+ distinct=True,
36 ),
37- storage=Sum(
38- "current_config__blockdevice__physicalblockdevice__size"
39+ storage=Subquery(
40+ node_storage_query_set.values("storage"),
41+ output_field=IntegerField(),
42 ),
43 pxe_mac=F("boot_interface__mac_address"),
44 fabric_name=F("boot_interface__vlan__fabric__name"),
45diff --git a/src/maasserver/websockets/handlers/tests/test_machine.py b/src/maasserver/websockets/handlers/tests/test_machine.py
46index 08afc62..f7a5b79 100644
47--- a/src/maasserver/websockets/handlers/tests/test_machine.py
48+++ b/src/maasserver/websockets/handlers/tests/test_machine.py
49@@ -6041,6 +6041,24 @@ class TestMachineHandlerNewSchema(MAASServerTestCase):
50 self.assertEqual(2, result["count"])
51 self.assertEqual(2, result["groups"][0]["count"])
52
53+ def test_filter_storage_counters(self):
54+ user = factory.make_User()
55+ node = factory.make_Machine(owner=user)
56+ [node.tags.add(factory.make_Tag()) for _ in range(2)]
57+
58+ handler = MachineHandler(user, {}, None)
59+ result = handler.list({"filter": {"free_text": node.hostname}})
60+
61+ self.assertEqual(1, result["count"])
62+ self.assertEqual(
63+ node.physicalblockdevice_set.count(),
64+ result["groups"][0]["items"][0]["physical_disk_count"],
65+ )
66+ self.assertEqual(
67+ round(node.physicalblockdevice_set.first().size / (1000**3), 1),
68+ result["groups"][0]["items"][0]["storage"],
69+ )
70+
71 def test_sort_alias(self):
72 user = factory.make_User()
73 fabrics = [factory.make_Fabric() for _ in range(2)]

Subscribers

People subscribed via source and target branches