xref: /OK3568_Linux_fs/yocto/poky/bitbake/lib/bb/tests/event.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# BitBake Tests for the Event implementation (event.py)
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Copyright (C) 2017 Intel Corporation
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0-only
7*4882a593Smuzhiyun#
8*4882a593Smuzhiyun
9*4882a593Smuzhiyunimport collections
10*4882a593Smuzhiyunimport importlib
11*4882a593Smuzhiyunimport logging
12*4882a593Smuzhiyunimport pickle
13*4882a593Smuzhiyunimport threading
14*4882a593Smuzhiyunimport time
15*4882a593Smuzhiyunimport unittest
16*4882a593Smuzhiyunfrom unittest.mock import Mock
17*4882a593Smuzhiyunfrom unittest.mock import call
18*4882a593Smuzhiyun
19*4882a593Smuzhiyunimport bb
20*4882a593Smuzhiyunimport bb.event
21*4882a593Smuzhiyunfrom bb.msg import BBLogFormatter
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun
24*4882a593Smuzhiyunclass EventQueueStubBase(object):
25*4882a593Smuzhiyun    """ Base class for EventQueueStub classes """
26*4882a593Smuzhiyun    def __init__(self):
27*4882a593Smuzhiyun        self.event_calls = []
28*4882a593Smuzhiyun        return
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun    def _store_event_data_string(self, event):
31*4882a593Smuzhiyun        if isinstance(event, logging.LogRecord):
32*4882a593Smuzhiyun            formatter = BBLogFormatter("%(levelname)s: %(message)s")
33*4882a593Smuzhiyun            self.event_calls.append(formatter.format(event))
34*4882a593Smuzhiyun        else:
35*4882a593Smuzhiyun            self.event_calls.append(bb.event.getName(event))
36*4882a593Smuzhiyun        return
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun
39*4882a593Smuzhiyunclass EventQueueStub(EventQueueStubBase):
40*4882a593Smuzhiyun    """ Class used as specification for UI event handler queue stub objects """
41*4882a593Smuzhiyun    def __init__(self):
42*4882a593Smuzhiyun        super(EventQueueStub, self).__init__()
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun    def send(self, event):
45*4882a593Smuzhiyun        super(EventQueueStub, self)._store_event_data_string(event)
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun
48*4882a593Smuzhiyunclass PickleEventQueueStub(EventQueueStubBase):
49*4882a593Smuzhiyun    """ Class used as specification for UI event handler queue stub objects
50*4882a593Smuzhiyun        with sendpickle method """
51*4882a593Smuzhiyun    def __init__(self):
52*4882a593Smuzhiyun        super(PickleEventQueueStub, self).__init__()
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun    def sendpickle(self, pickled_event):
55*4882a593Smuzhiyun        event = pickle.loads(pickled_event)
56*4882a593Smuzhiyun        super(PickleEventQueueStub, self)._store_event_data_string(event)
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun
59*4882a593Smuzhiyunclass UIClientStub(object):
60*4882a593Smuzhiyun    """ Class used as specification for UI event handler stub objects """
61*4882a593Smuzhiyun    def __init__(self):
62*4882a593Smuzhiyun        self.event = None
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun
65*4882a593Smuzhiyunclass EventHandlingTest(unittest.TestCase):
66*4882a593Smuzhiyun    """ Event handling test class """
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun    def setUp(self):
70*4882a593Smuzhiyun        self._test_process = Mock()
71*4882a593Smuzhiyun        ui_client1 = UIClientStub()
72*4882a593Smuzhiyun        ui_client2 = UIClientStub()
73*4882a593Smuzhiyun        self._test_ui1 = Mock(wraps=ui_client1)
74*4882a593Smuzhiyun        self._test_ui2 = Mock(wraps=ui_client2)
75*4882a593Smuzhiyun        importlib.reload(bb.event)
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun    def _create_test_handlers(self):
78*4882a593Smuzhiyun        """ Method used to create a test handler ordered dictionary """
79*4882a593Smuzhiyun        test_handlers = collections.OrderedDict()
80*4882a593Smuzhiyun        test_handlers["handler1"] = self._test_process.handler1
81*4882a593Smuzhiyun        test_handlers["handler2"] = self._test_process.handler2
82*4882a593Smuzhiyun        return test_handlers
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun    def test_class_handlers(self):
85*4882a593Smuzhiyun        """ Test set_class_handlers and get_class_handlers methods """
86*4882a593Smuzhiyun        test_handlers = self._create_test_handlers()
87*4882a593Smuzhiyun        bb.event.set_class_handlers(test_handlers)
88*4882a593Smuzhiyun        self.assertEqual(test_handlers,
89*4882a593Smuzhiyun                         bb.event.get_class_handlers())
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun    def test_handlers(self):
92*4882a593Smuzhiyun        """ Test set_handlers and get_handlers """
93*4882a593Smuzhiyun        test_handlers = self._create_test_handlers()
94*4882a593Smuzhiyun        bb.event.set_handlers(test_handlers)
95*4882a593Smuzhiyun        self.assertEqual(test_handlers,
96*4882a593Smuzhiyun                         bb.event.get_handlers())
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun    def test_clean_class_handlers(self):
99*4882a593Smuzhiyun        """ Test clean_class_handlers method """
100*4882a593Smuzhiyun        cleanDict = collections.OrderedDict()
101*4882a593Smuzhiyun        self.assertEqual(cleanDict,
102*4882a593Smuzhiyun                         bb.event.clean_class_handlers())
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun    def test_register(self):
105*4882a593Smuzhiyun        """ Test register method for class handlers """
106*4882a593Smuzhiyun        result = bb.event.register("handler", self._test_process.handler)
107*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
108*4882a593Smuzhiyun        handlers_dict = bb.event.get_class_handlers()
109*4882a593Smuzhiyun        self.assertIn("handler", handlers_dict)
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun    def test_already_registered(self):
112*4882a593Smuzhiyun        """ Test detection of an already registed class handler """
113*4882a593Smuzhiyun        bb.event.register("handler", self._test_process.handler)
114*4882a593Smuzhiyun        handlers_dict = bb.event.get_class_handlers()
115*4882a593Smuzhiyun        self.assertIn("handler", handlers_dict)
116*4882a593Smuzhiyun        result = bb.event.register("handler", self._test_process.handler)
117*4882a593Smuzhiyun        self.assertEqual(result, bb.event.AlreadyRegistered)
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun    def test_register_from_string(self):
120*4882a593Smuzhiyun        """ Test register method receiving code in string """
121*4882a593Smuzhiyun        result = bb.event.register("string_handler", "    return True")
122*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
123*4882a593Smuzhiyun        handlers_dict = bb.event.get_class_handlers()
124*4882a593Smuzhiyun        self.assertIn("string_handler", handlers_dict)
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun    def test_register_with_mask(self):
127*4882a593Smuzhiyun        """ Test register method with event masking """
128*4882a593Smuzhiyun        mask = ["bb.event.OperationStarted",
129*4882a593Smuzhiyun                "bb.event.OperationCompleted"]
130*4882a593Smuzhiyun        result = bb.event.register("event_handler",
131*4882a593Smuzhiyun                                   self._test_process.event_handler,
132*4882a593Smuzhiyun                                   mask)
133*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
134*4882a593Smuzhiyun        handlers_dict = bb.event.get_class_handlers()
135*4882a593Smuzhiyun        self.assertIn("event_handler", handlers_dict)
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun    def test_remove(self):
138*4882a593Smuzhiyun        """ Test remove method for class handlers """
139*4882a593Smuzhiyun        test_handlers = self._create_test_handlers()
140*4882a593Smuzhiyun        bb.event.set_class_handlers(test_handlers)
141*4882a593Smuzhiyun        count = len(test_handlers)
142*4882a593Smuzhiyun        bb.event.remove("handler1", None)
143*4882a593Smuzhiyun        test_handlers = bb.event.get_class_handlers()
144*4882a593Smuzhiyun        self.assertEqual(len(test_handlers), count - 1)
145*4882a593Smuzhiyun        with self.assertRaises(KeyError):
146*4882a593Smuzhiyun            bb.event.remove("handler1", None)
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun    def test_execute_handler(self):
149*4882a593Smuzhiyun        """ Test execute_handler method for class handlers """
150*4882a593Smuzhiyun        mask = ["bb.event.OperationProgress"]
151*4882a593Smuzhiyun        result = bb.event.register("event_handler",
152*4882a593Smuzhiyun                                   self._test_process.event_handler,
153*4882a593Smuzhiyun                                   mask)
154*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
155*4882a593Smuzhiyun        event = bb.event.OperationProgress(current=10, total=100)
156*4882a593Smuzhiyun        bb.event.execute_handler("event_handler",
157*4882a593Smuzhiyun                                 self._test_process.event_handler,
158*4882a593Smuzhiyun                                 event,
159*4882a593Smuzhiyun                                 None)
160*4882a593Smuzhiyun        self._test_process.event_handler.assert_called_once_with(event)
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun    def test_fire_class_handlers(self):
163*4882a593Smuzhiyun        """ Test fire_class_handlers method """
164*4882a593Smuzhiyun        mask = ["bb.event.OperationStarted"]
165*4882a593Smuzhiyun        result = bb.event.register("event_handler1",
166*4882a593Smuzhiyun                                   self._test_process.event_handler1,
167*4882a593Smuzhiyun                                   mask)
168*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
169*4882a593Smuzhiyun        result = bb.event.register("event_handler2",
170*4882a593Smuzhiyun                                   self._test_process.event_handler2,
171*4882a593Smuzhiyun                                   "*")
172*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
173*4882a593Smuzhiyun        event1 = bb.event.OperationStarted()
174*4882a593Smuzhiyun        event2 = bb.event.OperationCompleted(total=123)
175*4882a593Smuzhiyun        bb.event.fire_class_handlers(event1, None)
176*4882a593Smuzhiyun        bb.event.fire_class_handlers(event2, None)
177*4882a593Smuzhiyun        bb.event.fire_class_handlers(event2, None)
178*4882a593Smuzhiyun        expected_event_handler1 = [call(event1)]
179*4882a593Smuzhiyun        expected_event_handler2 = [call(event1),
180*4882a593Smuzhiyun                                   call(event2),
181*4882a593Smuzhiyun                                   call(event2)]
182*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler1.call_args_list,
183*4882a593Smuzhiyun                         expected_event_handler1)
184*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler2.call_args_list,
185*4882a593Smuzhiyun                         expected_event_handler2)
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun    def test_class_handler_filters(self):
188*4882a593Smuzhiyun        """ Test filters for class handlers """
189*4882a593Smuzhiyun        mask = ["bb.event.OperationStarted"]
190*4882a593Smuzhiyun        result = bb.event.register("event_handler1",
191*4882a593Smuzhiyun                                   self._test_process.event_handler1,
192*4882a593Smuzhiyun                                   mask)
193*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
194*4882a593Smuzhiyun        result = bb.event.register("event_handler2",
195*4882a593Smuzhiyun                                   self._test_process.event_handler2,
196*4882a593Smuzhiyun                                   "*")
197*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
198*4882a593Smuzhiyun        bb.event.set_eventfilter(
199*4882a593Smuzhiyun            lambda name, handler, event, d :
200*4882a593Smuzhiyun            name == 'event_handler2' and
201*4882a593Smuzhiyun            bb.event.getName(event) == "OperationStarted")
202*4882a593Smuzhiyun        event1 = bb.event.OperationStarted()
203*4882a593Smuzhiyun        event2 = bb.event.OperationCompleted(total=123)
204*4882a593Smuzhiyun        bb.event.fire_class_handlers(event1, None)
205*4882a593Smuzhiyun        bb.event.fire_class_handlers(event2, None)
206*4882a593Smuzhiyun        bb.event.fire_class_handlers(event2, None)
207*4882a593Smuzhiyun        expected_event_handler1 = []
208*4882a593Smuzhiyun        expected_event_handler2 = [call(event1)]
209*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler1.call_args_list,
210*4882a593Smuzhiyun                         expected_event_handler1)
211*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler2.call_args_list,
212*4882a593Smuzhiyun                         expected_event_handler2)
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun    def test_change_handler_event_mapping(self):
215*4882a593Smuzhiyun        """ Test changing the event mapping for class handlers """
216*4882a593Smuzhiyun        event1 = bb.event.OperationStarted()
217*4882a593Smuzhiyun        event2 = bb.event.OperationCompleted(total=123)
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun        # register handler for all events
220*4882a593Smuzhiyun        result = bb.event.register("event_handler1",
221*4882a593Smuzhiyun                                   self._test_process.event_handler1,
222*4882a593Smuzhiyun                                   "*")
223*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
224*4882a593Smuzhiyun        bb.event.fire_class_handlers(event1, None)
225*4882a593Smuzhiyun        bb.event.fire_class_handlers(event2, None)
226*4882a593Smuzhiyun        expected = [call(event1), call(event2)]
227*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler1.call_args_list,
228*4882a593Smuzhiyun                         expected)
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun        # unregister handler and register it only for OperationStarted
231*4882a593Smuzhiyun        bb.event.remove("event_handler1",
232*4882a593Smuzhiyun                        self._test_process.event_handler1)
233*4882a593Smuzhiyun        mask = ["bb.event.OperationStarted"]
234*4882a593Smuzhiyun        result = bb.event.register("event_handler1",
235*4882a593Smuzhiyun                                   self._test_process.event_handler1,
236*4882a593Smuzhiyun                                   mask)
237*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
238*4882a593Smuzhiyun        bb.event.fire_class_handlers(event1, None)
239*4882a593Smuzhiyun        bb.event.fire_class_handlers(event2, None)
240*4882a593Smuzhiyun        expected = [call(event1), call(event2), call(event1)]
241*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler1.call_args_list,
242*4882a593Smuzhiyun                         expected)
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun        # unregister handler and register it only for OperationCompleted
245*4882a593Smuzhiyun        bb.event.remove("event_handler1",
246*4882a593Smuzhiyun                        self._test_process.event_handler1)
247*4882a593Smuzhiyun        mask = ["bb.event.OperationCompleted"]
248*4882a593Smuzhiyun        result = bb.event.register("event_handler1",
249*4882a593Smuzhiyun                                   self._test_process.event_handler1,
250*4882a593Smuzhiyun                                   mask)
251*4882a593Smuzhiyun        self.assertEqual(result, bb.event.Registered)
252*4882a593Smuzhiyun        bb.event.fire_class_handlers(event1, None)
253*4882a593Smuzhiyun        bb.event.fire_class_handlers(event2, None)
254*4882a593Smuzhiyun        expected = [call(event1), call(event2), call(event1), call(event2)]
255*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler1.call_args_list,
256*4882a593Smuzhiyun                         expected)
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun    def test_register_UIHhandler(self):
259*4882a593Smuzhiyun        """ Test register_UIHhandler method """
260*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
261*4882a593Smuzhiyun        self.assertEqual(result, 1)
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun    def test_UIHhandler_already_registered(self):
264*4882a593Smuzhiyun        """ Test registering an UIHhandler already existing """
265*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
266*4882a593Smuzhiyun        self.assertEqual(result, 1)
267*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
268*4882a593Smuzhiyun        self.assertEqual(result, 2)
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun    def test_unregister_UIHhandler(self):
271*4882a593Smuzhiyun        """ Test unregister_UIHhandler method """
272*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
273*4882a593Smuzhiyun        self.assertEqual(result, 1)
274*4882a593Smuzhiyun        result = bb.event.unregister_UIHhandler(1)
275*4882a593Smuzhiyun        self.assertIs(result, None)
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun    def test_fire_ui_handlers(self):
278*4882a593Smuzhiyun        """ Test fire_ui_handlers method """
279*4882a593Smuzhiyun        self._test_ui1.event = Mock(spec_set=EventQueueStub)
280*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
281*4882a593Smuzhiyun        self.assertEqual(result, 1)
282*4882a593Smuzhiyun        self._test_ui2.event = Mock(spec_set=PickleEventQueueStub)
283*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
284*4882a593Smuzhiyun        self.assertEqual(result, 2)
285*4882a593Smuzhiyun        event1 = bb.event.OperationStarted()
286*4882a593Smuzhiyun        bb.event.fire_ui_handlers(event1, None)
287*4882a593Smuzhiyun        expected = [call(event1)]
288*4882a593Smuzhiyun        self.assertEqual(self._test_ui1.event.send.call_args_list,
289*4882a593Smuzhiyun                         expected)
290*4882a593Smuzhiyun        expected = [call(pickle.dumps(event1))]
291*4882a593Smuzhiyun        self.assertEqual(self._test_ui2.event.sendpickle.call_args_list,
292*4882a593Smuzhiyun                         expected)
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun    def test_ui_handler_mask_filter(self):
295*4882a593Smuzhiyun        """ Test filters for UI handlers """
296*4882a593Smuzhiyun        mask = ["bb.event.OperationStarted"]
297*4882a593Smuzhiyun        debug_domains = {}
298*4882a593Smuzhiyun        self._test_ui1.event = Mock(spec_set=EventQueueStub)
299*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
300*4882a593Smuzhiyun        bb.event.set_UIHmask(result, logging.INFO, debug_domains, mask)
301*4882a593Smuzhiyun        self._test_ui2.event = Mock(spec_set=PickleEventQueueStub)
302*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
303*4882a593Smuzhiyun        bb.event.set_UIHmask(result, logging.INFO, debug_domains, mask)
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun        event1 = bb.event.OperationStarted()
306*4882a593Smuzhiyun        event2 = bb.event.OperationCompleted(total=1)
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun        bb.event.fire_ui_handlers(event1, None)
309*4882a593Smuzhiyun        bb.event.fire_ui_handlers(event2, None)
310*4882a593Smuzhiyun        expected = [call(event1)]
311*4882a593Smuzhiyun        self.assertEqual(self._test_ui1.event.send.call_args_list,
312*4882a593Smuzhiyun                         expected)
313*4882a593Smuzhiyun        expected = [call(pickle.dumps(event1))]
314*4882a593Smuzhiyun        self.assertEqual(self._test_ui2.event.sendpickle.call_args_list,
315*4882a593Smuzhiyun                         expected)
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun    def test_ui_handler_log_filter(self):
318*4882a593Smuzhiyun        """ Test log filters for UI handlers """
319*4882a593Smuzhiyun        mask = ["*"]
320*4882a593Smuzhiyun        debug_domains = {'BitBake.Foo': logging.WARNING}
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun        self._test_ui1.event = EventQueueStub()
323*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
324*4882a593Smuzhiyun        bb.event.set_UIHmask(result, logging.ERROR, debug_domains, mask)
325*4882a593Smuzhiyun        self._test_ui2.event = PickleEventQueueStub()
326*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
327*4882a593Smuzhiyun        bb.event.set_UIHmask(result, logging.ERROR, debug_domains, mask)
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun        event1 = bb.event.OperationStarted()
330*4882a593Smuzhiyun        bb.event.fire_ui_handlers(event1, None)   # All events match
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun        event_log_handler = bb.event.LogHandler()
333*4882a593Smuzhiyun        logger = logging.getLogger("BitBake")
334*4882a593Smuzhiyun        logger.addHandler(event_log_handler)
335*4882a593Smuzhiyun        logger1 = logging.getLogger("BitBake.Foo")
336*4882a593Smuzhiyun        logger1.warning("Test warning LogRecord1") # Matches debug_domains level
337*4882a593Smuzhiyun        logger1.info("Test info LogRecord")        # Filtered out
338*4882a593Smuzhiyun        logger2 = logging.getLogger("BitBake.Bar")
339*4882a593Smuzhiyun        logger2.error("Test error LogRecord")      # Matches filter base level
340*4882a593Smuzhiyun        logger2.warning("Test warning LogRecord2") # Filtered out
341*4882a593Smuzhiyun        logger.removeHandler(event_log_handler)
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun        expected = ['OperationStarted',
344*4882a593Smuzhiyun                    'WARNING: Test warning LogRecord1',
345*4882a593Smuzhiyun                    'ERROR: Test error LogRecord']
346*4882a593Smuzhiyun        self.assertEqual(self._test_ui1.event.event_calls, expected)
347*4882a593Smuzhiyun        self.assertEqual(self._test_ui2.event.event_calls, expected)
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun    def test_fire(self):
350*4882a593Smuzhiyun        """ Test fire method used to trigger class and ui event handlers """
351*4882a593Smuzhiyun        mask = ["bb.event.ConfigParsed"]
352*4882a593Smuzhiyun        result = bb.event.register("event_handler1",
353*4882a593Smuzhiyun                                   self._test_process.event_handler1,
354*4882a593Smuzhiyun                                   mask)
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun        self._test_ui1.event = Mock(spec_set=EventQueueStub)
357*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
358*4882a593Smuzhiyun        self.assertEqual(result, 1)
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun        event1 = bb.event.ConfigParsed()
361*4882a593Smuzhiyun        bb.event.fire(event1, None)
362*4882a593Smuzhiyun        expected = [call(event1)]
363*4882a593Smuzhiyun        self.assertEqual(self._test_process.event_handler1.call_args_list,
364*4882a593Smuzhiyun                         expected)
365*4882a593Smuzhiyun        self.assertEqual(self._test_ui1.event.send.call_args_list,
366*4882a593Smuzhiyun                         expected)
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun    def test_fire_from_worker(self):
369*4882a593Smuzhiyun        """ Test fire_from_worker method """
370*4882a593Smuzhiyun        self._test_ui1.event = Mock(spec_set=EventQueueStub)
371*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
372*4882a593Smuzhiyun        self.assertEqual(result, 1)
373*4882a593Smuzhiyun        event1 = bb.event.ConfigParsed()
374*4882a593Smuzhiyun        bb.event.fire_from_worker(event1, None)
375*4882a593Smuzhiyun        expected = [call(event1)]
376*4882a593Smuzhiyun        self.assertEqual(self._test_ui1.event.send.call_args_list,
377*4882a593Smuzhiyun                         expected)
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun    def test_worker_fire(self):
380*4882a593Smuzhiyun        """ Test the triggering of bb.event.worker_fire callback """
381*4882a593Smuzhiyun        bb.event.worker_fire = Mock()
382*4882a593Smuzhiyun        event = bb.event.Event()
383*4882a593Smuzhiyun        bb.event.fire(event, None)
384*4882a593Smuzhiyun        expected = [call(event, None)]
385*4882a593Smuzhiyun        self.assertEqual(bb.event.worker_fire.call_args_list, expected)
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun    def test_print_ui_queue(self):
388*4882a593Smuzhiyun        """ Test print_ui_queue method """
389*4882a593Smuzhiyun        event1 = bb.event.OperationStarted()
390*4882a593Smuzhiyun        event2 = bb.event.OperationCompleted(total=123)
391*4882a593Smuzhiyun        bb.event.fire(event1, None)
392*4882a593Smuzhiyun        bb.event.fire(event2, None)
393*4882a593Smuzhiyun        event_log_handler = bb.event.LogHandler()
394*4882a593Smuzhiyun        logger = logging.getLogger("BitBake")
395*4882a593Smuzhiyun        logger.addHandler(event_log_handler)
396*4882a593Smuzhiyun        logger.info("Test info LogRecord")
397*4882a593Smuzhiyun        logger.warning("Test warning LogRecord")
398*4882a593Smuzhiyun        with self.assertLogs("BitBake", level="INFO") as cm:
399*4882a593Smuzhiyun            bb.event.print_ui_queue()
400*4882a593Smuzhiyun        logger.removeHandler(event_log_handler)
401*4882a593Smuzhiyun        self.assertEqual(cm.output,
402*4882a593Smuzhiyun                         ["INFO:BitBake:Test info LogRecord",
403*4882a593Smuzhiyun                          "WARNING:BitBake:Test warning LogRecord"])
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun    def _set_threadlock_test_mockups(self):
406*4882a593Smuzhiyun        """ Create UI event handler mockups used in enable and disable
407*4882a593Smuzhiyun            threadlock tests """
408*4882a593Smuzhiyun        def ui1_event_send(event):
409*4882a593Smuzhiyun            if type(event) is bb.event.ConfigParsed:
410*4882a593Smuzhiyun                self._threadlock_test_calls.append("w1_ui1")
411*4882a593Smuzhiyun            if type(event) is bb.event.OperationStarted:
412*4882a593Smuzhiyun                self._threadlock_test_calls.append("w2_ui1")
413*4882a593Smuzhiyun            time.sleep(2)
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun        def ui2_event_send(event):
416*4882a593Smuzhiyun            if type(event) is bb.event.ConfigParsed:
417*4882a593Smuzhiyun                self._threadlock_test_calls.append("w1_ui2")
418*4882a593Smuzhiyun            if type(event) is bb.event.OperationStarted:
419*4882a593Smuzhiyun                self._threadlock_test_calls.append("w2_ui2")
420*4882a593Smuzhiyun            time.sleep(2)
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun        self._threadlock_test_calls = []
423*4882a593Smuzhiyun        self._test_ui1.event = EventQueueStub()
424*4882a593Smuzhiyun        self._test_ui1.event.send = ui1_event_send
425*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui1, mainui=True)
426*4882a593Smuzhiyun        self.assertEqual(result, 1)
427*4882a593Smuzhiyun        self._test_ui2.event = EventQueueStub()
428*4882a593Smuzhiyun        self._test_ui2.event.send = ui2_event_send
429*4882a593Smuzhiyun        result = bb.event.register_UIHhandler(self._test_ui2, mainui=True)
430*4882a593Smuzhiyun        self.assertEqual(result, 2)
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun    def _set_and_run_threadlock_test_workers(self):
433*4882a593Smuzhiyun        """ Create and run the workers used to trigger events in enable and
434*4882a593Smuzhiyun            disable threadlock tests """
435*4882a593Smuzhiyun        worker1 = threading.Thread(target=self._thread_lock_test_worker1)
436*4882a593Smuzhiyun        worker2 = threading.Thread(target=self._thread_lock_test_worker2)
437*4882a593Smuzhiyun        worker1.start()
438*4882a593Smuzhiyun        time.sleep(1)
439*4882a593Smuzhiyun        worker2.start()
440*4882a593Smuzhiyun        worker1.join()
441*4882a593Smuzhiyun        worker2.join()
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun    def _thread_lock_test_worker1(self):
444*4882a593Smuzhiyun        """ First worker used to fire the ConfigParsed event for enable and
445*4882a593Smuzhiyun            disable threadlocks tests """
446*4882a593Smuzhiyun        bb.event.fire(bb.event.ConfigParsed(), None)
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun    def _thread_lock_test_worker2(self):
449*4882a593Smuzhiyun        """ Second worker used to fire the OperationStarted event for enable
450*4882a593Smuzhiyun            and disable threadlocks tests """
451*4882a593Smuzhiyun        bb.event.fire(bb.event.OperationStarted(), None)
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun    def test_enable_threadlock(self):
454*4882a593Smuzhiyun        """ Test enable_threadlock method """
455*4882a593Smuzhiyun        self._set_threadlock_test_mockups()
456*4882a593Smuzhiyun        bb.event.enable_threadlock()
457*4882a593Smuzhiyun        self._set_and_run_threadlock_test_workers()
458*4882a593Smuzhiyun        # Calls to UI handlers should be in order as all the registered
459*4882a593Smuzhiyun        # handlers for the event coming from the first worker should be
460*4882a593Smuzhiyun        # called before processing the event from the second worker.
461*4882a593Smuzhiyun        self.assertEqual(self._threadlock_test_calls,
462*4882a593Smuzhiyun                         ["w1_ui1", "w1_ui2", "w2_ui1", "w2_ui2"])
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun    def test_disable_threadlock(self):
466*4882a593Smuzhiyun        """ Test disable_threadlock method """
467*4882a593Smuzhiyun        self._set_threadlock_test_mockups()
468*4882a593Smuzhiyun        bb.event.disable_threadlock()
469*4882a593Smuzhiyun        self._set_and_run_threadlock_test_workers()
470*4882a593Smuzhiyun        # Calls to UI handlers should be intertwined together. Thanks to the
471*4882a593Smuzhiyun        # delay in the registered handlers for the event coming from the first
472*4882a593Smuzhiyun        # worker, the event coming from the second worker starts being
473*4882a593Smuzhiyun        # processed before finishing handling the first worker event.
474*4882a593Smuzhiyun        self.assertEqual(self._threadlock_test_calls,
475*4882a593Smuzhiyun                         ["w1_ui1", "w2_ui1", "w1_ui2", "w2_ui2"])
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun
478*4882a593Smuzhiyunclass EventClassesTest(unittest.TestCase):
479*4882a593Smuzhiyun    """ Event classes test class """
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun    _worker_pid = 54321
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun    def setUp(self):
484*4882a593Smuzhiyun        bb.event.worker_pid = EventClassesTest._worker_pid
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun    def test_Event(self):
487*4882a593Smuzhiyun        """ Test the Event base class """
488*4882a593Smuzhiyun        event = bb.event.Event()
489*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun    def test_HeartbeatEvent(self):
492*4882a593Smuzhiyun        """ Test the HeartbeatEvent class """
493*4882a593Smuzhiyun        time = 10
494*4882a593Smuzhiyun        event = bb.event.HeartbeatEvent(time)
495*4882a593Smuzhiyun        self.assertEqual(event.time, time)
496*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun    def test_OperationStarted(self):
499*4882a593Smuzhiyun        """ Test OperationStarted event class """
500*4882a593Smuzhiyun        msg = "Foo Bar"
501*4882a593Smuzhiyun        event = bb.event.OperationStarted(msg)
502*4882a593Smuzhiyun        self.assertEqual(event.msg, msg)
503*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun    def test_OperationCompleted(self):
506*4882a593Smuzhiyun        """ Test OperationCompleted event class """
507*4882a593Smuzhiyun        msg = "Foo Bar"
508*4882a593Smuzhiyun        total = 123
509*4882a593Smuzhiyun        event = bb.event.OperationCompleted(total, msg)
510*4882a593Smuzhiyun        self.assertEqual(event.msg, msg)
511*4882a593Smuzhiyun        self.assertEqual(event.total, total)
512*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
513*4882a593Smuzhiyun
514*4882a593Smuzhiyun    def test_OperationProgress(self):
515*4882a593Smuzhiyun        """ Test OperationProgress event class """
516*4882a593Smuzhiyun        msg = "Foo Bar"
517*4882a593Smuzhiyun        total = 123
518*4882a593Smuzhiyun        current = 111
519*4882a593Smuzhiyun        event = bb.event.OperationProgress(current, total, msg)
520*4882a593Smuzhiyun        self.assertEqual(event.msg, msg + ": %s/%s" % (current, total))
521*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun    def test_ConfigParsed(self):
524*4882a593Smuzhiyun        """ Test the ConfigParsed class """
525*4882a593Smuzhiyun        event = bb.event.ConfigParsed()
526*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
527*4882a593Smuzhiyun
528*4882a593Smuzhiyun    def test_MultiConfigParsed(self):
529*4882a593Smuzhiyun        """ Test MultiConfigParsed event class """
530*4882a593Smuzhiyun        mcdata = {"foobar": "Foo Bar"}
531*4882a593Smuzhiyun        event = bb.event.MultiConfigParsed(mcdata)
532*4882a593Smuzhiyun        self.assertEqual(event.mcdata, mcdata)
533*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun    def test_RecipeEvent(self):
536*4882a593Smuzhiyun        """ Test RecipeEvent event base class """
537*4882a593Smuzhiyun        callback = lambda a: 2 * a
538*4882a593Smuzhiyun        event = bb.event.RecipeEvent(callback)
539*4882a593Smuzhiyun        self.assertEqual(event.fn(1), callback(1))
540*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
541*4882a593Smuzhiyun
542*4882a593Smuzhiyun    def test_RecipePreFinalise(self):
543*4882a593Smuzhiyun        """ Test RecipePreFinalise event class """
544*4882a593Smuzhiyun        callback = lambda a: 2 * a
545*4882a593Smuzhiyun        event = bb.event.RecipePreFinalise(callback)
546*4882a593Smuzhiyun        self.assertEqual(event.fn(1), callback(1))
547*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun    def test_RecipeTaskPreProcess(self):
550*4882a593Smuzhiyun        """ Test RecipeTaskPreProcess event class """
551*4882a593Smuzhiyun        callback = lambda a: 2 * a
552*4882a593Smuzhiyun        tasklist = [("foobar", callback)]
553*4882a593Smuzhiyun        event = bb.event.RecipeTaskPreProcess(callback, tasklist)
554*4882a593Smuzhiyun        self.assertEqual(event.fn(1), callback(1))
555*4882a593Smuzhiyun        self.assertEqual(event.tasklist, tasklist)
556*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun    def test_RecipeParsed(self):
559*4882a593Smuzhiyun        """ Test RecipeParsed event base class """
560*4882a593Smuzhiyun        callback = lambda a: 2 * a
561*4882a593Smuzhiyun        event = bb.event.RecipeParsed(callback)
562*4882a593Smuzhiyun        self.assertEqual(event.fn(1), callback(1))
563*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun    def test_BuildBase(self):
566*4882a593Smuzhiyun        """ Test base class for bitbake build events """
567*4882a593Smuzhiyun        name = "foo"
568*4882a593Smuzhiyun        pkgs = ["bar"]
569*4882a593Smuzhiyun        failures = 123
570*4882a593Smuzhiyun        event = bb.event.BuildBase(name, pkgs, failures)
571*4882a593Smuzhiyun        self.assertEqual(event.name, name)
572*4882a593Smuzhiyun        self.assertEqual(event.pkgs, pkgs)
573*4882a593Smuzhiyun        self.assertEqual(event.getFailures(), failures)
574*4882a593Smuzhiyun        name = event.name = "bar"
575*4882a593Smuzhiyun        pkgs = event.pkgs = ["foo"]
576*4882a593Smuzhiyun        self.assertEqual(event.name, name)
577*4882a593Smuzhiyun        self.assertEqual(event.pkgs, pkgs)
578*4882a593Smuzhiyun        self.assertEqual(event.getFailures(), failures)
579*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun    def test_BuildInit(self):
582*4882a593Smuzhiyun        """ Test class for bitbake build invocation events """
583*4882a593Smuzhiyun        event = bb.event.BuildInit()
584*4882a593Smuzhiyun        self.assertEqual(event.name, None)
585*4882a593Smuzhiyun        self.assertEqual(event.pkgs, [])
586*4882a593Smuzhiyun        self.assertEqual(event.getFailures(), 0)
587*4882a593Smuzhiyun        name = event.name = "bar"
588*4882a593Smuzhiyun        pkgs = event.pkgs = ["foo"]
589*4882a593Smuzhiyun        self.assertEqual(event.name, name)
590*4882a593Smuzhiyun        self.assertEqual(event.pkgs, pkgs)
591*4882a593Smuzhiyun        self.assertEqual(event.getFailures(), 0)
592*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun    def test_BuildStarted(self):
595*4882a593Smuzhiyun        """ Test class for build started events """
596*4882a593Smuzhiyun        name = "foo"
597*4882a593Smuzhiyun        pkgs = ["bar"]
598*4882a593Smuzhiyun        failures = 123
599*4882a593Smuzhiyun        event = bb.event.BuildStarted(name, pkgs, failures)
600*4882a593Smuzhiyun        self.assertEqual(event.name, name)
601*4882a593Smuzhiyun        self.assertEqual(event.pkgs, pkgs)
602*4882a593Smuzhiyun        self.assertEqual(event.getFailures(), failures)
603*4882a593Smuzhiyun        self.assertEqual(event.msg, "Building Started")
604*4882a593Smuzhiyun        name = event.name = "bar"
605*4882a593Smuzhiyun        pkgs = event.pkgs = ["foo"]
606*4882a593Smuzhiyun        msg = event.msg = "foobar"
607*4882a593Smuzhiyun        self.assertEqual(event.name, name)
608*4882a593Smuzhiyun        self.assertEqual(event.pkgs, pkgs)
609*4882a593Smuzhiyun        self.assertEqual(event.getFailures(), failures)
610*4882a593Smuzhiyun        self.assertEqual(event.msg, msg)
611*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun    def test_BuildCompleted(self):
614*4882a593Smuzhiyun        """ Test class for build completed events """
615*4882a593Smuzhiyun        total = 1000
616*4882a593Smuzhiyun        name = "foo"
617*4882a593Smuzhiyun        pkgs = ["bar"]
618*4882a593Smuzhiyun        failures = 123
619*4882a593Smuzhiyun        interrupted = 1
620*4882a593Smuzhiyun        event = bb.event.BuildCompleted(total, name, pkgs, failures,
621*4882a593Smuzhiyun                                        interrupted)
622*4882a593Smuzhiyun        self.assertEqual(event.name, name)
623*4882a593Smuzhiyun        self.assertEqual(event.pkgs, pkgs)
624*4882a593Smuzhiyun        self.assertEqual(event.getFailures(), failures)
625*4882a593Smuzhiyun        self.assertEqual(event.msg, "Building Failed")
626*4882a593Smuzhiyun        event2 = bb.event.BuildCompleted(total, name, pkgs)
627*4882a593Smuzhiyun        self.assertEqual(event2.name, name)
628*4882a593Smuzhiyun        self.assertEqual(event2.pkgs, pkgs)
629*4882a593Smuzhiyun        self.assertEqual(event2.getFailures(), 0)
630*4882a593Smuzhiyun        self.assertEqual(event2.msg, "Building Succeeded")
631*4882a593Smuzhiyun        self.assertEqual(event2.pid, EventClassesTest._worker_pid)
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun    def test_DiskFull(self):
634*4882a593Smuzhiyun        """ Test DiskFull event class """
635*4882a593Smuzhiyun        dev = "/dev/foo"
636*4882a593Smuzhiyun        type = "ext4"
637*4882a593Smuzhiyun        freespace = "104M"
638*4882a593Smuzhiyun        mountpoint = "/"
639*4882a593Smuzhiyun        event = bb.event.DiskFull(dev, type, freespace, mountpoint)
640*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun    def test_MonitorDiskEvent(self):
643*4882a593Smuzhiyun        """ Test MonitorDiskEvent class """
644*4882a593Smuzhiyun        available_bytes = 10000000
645*4882a593Smuzhiyun        free_bytes = 90000000
646*4882a593Smuzhiyun        total_bytes = 1000000000
647*4882a593Smuzhiyun        du = bb.event.DiskUsageSample(available_bytes, free_bytes,
648*4882a593Smuzhiyun                                      total_bytes)
649*4882a593Smuzhiyun        event = bb.event.MonitorDiskEvent(du)
650*4882a593Smuzhiyun        self.assertEqual(event.disk_usage.available_bytes, available_bytes)
651*4882a593Smuzhiyun        self.assertEqual(event.disk_usage.free_bytes, free_bytes)
652*4882a593Smuzhiyun        self.assertEqual(event.disk_usage.total_bytes, total_bytes)
653*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun    def test_NoProvider(self):
656*4882a593Smuzhiyun        """ Test NoProvider event class """
657*4882a593Smuzhiyun        item = "foobar"
658*4882a593Smuzhiyun        event1 = bb.event.NoProvider(item)
659*4882a593Smuzhiyun        self.assertEqual(event1.getItem(), item)
660*4882a593Smuzhiyun        self.assertEqual(event1.isRuntime(), False)
661*4882a593Smuzhiyun        self.assertEqual(str(event1), "Nothing PROVIDES 'foobar'")
662*4882a593Smuzhiyun        runtime = True
663*4882a593Smuzhiyun        dependees = ["foo", "bar"]
664*4882a593Smuzhiyun        reasons = None
665*4882a593Smuzhiyun        close_matches = ["foibar", "footbar"]
666*4882a593Smuzhiyun        event2 = bb.event.NoProvider(item, runtime, dependees, reasons,
667*4882a593Smuzhiyun                                     close_matches)
668*4882a593Smuzhiyun        self.assertEqual(event2.isRuntime(), True)
669*4882a593Smuzhiyun        expected = ("Nothing RPROVIDES 'foobar' (but foo, bar RDEPENDS"
670*4882a593Smuzhiyun                    " on or otherwise requires it). Close matches:\n"
671*4882a593Smuzhiyun                    "  foibar\n"
672*4882a593Smuzhiyun                    "  footbar")
673*4882a593Smuzhiyun        self.assertEqual(str(event2), expected)
674*4882a593Smuzhiyun        reasons = ["Item does not exist on database"]
675*4882a593Smuzhiyun        close_matches = ["foibar", "footbar"]
676*4882a593Smuzhiyun        event3 = bb.event.NoProvider(item, runtime, dependees, reasons,
677*4882a593Smuzhiyun                                     close_matches)
678*4882a593Smuzhiyun        expected = ("Nothing RPROVIDES 'foobar' (but foo, bar RDEPENDS"
679*4882a593Smuzhiyun                    " on or otherwise requires it)\n"
680*4882a593Smuzhiyun                    "Item does not exist on database")
681*4882a593Smuzhiyun        self.assertEqual(str(event3), expected)
682*4882a593Smuzhiyun        self.assertEqual(event3.pid, EventClassesTest._worker_pid)
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun    def test_MultipleProviders(self):
685*4882a593Smuzhiyun        """ Test MultipleProviders event class """
686*4882a593Smuzhiyun        item = "foobar"
687*4882a593Smuzhiyun        candidates = ["foobarv1", "foobars"]
688*4882a593Smuzhiyun        event1 = bb.event.MultipleProviders(item, candidates)
689*4882a593Smuzhiyun        self.assertEqual(event1.isRuntime(), False)
690*4882a593Smuzhiyun        self.assertEqual(event1.getItem(), item)
691*4882a593Smuzhiyun        self.assertEqual(event1.getCandidates(), candidates)
692*4882a593Smuzhiyun        expected = ("Multiple providers are available for foobar (foobarv1,"
693*4882a593Smuzhiyun                    " foobars)\n"
694*4882a593Smuzhiyun                    "Consider defining a PREFERRED_PROVIDER entry to match "
695*4882a593Smuzhiyun                    "foobar")
696*4882a593Smuzhiyun        self.assertEqual(str(event1), expected)
697*4882a593Smuzhiyun        runtime = True
698*4882a593Smuzhiyun        event2 = bb.event.MultipleProviders(item, candidates, runtime)
699*4882a593Smuzhiyun        self.assertEqual(event2.isRuntime(), runtime)
700*4882a593Smuzhiyun        expected = ("Multiple providers are available for runtime foobar "
701*4882a593Smuzhiyun                    "(foobarv1, foobars)\n"
702*4882a593Smuzhiyun                    "Consider defining a PREFERRED_RPROVIDER entry to match "
703*4882a593Smuzhiyun                    "foobar")
704*4882a593Smuzhiyun        self.assertEqual(str(event2), expected)
705*4882a593Smuzhiyun        self.assertEqual(event2.pid, EventClassesTest._worker_pid)
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun    def test_ParseStarted(self):
708*4882a593Smuzhiyun        """ Test ParseStarted event class """
709*4882a593Smuzhiyun        total = 123
710*4882a593Smuzhiyun        event = bb.event.ParseStarted(total)
711*4882a593Smuzhiyun        self.assertEqual(event.msg, "Recipe parsing Started")
712*4882a593Smuzhiyun        self.assertEqual(event.total, total)
713*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
714*4882a593Smuzhiyun
715*4882a593Smuzhiyun    def test_ParseCompleted(self):
716*4882a593Smuzhiyun        """ Test ParseCompleted event class """
717*4882a593Smuzhiyun        cached = 10
718*4882a593Smuzhiyun        parsed = 13
719*4882a593Smuzhiyun        skipped = 7
720*4882a593Smuzhiyun        virtuals = 2
721*4882a593Smuzhiyun        masked = 1
722*4882a593Smuzhiyun        errors = 0
723*4882a593Smuzhiyun        total = 23
724*4882a593Smuzhiyun        event = bb.event.ParseCompleted(cached, parsed, skipped, masked,
725*4882a593Smuzhiyun                                        virtuals, errors, total)
726*4882a593Smuzhiyun        self.assertEqual(event.msg, "Recipe parsing Completed")
727*4882a593Smuzhiyun        expected = [cached, parsed, skipped, virtuals, masked, errors,
728*4882a593Smuzhiyun                    cached + parsed, total]
729*4882a593Smuzhiyun        actual = [event.cached, event.parsed, event.skipped, event.virtuals,
730*4882a593Smuzhiyun                  event.masked, event.errors, event.sofar, event.total]
731*4882a593Smuzhiyun        self.assertEqual(str(actual), str(expected))
732*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
733*4882a593Smuzhiyun
734*4882a593Smuzhiyun    def test_ParseProgress(self):
735*4882a593Smuzhiyun        """ Test ParseProgress event class """
736*4882a593Smuzhiyun        current = 10
737*4882a593Smuzhiyun        total = 100
738*4882a593Smuzhiyun        event = bb.event.ParseProgress(current, total)
739*4882a593Smuzhiyun        self.assertEqual(event.msg,
740*4882a593Smuzhiyun                         "Recipe parsing" + ": %s/%s" % (current, total))
741*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
742*4882a593Smuzhiyun
743*4882a593Smuzhiyun    def test_CacheLoadStarted(self):
744*4882a593Smuzhiyun        """ Test CacheLoadStarted event class """
745*4882a593Smuzhiyun        total = 123
746*4882a593Smuzhiyun        event = bb.event.CacheLoadStarted(total)
747*4882a593Smuzhiyun        self.assertEqual(event.msg, "Loading cache Started")
748*4882a593Smuzhiyun        self.assertEqual(event.total, total)
749*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun    def test_CacheLoadProgress(self):
752*4882a593Smuzhiyun        """ Test CacheLoadProgress event class """
753*4882a593Smuzhiyun        current = 10
754*4882a593Smuzhiyun        total = 100
755*4882a593Smuzhiyun        event = bb.event.CacheLoadProgress(current, total)
756*4882a593Smuzhiyun        self.assertEqual(event.msg,
757*4882a593Smuzhiyun                         "Loading cache" + ": %s/%s" % (current, total))
758*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun    def test_CacheLoadCompleted(self):
761*4882a593Smuzhiyun        """ Test CacheLoadCompleted event class """
762*4882a593Smuzhiyun        total = 23
763*4882a593Smuzhiyun        num_entries = 12
764*4882a593Smuzhiyun        event = bb.event.CacheLoadCompleted(total, num_entries)
765*4882a593Smuzhiyun        self.assertEqual(event.msg, "Loading cache Completed")
766*4882a593Smuzhiyun        expected = [total, num_entries]
767*4882a593Smuzhiyun        actual = [event.total, event.num_entries]
768*4882a593Smuzhiyun        self.assertEqual(str(actual), str(expected))
769*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun    def test_TreeDataPreparationStarted(self):
772*4882a593Smuzhiyun        """ Test TreeDataPreparationStarted event class """
773*4882a593Smuzhiyun        event = bb.event.TreeDataPreparationStarted()
774*4882a593Smuzhiyun        self.assertEqual(event.msg, "Preparing tree data Started")
775*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun    def test_TreeDataPreparationProgress(self):
778*4882a593Smuzhiyun        """ Test TreeDataPreparationProgress event class """
779*4882a593Smuzhiyun        current = 10
780*4882a593Smuzhiyun        total = 100
781*4882a593Smuzhiyun        event = bb.event.TreeDataPreparationProgress(current, total)
782*4882a593Smuzhiyun        self.assertEqual(event.msg,
783*4882a593Smuzhiyun                         "Preparing tree data" + ": %s/%s" % (current, total))
784*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun    def test_TreeDataPreparationCompleted(self):
787*4882a593Smuzhiyun        """ Test TreeDataPreparationCompleted event class """
788*4882a593Smuzhiyun        total = 23
789*4882a593Smuzhiyun        event = bb.event.TreeDataPreparationCompleted(total)
790*4882a593Smuzhiyun        self.assertEqual(event.msg, "Preparing tree data Completed")
791*4882a593Smuzhiyun        self.assertEqual(event.total, total)
792*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun    def test_DepTreeGenerated(self):
795*4882a593Smuzhiyun        """ Test DepTreeGenerated event class """
796*4882a593Smuzhiyun        depgraph = Mock()
797*4882a593Smuzhiyun        event = bb.event.DepTreeGenerated(depgraph)
798*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun    def test_TargetsTreeGenerated(self):
801*4882a593Smuzhiyun        """ Test TargetsTreeGenerated event class """
802*4882a593Smuzhiyun        model = Mock()
803*4882a593Smuzhiyun        event = bb.event.TargetsTreeGenerated(model)
804*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun    def test_ReachableStamps(self):
807*4882a593Smuzhiyun        """ Test ReachableStamps event class """
808*4882a593Smuzhiyun        stamps = [Mock(), Mock()]
809*4882a593Smuzhiyun        event = bb.event.ReachableStamps(stamps)
810*4882a593Smuzhiyun        self.assertEqual(event.stamps, stamps)
811*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun    def test_FilesMatchingFound(self):
814*4882a593Smuzhiyun        """ Test FilesMatchingFound event class """
815*4882a593Smuzhiyun        pattern = "foo.*bar"
816*4882a593Smuzhiyun        matches = ["foobar"]
817*4882a593Smuzhiyun        event = bb.event.FilesMatchingFound(pattern, matches)
818*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun    def test_ConfigFilesFound(self):
821*4882a593Smuzhiyun        """ Test ConfigFilesFound event class """
822*4882a593Smuzhiyun        variable = "FOO_BAR"
823*4882a593Smuzhiyun        values = ["foo", "bar"]
824*4882a593Smuzhiyun        event = bb.event.ConfigFilesFound(variable, values)
825*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun    def test_ConfigFilePathFound(self):
828*4882a593Smuzhiyun        """ Test ConfigFilePathFound event class """
829*4882a593Smuzhiyun        path = "/foo/bar"
830*4882a593Smuzhiyun        event = bb.event.ConfigFilePathFound(path)
831*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun    def test_message_classes(self):
834*4882a593Smuzhiyun        """ Test message event classes """
835*4882a593Smuzhiyun        msg = "foobar foo bar"
836*4882a593Smuzhiyun        event = bb.event.MsgBase(msg)
837*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
838*4882a593Smuzhiyun        event = bb.event.MsgDebug(msg)
839*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
840*4882a593Smuzhiyun        event = bb.event.MsgNote(msg)
841*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
842*4882a593Smuzhiyun        event = bb.event.MsgWarn(msg)
843*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
844*4882a593Smuzhiyun        event = bb.event.MsgError(msg)
845*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
846*4882a593Smuzhiyun        event = bb.event.MsgFatal(msg)
847*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
848*4882a593Smuzhiyun        event = bb.event.MsgPlain(msg)
849*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun    def test_LogExecTTY(self):
852*4882a593Smuzhiyun        """ Test LogExecTTY event class """
853*4882a593Smuzhiyun        msg = "foo bar"
854*4882a593Smuzhiyun        prog = "foo.sh"
855*4882a593Smuzhiyun        sleep_delay = 10
856*4882a593Smuzhiyun        retries = 3
857*4882a593Smuzhiyun        event = bb.event.LogExecTTY(msg, prog, sleep_delay, retries)
858*4882a593Smuzhiyun        self.assertEqual(event.msg, msg)
859*4882a593Smuzhiyun        self.assertEqual(event.prog, prog)
860*4882a593Smuzhiyun        self.assertEqual(event.sleep_delay, sleep_delay)
861*4882a593Smuzhiyun        self.assertEqual(event.retries, retries)
862*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun    def _throw_zero_division_exception(self):
865*4882a593Smuzhiyun        a = 1 / 0
866*4882a593Smuzhiyun        return
867*4882a593Smuzhiyun
868*4882a593Smuzhiyun    def _worker_handler(self, event, d):
869*4882a593Smuzhiyun        self._returned_event = event
870*4882a593Smuzhiyun        return
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun    def test_LogHandler(self):
873*4882a593Smuzhiyun        """ Test LogHandler class """
874*4882a593Smuzhiyun        logger = logging.getLogger("TestEventClasses")
875*4882a593Smuzhiyun        logger.propagate = False
876*4882a593Smuzhiyun        handler = bb.event.LogHandler(logging.INFO)
877*4882a593Smuzhiyun        logger.addHandler(handler)
878*4882a593Smuzhiyun        bb.event.worker_fire = self._worker_handler
879*4882a593Smuzhiyun        try:
880*4882a593Smuzhiyun            self._throw_zero_division_exception()
881*4882a593Smuzhiyun        except ZeroDivisionError as ex:
882*4882a593Smuzhiyun            logger.exception(ex)
883*4882a593Smuzhiyun        event = self._returned_event
884*4882a593Smuzhiyun        try:
885*4882a593Smuzhiyun            pe = pickle.dumps(event)
886*4882a593Smuzhiyun            newevent = pickle.loads(pe)
887*4882a593Smuzhiyun        except:
888*4882a593Smuzhiyun            self.fail('Logged event is not serializable')
889*4882a593Smuzhiyun        self.assertEqual(event.taskpid, EventClassesTest._worker_pid)
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun    def test_MetadataEvent(self):
892*4882a593Smuzhiyun        """ Test MetadataEvent class """
893*4882a593Smuzhiyun        eventtype = "footype"
894*4882a593Smuzhiyun        eventdata = {"foo": "bar"}
895*4882a593Smuzhiyun        event = bb.event.MetadataEvent(eventtype, eventdata)
896*4882a593Smuzhiyun        self.assertEqual(event.type, eventtype)
897*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
898*4882a593Smuzhiyun
899*4882a593Smuzhiyun    def test_ProcessStarted(self):
900*4882a593Smuzhiyun        """ Test ProcessStarted class """
901*4882a593Smuzhiyun        processname = "foo"
902*4882a593Smuzhiyun        total = 9783128974
903*4882a593Smuzhiyun        event = bb.event.ProcessStarted(processname, total)
904*4882a593Smuzhiyun        self.assertEqual(event.processname, processname)
905*4882a593Smuzhiyun        self.assertEqual(event.total, total)
906*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun    def test_ProcessProgress(self):
909*4882a593Smuzhiyun        """ Test ProcessProgress class """
910*4882a593Smuzhiyun        processname = "foo"
911*4882a593Smuzhiyun        progress = 243224
912*4882a593Smuzhiyun        event = bb.event.ProcessProgress(processname, progress)
913*4882a593Smuzhiyun        self.assertEqual(event.processname, processname)
914*4882a593Smuzhiyun        self.assertEqual(event.progress, progress)
915*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun    def test_ProcessFinished(self):
918*4882a593Smuzhiyun        """ Test ProcessFinished class """
919*4882a593Smuzhiyun        processname = "foo"
920*4882a593Smuzhiyun        total = 1242342344
921*4882a593Smuzhiyun        event = bb.event.ProcessFinished(processname)
922*4882a593Smuzhiyun        self.assertEqual(event.processname, processname)
923*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun    def test_SanityCheck(self):
926*4882a593Smuzhiyun        """ Test SanityCheck class """
927*4882a593Smuzhiyun        event1 = bb.event.SanityCheck()
928*4882a593Smuzhiyun        self.assertEqual(event1.generateevents, True)
929*4882a593Smuzhiyun        self.assertEqual(event1.pid, EventClassesTest._worker_pid)
930*4882a593Smuzhiyun        generateevents = False
931*4882a593Smuzhiyun        event2 = bb.event.SanityCheck(generateevents)
932*4882a593Smuzhiyun        self.assertEqual(event2.generateevents, generateevents)
933*4882a593Smuzhiyun        self.assertEqual(event2.pid, EventClassesTest._worker_pid)
934*4882a593Smuzhiyun
935*4882a593Smuzhiyun    def test_SanityCheckPassed(self):
936*4882a593Smuzhiyun        """ Test SanityCheckPassed class """
937*4882a593Smuzhiyun        event = bb.event.SanityCheckPassed()
938*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun    def test_SanityCheckFailed(self):
941*4882a593Smuzhiyun        """ Test SanityCheckFailed class """
942*4882a593Smuzhiyun        msg = "The sanity test failed."
943*4882a593Smuzhiyun        event1 = bb.event.SanityCheckFailed(msg)
944*4882a593Smuzhiyun        self.assertEqual(event1.pid, EventClassesTest._worker_pid)
945*4882a593Smuzhiyun        network_error = True
946*4882a593Smuzhiyun        event2 = bb.event.SanityCheckFailed(msg, network_error)
947*4882a593Smuzhiyun        self.assertEqual(event2.pid, EventClassesTest._worker_pid)
948*4882a593Smuzhiyun
949*4882a593Smuzhiyun    def test_network_event_classes(self):
950*4882a593Smuzhiyun        """ Test network event classes """
951*4882a593Smuzhiyun        event1 = bb.event.NetworkTest()
952*4882a593Smuzhiyun        generateevents = False
953*4882a593Smuzhiyun        self.assertEqual(event1.pid, EventClassesTest._worker_pid)
954*4882a593Smuzhiyun        event2 = bb.event.NetworkTest(generateevents)
955*4882a593Smuzhiyun        self.assertEqual(event2.pid, EventClassesTest._worker_pid)
956*4882a593Smuzhiyun        event3 = bb.event.NetworkTestPassed()
957*4882a593Smuzhiyun        self.assertEqual(event3.pid, EventClassesTest._worker_pid)
958*4882a593Smuzhiyun        event4 = bb.event.NetworkTestFailed()
959*4882a593Smuzhiyun        self.assertEqual(event4.pid, EventClassesTest._worker_pid)
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun    def test_FindSigInfoResult(self):
962*4882a593Smuzhiyun        """ Test FindSigInfoResult event class """
963*4882a593Smuzhiyun        result = [Mock()]
964*4882a593Smuzhiyun        event = bb.event.FindSigInfoResult(result)
965*4882a593Smuzhiyun        self.assertEqual(event.result, result)
966*4882a593Smuzhiyun        self.assertEqual(event.pid, EventClassesTest._worker_pid)
967