Test Failed
Pull Request — master (#62)
by Gleyberson
15:47 queued 01:03
created

build.tests.test_main.TestMain.setUp()   A

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nop 1
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
"""Test main."""
2
3
from unittest import TestCase
4
from unittest.mock import Mock
5
6
from pyof.utils import unpack
7
from pyof.v0x01.controller2switch.features_reply import \
8
    FeaturesReply as FReply_v0x01
9
from pyof.v0x01.controller2switch.stats_reply import StatsReply
10
from pyof.v0x04.controller2switch.features_reply import \
11
    FeaturesReply as FReply_v0x04
12
from pyof.v0x04.controller2switch.features_request import FeaturesRequest
13
from pyof.v0x04.controller2switch.multipart_reply import MultipartReply
14
from pyof.v0x04.symmetric.echo_request import EchoRequest
15
16
from kytos.core import Controller
17
from kytos.core.config import KytosConfig
18
from kytos.core.connection import Connection, ConnectionState
19
from kytos.core.events import KytosEvent
20
from kytos.core.interface import Interface
21
from kytos.core.switch import Switch
22
from napps.kytos.of_core.main import Main
23
24
25
class TestMain(TestCase):
26
    """docstring for TestMain."""
27
28
    def setUp(self):
29
        """Execute steps before each tests.
30
31
        Set the server_name_url from kytos/of_core
32
        """
33
        self.server_name_url = 'http://localhost:8181/api/kytos/of_core'
34
        self.controller = self._get_controller_mock()
35
        self.napp = Main(self.controller)
36
        self.patched_events = []
37
38
    @staticmethod
39
    def _get_controller_mock():
40
        """Return a controller mock."""
41
        options = KytosConfig().options['daemon']
42
        controller = Controller(options)
43
        controller.log = Mock()
44
        return controller
45
46
    @staticmethod
47
    def _get_switch_mock(of_version, connection_state=ConnectionState.NEW,
48
                         dpid="00:00:00:00:00:00:00:01"):
49
        """Return a switch mock."""
50
        switch = Switch(dpid)
51
        address = Mock()
52
        port = Mock()
53
        socket = Mock()
54
        switch.connection = Connection(address, port, socket)
55
        switch.connection.protocol.unpack = unpack
56
        switch.connection.protocol.version = of_version
57
        switch.connection.state = connection_state
58
        return switch
59
60
    def _get_interface(self, interface_name, port, *args, **kwargs):
61
        """Return a interface mock."""
62
        switch1 = self._get_switch_mock(0x04)
63
        switch1.connection = Mock()
64
        iface1 = Interface(interface_name, port, switch1, *args, **kwargs)
65
        return iface1
66
67
    def test_get_event_listeners(self):
68
        """Verify all event listeners registered."""
69
        expected_events = [
70
            'kytos/of_core.v0x01.messages.in.ofpt_stats_reply',
71
            'kytos/of_core.v0x0[14].messages.in.ofpt_features_reply',
72
            'kytos/of_core.v0x04.messages.in.ofpt_multipart_reply',
73
            'kytos/core.openflow.raw.in',
74
            'kytos/of_core.v0x0[14].messages.in.ofpt_echo_request',
75
            'kytos/of_core.v0x0[14].messages.out.ofpt_echo_reply',
76
            'kytos/of_core.v0x[0-9a-f]{2}.messages.in.hello_failed',
77
            'kytos/of_core.v0x0[14].messages.out.hello_failed',
78
        ]
79
80
        actual_events = self.napp.listeners()
81
        for _event in expected_events:
82
            self.assertIn(_event, actual_events, '%s' % _event)
83
84
    def test_execute(self):
85
        """Test 'execute' main method."""
86
        dpid_01 = "00:00:00:00:00:00:00:01"
87
        sw_01 = self._get_switch_mock(0x01, ConnectionState.ESTABLISHED,
88
                                      dpid_01)
89
        self.napp.controller.get_switch_or_create(dpid_01, sw_01.connection)
90
        dpid_02 = "00:00:00:00:00:00:00:02"
91
        sw_04 = self._get_switch_mock(0x04, ConnectionState.ESTABLISHED,
92
                                      dpid_02)
93
        self.napp.controller.get_switch_or_create(dpid_02, sw_04.connection)
94
        self.napp.execute()
95
96
    def test_handle_stats_reply(self):
97
        """Test handling stats reply message."""
98
        event_name = 'kytos/of_core.v0x01.messages.in.ofpt_stats_reply'
99
        switch = self._get_switch_mock(0x01)
100
        switch.connection = Mock()
101
102
        stats_data = b'\x01\x11\x00\x0c\x00\x00\x00\x01\x00\x01\x00\x01'
103
        stats_reply = StatsReply()
104
        stats_reply.unpack(stats_data[8:])
105
        stats_event = KytosEvent(name=event_name,
106
                                 content={'source': switch.connection,
107
                                          'message': stats_reply})
108
        self.napp.handle_stats_reply(stats_event)
109
110
        desc_stats_data = b'\x01\x11\x00\x0c\x00\x00\x00\x0e\x00\x00\x00\x00'
111
        desc_stats_reply = StatsReply()
112
        desc_stats_reply.unpack(desc_stats_data[8:])
113
        desc_stats_event = KytosEvent(name=event_name,
114
                                      content={'source': switch.connection,
115
                                               'message': desc_stats_reply})
116
        self.napp.handle_stats_reply(desc_stats_event)
117
118
    def test_handle_04_features_reply(self):
119
        """Test handling features reply message."""
120
        event_name = 'kytos/of_core.v0x04.messages.in.ofpt_features_reply'
121
        switch = self._get_switch_mock(0x04, ConnectionState.SETUP)
122
        switch.connection.protocol.state = 'waiting_features_reply'
123
124
        data = b'\x04\x06\x00\x20\x00\x00\x00\x00\x00\x00\x08\x60\x6e\x7f\x74'
125
        data += b'\xe7\x00\x00\x00\x00\xff\x63\x00\x00\x00\x00\x00\x4f\x00\x00'
126
        data += b'\x00\x00'
127
128
        features_reply = FReply_v0x04()
129
        features_reply.unpack(data)
130
131
        event = KytosEvent(name=event_name,
132
                           content={'source': switch.connection,
133
                                    'message': features_reply})
134
        self.napp.handle_features_reply(event)
135
136
    def test_handle_01_features_reply(self):
137
        """Test handling features reply message."""
138
        event_name = 'kytos/of_core.v0x01.messages.in.ofpt_features_reply'
139
        switch = self._get_switch_mock(0x01, ConnectionState.SETUP)
140
        switch.connection.protocol.state = 'waiting_features_reply'
141
142
        data = b'\x01\x06\x00\x80\x00\x00\x00\x00\x00\x00\x00\xff\x12\x34\x56'
143
        data += b'\x78\x00\x00\x00\x00\xff\x00\x00\x00\x00\x00\x00\xa9\x00\x00'
144
        data += b'\x08\x43\x00\x07\xf2\x0b\xa4\xd0\x3f\x70\x50\x6f\x72\x74\x37'
145
        data += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
146
        data += b'\x00\x00\x00\x10\x00\x00\x02\x88\x00\x00\x02\x80\x00\x00\x02'
147
        data += b'\x88\x00\x00\x02\x88\x00\x06\xf2\x0b\xa4\x7d\xf8\xea\x50\x6f'
148
        data += b'\x72\x74\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
149
        data += b'\x00\x00\x00\x00\x00\x00\x02\x00\x00\x02\x88\x00\x00\x02\x80'
150
        data += b'\x00\x00\x02\x88\x00\x00\x02\x88'
151
152
        features_reply = FReply_v0x01()
153
        features_reply.unpack(data[8:])
154
155
        event = KytosEvent(name=event_name,
156
                           content={'source': switch.connection,
157
                                    'message': features_reply})
158
        self.napp.handle_features_reply(event)
159
160
    def test_handle_features_request_sent(self):
161
        """Test handling features request sent message."""
162
        event_name = 'kytos/of_core.v0x01.messages.out.ofpt_features_request'
163
        switch = self._get_switch_mock(0x01)
164
        switch.connection.protocol.state = 'sending_features'
165
166
        data = b'\x04\x05\x00\x08\x00\x00\x00\x03'
167
        features_request = FeaturesRequest()
168
        features_request.unpack(data)
169
170
        event = KytosEvent(name=event_name,
171
                           content={'destination': switch.connection,
172
                                    'message': features_request})
173
        self.napp.handle_features_request_sent(event)
174
175
    def test_handle_echo_request(self):
176
        """Test handling echo request message."""
177
        event_name = 'kytos/of_core.v0x04.messages.in.ofpt_echo_request'
178
        switch = self._get_switch_mock(0x04)
179
180
        data = b'\x04\x02\x00\x0c\x00\x00\x00\x00\x68\x6f\x67\x65'
181
        echo_request = EchoRequest()
182
        echo_request.unpack(data)
183
184
        event = KytosEvent(name=event_name,
185
                           content={'source': switch.connection,
186
                                    'message': echo_request})
187
        self.napp.handle_echo_request(event)
188
189
    def test_handle_hello_raw_in(self):
190
        """Test handling hello raw in message."""
191
        event_name = 'kytos/core.openflow.raw.in'
192
        switch = self._get_switch_mock(0x04)
193
194
        data = b'\x04\x00\x00\x10\x00\x00\x00\x3e'
195
        data += b'\x00\x01\x00\x08\x00\x00\x00\x10'
196
197
        event = KytosEvent(name=event_name,
198
                           content={'source': switch.connection,
199
                                    'new_data': data})
200
        self.napp.handle_raw_in(event)
201
202
    def test_handle_port_status_raw_in(self):
203
        """Test handling port_status raw in message."""
204
        event_name = 'kytos/core.openflow.raw.in'
205
        switch = self._get_switch_mock(0x04, ConnectionState.ESTABLISHED)
206
        switch.connection.switch = self._get_switch_mock(0x04)
207
208
        data = b'\x04\x0c\x00\x50\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00'
209
        data += b'\x00\x00\x00\x00\x01\x00\x00\x00\x00\x62\x43\xe5\xdb\x35\x0a'
210
        data += b'\x00\x00\x73\x31\x2d\x65\x74\x68\x31\x00\x00\x00\x00\x00\x00'
211
        data += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x08\x40'
212
        data += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x96'
213
        data += b'\x80\x00\x00\x00\x00'
214
215
        event = KytosEvent(name=event_name,
216
                           content={'source': switch.connection,
217
                                    'new_data': data})
218
        self.napp.handle_raw_in(event)
219
220
    def test_handle_packet_in_raw_in(self):
221
        """Test handling packet_in raw in message."""
222
        event_name = 'kytos/core.openflow.raw.in'
223
        switch = self._get_switch_mock(0x04, ConnectionState.ESTABLISHED)
224
        switch.connection.switch = self._get_switch_mock(0x04)
225
226
        data = b'\x04\x0a\x00\x94\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x01'
227
        data += b'\x01\x00\x01\x02\x03\x00\x00\x00\x00\x00\x01\x00\x50\x80\x00'
228
        data += b'\x00\x04\x00\x00\x00\x06\x80\x00\x0a\x02\x08\x06\x80\x00\x06'
229
        data += b'\x06\xff\xff\xff\xff\xff\xff\x80\x00\x08\x06\xf2\x0b\xa4\x7d'
230
        data += b'\xf8\xea\x80\x00\x2a\x02\x00\x01\x80\x00\x2c\x04\x0a\x00\x00'
231
        data += b'\x01\x80\x00\x2e\x04\x0a\x00\x00\x03\x80\x00\x30\x06\xf2\x0b'
232
        data += b'\xa4\x7d\xf8\xea\x80\x00\x32\x06\x00\x00\x00\x00\x00\x00\x00'
233
        data += b'\x00\xff\xff\xff\xff\xff\xff\xf2\x0b\xa4\x7d\xf8\xea\x08\x06'
234
        data += b'\x00\x01\x08\x00\x06\x04\x00\x01\xf2\x0b\xa4\x7d\xf8\xea\x0a'
235
        data += b'\x00\x00\x01\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x03'
236
237
        event = KytosEvent(name=event_name,
238
                           content={'source': switch.connection,
239
                                    'new_data': data})
240
        self.napp.handle_raw_in(event)
241
242
    def test_handle_multipart_reply(self):
243
        """Test handling ofpt_multipart_reply."""
244
        event_name = 'kytos/of_core.v0x04.messages.in.ofpt_multipart_reply'
245
        switch = self._get_switch_mock(0x04, dpid='00:00:00:00:00:00:00:02')
246
        switch.connection.switch = self._get_switch_mock(0x04)
247
        self.napp.controller.get_switch_or_create(switch.dpid,
248
                                                  switch.connection)
249
250
        data = b'\x04\x13\x00\x68\xac\xc8\xdf\x58\x00\x01\x00\x00\x00\x00\x00'
251
        data += b'\x00\x00\x58\x00\x00\x00\x00\x00\x38\x25\xd9\x54\xc0\x03\xe8'
252
        data += b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'
253
        data += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00'
254
        data += b'\x00\x00\x02\xf4\x00\x01\x00\x10\x80\x00\x0a\x02\x88\xcc\x80'
255
        data += b'\x00\x0c\x02\x1e\xd7\x00\x04\x00\x18\x00\x00\x00\x00\x00\x00'
256
        data += b'\x00\x10\xff\xff\xff\xfd\xff\xff\x00\x00\x00\x00\x00\x00'
257
258
        # pylint: disable=protected-access
259
        xid = self.napp._multipart_replies_xids[switch.dpid]
260
        # pylint: enable=protected-access
261
        multipart_reply = MultipartReply(xid=xid)
262
        multipart_reply.unpack(data[8:])
263
        stats_event = KytosEvent(name=event_name,
264
                                 content={'source': switch.connection,
265
                                          'message': multipart_reply})
266
267
        self.napp.handle_multipart_reply(stats_event)
268
269
        # test ofpmp_desc
270
        data = b'\x04\x12\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
271
        data += b'\x00'
272
        multipart_desc = MultipartReply()
273
        multipart_desc.unpack(data[8:])
274
        stats_desc_event = KytosEvent(name=event_name,
275
                                      content={'source': switch.connection,
276
                                               'message': multipart_desc})
277
278
        self.napp.handle_multipart_reply(stats_desc_event)
279
280
    def test_handle_port_desc_multipart_reply(self):
281
        """Test handling to ofpt_PORT_DESC."""
282
283
        event_name = 'kytos/of_core.v0x04.messages.in.ofpt_multipart_reply'
284
        switch = self._get_switch_mock(0x04)
285
        switch.connection.switch = self._get_switch_mock(0x04)
286
        data = b'\x04\x13\x00\x90\x00\x00\x00\x00\x00\x0d\x00\x00\x00\x00\x00'
287
        data += b'\x00\x00\x00\x00\x07\x00\x00\x00\x00\xf2\x0b\xa4\xd0\x3f\x70'
288
        data += b'\x00\x00\x50\x6f\x72\x74\x37\x00\x00\x00\x00\x00\x00\x00\x00'
289
        data += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x28\x08'
290
        data += b'\x00\x00\x28\x00\x00\x00\x28\x08\x00\x00\x28\x08\x00\x00\x13'
291
        data += b'\x88\x00\x00\x13\x88\x00\x00\x00\x06\x00\x00\x00\x00\xf2\x0b'
292
        data += b'\xa4\x7d\xf8\xea\x00\x00\x50\x6f\x72\x74\x36\x00\x00\x00\x00'
293
        data += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04'
294
        data += b'\x00\x00\x28\x08\x00\x00\x28\x00\x00\x00\x28\x08\x00\x00\x28'
295
        data += b'\x08\x00\x00\x13\x88\x00\x00\x13\x88'
296
297
        port_desc = MultipartReply()
298
        port_desc.unpack(data[8:])
299
        interface_1 = self._get_interface("interface1", 6)
300
        interface_2 = self._get_interface("interface2", 7)
301
        switch.connection.switch.interfaces = {6: interface_1, 7: interface_2}
302
303
        stats_event = KytosEvent(name=event_name,
304
                                 content={'source': switch.connection,
305
                                          'message': port_desc})
306
        self.napp.handle_multipart_reply(stats_event)
307
308
        # Send port_desc pack without interface
309
        switch = self._get_switch_mock(0x04)
310
        switch.connection.switch = self._get_switch_mock(0x04)
311
        stats_event = KytosEvent(name=event_name,
312
                                 content={'source': switch.connection,
313
                                          'message': port_desc})
314
315
        self.napp.handle_multipart_reply(stats_event)
316