summaryrefslogtreecommitdiff
path: root/src/leap/common/tests/test_events.py
blob: 7286bdc4ba19fdfefe9dd8aa210784ec0d788b35 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
## -*- coding: utf-8 -*-
# test_events.py
# Copyright (C) 2013 LEAP
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import unittest
import sets
import time
from protobuf.socketrpc import RpcService
from leap.common import events
from leap.common.events import (
    server,
    component,
    mac_auth,
)
from leap.common.events.events_pb2 import (
    EventsServerService,
    EventsServerService_Stub,
    EventResponse,
    SignalRequest,
    RegisterRequest,
    SOLEDAD_CREATING_KEYS,
    CLIENT_UID,
)


port = 8090

received = False
local_callback_executed = False


def callback(request, reponse):
    return True


class EventsTestCase(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        server.EventsServerDaemon.ensure(8090)
        cls.callbacks = events.component.registered_callbacks

    @classmethod
    def tearDownClass(cls):
        # give some time for requests to be processed.
        time.sleep(1)

    def setUp(self):
        super(EventsTestCase, self).setUp()

    def tearDown(self):
        #events.component.registered_callbacks = {}
        server.registered_components = {}
        super(EventsTestCase, self).tearDown()

    def test_service_singleton(self):
        """
        Ensure that there's always just one instance of the server daemon
        running.
        """
        service1 = server.EventsServerDaemon.ensure(8090)
        service2 = server.EventsServerDaemon.ensure(8090)
        self.assertEqual(service1, service2,
                         "Can't get singleton class for service.")

    def test_component_register(self):
        """
        Ensure components can register callbacks.
        """
        self.assertTrue(1 not in self.callbacks,
                        'There should should be no callback for this signal.')
        events.register(1, lambda x: True)
        self.assertTrue(1 in self.callbacks,
                        'Could not register signal in local component.')
        events.register(2, lambda x: True)
        self.assertTrue(1 in self.callbacks,
                        'Could not register signal in local component.')
        self.assertTrue(2 in self.callbacks,
                        'Could not register signal in local component.')

    def test_register_signal_replace(self):
        """
        Make sure components can replace already registered callbacks.
        """
        sig = 3
        cbk = lambda x: True
        events.register(sig, cbk, uid=1)
        self.assertRaises(Exception, events.register, sig, lambda x: True,
                          uid=1)
        events.register(sig, lambda x: True, uid=1, replace=True)
        self.assertTrue(sig in self.callbacks, 'Could not register signal.')
        self.assertEqual(1, len(self.callbacks[sig]),
                         'Wrong number of registered callbacks.')

    def test_signal_response_status(self):
        """
        Ensure there's an appropriate response from server when signaling.
        """
        sig = 4
        request = SignalRequest()
        request.event = sig
        request.content = 'my signal contents'
        request.mac_method = mac_auth.MacMethod.MAC_NONE
        request.mac = ""
        service = RpcService(EventsServerService_Stub, port, 'localhost')
        # test synch
        response = service.signal(request, timeout=1000)
        self.assertEqual(EventResponse.OK, response.status,
                         'Wrong response status.')
        # test asynch

        def local_callback(request, response):
            global local_callback_executed
            local_callback_executed = True

        events.register(sig, local_callback)
        service.signal(request, callback=local_callback)
        time.sleep(0.1)
        self.assertTrue(local_callback_executed,
                        'Local callback did not execute.')

    def test_events_server_service_register(self):
        """
        Ensure the server can register components to be signaled.
        """
        sig = 5
        request = RegisterRequest()
        request.event = sig
        request.port = 8091
        request.mac_method = mac_auth.MacMethod.MAC_NONE
        request.mac = ""
        service = RpcService(EventsServerService_Stub, port, 'localhost')
        complist = server.registered_components
        self.assertEqual({}, complist,
                         'There should be no registered_ports when '
                         'server has just been created.')
        response = service.register(request, timeout=1000)
        self.assertTrue(sig in complist, "Signal not registered succesfully.")
        self.assertTrue(8091 in complist[sig],
                        'Failed registering component port.')

    def test_component_request_register(self):
        """
        Ensure components can register themselves with server.
        """
        sig = 6
        complist = server.registered_components
        self.assertTrue(sig not in complist,
                        'There should be no registered components for this '
                        'signal.')
        events.register(sig, lambda x: True)
        time.sleep(0.1)
        port = component.EventsComponentDaemon.get_instance().get_port()
        self.assertTrue(sig in complist, 'Failed registering component.')
        self.assertTrue(port in complist[sig],
                        'Failed registering component port.')

    def test_component_receives_signal(self):
        """
        Ensure components can receive signals.
        """
        sig = 7

        def getsig(param=None):
            global received
            received = True

        events.register(sig, getsig)
        request = SignalRequest()
        request.event = sig
        request.content = ""
        request.mac_method = mac_auth.MacMethod.MAC_NONE
        request.mac = ""
        service = RpcService(EventsServerService_Stub, port, 'localhost')
        response = service.signal(request, timeout=1000)
        self.assertTrue(response is not None, 'Did not receive response.')
        time.sleep(0.5)
        self.assertTrue(received, 'Did not receive signal back.')

    def test_component_send_signal(self):
        """
        Ensure components can send signals.
        """
        sig = 8
        response = events.signal(sig)
        self.assertTrue(response.status == response.OK,
                        'Received wrong response status when signaling.')

    def test_component_unregister_all(self):
        """
        Test that the component can unregister all events for one signal.
        """
        sig = CLIENT_UID
        complist = server.registered_components
        events.register(sig, lambda x: True)
        events.register(sig, lambda x: True)
        time.sleep(0.1)
        events.unregister(sig)
        time.sleep(0.1)
        port = component.EventsComponentDaemon.get_instance().get_port()
        self.assertFalse(bool(complist[sig]))
        self.assertTrue(port not in complist[sig])

    def test_component_unregister_by_uid(self):
        """
        Test that the component can unregister an event by uid.
        """
        sig = CLIENT_UID
        complist = server.registered_components
        events.register(sig, lambda x: True, uid='cbkuid')
        events.register(sig, lambda x: True, uid='cbkuid2')
        time.sleep(0.1)
        events.unregister(sig, uid='cbkuid')
        time.sleep(0.1)
        port = component.EventsComponentDaemon.get_instance().get_port()
        self.assertTrue(sig in complist)
        self.assertTrue(len(complist[sig]) == 1)
        self.assertTrue(
            component.registered_callbacks[sig].pop()[0] == 'cbkuid2')
        self.assertTrue(port in complist[sig])