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

Proposed by Anton Troyanov
Status: Merged
Approved by: Anton Troyanov
Approved revision: 97283388f46f3cefb9b517aac7c13ce1f787c7aa
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~troyanov/maas:fix-2003940
Merge into: maas:master
Diff against target: 77 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
Alberto Donato (community) Approve
Review via email: mp+442021@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 lp:~troyanov/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/2414/console
COMMIT: 7ba51c382953effa7049c41e70f69bf8e9900aed

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

jenkins: !test

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

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

STATUS: SUCCESS
COMMIT: d5d20f84973dfff5963d8a57dae36ef3c9b1423e

review: Approve
Revision history for this message
Alberto Donato (ack) wrote :

+1

you can probably drop tags and the filtering in the list() call as they shouldn't be needed

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

It can be reproduced only if machine has tags and if filtering is applied. If I will remove filtering and tags -- then the test will work even without fix.

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

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

STATUS: SUCCESS
COMMIT: 97283388f46f3cefb9b517aac7c13ce1f787c7aa

review: Approve

Preview Diff

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

Subscribers

People subscribed via source and target branches