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