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