~lutostag/ubuntu/trusty/maas/1.5.2+packagefix

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2014-03-28 10:43:53 UTC
  • mto: This revision was merged to the branch mainline in revision 57.
  • Revision ID: package-import@ubuntu.com-20140328104353-ekpolg0pm5xnvq2s
Tags: upstream-1.5+bzr2204
ImportĀ upstreamĀ versionĀ 1.5+bzr2204

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
from lxml.html import fromstring
31
31
import maasserver.api
32
32
from maasserver.enum import (
33
 
    ARCHITECTURE_CHOICES,
34
 
    NODE_AFTER_COMMISSIONING_ACTION,
35
33
    NODE_STATUS,
36
34
    NODEGROUP_STATUS,
37
35
    NODEGROUPINTERFACE_MANAGEMENT,
57
55
    reload_object,
58
56
    reload_objects,
59
57
    )
 
58
from maasserver.testing.architecture import make_usable_architecture
60
59
from maasserver.testing.factory import factory
61
60
from maasserver.testing.testcase import (
62
61
    MAASServerTestCase,
63
62
    SeleniumTestCase,
64
63
    )
65
64
from maasserver.utils import map_enum
 
65
from maasserver.utils.orm import get_one
66
66
from maasserver.views import nodes as nodes_views
67
67
from maasserver.views.nodes import message_from_form_stats
68
68
from maastesting.djangotestcase import count_queries
70
70
from testtools.matchers import ContainsAll
71
71
 
72
72
 
 
73
class TestGenerateJSPowerTypes(MAASServerTestCase):
 
74
    def patch_power_types(self, enum):
 
75
        """Make `get_power_types` return the given `enum` dict."""
 
76
        self.patch(nodes_views, 'get_power_types').return_value = enum
 
77
 
 
78
    def test_lists_power_types_as_JS_array(self):
 
79
        power_type = factory.make_name('power')
 
80
        self.patch_power_types({power_type: power_type})
 
81
        self.assertEqual(
 
82
            '[\n"%s"\n]' % power_type,
 
83
            nodes_views.generate_js_power_types())
 
84
 
 
85
    def test_uses_power_type_names_not_descriptions(self):
 
86
        name = factory.make_name('name')
 
87
        description = factory.make_name('description')
 
88
        self.patch_power_types({name: description})
 
89
        output = nodes_views.generate_js_power_types()
 
90
        self.assertIn(name, output)
 
91
        self.assertNotIn(description, output)
 
92
 
 
93
    def test_works_with_real_get_power_types(self):
 
94
        self.assertIn('ipmi', nodes_views.generate_js_power_types())
 
95
 
 
96
    def test_uses_comma_as_item_separator_not_as_terminator(self):
 
97
        self.patch(nodes_views, 'get_power_types').return_value = {
 
98
            'a': factory.make_name('a'),
 
99
            'b': factory.make_name('b'),
 
100
            }
 
101
        self.assertEqual(
 
102
            ['[', '"a",', '"b"', ']'],
 
103
            nodes_views.generate_js_power_types().strip().split())
 
104
 
 
105
    def test_sorts_entries(self):
 
106
        power_types = {
 
107
            factory.make_name('power'): factory.make_name('desc')
 
108
            for _ in range(3)
 
109
            }
 
110
        self.patch_power_types(power_types)
 
111
        output = nodes_views.generate_js_power_types()
 
112
        self.assertEqual(
 
113
            sorted(power_types.keys()),
 
114
            [
 
115
                item.rstrip(',').strip('"\'')
 
116
                for item in output.strip('[]').strip().split()
 
117
            ])
 
118
 
 
119
 
73
120
class NodeViewsTest(MAASServerTestCase):
74
121
 
75
122
    def set_up_oauth_token(self):
190
237
 
191
238
    def test_node_list_sorts_by_zone(self):
192
239
        self.client_log_in()
193
 
        zones = [factory.make_zone() for _ in range(5)]
 
240
        zones = [factory.make_zone(sortable_name=True) for _ in range(5)]
194
241
        nodes = [factory.make_node(zone=zone) for zone in zones]
195
242
 
196
243
        # We use PostgreSQL's case-insensitive text sorting algorithm.
475
522
            [reverse('zone-view', args=[node.zone.name])],
476
523
            get_content_links(response, '#zone'))
477
524
 
 
525
    def test_view_node_shows_macs(self):
 
526
        self.client_log_in()
 
527
        mac = factory.make_mac_address()
 
528
 
 
529
        response = self.client.get(
 
530
            reverse('node-view', args=[mac.node.system_id]))
 
531
        self.assertEqual(httplib.OK, response.status_code)
 
532
 
 
533
        [interfaces_section] = fromstring(response.content).cssselect(
 
534
            '#network-interfaces')
 
535
        [listing] = get_one(interfaces_section.cssselect('span'))
 
536
        self.assertEqual(mac.mac_address, listing.text_content().strip())
 
537
 
 
538
    def test_view_node_lists_macs_as_list_items(self):
 
539
        self.client_log_in()
 
540
        node = factory.make_node()
 
541
        factory.make_mac_address('11:11:11:11:11:11', node=node)
 
542
        factory.make_mac_address('22:22:22:22:22:22', node=node)
 
543
 
 
544
        response = self.client.get(reverse('node-view', args=[node.system_id]))
 
545
        self.assertEqual(httplib.OK, response.status_code)
 
546
 
 
547
        [interfaces_section] = fromstring(response.content).cssselect(
 
548
            '#network-interfaces')
 
549
        [interfaces_list] = interfaces_section.cssselect('ul')
 
550
        interfaces = interfaces_list.cssselect('li')
 
551
        self.assertEqual(
 
552
            ['11:11:11:11:11:11', '22:22:22:22:22:22'],
 
553
            [interface.text_content().strip() for interface in interfaces])
 
554
 
 
555
    def test_view_node_links_network_interfaces_to_networks(self):
 
556
        self.client_log_in()
 
557
        network = factory.make_network()
 
558
        mac = factory.make_mac_address(networks=[network])
 
559
 
 
560
        response = self.client.get(
 
561
            reverse('node-view', args=[mac.node.system_id]))
 
562
        self.assertEqual(httplib.OK, response.status_code)
 
563
 
 
564
        [interfaces_section] = fromstring(response.content).cssselect(
 
565
            '#network-interfaces')
 
566
        [interfaces_list] = interfaces_section.cssselect('ul')
 
567
        [interface] = interfaces_list.cssselect('li')
 
568
        self.assertEqual(
 
569
            "%s (on %s)" % (mac.mac_address, network.name),
 
570
            ' '.join(interface.text_content().split()))
 
571
        [link] = interface.cssselect('a')
 
572
        self.assertEqual(network.name, link.text_content().strip())
 
573
        self.assertEqual(
 
574
            reverse('network-view', args=[network.name]),
 
575
            link.get('href'))
 
576
 
 
577
    def test_view_node_sorts_networks_by_name(self):
 
578
        self.client_log_in()
 
579
        networks = factory.make_networks(3, sortable_name=True)
 
580
        mac = factory.make_mac_address(networks=networks)
 
581
 
 
582
        response = self.client.get(
 
583
            reverse('node-view', args=[mac.node.system_id]))
 
584
        self.assertEqual(httplib.OK, response.status_code)
 
585
 
 
586
        sorted_names = sorted(network.name for network in networks)
 
587
        [interfaces_section] = fromstring(response.content).cssselect(
 
588
            '#network-interfaces')
 
589
        [interfaces_list] = interfaces_section.cssselect('ul')
 
590
        [interface] = interfaces_list.cssselect('li')
 
591
        self.assertEqual(
 
592
            "%s (on %s)" % (mac.mac_address, ', '.join(sorted_names)),
 
593
            ' '.join(interface.text_content().split()))
 
594
 
478
595
    def test_view_node_displays_link_to_edit_if_user_owns_node(self):
479
596
        self.client_log_in()
480
597
        node = factory.make_node(owner=self.logged_in_user)
586
703
        node_edit_link = reverse('node-edit', args=[node.system_id])
587
704
        params = {
588
705
            'hostname': factory.getRandomString(),
589
 
            'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
590
 
            'after_commissioning_action': factory.getRandomEnum(
591
 
                NODE_AFTER_COMMISSIONING_ACTION),
 
706
            'architecture': make_usable_architecture(self),
592
707
        }
593
708
        response = self.client.post(node_edit_link, params)
594
709
 
1305
1420
        mac_delete_link = reverse('mac-delete', args=[node.system_id, mac])
1306
1421
        response = self.client.get(mac_delete_link)
1307
1422
        self.assertIn(
1308
 
            'Are you sure you want to delete the MAC address "%s"' %
 
1423
            'Are you sure you want to delete network interface "%s"' %
1309
1424
            mac.mac_address,
1310
1425
            response.content)
1311
1426
 
1332
1447
            ["Mac address %s deleted." % mac.mac_address],
1333
1448
            [message.message for message in response.context['messages']])
1334
1449
 
 
1450
    def test_node_delete_mac_POST_disconnects_MAC_from_network(self):
 
1451
        self.client_log_in()
 
1452
        network = factory.make_network()
 
1453
        node = factory.make_node(owner=self.logged_in_user)
 
1454
        mac = factory.make_mac_address(node=node, networks=[network])
 
1455
        response = self.client.post(
 
1456
            reverse('mac-delete', args=[node.system_id, mac]), {'post': 'yes'})
 
1457
        self.assertEqual(httplib.FOUND, response.status_code)
 
1458
        self.assertIsNotNone(reload_object(network))
 
1459
 
1335
1460
 
1336
1461
class NodeAddMacTest(MAASServerTestCase):
1337
1462
 
1376
1501
        node_edit_link = reverse('node-edit', args=[node.system_id])
1377
1502
        params = {
1378
1503
            'hostname': factory.getRandomString(),
1379
 
            'after_commissioning_action': factory.getRandomEnum(
1380
 
                NODE_AFTER_COMMISSIONING_ACTION),
1381
1504
            'power_type': factory.getRandomPowerType(),
1382
 
            'architecture': factory.getRandomChoice(ARCHITECTURE_CHOICES),
 
1505
            'architecture': make_usable_architecture(self),
1383
1506
        }
1384
1507
        response = self.client.post(node_edit_link, params)
1385
1508