~rvb/maas/transaction-1.7-bug-1409852

« back to all changes in this revision

Viewing changes to src/maasserver/views/tests/test_nodes.py

merged upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
144
144
 
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))
158
158
    def test_node_list_contains_column_sort_links(self):
159
159
        # Just create a node to have something in the list
160
160
        self.client_log_in()
161
 
        factory.make_node()
 
161
        factory.make_Node()
162
162
        response = self.client.get(reverse('node-list'))
163
163
        sort_hostname = '?sort=hostname&dir=asc'
164
164
        sort_status = '?sort=status&dir=asc'
179
179
 
180
180
    def test_node_list_ignores_unknown_sort_param(self):
181
181
        self.client_log_in()
182
 
        factory.make_node()
 
182
        factory.make_Node()
183
183
        response = self.client.get(
184
184
            reverse('node-list'), {'sort': 'unknown', 'dir': 'asc'})
185
185
        # No error: the unknown sorting parameter was ignored.
188
188
    def test_node_list_lists_nodes_from_different_nodegroups(self):
189
189
        # Bug 1084443.
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)
198
198
 
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]
203
203
 
204
204
        # First check the ascending sort order
205
205
        sorted_nodes = sorted(nodes, key=attrgetter('hostname'))
234
234
            NODE_STATUS.NEW,
235
235
            NODE_STATUS.FAILED_COMMISSIONING,
236
236
            }
237
 
        nodes = [factory.make_node(status=s) for s in statuses]
 
237
        nodes = [factory.make_Node(status=s) for s in statuses]
238
238
 
239
239
        # First check the ascending sort order
240
240
        sorted_nodes = sorted(nodes, key=attrgetter('status'))
264
264
 
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]
269
269
 
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)
304
304
 
305
305
        nodes = []
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)
311
311
 
331
331
 
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))
338
338
 
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))
348
348
 
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())
355
355
 
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)
404
404
 
405
 
        nodegroup = factory.make_node_group()
 
405
        nodegroup = factory.make_NodeGroup()
406
406
        make_nodes(nodegroup, 10)
407
407
 
408
408
        url = reverse('node-list')
422
422
    def test_view_node_displays_node_info(self):
423
423
        # The node page features the basic information about the node.
424
424
        self.client_log_in()
425
 
        node = factory.make_node(owner=self.logged_in_user)
 
425
        node = factory.make_Node(owner=self.logged_in_user)
426
426
        node.cpu_count = 123
427
427
        node.memory = 512
428
428
        node.save()
439
439
 
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])
456
456
 
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
461
461
        macs = [
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)
470
470
 
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)
487
487
 
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])
495
495
 
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])
500
500
 
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])
513
513
 
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])
526
526
 
527
527
        response = self.client.get(node_link)
535
535
 
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])
540
540
 
541
541
        response = self.client.get(node_link)
551
551
 
552
552
    def test_view_node_shows_macs(self):
553
553
        self.client_log_in()
554
 
        mac = factory.make_mac_address()
 
554
        mac = factory.make_MACAddress()
555
555
 
556
556
        response = self.client.get(
557
557
            reverse('node-view', args=[mac.node.system_id]))
564
564
 
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)
570
570
 
571
571
        response = self.client.get(reverse('node-view', args=[node.system_id]))
572
572
        self.assertEqual(httplib.OK, response.status_code)
581
581
 
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])
586
586
 
587
587
        response = self.client.get(
588
588
            reverse('node-view', args=[mac.node.system_id]))
603
603
 
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)
608
608
 
609
609
        response = self.client.get(
610
610
            reverse('node-view', args=[mac.node.system_id]))
621
621
 
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])
638
638
 
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')
660
660
 
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)
668
668
 
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])
682
682
 
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)
689
689
 
691
691
 
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)
698
698
 
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)
705
705
 
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)
712
712
 
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)
719
719
 
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)
726
726
 
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])
731
731
        params = {
732
732
            'hostname': factory.make_string(),
740
740
 
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)
744
744
        macs = [
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)
747
747
        ]
748
748
        node_edit_link = reverse('node-edit', args=[node.system_id])
751
751
 
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)
755
755
        macs = [
756
 
            factory.make_mac_address(node=node).mac_address
 
756
            factory.make_MACAddress(node=node).mac_address
757
757
            for i in range(3)
758
758
        ]
759
759
        node_edit_link = reverse('node-edit', args=[node.system_id])
766
766
 
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)
772
772
        self.assertIn(
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", )
792
792
 
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
824
824
        # output.
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])
847
847
 
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 = []
860
860
 
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',
872
872
 
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])
877
877
 
878
878
        response = self.client.get(node_link)
883
883
 
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])
891
891
 
907
907
 
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})
926
926
 
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)
934
934
        self.assertIn(
961
961
 
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]
970
970
        node3.tags = []
983
983
        page_size = 2
984
984
        self.patch(nodes_views.NodeListView, 'paginate_by', page_size)
985
985
        nodes = [
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)
988
988
        ]
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)
1030
1030
        nodes = [
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])
1054
1054
 
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'),
1080
1080
 
1081
1081
    def test_node_list_post_form_preserves_get_params(self):
1082
1082
        self.client_log_in()
1083
 
        factory.make_node()
 
1083
        factory.make_Node()
1084
1084
        params = {
1085
1085
            "dir": "desc",
1086
1086
            "query": factory.make_name("query"),
1096
1096
 
1097
1097
    def test_node_list_view_shows_third_party_drivers_warning(self):
1098
1098
        self.client_log_in()
1099
 
        factory.make_node()
 
1099
        factory.make_Node()
1100
1100
        Config.objects.set_config(
1101
1101
            name='enable_third_party_drivers', value=True)
1102
1102
        response = self.client.get(reverse('node-list'))
1108
1108
 
1109
1109
    def test_node_list_view_shows_third_party_drivers_admin_warning(self):
1110
1110
        self.client_log_in(as_admin=True)
1111
 
        factory.make_node()
 
1111
        factory.make_Node()
1112
1112
        Config.objects.set_config(
1113
1113
            name='enable_third_party_drivers', value=True)
1114
1114
        response = self.client.get(reverse('node-list'))
1121
1121
 
1122
1122
    def test_node_list_view_hides_drivers_warning_if_drivers_disabled(self):
1123
1123
        self.client_log_in()
1124
 
        factory.make_node()
 
1124
        factory.make_Node()
1125
1125
        Config.objects.set_config(
1126
1126
            name='enable_third_party_drivers', value=False)
1127
1127
        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)
1139
1139
 
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]))
1167
1167
 
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.
1172
1172
        [
1173
 
            factory.make_event(node=node)
 
1173
            factory.make_Event(node=node)
1174
1174
            for _ in range(4)
1175
1175
        ]
1176
1176
        # Create NodeView.number_of_events_shown events.
1177
1177
        events = [
1178
 
            factory.make_event(node=node)
 
1178
            factory.make_Event(node=node)
1179
1179
            for _ in range(NodeView.number_of_events_shown)
1180
1180
        ]
1181
1181
        response = self.client.get(reverse('node-view', args=[node.system_id]))
1190
1190
 
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)
1205
1205
 
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)
1218
1218
 
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)
1233
1233
 
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.
1238
1238
        [
1239
 
            factory.make_event(node=node)
 
1239
            factory.make_Event(node=node)
1240
1240
            for _ in range(4)
1241
1241
        ]
1242
1242
        response = self.client.get(
1250
1250
 
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()
1254
1254
        events = [
1255
 
            factory.make_event(node=node)
 
1255
            factory.make_Event(node=node)
1256
1256
            for _ in range(NodeView.number_of_events_shown)
1257
1257
        ]
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)]
1274
1274
 
1275
1275
        response = self.client.get(
1276
1276
            reverse('node-event-list-view', args=[node.system_id]))
1348
1348
 
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)
1359
1359
 
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))
1365
1365
 
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)
1379
1379
 
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))
1390
1390
 
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)
1400
1400
 
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)
1413
1413
 
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))
1419
1419
 
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)
1433
1433
 
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):
1508
1508
 
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)
1632
1632
 
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)
1641
1641
 
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}}")
1652
1652
 
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,
1658
1658
            )
1665
1665
 
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)
1705
1705
 
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)
1713
1713
 
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)
1720
1720
        self.assertIn(
1724
1724
 
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(
1735
1735
 
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)
1747
1747
 
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)
1760
1760
 
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)
1768
1768
 
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})
1780
1780
 
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})
1795
1795
 
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])
1800
1800
        params = {
1801
1801
            'hostname': factory.make_string(),