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