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