~allenap/maas/human-readable-bytes-alt

« back to all changes in this revision

Viewing changes to src/maasserver/clusterrpc/tests/test_power.py

  • Committer: MAAS Lander
  • Author(s): Blake Rouse, Andres Rodriguez
  • Date: 2016-03-12 05:12:30 UTC
  • mfrom: (4774.1.1 maas)
  • Revision ID: maas_lander-20160312051230-zqj4r6oz5d8b5mtz
[r=andreserl][bug=][author=andreserl] Allow BMC to be on a network where a rack controller does not have direct access.

When a node is to be powered on or off and no direct rack controllers can be identified the region will ask all connected rack controllers to figure out which rack controllers can access that BMC by performing a power query. A many to many relationship between the rack controllers and BMC is updated to mark which rack controllers are routeable and which are not.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
__all__ = []
7
7
 
 
8
from crochet import wait_for
 
9
from maasserver.clusterrpc import power as power_module
8
10
from maasserver.clusterrpc.power import (
 
11
    pick_best_power_state,
9
12
    power_driver_check,
10
13
    power_off_node,
11
14
    power_on_node,
 
15
    power_query_all,
12
16
)
 
17
from maasserver.enum import POWER_STATE
13
18
from maasserver.testing.factory import factory
14
 
from maasserver.testing.testcase import MAASServerTestCase
 
19
from maasserver.testing.testcase import (
 
20
    MAASServerTestCase,
 
21
    MAASTransactionServerTestCase,
 
22
)
 
23
from maasserver.utils.orm import transactional
 
24
from maasserver.utils.threads import deferToDatabase
15
25
from maastesting.matchers import MockCalledOnceWith
16
26
from mock import Mock
17
27
from provisioningserver.rpc.cluster import (
20
30
    PowerOn,
21
31
)
22
32
from provisioningserver.utils.twisted import reactor_sync
 
33
from twisted.internet import reactor
 
34
from twisted.internet.defer import (
 
35
    fail,
 
36
    inlineCallbacks,
 
37
    succeed,
 
38
)
 
39
from twisted.internet.task import deferLater
 
40
 
 
41
 
 
42
wait_for_reactor = wait_for(30)  # 30 seconds.
23
43
 
24
44
 
25
45
class TestPowerNode(MAASServerTestCase):
70
90
            MockCalledOnceWith(
71
91
                PowerDriverCheck, power_type=power_info.power_type
72
92
            ))
 
93
 
 
94
 
 
95
class TestPowerQueryAll(MAASTransactionServerTestCase):
 
96
    """Tests for `power_query_all`."""
 
97
 
 
98
    @transactional
 
99
    def make_node_with_power_info(self):
 
100
        node = factory.make_Node()
 
101
        power_info = node.get_effective_power_info()
 
102
        return node, power_info
 
103
 
 
104
    @wait_for_reactor
 
105
    @inlineCallbacks
 
106
    def test__calls_PowerQuery_on_all_clients(self):
 
107
        node, power_info = yield deferToDatabase(
 
108
            self.make_node_with_power_info)
 
109
 
 
110
        successful_rack_ids = [
 
111
            factory.make_name("system_id")
 
112
            for _ in range(3)
 
113
        ]
 
114
        failed_rack_ids = [
 
115
            factory.make_name("system_id")
 
116
            for _ in range(3)
 
117
        ]
 
118
        clients = []
 
119
        power_states = []
 
120
        for rack_id in successful_rack_ids:
 
121
            power_state = factory.pick_enum(POWER_STATE)
 
122
            power_states.append(power_state)
 
123
            client = Mock()
 
124
            client.ident = rack_id
 
125
            client.return_value = succeed({
 
126
                "state": power_state,
 
127
            })
 
128
            clients.append(client)
 
129
        for rack_id in failed_rack_ids:
 
130
            client = Mock()
 
131
            client.ident = rack_id
 
132
            client.return_value = fail(factory.make_exception())
 
133
            clients.append(client)
 
134
 
 
135
        self.patch(power_module, "getAllClients").return_value = clients
 
136
        power_state, success_racks, failed_racks = yield power_query_all(
 
137
            node.system_id, node.hostname, power_info)
 
138
 
 
139
        self.assertEqual(pick_best_power_state(power_states), power_state)
 
140
        self.assertItemsEqual(successful_rack_ids, success_racks)
 
141
        self.assertItemsEqual(failed_rack_ids, failed_racks)
 
142
 
 
143
    @wait_for_reactor
 
144
    @inlineCallbacks
 
145
    def test__handles_timeout(self):
 
146
        node, power_info = yield deferToDatabase(
 
147
            self.make_node_with_power_info)
 
148
 
 
149
        def defer_way_later(*args, **kwargs):
 
150
            # Create a defer that will finish in 1 minute.
 
151
            return deferLater(reactor, 60 * 60, lambda: None)
 
152
 
 
153
        rack_id = factory.make_name("system_id")
 
154
        client = Mock()
 
155
        client.ident = rack_id
 
156
        client.side_effect = defer_way_later
 
157
 
 
158
        self.patch(power_module, "getAllClients").return_value = [client]
 
159
        power_state, success_racks, failed_racks = yield power_query_all(
 
160
            node.system_id, node.hostname, power_info, timeout=0.5)
 
161
 
 
162
        self.assertEqual(POWER_STATE.UNKNOWN, power_state)
 
163
        self.assertItemsEqual([], success_racks)
 
164
        self.assertItemsEqual([rack_id], failed_racks)