Merge ~bjornt/maas:power-driver-metrics-3.2 into maas:3.2

Proposed by Björn Tillenius
Status: Merged
Approved by: Björn Tillenius
Approved revision: f3f7d9906acff90e81b3ae9ece6a0e2f171eb1a4
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~bjornt/maas:power-driver-metrics-3.2
Merge into: maas:3.2
Diff against target: 542 lines (+215/-38)
14 files modified
src/maasserver/forms/__init__.py (+1/-1)
src/maasserver/forms/tests/test_controller.py (+1/-0)
src/maasserver/forms/tests/test_machine.py (+1/-1)
src/maasserver/migrations/maasserver/0276_bmc_autodetect_metric.py (+27/-0)
src/maasserver/models/bmc.py (+8/-0)
src/maasserver/models/node.py (+20/-14)
src/maasserver/models/tests/test_node.py (+73/-7)
src/maasserver/rpc/tests/test_nodes.py (+6/-7)
src/maasserver/rpc/tests/test_regionservice_calls.py (+2/-2)
src/maasserver/stats.py (+27/-0)
src/maasserver/testing/factory.py (+2/-4)
src/maasserver/tests/test_stats.py (+42/-0)
src/metadataserver/api.py (+3/-1)
src/metadataserver/tests/test_api.py (+2/-1)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Björn Tillenius Approve
Review via email: mp+423940@code.launchpad.net

Commit message

Remove unused code from Node.set_power_config().

There was code that checked for self.bmc, even though it couldn't really
be None, except for in unit tests.

A lot of tests passed in "" as the power type, expecting to get a node
without a BMC configured. But in reality, that created a BMC with power
type "", which is invalid.

(cherry picked from commit eb055f00437974e4a36ea2969002b2830f81af9f)

Add stats for power drivers.

Also added an attribute to BMC, so that we can track whether the BMC was
auto-detected in commissioning, or whether the user created it manually.

(cherry picked from commit ab360b09b24e750d106e07778574e72a8dfc99fc)

To post a comment you must log in.
Revision history for this message
Björn Tillenius (bjornt) wrote :

Self-approve backport.

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

UNIT TESTS
-b power-driver-metrics-3.2 lp:~bjornt/maas/+git/maas into -b 3.2 lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas/job/branch-tester/12818/console
COMMIT: 652a123f80edcdf5bd815eefc0781e3ab4fad8ff

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

UNIT TESTS
-b power-driver-metrics-3.2 lp:~bjornt/maas/+git/maas into -b 3.2 lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: f3f7d9906acff90e81b3ae9ece6a0e2f171eb1a4

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/forms/__init__.py b/src/maasserver/forms/__init__.py
2index fa8983d..f77e344 100644
3--- a/src/maasserver/forms/__init__.py
4+++ b/src/maasserver/forms/__init__.py
5@@ -385,7 +385,7 @@ class WithPowerTypeMixin:
6 power_parameters["certificate"] = cert.certificate_pem()
7 power_parameters["key"] = cert.private_key_pem()
8
9- if type_changed or initial_parameters:
10+ if type_changed or initial_parameters and power_type:
11 machine.set_power_config(power_type, power_parameters)
12
13 def clean(self):
14diff --git a/src/maasserver/forms/tests/test_controller.py b/src/maasserver/forms/tests/test_controller.py
15index 904501f..61385f7 100644
16--- a/src/maasserver/forms/tests/test_controller.py
17+++ b/src/maasserver/forms/tests/test_controller.py
18@@ -55,6 +55,7 @@ class TestControllerForm(MAASServerTestCase):
19 power_parameters_field = factory.make_string()
20 form = ControllerForm(
21 data={
22+ "power_type": "ipmi",
23 "power_parameters_field": power_parameters_field,
24 "power_parameters_skip_check": "true",
25 },
26diff --git a/src/maasserver/forms/tests/test_machine.py b/src/maasserver/forms/tests/test_machine.py
27index cb7d6f2..089587b 100644
28--- a/src/maasserver/forms/tests/test_machine.py
29+++ b/src/maasserver/forms/tests/test_machine.py
30@@ -572,7 +572,7 @@ class TestAdminMachineForm(MAASServerTestCase):
31 self.assertEqual(power_type, node.power_type)
32
33 def test_AdminMachineForm_needs_interface_for_power_types(self):
34- node = factory.make_Node(power_type="")
35+ node = factory.make_Node(power_type=None)
36 arch = make_usable_architecture(self)
37 form = AdminMachineForm(
38 data={
39diff --git a/src/maasserver/migrations/maasserver/0276_bmc_autodetect_metric.py b/src/maasserver/migrations/maasserver/0276_bmc_autodetect_metric.py
40new file mode 100644
41index 0000000..d9ac5a0
42--- /dev/null
43+++ b/src/maasserver/migrations/maasserver/0276_bmc_autodetect_metric.py
44@@ -0,0 +1,27 @@
45+# Generated by Django 2.2.12 on 2022-05-24 13:08
46+
47+from django.db import migrations, models
48+
49+
50+class Migration(migrations.Migration):
51+
52+ dependencies = [
53+ ("maasserver", "0275_interface_children"),
54+ ]
55+
56+ operations = [
57+ # All existing rows should have NULL values
58+ migrations.AddField(
59+ model_name="bmc",
60+ name="created_by_commissioning",
61+ field=models.BooleanField(default=None, editable=False, null=True),
62+ ),
63+ # All new rows should default to False.
64+ migrations.AlterField(
65+ model_name="bmc",
66+ name="created_by_commissioning",
67+ field=models.BooleanField(
68+ default=False, editable=False, null=True
69+ ),
70+ ),
71+ ]
72diff --git a/src/maasserver/models/bmc.py b/src/maasserver/models/bmc.py
73index 5fda784..7baf693 100644
74--- a/src/maasserver/models/bmc.py
75+++ b/src/maasserver/models/bmc.py
76@@ -289,6 +289,14 @@ class BMC(CleanSave, TimestampedModel):
77 default=None,
78 editable=False,
79 )
80+ created_by_commissioning = BooleanField(
81+ # We allow None, since before 3.2 we didn't track this, and we
82+ # don't know whether the BMC was created manually or
83+ # automatically by commissioning.
84+ null=True,
85+ default=False,
86+ editable=False,
87+ )
88
89 def __str__(self):
90 return "{} ({})".format(
91diff --git a/src/maasserver/models/node.py b/src/maasserver/models/node.py
92index 2a01c4b..2543ae2 100644
93--- a/src/maasserver/models/node.py
94+++ b/src/maasserver/models/node.py
95@@ -1374,7 +1374,12 @@ class Node(CleanSave, TimestampedModel):
96 def is_commissioning(self):
97 return self.status not in (NODE_STATUS.DEPLOYED, NODE_STATUS.DEPLOYING)
98
99- def set_power_config(self, power_type, power_params):
100+ def set_power_config(
101+ self,
102+ power_type,
103+ power_params,
104+ from_commissioning=False,
105+ ):
106 """Update the power configuration for a node.
107
108 If power_type is not changed, this will update power parameters for the
109@@ -1383,6 +1388,7 @@ class Node(CleanSave, TimestampedModel):
110 """
111 from maasserver.models.bmc import BMC
112
113+ created_by_commissioning = from_commissioning
114 old_bmc = self.bmc
115 chassis, bmc_params, node_params = BMC.scope_power_parameters(
116 power_type, power_params
117@@ -1396,27 +1402,27 @@ class Node(CleanSave, TimestampedModel):
118 power_type=power_type, power_parameters=bmc_params
119 ).first()
120 if existing_bmc and existing_bmc.id != self.bmc_id:
121- if self.bmc:
122- # Point all nodes using old BMC at the new one.
123- for node in self.bmc.node_set.exclude(id=self.id):
124- node.bmc = existing_bmc
125- node.save()
126+ # Point all nodes using old BMC at the new one.
127+ for node in self.bmc.node_set.exclude(id=self.id):
128+ node.bmc = existing_bmc
129+ node.save()
130 self.bmc = existing_bmc
131 elif not existing_bmc:
132- if self.bmc:
133- self.bmc.power_parameters = bmc_params
134- else:
135- self.bmc = BMC.objects.create(
136- power_type=power_type, power_parameters=bmc_params
137- )
138+ self.bmc.power_parameters = bmc_params
139 self.bmc.save()
140 elif chassis:
141 self.bmc, _ = BMC.objects.get_or_create(
142- power_type=power_type, power_parameters=bmc_params
143+ power_type=power_type,
144+ power_parameters=bmc_params,
145+ defaults={
146+ "created_by_commissioning": created_by_commissioning
147+ },
148 )
149 else:
150 self.bmc = BMC.objects.create(
151- power_type=power_type, power_parameters=bmc_params
152+ power_type=power_type,
153+ power_parameters=bmc_params,
154+ created_by_commissioning=created_by_commissioning,
155 )
156 self.bmc.save()
157
158diff --git a/src/maasserver/models/tests/test_node.py b/src/maasserver/models/tests/test_node.py
159index 7a468c0..987e03f 100644
160--- a/src/maasserver/models/tests/test_node.py
161+++ b/src/maasserver/models/tests/test_node.py
162@@ -1641,7 +1641,7 @@ class TestNode(MAASServerTestCase):
163 self.assertEqual("new-hostname", node.hostname)
164
165 def test_get_effective_power_type_raises_if_not_set(self):
166- node = factory.make_Node(power_type="")
167+ node = factory.make_Node(power_type=None)
168 self.assertRaises(UnknownPowerType, node.get_effective_power_type)
169
170 def test_get_effective_power_type_reads_node_field(self):
171@@ -1706,7 +1706,7 @@ class TestNode(MAASServerTestCase):
172 self.assertEqual("pxe", params["boot_mode"])
173
174 def test_get_effective_power_info_is_False_for_unset_power_type(self):
175- node = factory.make_Node(power_type="")
176+ node = factory.make_Node(power_type=None)
177 self.assertEqual(
178 (False, False, False, False, None, None),
179 node.get_effective_power_info(),
180@@ -3338,7 +3338,9 @@ class TestNode(MAASServerTestCase):
181
182 def test_start_commissioning_errors_for_unconfigured_power_type(self):
183 node = factory.make_Node(
184- interface=True, status=NODE_STATUS.NEW, power_type=""
185+ interface=True,
186+ status=NODE_STATUS.NEW,
187+ power_type=None,
188 )
189 admin = factory.make_admin()
190 self.assertRaises(UnknownPowerType, node.start_commissioning, admin)
191@@ -4026,7 +4028,9 @@ class TestNode(MAASServerTestCase):
192
193 def test_start_testing_errors_for_unconfigured_power_type(self):
194 node = factory.make_Node(
195- interface=True, status=NODE_STATUS.DEPLOYED, power_type=""
196+ interface=True,
197+ status=NODE_STATUS.DEPLOYED,
198+ power_type=None,
199 )
200 admin = factory.make_admin()
201 self.assertRaises(UnknownPowerType, node.start_testing, admin)
202@@ -5673,7 +5677,7 @@ class TestNode(MAASServerTestCase):
203 status=random.choice(
204 [NODE_STATUS.READY, NODE_STATUS.BROKEN, NODE_STATUS.DEPLOYED]
205 ),
206- power_type="",
207+ power_type=None,
208 )
209 self.assertRaises(
210 UnknownPowerType, node.start_rescue_mode, factory.make_admin()
211@@ -6179,14 +6183,76 @@ class TestNodePowerParameters(MAASServerTestCase):
212
213 def test_power_parameters_are_stored(self):
214 parameters = dict(user="tarquin", address="10.1.2.3")
215- node = factory.make_Node(power_type="", power_parameters=parameters)
216+ node = factory.make_Node(
217+ power_type="ipmi", power_parameters=parameters
218+ )
219 node.save()
220 node = reload_object(node)
221 self.assertEqual(parameters, node.power_parameters)
222
223 def test_power_parameters_default(self):
224- node = factory.make_Node(power_type="")
225+ node = factory.make_Node(power_type=None)
226 self.assertEqual({}, node.power_parameters)
227+ self.assertIsNone(node.bmc)
228+
229+ def test_power_parameters_from_commissioning_not_new(self):
230+ node = factory.make_Node(power_type="virsh")
231+ node.set_power_config("ipmi", {}, from_commissioning=True)
232+ self.assertTrue(node.bmc.created_by_commissioning)
233+
234+ def test_power_parameters_not_from_commissioning_not_new(self):
235+ node = factory.make_Node(power_type="virsh")
236+ node.set_power_config("ipmi", {}, from_commissioning=False)
237+ self.assertIsNotNone(node.bmc.created_by_commissioning)
238+ self.assertFalse(node.bmc.created_by_commissioning)
239+
240+ def test_power_parameters_from_commissioning_not_new_chassis(self):
241+ node = factory.make_Node(power_type="virsh")
242+ node.set_power_config("redfish", {}, from_commissioning=True)
243+ self.assertTrue(node.bmc.created_by_commissioning)
244+
245+ def test_power_parameters_not_from_commissioning_not_new_chassis(self):
246+ node = factory.make_Node(power_type="virsh")
247+ node.set_power_config("redfish", {}, from_commissioning=False)
248+ self.assertIsNotNone(node.bmc.created_by_commissioning)
249+ self.assertFalse(node.bmc.created_by_commissioning)
250+
251+ def test_power_parameters_from_commissioning_new(self):
252+ node = factory.make_Node(power_type=None)
253+ node.set_power_config("ipmi", {}, from_commissioning=True)
254+ self.assertTrue(node.bmc.created_by_commissioning)
255+
256+ def test_power_parameters_not_from_commissioning_new(self):
257+ node = factory.make_Node(power_type=None)
258+ node.set_power_config("ipmi", {}, from_commissioning=False)
259+ self.assertIsNotNone(node.bmc.created_by_commissioning)
260+ self.assertFalse(node.bmc.created_by_commissioning)
261+
262+ def test_power_parameters_from_commissioning_new_chassis(self):
263+ node = factory.make_Node(power_type=None)
264+ node.set_power_config("redfish", {}, from_commissioning=True)
265+ self.assertTrue(node.bmc.created_by_commissioning)
266+
267+ def test_power_parameters_not_from_commissioning_new_chassis(self):
268+ node = factory.make_Node(power_type=None)
269+ node.set_power_config("redfish", {}, from_commissioning=False)
270+ self.assertIsNotNone(node.bmc.created_by_commissioning)
271+ self.assertFalse(node.bmc.created_by_commissioning)
272+
273+ def test_power_parameters_from_commissioning_same(self):
274+ node = factory.make_Node(
275+ power_type="ipmi",
276+ power_parameters={"power_address": factory.make_ipv4_address()},
277+ )
278+ old_value = random.choice([None, True, False])
279+ node.bmc.created_by_commissioning = old_value
280+ node.bmc.save()
281+ node.set_power_config(
282+ "ipmi",
283+ {"power_address": factory.make_ipv6_address()},
284+ from_commissioning=True,
285+ )
286+ self.assertEqual(node.bmc.created_by_commissioning, old_value)
287
288 def test_power_type_and_bmc_power_parameters_stored_in_bmc(self):
289 node = factory.make_Node(power_type="hmc")
290diff --git a/src/maasserver/rpc/tests/test_nodes.py b/src/maasserver/rpc/tests/test_nodes.py
291index 0d4bc07..1132db8 100644
292--- a/src/maasserver/rpc/tests/test_nodes.py
293+++ b/src/maasserver/rpc/tests/test_nodes.py
294@@ -353,14 +353,12 @@ class TestListClusterNodesPowerParameters(MAASServerTestCase):
295 # Those tests have been left there for now because they also check
296 # that the return values are being formatted correctly for RPC.
297
298- def make_Node(self, power_type=None, power_state_queried=None, **kwargs):
299+ def make_Node(self, power_state_queried=None, **kwargs):
300 if power_state_queried is None:
301 # Ensure that this node was last queried at least 5 minutes ago.
302 power_state_queried = now() - timedelta(minutes=randint(6, 16))
303 node = factory.make_Node(
304- power_type=power_type,
305- power_state_queried=power_state_queried,
306- **kwargs
307+ power_state_queried=power_state_queried, **kwargs
308 )
309 return node
310
311@@ -452,10 +450,11 @@ class TestListClusterNodesPowerParameters(MAASServerTestCase):
312 rack = factory.make_RackController()
313 node_queryable = self.make_Node(bmc_connected_to=rack)
314
315- factory.make_Device(power_type="")
316- factory.make_Device(power_type="")
317+ factory.make_Device(power_type=None)
318+ factory.make_Device(power_type=None)
319 factory.make_Device(
320- power_type="", power_state_queried=(now() - timedelta(minutes=10))
321+ power_type=None,
322+ power_state_queried=(now() - timedelta(minutes=10)),
323 )
324
325 power_parameters = list_cluster_nodes_power_parameters(rack.system_id)
326diff --git a/src/maasserver/rpc/tests/test_regionservice_calls.py b/src/maasserver/rpc/tests/test_regionservice_calls.py
327index 2843f66..fbb553b 100644
328--- a/src/maasserver/rpc/tests/test_regionservice_calls.py
329+++ b/src/maasserver/rpc/tests/test_regionservice_calls.py
330@@ -549,10 +549,10 @@ class TestRegionProtocol_ListNodePowerParameters(
331 }
332 )
333
334- # Create a node with an invalid power type (i.e. the empty string).
335+ # Create a node with an invalid power type.
336 # This will not be reported by the call to ListNodePowerParameters.
337 yield deferToDatabase(
338- self.create_node, power_type="", power_state_updated=None
339+ self.create_node, power_type="invalid", power_state_updated=None
340 )
341
342 response = yield call_responder(
343diff --git a/src/maasserver/stats.py b/src/maasserver/stats.py
344index 4f6d960..f2596cc 100644
345--- a/src/maasserver/stats.py
346+++ b/src/maasserver/stats.py
347@@ -25,6 +25,7 @@ from maasserver.enum import (
348 NODE_TYPE,
349 )
350 from maasserver.models import (
351+ BMC,
352 BootResourceFile,
353 Config,
354 Fabric,
355@@ -408,6 +409,31 @@ def get_tls_configuration_stats():
356 return {"tls_enabled": True, "tls_cert_validity_days": validity_days}
357
358
359+def get_bmc_stats():
360+ stats = (
361+ BMC.objects.all()
362+ .values("power_type")
363+ .annotate(
364+ auto_detected=count_of(created_by_commissioning=True),
365+ user_created=count_of(created_by_commissioning__exact=False),
366+ unknown=count_of(created_by_commissioning__exact=None),
367+ )
368+ )
369+ result = {
370+ # BMCs that were auto-detected and created by commissoning.
371+ "auto_detected": {},
372+ # BMCs that the user manually created.
373+ "user_created": {},
374+ # Before 3.2 we didn't track whether the BMC was auto-detected.
375+ "unknown": {},
376+ }
377+ for entry in stats:
378+ for key in result.keys():
379+ if entry[key]:
380+ result[key][entry["power_type"]] = entry[key]
381+ return result
382+
383+
384 def get_maas_stats():
385 # TODO
386 # - architectures
387@@ -457,6 +483,7 @@ def get_maas_stats():
388 "vmcluster": get_vmcluster_stats(),
389 "storage_layouts": get_storage_layouts_stats(),
390 "tls_configuration": get_tls_configuration_stats(),
391+ "bmcs": get_bmc_stats(),
392 }
393
394
395diff --git a/src/maasserver/testing/factory.py b/src/maasserver/testing/factory.py
396index dc72f91..62bbd01 100644
397--- a/src/maasserver/testing/factory.py
398+++ b/src/maasserver/testing/factory.py
399@@ -380,7 +380,7 @@ class Factory(maastesting.factory.Factory):
400 zone=None,
401 networks=None,
402 sortable_name=False,
403- power_type=None,
404+ power_type="virsh",
405 power_parameters=None,
406 power_state=None,
407 power_state_updated=undefined,
408@@ -420,8 +420,6 @@ class Factory(maastesting.factory.Factory):
409 status = NODE_STATUS.DEFAULT
410 if zone is None:
411 zone = Zone.objects.get_default_zone()
412- if power_type is None:
413- power_type = "virsh"
414 if power_state is None:
415 power_state = self.pick_enum(POWER_STATE)
416 if power_state_updated is undefined:
417@@ -449,7 +447,7 @@ class Factory(maastesting.factory.Factory):
418 cpu_speed=random.randint(1000, 5000),
419 **kwargs,
420 )
421- if bmc is None:
422+ if bmc is None and power_type:
423 # These setters will overwrite the BMC, so don't use them if the
424 # BMC was specified.
425 node.set_power_config(power_type, power_parameters or {})
426diff --git a/src/maasserver/tests/test_stats.py b/src/maasserver/tests/test_stats.py
427index 5abc2cc..a11b2d4 100644
428--- a/src/maasserver/tests/test_stats.py
429+++ b/src/maasserver/tests/test_stats.py
430@@ -21,6 +21,7 @@ from maasserver.enum import (
431 )
432 from maasserver.forms import AdminMachineForm
433 from maasserver.models import (
434+ BMC,
435 BootResourceFile,
436 Config,
437 Fabric,
438@@ -31,6 +32,7 @@ from maasserver.models import (
439 VLAN,
440 )
441 from maasserver.stats import (
442+ get_bmc_stats,
443 get_brownfield_stats,
444 get_custom_images_deployed_stats,
445 get_custom_images_uploaded_stats,
446@@ -456,6 +458,11 @@ class TestMAASStats(MAASServerTestCase):
447 "tls_cert_validity_days": None,
448 "tls_enabled": False,
449 },
450+ "bmcs": {
451+ "auto_detected": {},
452+ "user_created": {"lxd": 1, "virsh": 2},
453+ "unknown": {},
454+ },
455 }
456 self.assertEqual(stats, expected)
457
458@@ -628,6 +635,11 @@ class TestMAASStats(MAASServerTestCase):
459 "tls_cert_validity_days": None,
460 "tls_enabled": False,
461 },
462+ "bmcs": {
463+ "auto_detected": {},
464+ "user_created": {},
465+ "unknown": {},
466+ },
467 }
468 self.assertEqual(get_maas_stats(), expected)
469
470@@ -1047,6 +1059,36 @@ class TestGetSubnetsUtilisationStats(MAASServerTestCase):
471 )
472
473
474+class TestGetBMCStats(MAASServerTestCase):
475+ def test_get_bmc_stats_no_bmcs(self):
476+ self.assertEqual(0, BMC.objects.all().count())
477+ self.assertEqual(
478+ {
479+ "auto_detected": {},
480+ "user_created": {},
481+ "unknown": {},
482+ },
483+ get_bmc_stats(),
484+ )
485+
486+ def test_get_bmc_stats_with_bmcs(self):
487+ factory.make_BMC(power_type="redfish", created_by_commissioning=True)
488+ factory.make_BMC(power_type="ipmi", created_by_commissioning=False)
489+ factory.make_BMC(power_type="lxd", created_by_commissioning=None)
490+ self.assertEqual(
491+ {
492+ "auto_detected": {"redfish": 1},
493+ "user_created": {
494+ "ipmi": 1,
495+ },
496+ "unknown": {
497+ "lxd": 1,
498+ },
499+ },
500+ get_bmc_stats(),
501+ )
502+
503+
504 class TestStatsService(MAASTestCase):
505 """Tests for `ImportStatsService`."""
506
507diff --git a/src/metadataserver/api.py b/src/metadataserver/api.py
508index 5c4ad54..2de6c83 100644
509--- a/src/metadataserver/api.py
510+++ b/src/metadataserver/api.py
511@@ -374,7 +374,9 @@ def store_node_power_parameters(node, request):
512 **node.instance_power_parameters,
513 **power_parameters,
514 }
515- node.set_power_config(power_type, power_parameters)
516+ node.set_power_config(
517+ power_type, power_parameters, from_commissioning=True
518+ )
519 node.save()
520
521
522diff --git a/src/metadataserver/tests/test_api.py b/src/metadataserver/tests/test_api.py
523index a020b2e..6bfd733 100644
524--- a/src/metadataserver/tests/test_api.py
525+++ b/src/metadataserver/tests/test_api.py
526@@ -4166,7 +4166,7 @@ class TestStoreNodeParameters(APITestCase.ForUser):
527 def test_power_type_set_with_parameters(self):
528 # When power_type is valid, and power_parameters is valid JSON, both
529 # fields are set on the node, and the node is saved.
530- power_type = factory.pick_power_type()
531+ power_type = factory.pick_power_type(but_not=[self.node.power_type])
532 power_parameters = {"foo": [1, 2, 3]}
533 self.request.POST = {
534 "power_type": power_type,
535@@ -4175,6 +4175,7 @@ class TestStoreNodeParameters(APITestCase.ForUser):
536 store_node_power_parameters(self.node, self.request)
537 self.assertEqual(power_type, self.node.power_type)
538 self.assertEqual(power_parameters, self.node.power_parameters)
539+ self.assertTrue(self.node.bmc.created_by_commissioning)
540 self.save.assert_called_once_with()
541
542 def test_power_type_set_with_invalid_parameters(self):

Subscribers

People subscribed via source and target branches