145
145
def test_node_list_contains_link_to_node_view(self):
146
146
self.client_log_in()
147
node = factory.make_node()
147
node = factory.make_Node()
148
148
response = self.client.get(reverse('node-list'))
149
149
node_link = reverse('node-view', args=[node.system_id])
150
150
self.assertIn(node_link, get_content_links(response))
188
188
def test_node_list_lists_nodes_from_different_nodegroups(self):
190
190
self.client_log_in()
191
nodegroup1 = factory.make_node_group()
192
nodegroup2 = factory.make_node_group()
193
factory.make_node(nodegroup=nodegroup1)
194
factory.make_node(nodegroup=nodegroup2)
195
factory.make_node(nodegroup=nodegroup2)
191
nodegroup1 = factory.make_NodeGroup()
192
nodegroup2 = factory.make_NodeGroup()
193
factory.make_Node(nodegroup=nodegroup1)
194
factory.make_Node(nodegroup=nodegroup2)
195
factory.make_Node(nodegroup=nodegroup2)
196
196
response = self.client.get(reverse('node-list'))
197
197
self.assertEqual(httplib.OK, response.status_code)
199
199
def test_node_list_sorts_by_hostname(self):
200
200
self.client_log_in()
201
201
names = ['zero', 'one', 'five']
202
nodes = [factory.make_node(hostname=n) for n in names]
202
nodes = [factory.make_Node(hostname=n) for n in names]
204
204
# First check the ascending sort order
205
205
sorted_nodes = sorted(nodes, key=attrgetter('hostname'))
235
235
NODE_STATUS.FAILED_COMMISSIONING,
237
nodes = [factory.make_node(status=s) for s in statuses]
237
nodes = [factory.make_Node(status=s) for s in statuses]
239
239
# First check the ascending sort order
240
240
sorted_nodes = sorted(nodes, key=attrgetter('status'))
265
265
def test_node_list_sorts_by_zone(self):
266
266
self.client_log_in()
267
zones = [factory.make_zone(sortable_name=True) for _ in range(5)]
268
nodes = [factory.make_node(zone=zone) for zone in zones]
267
zones = [factory.make_Zone(sortable_name=True) for _ in range(5)]
268
nodes = [factory.make_Node(zone=zone) for zone in zones]
270
270
# We use PostgreSQL's case-insensitive text sorting algorithm.
271
271
sorted_nodes = sorted(
303
303
self.patch(nodes_views.NodeListView, 'paginate_by', page_size)
306
tag = factory.make_tag('shiny')
306
tag = factory.make_Tag('shiny')
307
307
for name in ('bbb', 'ccc', 'ddd', 'aaa'):
308
node = factory.make_node(hostname=name)
308
node = factory.make_Node(hostname=name)
309
309
node.tags = [tag]
310
310
nodes.append(node)
332
332
def test_node_list_displays_fqdn_dns_not_managed(self):
333
333
self.client_log_in()
334
nodes = [factory.make_node() for i in range(3)]
334
nodes = [factory.make_Node() for i in range(3)]
335
335
response = self.client.get(reverse('node-list'))
336
336
node_fqdns = [node.fqdn for node in nodes]
337
337
self.assertThat(response.content, ContainsAll(node_fqdns))
339
339
def test_node_list_displays_fqdn_dns_managed(self):
340
340
self.client_log_in()
341
nodegroup = factory.make_node_group(
341
nodegroup = factory.make_NodeGroup(
342
342
status=NODEGROUP_STATUS.ACCEPTED,
343
343
management=NODEGROUPINTERFACE_MANAGEMENT.DHCP_AND_DNS)
344
nodes = [factory.make_node(nodegroup=nodegroup) for i in range(3)]
344
nodes = [factory.make_Node(nodegroup=nodegroup) for i in range(3)]
345
345
response = self.client.get(reverse('node-list'))
346
346
node_fqdns = [node.fqdn for node in nodes]
347
347
self.assertThat(response.content, ContainsAll(node_fqdns))
349
349
def test_node_list_displays_zone(self):
350
350
self.client_log_in()
351
node = factory.make_node()
351
node = factory.make_Node()
352
352
response = self.client.get(reverse('node-list'))
353
353
[zone_field] = fromstring(response.content).cssselect('.zone-column')
354
354
self.assertEqual(node.zone.name, zone_field.text_content().strip())
356
356
def test_node_list_links_to_zone(self):
357
357
self.client_log_in()
358
node = factory.make_node()
358
node = factory.make_Node()
359
359
response = self.client.get(reverse('node-list'))
360
360
zone_link = reverse('zone-view', args=[node.zone.name])
361
361
self.assertEqual(
365
365
def test_node_list_displays_sorted_list_of_nodes(self):
366
366
# Nodes are sorted on the node list page, newest first.
367
367
self.client_log_in()
368
nodes = [factory.make_node() for i in range(3)]
368
nodes = [factory.make_Node() for i in range(3)]
369
369
# Explicitely set node.created since all of these node will
370
370
# be created in the same transaction and thus have the same
371
371
# 'created' value by default.
400
400
def make_nodes(nodegroup, number):
401
401
"""Create `number` new nodes."""
402
402
for counter in range(number):
403
factory.make_node(nodegroup=nodegroup, mac=True)
403
factory.make_Node(nodegroup=nodegroup, mac=True)
405
nodegroup = factory.make_node_group()
405
nodegroup = factory.make_NodeGroup()
406
406
make_nodes(nodegroup, 10)
408
408
url = reverse('node-list')
440
440
def test_view_node_contains_tag_names(self):
441
441
self.client_log_in()
442
node = factory.make_node(owner=self.logged_in_user)
443
tag_a = factory.make_tag()
444
tag_b = factory.make_tag()
442
node = factory.make_Node(owner=self.logged_in_user)
443
tag_a = factory.make_Tag()
444
tag_b = factory.make_Tag()
445
445
node.tags.add(tag_a)
446
446
node.tags.add(tag_b)
447
447
node_link = reverse('node-view', args=[node.system_id])
457
457
def test_view_node_contains_ip_addresses(self):
458
458
self.client_log_in()
459
node = factory.make_node(owner=self.logged_in_user, disable_ipv4=False)
459
node = factory.make_Node(owner=self.logged_in_user, disable_ipv4=False)
460
460
nodegroup = node.nodegroup
462
factory.make_mac_address(node=node).mac_address for i in range(2)]
462
factory.make_MACAddress(node=node).mac_address for i in range(2)]
463
463
ips = [factory.getRandomIPAddress() for i in range(2)]
464
464
for i in range(2):
465
factory.make_dhcp_lease(
465
factory.make_DHCPLease(
466
466
nodegroup=nodegroup, mac=macs[i], ip=ips[i])
467
467
node_link = reverse('node-view', args=[node.system_id])
468
468
response = self.client.get(node_link)
471
471
def test_view_node_does_not_contain_ip_addresses_if_no_lease(self):
472
472
self.client_log_in()
473
node = factory.make_node(owner=self.logged_in_user, disable_ipv4=False)
473
node = factory.make_Node(owner=self.logged_in_user, disable_ipv4=False)
474
474
node_link = reverse('node-view', args=[node.system_id])
475
475
response = self.client.get(node_link)
476
476
self.assertNotIn("IP addresses", response.content)
478
478
def test_view_node_displays_node_info_no_owner(self):
479
479
# If the node has no owner, the Owner 'slot' does not exist.
480
480
self.client_log_in()
481
node = factory.make_node()
481
node = factory.make_Node()
482
482
node_link = reverse('node-view', args=[node.system_id])
483
483
response = self.client.get(node_link)
484
484
doc = fromstring(response.content)
488
488
def test_view_node_displays_link_to_view_preseed(self):
489
489
self.client_log_in()
490
node = factory.make_node(owner=self.logged_in_user)
490
node = factory.make_Node(owner=self.logged_in_user)
491
491
node_link = reverse('node-view', args=[node.system_id])
492
492
response = self.client.get(node_link)
493
493
node_preseed_link = reverse('node-preseed-view', args=[node.system_id])
496
496
def test_view_node_displays_no_routers_if_no_routers_discovered(self):
497
497
self.client_log_in()
498
node = factory.make_node(owner=self.logged_in_user, routers=[])
498
node = factory.make_Node(owner=self.logged_in_user, routers=[])
499
499
node_link = reverse('node-view', args=[node.system_id])
501
501
response = self.client.get(node_link)
508
508
def test_view_node_displays_routers_if_any(self):
509
509
self.client_log_in()
510
510
router = factory.make_MAC()
511
node = factory.make_node(owner=self.logged_in_user, routers=[router])
511
node = factory.make_Node(owner=self.logged_in_user, routers=[router])
512
512
node_link = reverse('node-view', args=[node.system_id])
514
514
response = self.client.get(node_link)
521
521
def test_view_node_separates_routers_by_comma(self):
522
522
self.client_log_in()
523
523
routers = [factory.make_MAC(), factory.make_MAC()]
524
node = factory.make_node(owner=self.logged_in_user, routers=routers)
524
node = factory.make_Node(owner=self.logged_in_user, routers=routers)
525
525
node_link = reverse('node-view', args=[node.system_id])
527
527
response = self.client.get(node_link)
536
536
def test_view_node_links_to_physical_zone(self):
537
537
self.client_log_in()
538
node = factory.make_node()
538
node = factory.make_Node()
539
539
node_link = reverse('node-view', args=[node.system_id])
541
541
response = self.client.get(node_link)
565
565
def test_view_node_lists_macs_as_list_items(self):
566
566
self.client_log_in()
567
node = factory.make_node()
568
factory.make_mac_address('11:11:11:11:11:11', node=node)
569
factory.make_mac_address('22:22:22:22:22:22', node=node)
567
node = factory.make_Node()
568
factory.make_MACAddress('11:11:11:11:11:11', node=node)
569
factory.make_MACAddress('22:22:22:22:22:22', node=node)
571
571
response = self.client.get(reverse('node-view', args=[node.system_id]))
572
572
self.assertEqual(httplib.OK, response.status_code)
582
582
def test_view_node_links_network_interfaces_to_networks(self):
583
583
self.client_log_in()
584
network = factory.make_network()
585
mac = factory.make_mac_address(networks=[network])
584
network = factory.make_Network()
585
mac = factory.make_MACAddress(networks=[network])
587
587
response = self.client.get(
588
588
reverse('node-view', args=[mac.node.system_id]))
604
604
def test_view_node_sorts_networks_by_name(self):
605
605
self.client_log_in()
606
networks = factory.make_networks(3, sortable_name=True)
607
mac = factory.make_mac_address(networks=networks)
606
networks = factory.make_Networks(3, sortable_name=True)
607
mac = factory.make_MACAddress(networks=networks)
609
609
response = self.client.get(
610
610
reverse('node-view', args=[mac.node.system_id]))
622
622
def test_view_node_displays_link_to_edit_if_user_owns_node(self):
623
623
self.client_log_in()
624
node = factory.make_node(owner=self.logged_in_user)
624
node = factory.make_Node(owner=self.logged_in_user)
625
625
node_link = reverse('node-view', args=[node.system_id])
626
626
response = self.client.get(node_link)
627
627
node_edit_link = reverse('node-edit', args=[node.system_id])
630
630
def test_view_node_does_not_show_link_to_delete_node(self):
631
631
# Only admin users can delete nodes.
632
632
self.client_log_in()
633
node = factory.make_node(owner=self.logged_in_user)
633
node = factory.make_Node(owner=self.logged_in_user)
634
634
node_link = reverse('node-view', args=[node.system_id])
635
635
response = self.client.get(node_link)
636
636
node_delete_link = reverse('node-delete', args=[node.system_id])
639
639
def test_user_cannot_delete_node(self):
640
640
self.client_log_in()
641
node = factory.make_node(owner=self.logged_in_user)
641
node = factory.make_Node(owner=self.logged_in_user)
642
642
node_delete_link = reverse('node-delete', args=[node.system_id])
643
643
response = self.client.get(node_delete_link)
644
644
self.assertEqual(httplib.FORBIDDEN, response.status_code)
649
649
NODE_STATUS.READY, NODE_STATUS.COMMISSIONING)
650
650
help_link = "https://maas.ubuntu.com/docs/nodes.html"
651
651
for status in map_enum(NODE_STATUS).values():
652
node = factory.make_node(status=status)
652
node = factory.make_Node(status=status)
653
653
node_link = reverse('node-view', args=[node.system_id])
654
654
response = self.client.get(node_link)
655
655
links = get_content_links(response, '#flash-messages')
661
661
def test_admin_can_delete_nodes(self):
662
662
self.client_log_in(as_admin=True)
663
node = factory.make_node()
663
node = factory.make_Node()
664
664
node_delete_link = reverse('node-delete', args=[node.system_id])
665
665
response = self.client.post(node_delete_link, {'post': 'yes'})
666
666
self.assertEqual(httplib.FOUND, response.status_code)
669
669
def test_allocated_node_view_page_says_node_cannot_be_deleted(self):
670
670
self.client_log_in(as_admin=True)
671
node = factory.make_node(
672
status=NODE_STATUS.ALLOCATED, owner=factory.make_user())
671
node = factory.make_Node(
672
status=NODE_STATUS.ALLOCATED, owner=factory.make_User())
673
673
node_view_link = reverse('node-view', args=[node.system_id])
674
674
response = self.client.get(node_view_link)
675
675
node_delete_link = reverse('node-delete', args=[node.system_id])
683
683
def test_allocated_node_cannot_be_deleted(self):
684
684
self.client_log_in(as_admin=True)
685
node = factory.make_node(
686
status=NODE_STATUS.ALLOCATED, owner=factory.make_user())
685
node = factory.make_Node(
686
status=NODE_STATUS.ALLOCATED, owner=factory.make_User())
687
687
node_delete_link = reverse('node-delete', args=[node.system_id])
688
688
response = self.client.get(node_delete_link)
692
692
def test_user_can_view_someone_elses_node(self):
693
693
self.client_log_in()
694
node = factory.make_node(owner=factory.make_user())
694
node = factory.make_Node(owner=factory.make_User())
695
695
node_view_link = reverse('node-view', args=[node.system_id])
696
696
response = self.client.get(node_view_link)
697
697
self.assertEqual(httplib.OK, response.status_code)
699
699
def test_user_cannot_edit_someone_elses_node(self):
700
700
self.client_log_in()
701
node = factory.make_node(owner=factory.make_user())
701
node = factory.make_Node(owner=factory.make_User())
702
702
node_edit_link = reverse('node-edit', args=[node.system_id])
703
703
response = self.client.get(node_edit_link)
704
704
self.assertEqual(httplib.FORBIDDEN, response.status_code)
706
706
def test_admin_can_view_someonelses_node(self):
707
707
self.client_log_in(as_admin=True)
708
node = factory.make_node(owner=factory.make_user())
708
node = factory.make_Node(owner=factory.make_User())
709
709
node_view_link = reverse('node-view', args=[node.system_id])
710
710
response = self.client.get(node_view_link)
711
711
self.assertEqual(httplib.OK, response.status_code)
713
713
def test_admin_can_edit_someonelses_node(self):
714
714
self.client_log_in(as_admin=True)
715
node = factory.make_node(owner=factory.make_user())
715
node = factory.make_Node(owner=factory.make_User())
716
716
node_edit_link = reverse('node-edit', args=[node.system_id])
717
717
response = self.client.get(node_edit_link)
718
718
self.assertEqual(httplib.OK, response.status_code)
720
720
def test_user_can_access_the_edition_page_for_his_nodes(self):
721
721
self.client_log_in()
722
node = factory.make_node(owner=self.logged_in_user)
722
node = factory.make_Node(owner=self.logged_in_user)
723
723
node_edit_link = reverse('node-edit', args=[node.system_id])
724
724
response = self.client.get(node_edit_link)
725
725
self.assertEqual(httplib.OK, response.status_code)
727
727
def test_user_can_edit_his_nodes(self):
728
728
self.client_log_in()
729
node = factory.make_node(owner=self.logged_in_user)
729
node = factory.make_Node(owner=self.logged_in_user)
730
730
node_edit_link = reverse('node-edit', args=[node.system_id])
732
732
'hostname': factory.make_string(),
741
741
def test_edit_nodes_contains_list_of_macaddresses(self):
742
742
self.client_log_in()
743
node = factory.make_node(owner=self.logged_in_user)
743
node = factory.make_Node(owner=self.logged_in_user)
745
unicode(factory.make_mac_address(node=node).mac_address)
745
unicode(factory.make_MACAddress(node=node).mac_address)
746
746
for i in range(3)
748
748
node_edit_link = reverse('node-edit', args=[node.system_id])
752
752
def test_edit_nodes_contains_links_to_delete_the_macaddresses(self):
753
753
self.client_log_in()
754
node = factory.make_node(owner=self.logged_in_user)
754
node = factory.make_Node(owner=self.logged_in_user)
756
factory.make_mac_address(node=node).mac_address
756
factory.make_MACAddress(node=node).mac_address
757
757
for i in range(3)
759
759
node_edit_link = reverse('node-edit', args=[node.system_id])
767
767
def test_edit_nodes_contains_link_to_add_a_macaddresses(self):
768
768
self.client_log_in()
769
node = factory.make_node(owner=self.logged_in_user)
769
node = factory.make_Node(owner=self.logged_in_user)
770
770
node_edit_link = reverse('node-edit', args=[node.system_id])
771
771
response = self.client.get(node_edit_link)
775
775
def test_view_node_shows_global_kernel_params(self):
776
776
self.client_log_in()
777
777
Config.objects.create(name='kernel_opts', value='--test param')
778
node = factory.make_node()
778
node = factory.make_Node()
779
779
self.assertEqual(
780
780
node.get_effective_kernel_options(),
781
781
(None, "--test param", )
793
793
def test_view_node_shows_tag_kernel_params(self):
794
794
self.client_log_in()
795
tag = factory.make_tag(name='shiny', kernel_opts="--test params")
796
node = factory.make_node()
795
tag = factory.make_Tag(name='shiny', kernel_opts="--test params")
796
node = factory.make_Node()
797
797
node.tags = [tag]
798
798
self.assertEqual(
799
799
(tag, '--test params',),
811
811
def test_view_node_has_button_to_accept_enlistment_for_user(self):
812
812
# A simple user can't see the button to enlist a declared node.
813
813
self.client_log_in()
814
node = factory.make_node(status=NODE_STATUS.NEW)
814
node = factory.make_Node(status=NODE_STATUS.NEW)
815
815
node_link = reverse('node-view', args=[node.system_id])
816
816
response = self.client.get(node_link)
817
817
doc = fromstring(response.content)
823
823
# error condition, the contents of node.error are displayed as console
825
825
self.client_log_in()
826
node = factory.make_node(
826
node = factory.make_Node(
827
827
owner=self.logged_in_user, error=factory.make_string(),
828
828
status=NODE_STATUS.READY)
829
829
node_link = reverse('node-view', args=[node.system_id])
836
836
# When node.error is set and the node's status indicates an error
837
837
# condition, the contents of node.error are displayed as error output.
838
838
self.client_log_in()
839
node = factory.make_node(
839
node = factory.make_Node(
840
840
owner=self.logged_in_user, error=factory.make_string(),
841
841
status=NODE_STATUS.FAILED_COMMISSIONING)
842
842
node_link = reverse('node-view', args=[node.system_id])
848
848
def test_view_node_shows_no_error_if_no_error_set(self):
849
849
self.client_log_in()
850
node = factory.make_node(owner=self.logged_in_user)
850
node = factory.make_Node(owner=self.logged_in_user)
851
851
node_link = reverse('node-view', args=[node.system_id])
852
852
response = self.client.get(node_link)
853
853
doc = fromstring(response.content)
859
859
self.patch(node_module, "update_host_maps").return_value = []
861
861
self.client_log_in()
862
factory.make_sshkey(self.logged_in_user)
862
factory.make_SSHKey(self.logged_in_user)
863
863
self.set_up_oauth_token()
864
864
node = factory.make_node_with_mac_attached_to_nodegroupinterface(
865
865
status=NODE_STATUS.ALLOCATED, power_type='ether_wake',
873
873
def test_view_node_skips_probed_details_output_if_none_set(self):
874
874
self.client_log_in()
875
node = factory.make_node(owner=self.logged_in_user)
875
node = factory.make_Node(owner=self.logged_in_user)
876
876
node_link = reverse('node-view', args=[node.system_id])
878
878
response = self.client.get(node_link)
884
884
def test_view_node_shows_probed_details_output_if_set(self):
885
885
self.client_log_in()
886
node = factory.make_node(owner=self.logged_in_user)
886
node = factory.make_Node(owner=self.logged_in_user)
887
887
lldp_data = "<foo>bar</foo>".encode("utf-8")
888
factory.make_node_commission_result(
888
factory.make_NodeResult_for_commissioning(
889
889
node=node, name=LLDP_OUTPUT_NAME, script_result=0, data=lldp_data)
890
890
node_link = reverse('node-view', args=[node.system_id])
908
908
def test_view_node_POST_commission(self):
909
909
self.client_log_in(as_admin=True)
910
node = factory.make_node(status=NODE_STATUS.READY)
910
node = factory.make_Node(status=NODE_STATUS.READY)
911
911
node_link = reverse('node-view', args=[node.system_id])
912
912
response = self.client.post(
913
913
node_link, data={NodeActionForm.input_name: Commission.name})
927
927
def test_view_node_POST_action_displays_message(self):
928
928
self.client_log_in()
929
factory.make_sshkey(self.logged_in_user)
929
factory.make_SSHKey(self.logged_in_user)
930
930
self.set_up_oauth_token()
931
node = factory.make_node(status=NODE_STATUS.READY)
931
node = factory.make_Node(status=NODE_STATUS.READY)
932
932
response = self.perform_action_and_get_node_page(
933
933
node, AcquireNode.name)
962
962
def test_node_list_query_selects_subset(self):
963
963
self.client_log_in()
964
tag = factory.make_tag("shiny")
965
node1 = factory.make_node(cpu_count=1)
966
node2 = factory.make_node(cpu_count=2)
967
node3 = factory.make_node(cpu_count=2)
964
tag = factory.make_Tag("shiny")
965
node1 = factory.make_Node(cpu_count=1)
966
node2 = factory.make_Node(cpu_count=2)
967
node3 = factory.make_Node(cpu_count=2)
968
968
node1.tags = [tag]
969
969
node2.tags = [tag]
984
984
self.patch(nodes_views.NodeListView, 'paginate_by', page_size)
986
factory.make_node(created="2012-10-12 12:00:%02d" % i)
986
factory.make_Node(created="2012-10-12 12:00:%02d" % i)
987
987
for i in range(page_size * 2 + 1)
989
989
# Order node links with newest first as the view is expected to
1028
1028
# Set a very small page size to save creating lots of nodes
1029
1029
self.patch(nodes_views.NodeListView, 'paginate_by', 2)
1031
factory.make_node(created="2012-10-12 12:00:%02d" % i)
1031
factory.make_Node(created="2012-10-12 12:00:%02d" % i)
1032
1032
for i in range(10)]
1033
tag = factory.make_tag("odd")
1033
tag = factory.make_Tag("odd")
1034
1034
for node in nodes[::2]:
1035
1035
node.tags = [tag]
1036
1036
last_node_link = reverse('node-view', args=[nodes[0].system_id])
1055
1055
def test_node_list_performs_bulk_action(self):
1056
1056
self.client_log_in(as_admin=True)
1057
node1 = factory.make_node()
1058
node2 = factory.make_node()
1059
node3 = factory.make_node()
1057
node1 = factory.make_Node()
1058
node2 = factory.make_Node()
1059
node3 = factory.make_Node()
1060
1060
system_id_to_delete = [node1.system_id, node2.system_id]
1061
1061
response = self.client.post(
1062
1062
reverse('node-list'),
1109
1109
def test_node_list_view_shows_third_party_drivers_admin_warning(self):
1110
1110
self.client_log_in(as_admin=True)
1112
1112
Config.objects.set_config(
1113
1113
name='enable_third_party_drivers', value=True)
1114
1114
response = self.client.get(reverse('node-list'))
1133
1133
self.client_log_in()
1134
1134
Config.objects.set_config(
1135
1135
name='enable_third_party_drivers', value=True)
1136
node = factory.make_node(status=NODE_STATUS.READY)
1136
node = factory.make_Node(status=NODE_STATUS.READY)
1137
1137
response = self.client.get(reverse('node-view', args=[node.system_id]))
1138
1138
self.assertNotIn("Third Party Drivers", response.content)
1141
1141
self.client_log_in()
1142
1142
Config.objects.set_config(
1143
1143
name='enable_third_party_drivers', value=True)
1144
node = factory.make_node(status=NODE_STATUS.READY)
1144
node = factory.make_Node(status=NODE_STATUS.READY)
1145
1145
data = "pci:v00001590d00000047sv00001590sd00000047bc*sc*i*"
1146
factory.make_node_commission_result(
1146
factory.make_NodeResult_for_commissioning(
1147
1147
node=node, name=LIST_MODALIASES_OUTPUT_NAME, script_result=0,
1148
1148
data=data.encode("utf-8"))
1149
1149
response = self.client.get(reverse('node-view', args=[node.system_id]))
1157
1157
self.client_log_in()
1158
1158
Config.objects.set_config(
1159
1159
name='enable_third_party_drivers', value=False)
1160
node = factory.make_node(status=NODE_STATUS.READY)
1160
node = factory.make_Node(status=NODE_STATUS.READY)
1161
1161
data = "pci:v00001590d00000047sv00001590sd00000047bc*sc*i*"
1162
factory.make_node_commission_result(
1162
factory.make_NodeResult_for_commissioning(
1163
1163
node=node, name=LIST_MODALIASES_OUTPUT_NAME, script_result=0,
1164
1164
data=data.encode("utf-8"))
1165
1165
response = self.client.get(reverse('node-view', args=[node.system_id]))
1168
1168
def test_node_view_show_latest_node_events(self):
1169
1169
self.client_log_in()
1170
node = factory.make_node()
1170
node = factory.make_Node()
1171
1171
# Create old events.
1173
factory.make_event(node=node)
1173
factory.make_Event(node=node)
1174
1174
for _ in range(4)
1176
1176
# Create NodeView.number_of_events_shown events.
1178
factory.make_event(node=node)
1178
factory.make_Event(node=node)
1179
1179
for _ in range(NodeView.number_of_events_shown)
1181
1181
response = self.client.get(reverse('node-view', args=[node.system_id]))
1191
1191
def test_node_view_doesnt_show_events_from_other_nodes(self):
1192
1192
self.client_log_in()
1193
node = factory.make_node()
1193
node = factory.make_Node()
1194
1194
# Create an event related to another node.
1195
event = factory.make_event()
1195
event = factory.make_Event()
1196
1196
response = self.client.get(
1197
1197
reverse('node-view', args=[node.system_id]))
1198
1198
self.assertIn("Latest node events", response.content)
1206
1206
def test_node_view_links_to_node_event_log(self):
1207
1207
self.client_log_in()
1208
node = factory.make_node()
1209
factory.make_event(node=node)
1208
node = factory.make_Node()
1209
factory.make_Event(node=node)
1210
1210
response = self.client.get(
1211
1211
reverse('node-view', args=[node.system_id]))
1212
1212
self.assertIn("Latest node events", response.content)
1219
1219
def test_node_view_pluralises_link_to_node_event_log(self):
1220
1220
self.client_log_in()
1221
node = factory.make_node()
1221
node = factory.make_Node()
1222
1222
num_events = randint(2, 3)
1223
1223
for _ in range(num_events):
1224
factory.make_event(node=node)
1224
factory.make_Event(node=node)
1225
1225
response = self.client.get(
1226
1226
reverse('node-view', args=[node.system_id]))
1227
1227
self.assertIn("Latest node events", response.content)
1234
1234
def test_node_view_contains_link_to_node_event_log(self):
1235
1235
self.client_log_in()
1236
node = factory.make_node()
1236
node = factory.make_Node()
1237
1237
# Create an event related to another node.
1239
factory.make_event(node=node)
1239
factory.make_Event(node=node)
1240
1240
for _ in range(4)
1242
1242
response = self.client.get(
1251
1251
def test_event_log_shows_event_list(self):
1252
1252
self.client_log_in()
1253
node = factory.make_node()
1253
node = factory.make_Node()
1255
factory.make_event(node=node)
1255
factory.make_Event(node=node)
1256
1256
for _ in range(NodeView.number_of_events_shown)
1258
1258
response = self.client.get(
1268
1268
def test_event_log_is_paginated(self):
1269
1269
self.client_log_in()
1270
1270
self.patch(NodeEventListView, "paginate_by", 3)
1271
node = factory.make_node()
1271
node = factory.make_Node()
1272
1272
# Create 4 events.
1273
[factory.make_event(node=node) for _ in range(4)]
1273
[factory.make_Event(node=node) for _ in range(4)]
1275
1275
response = self.client.get(
1276
1276
reverse('node-event-list-view', args=[node.system_id]))
1349
1349
def test_view_node_links_to_commissioning_results_if_appropriate(self):
1350
1350
self.client_log_in(as_admin=True)
1351
result = factory.make_node_commission_result()
1351
result = factory.make_NodeResult_for_commissioning()
1352
1352
section = self.request_results_display(
1353
1353
result.node, RESULT_TYPE.COMMISSIONING)
1354
1354
link = self.get_results_link(section)
1360
1360
def test_view_node_shows_commissioning_results_only_if_present(self):
1361
1361
self.client_log_in(as_admin=True)
1362
node = factory.make_node()
1362
node = factory.make_Node()
1363
1363
self.assertIsNone(
1364
1364
self.request_results_display(node, RESULT_TYPE.COMMISSIONING))
1366
1366
def test_view_node_shows_commissioning_results_with_edit_perm(self):
1367
1367
password = 'test'
1368
user = factory.make_user(password=password)
1369
node = factory.make_node(owner=user)
1368
user = factory.make_User(password=password)
1369
node = factory.make_Node(owner=user)
1370
1370
self.client.login(username=user.username, password=password)
1371
1371
self.logged_in_user = user
1372
result = factory.make_node_commission_result(node=node)
1372
result = factory.make_NodeResult_for_commissioning(node=node)
1373
1373
section = self.request_results_display(
1374
1374
result.node, RESULT_TYPE.COMMISSIONING)
1375
1375
link = self.get_results_link(section)
1380
1380
def test_view_node_shows_commissioning_results_requires_edit_perm(self):
1381
1381
password = 'test'
1382
user = factory.make_user(password=password)
1383
node = factory.make_node()
1382
user = factory.make_User(password=password)
1383
node = factory.make_Node()
1384
1384
self.client.login(username=user.username, password=password)
1385
1385
self.logged_in_user = user
1386
result = factory.make_node_commission_result(node=node)
1386
result = factory.make_NodeResult_for_commissioning(node=node)
1387
1387
self.assertIsNone(
1388
1388
self.request_results_display(
1389
1389
result.node, RESULT_TYPE.COMMISSIONING))
1391
1391
def test_view_node_shows_single_commissioning_result(self):
1392
1392
self.client_log_in(as_admin=True)
1393
result = factory.make_node_commission_result()
1393
result = factory.make_NodeResult_for_commissioning()
1394
1394
section = self.request_results_display(
1395
1395
result.node, RESULT_TYPE.COMMISSIONING)
1396
1396
link = self.get_results_link(section)
1401
1401
def test_view_node_shows_multiple_commissioning_results(self):
1402
1402
self.client_log_in(as_admin=True)
1403
node = factory.make_node()
1403
node = factory.make_Node()
1404
1404
num_results = randint(2, 5)
1405
1405
for _ in range(num_results):
1406
factory.make_node_commission_result(node=node)
1406
factory.make_NodeResult_for_commissioning(node=node)
1407
1407
section = self.request_results_display(
1408
1408
node, RESULT_TYPE.COMMISSIONING)
1409
1409
link = self.get_results_link(section)
1414
1414
def test_view_node_shows_installing_results_only_if_present(self):
1415
1415
self.client_log_in(as_admin=True)
1416
node = factory.make_node()
1416
node = factory.make_Node()
1417
1417
self.assertIsNone(
1418
1418
self.request_results_display(node, RESULT_TYPE.INSTALLING))
1420
1420
def test_view_node_shows_installing_results_with_edit_perm(self):
1421
1421
password = 'test'
1422
user = factory.make_user(password=password)
1423
node = factory.make_node(owner=user)
1422
user = factory.make_User(password=password)
1423
node = factory.make_Node(owner=user)
1424
1424
self.client.login(username=user.username, password=password)
1425
1425
self.logged_in_user = user
1426
result = factory.make_node_install_result(node=node)
1426
result = factory.make_NodeResult_for_installing(node=node)
1427
1427
section = self.request_results_display(
1428
1428
result.node, RESULT_TYPE.INSTALLING)
1429
1429
link = self.get_results_link(section)
1434
1434
def test_view_node_shows_installing_results_requires_edit_perm(self):
1435
1435
password = 'test'
1436
user = factory.make_user(password=password)
1437
node = factory.make_node()
1436
user = factory.make_User(password=password)
1437
node = factory.make_Node()
1438
1438
self.client.login(username=user.username, password=password)
1439
1439
self.logged_in_user = user
1440
result = factory.make_node_install_result(node=node)
1440
result = factory.make_NodeResult_for_installing(node=node)
1441
1441
self.assertIsNone(
1442
1442
self.request_results_display(
1443
1443
result.node, RESULT_TYPE.INSTALLING))
1507
1507
class NodeProbedDetailsExpanderTest(SeleniumTestCase):
1509
1509
def make_node_with_lldp_output(self):
1510
node = factory.make_node()
1511
factory.make_node_commission_result(
1510
node = factory.make_Node()
1511
factory.make_NodeResult_for_commissioning(
1512
1512
node=node, name=LLDP_OUTPUT_NAME,
1513
1513
data="<foo>bar</foo>".encode("utf-8"),
1514
1514
script_result=0)
1633
1633
def test_preseedview_node_displays_preseed_data(self):
1634
1634
self.client_log_in()
1635
node = factory.make_node(
1635
node = factory.make_Node(
1636
1636
nodegroup=self.rpc_nodegroup, owner=self.logged_in_user)
1637
1637
node_preseed_link = reverse('node-preseed-view', args=[node.system_id])
1638
1638
response = self.client.get(node_preseed_link)
1642
1642
def test_preseedview_node_catches_template_error(self):
1643
1643
self.client_log_in()
1644
node = factory.make_node(
1644
node = factory.make_Node(
1645
1645
nodegroup=self.rpc_nodegroup, owner=self.logged_in_user)
1646
1646
node_preseed_link = reverse('node-preseed-view', args=[node.system_id])
1647
1647
path = self.make_file(name="generic", contents="{{invalid}}")
1653
1653
def test_preseedview_node_displays_message_if_commissioning(self):
1654
1654
self.client_log_in()
1655
node = factory.make_node(
1655
node = factory.make_Node(
1656
1656
nodegroup=self.rpc_nodegroup, owner=self.logged_in_user,
1657
1657
status=NODE_STATUS.COMMISSIONING,
1666
1666
def test_preseedview_node_displays_link_to_view_node(self):
1667
1667
self.client_log_in()
1668
node = factory.make_node(
1668
node = factory.make_Node(
1669
1669
nodegroup=self.rpc_nodegroup, owner=self.logged_in_user)
1670
1670
node_preseed_link = reverse('node-preseed-view', args=[node.system_id])
1671
1671
response = self.client.get(node_preseed_link)
1695
1695
# If the MAC address does not exist, the user is redirected
1696
1696
# to the node edit page.
1697
1697
self.client_log_in()
1698
node = factory.make_node(owner=self.logged_in_user)
1698
node = factory.make_Node(owner=self.logged_in_user)
1699
1699
mac = factory.getRandomMACAddress()
1700
1700
mac_delete_link = reverse('mac-delete', args=[node.system_id, mac])
1701
1701
response = self.client.get(mac_delete_link)
1706
1706
def test_node_delete_access_denied_if_user_cannot_edit_node(self):
1707
1707
self.client_log_in()
1708
node = factory.make_node(owner=factory.make_user())
1709
mac = factory.make_mac_address(node=node)
1708
node = factory.make_Node(owner=factory.make_User())
1709
mac = factory.make_MACAddress(node=node)
1710
1710
mac_delete_link = reverse('mac-delete', args=[node.system_id, mac])
1711
1711
response = self.client.get(mac_delete_link)
1712
1712
self.assertEqual(httplib.FORBIDDEN, response.status_code)
1714
1714
def test_node_delete_mac_contains_mac(self):
1715
1715
self.client_log_in()
1716
node = factory.make_node(owner=self.logged_in_user)
1717
mac = factory.make_mac_address(node=node)
1716
node = factory.make_Node(owner=self.logged_in_user)
1717
mac = factory.make_MACAddress(node=node)
1718
1718
mac_delete_link = reverse('mac-delete', args=[node.system_id, mac])
1719
1719
response = self.client.get(mac_delete_link)
1725
1725
def test_node_delete_mac_POST_deletes_mac(self):
1726
1726
self.client_log_in()
1727
node = factory.make_node(owner=self.logged_in_user)
1728
mac = factory.make_mac_address(node=node)
1727
node = factory.make_Node(owner=self.logged_in_user)
1728
mac = factory.make_MACAddress(node=node)
1729
1729
mac_delete_link = reverse('mac-delete', args=[node.system_id, mac])
1730
1730
response = self.client.post(mac_delete_link, {'post': 'yes'})
1731
1731
self.assertEqual(
1736
1736
def test_node_delete_mac_POST_displays_message(self):
1737
1737
self.client_log_in()
1738
node = factory.make_node(owner=self.logged_in_user)
1739
mac = factory.make_mac_address(node=node)
1738
node = factory.make_Node(owner=self.logged_in_user)
1739
mac = factory.make_MACAddress(node=node)
1740
1740
mac_delete_link = reverse('mac-delete', args=[node.system_id, mac])
1741
1741
response = self.client.post(mac_delete_link, {'post': 'yes'})
1742
1742
redirect = extract_redirect(response)
1748
1748
def test_node_delete_mac_POST_disconnects_MAC_from_network(self):
1749
1749
self.client_log_in()
1750
network = factory.make_network()
1751
node = factory.make_node(owner=self.logged_in_user)
1752
mac = factory.make_mac_address(node=node, networks=[network])
1750
network = factory.make_Network()
1751
node = factory.make_Node(owner=self.logged_in_user)
1752
mac = factory.make_MACAddress(node=node, networks=[network])
1753
1753
response = self.client.post(
1754
1754
reverse('mac-delete', args=[node.system_id, mac]), {'post': 'yes'})
1755
1755
self.assertEqual(httplib.FOUND, response.status_code)
1761
1761
def test_node_add_mac_contains_form(self):
1762
1762
self.client_log_in()
1763
node = factory.make_node(owner=self.logged_in_user)
1763
node = factory.make_Node(owner=self.logged_in_user)
1764
1764
mac_add_link = reverse('mac-add', args=[node.system_id])
1765
1765
response = self.client.get(mac_add_link)
1766
1766
doc = fromstring(response.content)
1769
1769
def test_node_add_mac_POST_adds_mac(self):
1770
1770
self.client_log_in()
1771
node = factory.make_node(owner=self.logged_in_user)
1771
node = factory.make_Node(owner=self.logged_in_user)
1772
1772
mac_add_link = reverse('mac-add', args=[node.system_id])
1773
1773
mac = factory.getRandomMACAddress()
1774
1774
response = self.client.post(mac_add_link, {'mac_address': mac})
1781
1781
def test_node_add_mac_POST_displays_message(self):
1782
1782
self.client_log_in()
1783
node = factory.make_node(owner=self.logged_in_user)
1783
node = factory.make_Node(owner=self.logged_in_user)
1784
1784
mac_add_link = reverse('mac-add', args=[node.system_id])
1785
1785
mac = factory.getRandomMACAddress()
1786
1786
response = self.client.post(mac_add_link, {'mac_address': mac})
1796
1796
def test_admin_can_edit_nodes(self):
1797
1797
self.client_log_in(as_admin=True)
1798
node = factory.make_node(owner=factory.make_user())
1798
node = factory.make_Node(owner=factory.make_User())
1799
1799
node_edit_link = reverse('node-edit', args=[node.system_id])
1801
1801
'hostname': factory.make_string(),