|
4 | 4 | """ |
5 | 5 | This module contains unit tests for the common functions in the amd-debug-tools package. |
6 | 6 | """ |
7 | | -from unittest.mock import patch, mock_open, call |
| 7 | +from unittest.mock import patch, mock_open, call, Mock |
8 | 8 |
|
| 9 | +import asyncio |
| 10 | +import builtins |
9 | 11 | import logging |
10 | 12 | import tempfile |
11 | 13 | import unittest |
12 | 14 | import os |
13 | 15 | from platform import uname_result |
| 16 | +import sys |
14 | 17 |
|
15 | 18 |
|
16 | 19 | from amd_debug.common import ( |
@@ -474,63 +477,84 @@ def test_get_system_mem_valid(self, _mock_join, mock_file): |
474 | 477 | self.assertAlmostEqual(get_system_mem(), expected_gb) |
475 | 478 | mock_file.assert_called_once_with("/proc/meminfo", "r", encoding="utf-8") |
476 | 479 |
|
477 | | - @patch("builtins.open", new_callable=mock_open, read_data="NoMemHere: 1234\n") |
478 | | - @patch("os.path.join", return_value="/proc/meminfo") |
479 | | - def test_get_system_mem_missing(self, _mock_join, _mock_file): |
480 | | - """Test get_system_mem raises ValueError if MemTotal is missing""" |
481 | | - with self.assertRaises(ValueError): |
482 | | - get_system_mem() |
483 | | - |
484 | | - @patch("amd_debug.common.fatal_error") |
485 | | - def test_reboot_importerror(self, mock_fatal_error): |
486 | | - """Test reboot handles ImportError""" |
487 | | - with patch.dict("sys.modules", {"dbus": None}): |
488 | | - reboot() |
489 | | - mock_fatal_error.assert_called_once_with("Missing dbus") |
490 | | - |
491 | | - @patch("amd_debug.common.fatal_error") |
492 | | - def test_reboot_dbus_exception(self, mock_fatal_error): |
493 | | - """Test reboot handles dbus.exceptions.DBusException""" |
494 | | - |
495 | | - class DummyDBusException(Exception): |
496 | | - """Dummy exception""" |
497 | | - |
498 | | - class DummyIntf: |
499 | | - """Dummy interface""" |
| 480 | + def test_reboot_dbus_fast_success(self): |
| 481 | + """Test reboot returns True when reboot_dbus_fast succeeds""" |
500 | 482 |
|
501 | | - def Reboot(self, _arg): # pylint: disable=invalid-name |
502 | | - """Dummy Reboot method""" |
503 | | - raise DummyDBusException("fail") |
504 | | - |
505 | | - class DummyObj: # pylint: disable=too-few-public-methods |
506 | | - """Dummy object""" |
507 | | - |
508 | | - def __init__(self): |
| 483 | + # Create a mock loop that properly handles coroutines |
| 484 | + def mock_run_until_complete(coro): |
| 485 | + # Consume the coroutine to prevent the warning |
| 486 | + try: |
| 487 | + # Close the coroutine to prevent the warning |
| 488 | + coro.close() |
| 489 | + except (AttributeError, RuntimeError): |
509 | 490 | pass |
| 491 | + return True |
510 | 492 |
|
511 | | - class DummyBus: # pylint: disable=too-few-public-methods |
512 | | - """Dummy bus""" |
| 493 | + mock_loop = Mock() |
| 494 | + mock_loop.run_until_complete.side_effect = mock_run_until_complete |
513 | 495 |
|
514 | | - def get_object(self, *args, **kwargs): |
515 | | - """Dummy get_object method""" |
516 | | - return DummyObj() |
| 496 | + with patch("amd_debug.common.asyncio.get_event_loop", return_value=mock_loop): |
| 497 | + result = reboot() |
| 498 | + self.assertTrue(result) |
| 499 | + mock_loop.run_until_complete.assert_called_once() |
517 | 500 |
|
518 | | - class DummyDBus: |
519 | | - """Dummy dbus""" |
| 501 | + @patch("asyncio.get_event_loop") |
| 502 | + def test_reboot_dbus_fast_failure_and_dbus_success(self, mock_get_event_loop): |
| 503 | + """Test reboot falls back to reboot_dbus when reboot_dbus_fast fails""" |
520 | 504 |
|
521 | | - class exceptions: # pylint: disable=invalid-name |
522 | | - """Dummy exceptions""" |
| 505 | + # Create a mock loop that properly handles coroutines |
| 506 | + def mock_run_until_complete(coro): |
| 507 | + # Consume the coroutine to prevent the warning |
| 508 | + try: |
| 509 | + coro.close() |
| 510 | + except (AttributeError, RuntimeError): |
| 511 | + pass |
| 512 | + return False |
| 513 | + |
| 514 | + mock_loop = Mock() |
| 515 | + mock_loop.run_until_complete.side_effect = mock_run_until_complete |
| 516 | + mock_get_event_loop.return_value = mock_loop |
| 517 | + |
| 518 | + # Mock the dbus module to avoid ImportError in CI |
| 519 | + mock_dbus = Mock() |
| 520 | + mock_bus = Mock() |
| 521 | + mock_obj = Mock() |
| 522 | + mock_intf = Mock() |
| 523 | + |
| 524 | + mock_dbus.SystemBus.return_value = mock_bus |
| 525 | + mock_bus.get_object.return_value = mock_obj |
| 526 | + mock_obj.get_interface.return_value = mock_intf |
| 527 | + mock_dbus.Interface = Mock(return_value=mock_intf) |
| 528 | + |
| 529 | + with patch.dict("sys.modules", {"dbus": mock_dbus}): |
| 530 | + result = reboot() |
| 531 | + self.assertTrue(result) |
| 532 | + |
| 533 | + @patch("asyncio.get_event_loop") |
| 534 | + def test_reboot_dbus_fast_failure_and_dbus_failure(self, mock_get_event_loop): |
| 535 | + """Test reboot returns False when both reboot_dbus_fast and reboot_dbus fail""" |
| 536 | + |
| 537 | + # Create a mock loop that properly handles coroutines |
| 538 | + def mock_run_until_complete(coro): |
| 539 | + # Consume the coroutine to prevent the warning |
| 540 | + try: |
| 541 | + coro.close() |
| 542 | + except (AttributeError, RuntimeError): |
| 543 | + pass |
| 544 | + return False |
523 | 545 |
|
524 | | - DBusException = DummyDBusException |
| 546 | + mock_loop = Mock() |
| 547 | + mock_loop.run_until_complete.side_effect = mock_run_until_complete |
| 548 | + mock_get_event_loop.return_value = mock_loop |
525 | 549 |
|
526 | | - def SystemBus(self): # pylint: disable=invalid-name |
527 | | - """Dummy SystemBus method""" |
528 | | - return DummyBus() |
| 550 | + # Mock the import to raise ImportError when dbus is imported |
| 551 | + original_import = builtins.__import__ |
529 | 552 |
|
530 | | - def Interface(self, _obj, _name): # pylint: disable=invalid-name |
531 | | - """Dummy Interface method""" |
532 | | - return DummyIntf() |
| 553 | + def mock_import(name, *args, **kwargs): |
| 554 | + if name == "dbus": |
| 555 | + raise ImportError("No module named 'dbus'") |
| 556 | + return original_import(name, *args, **kwargs) |
533 | 557 |
|
534 | | - with patch.dict("sys.modules", {"dbus": DummyDBus()}): |
535 | | - reboot() |
536 | | - self.assertTrue(mock_fatal_error.called) |
| 558 | + with patch("builtins.__import__", side_effect=mock_import): |
| 559 | + result = reboot() |
| 560 | + self.assertFalse(result) |
0 commit comments