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