예제 #1
0
    def test_output(self):
        """Simple test for `output` base method"""
        user_instance_mock = HelperMethods.entry_mock(User)

        output_mock = MagicMock()
        User.output(user_instance_mock, output_mock)

        self.assertEqual(output_mock.append.call_args[0][1],
                         DEFAULT_CONFIG['default_strings']['not_detected'])
예제 #2
0
    def test_no_match(self):
        """Test when no information could be retrieved"""
        model_instance_mock = HelperMethods.entry_mock(Model)

        output_mock = MagicMock()
        Model.output(model_instance_mock, output_mock)

        self.assertIsNone(model_instance_mock.value)
        self.assertEqual(output_mock.append.call_args[0][1],
                         DEFAULT_CONFIG['default_strings']['not_detected'])
예제 #3
0
    def test_various_output_configuration(self):
        """Test `output` overloading based on user preferences combination"""
        cpu_instance_mock = HelperMethods.entry_mock(CPU)
        output_mock = MagicMock()

        cpu_instance_mock.value = [{
            'CPU-MODEL-NAME': 1
        }, {
            'ANOTHER-CPU-MODEL': 2
        }]

        with self.subTest('Single-line combined output.'):
            cpu_instance_mock.options['one_line'] = True

            CPU.output(cpu_instance_mock, output_mock)
            output_mock.append.assert_called_once_with(
                'CPU', 'CPU-MODEL-NAME, 2 x ANOTHER-CPU-MODEL')

        output_mock.reset_mock()

        with self.subTest('Single-line combined output (no count).'):
            cpu_instance_mock.options['show_cores'] = False
            cpu_instance_mock.options['one_line'] = True

            CPU.output(cpu_instance_mock, output_mock)
            output_mock.append.assert_called_once_with(
                'CPU', 'CPU-MODEL-NAME, ANOTHER-CPU-MODEL')

        output_mock.reset_mock()

        with self.subTest('Multi-lines output (with counts).'):
            cpu_instance_mock.options['show_cores'] = True
            cpu_instance_mock.options['one_line'] = False

            CPU.output(cpu_instance_mock, output_mock)
            self.assertEqual(output_mock.append.call_count, 2)
            output_mock.append.assert_has_calls(
                [
                    call('CPU', 'CPU-MODEL-NAME'),
                    call('CPU', '2 x ANOTHER-CPU-MODEL')
                ],
                any_order=
                True  # Since Python < 3.6 doesn't have definite `dict` ordering.
            )

        output_mock.reset_mock()

        with self.subTest('No CPU detected output.'):
            cpu_instance_mock.value = {}

            CPU.output(cpu_instance_mock, output_mock)
            output_mock.append.assert_called_once_with(
                'CPU', DEFAULT_CONFIG['default_strings']['not_detected'])
    def test_unknown_distro_output(self):
        """Test for `output` method when distribution name couldn't be found"""
        distro_intance_mock = HelperMethods.entry_mock(Distro)
        output_mock = MagicMock()

        distro_intance_mock.value = {'name': None, 'arch': 'ARCHITECTURE'}

        Distro.output(distro_intance_mock, output_mock)
        self.assertEqual(
            output_mock.append.call_args[0][1],
            f"{DEFAULT_CONFIG['default_strings']['not_detected']} [ARCHITECTURE]"
        )
예제 #5
0
    def test_various_output_configuration(self):
        """Test `output` overloading based on user preferences"""
        ram_instance_mock = HelperMethods.entry_mock(RAM)
        output_mock = MagicMock()

        with self.subTest('Output in case of non-detection.'):
            RAM.output(ram_instance_mock, output_mock)
            self.assertEqual(output_mock.append.call_args[0][1],
                             DEFAULT_CONFIG['default_strings']['not_detected'])

        output_mock.reset_mock()

        with self.subTest('"Normal" output (green).'):
            ram_instance_mock.value = {
                'used': 2043.0,
                'total': 15658.0,
                'unit': 'MiB'
            }
            ram_instance_mock.options = {
                'warning_use_percent': 33.3,
                'danger_use_percent': 66.7
            }

            RAM.output(ram_instance_mock, output_mock)
            self.assertEqual(
                output_mock.append.call_args[0][1],
                f'{Colors.GREEN_NORMAL}2043 MiB{Colors.CLEAR} / 15658 MiB')

        output_mock.reset_mock()

        with self.subTest('"Danger" output (red).'):
            ram_instance_mock.value = {
                'used': 7830.0,
                'total': 15658.0,
                'unit': 'MiB'
            }
            ram_instance_mock.options = {
                'warning_use_percent': 25,
                'danger_use_percent': 50
            }

            RAM.output(ram_instance_mock, output_mock)
            self.assertEqual(
                output_mock.append.call_args[0][1],
                f'{Colors.RED_NORMAL}7830 MiB{Colors.CLEAR} / 15658 MiB')
    def test_output_coloration(self):
        """Test `output` coloration based on user preferences"""
        load_average_mock = HelperMethods.entry_mock(LoadAverage)
        output_mock = MagicMock()

        load_average_mock.value = (0.5, 1.25, 2.5)
        load_average_mock.options = {
            "warning_threshold": 0.75,
            "danger_threshold": 2.25,
        }

        LoadAverage.output(load_average_mock, output_mock)
        self.assertEqual(
            output_mock.append.call_args[0][1],
            f"{Colors.GREEN_NORMAL}0.5{Colors.CLEAR} "
            f"{Colors.YELLOW_NORMAL}1.25{Colors.CLEAR} "
            f"{Colors.RED_NORMAL}2.5{Colors.CLEAR}",
        )
예제 #7
0
    def test_various_output_configuration(self):
        """Test `output` overloading based on user preferences"""
        gpu_instance_mock = HelperMethods.entry_mock(GPU)
        output_mock = MagicMock()

        gpu_instance_mock.value = [
            '3D GPU-MODEL-NAME TAKES ADVANTAGE', 'GPU-MODEL-NAME',
            'ANOTHER-MATCHING-VIDEO'
        ]

        with self.subTest('Single-line combined output.'):
            gpu_instance_mock.options['one_line'] = True

            GPU.output(gpu_instance_mock, output_mock)
            output_mock.append.assert_called_once_with(
                'GPU',
                '3D GPU-MODEL-NAME TAKES ADVANTAGE, GPU-MODEL-NAME, ANOTHER-MATCHING-VIDEO'
            )

        output_mock.reset_mock()

        with self.subTest('Multi-lines output.'):
            gpu_instance_mock.options['one_line'] = False

            GPU.output(gpu_instance_mock, output_mock)
            self.assertEqual(output_mock.append.call_count, 3)
            output_mock.append.assert_has_calls([
                call('GPU', '3D GPU-MODEL-NAME TAKES ADVANTAGE'),
                call('GPU', 'GPU-MODEL-NAME'),
                call('GPU', 'ANOTHER-MATCHING-VIDEO')
            ])

        output_mock.reset_mock()

        with self.subTest('No GPU detected output.'):
            gpu_instance_mock.value = []

            GPU.output(gpu_instance_mock, output_mock)
            output_mock.append.assert_called_once_with(
                'GPU', DEFAULT_CONFIG['default_strings']['not_detected'])
 def setUp(self):
     """We use these mocks so often, it's worth defining them here."""
     self.wan_ip_mock = HelperMethods.entry_mock(WanIP)
     self.output_mock = MagicMock()
예제 #9
0
    def test_fetch_virtual_env_info(self, check_output_mock, getuid_mock):
        """Test `_fetch_virtual_env_info` method"""
        model_mock = HelperMethods.entry_mock(Model)

        with self.subTest('Detected virtual environment.'):
            check_output_mock.side_effect = [
                FileNotFoundError(),  # `systemd-detect-virt` is not available.
                'xen\nxen-domU\n',  # `virt-what` example output.
                'HYPERVISOR-NAME\n'  # `dmidecode` example output.
            ]
            getuid_mock.return_value = 0

            self.assertEqual(
                Model._fetch_virtual_env_info(model_mock),  # pylint: disable=protected-access
                'HYPERVISOR-NAME (xen, xen-domU)')

        with self.subTest('Virtual environment without `dmidecode`.'):
            check_output_mock.reset_mock()
            getuid_mock.reset_mock()
            check_output_mock.side_effect = [
                FileNotFoundError(),  # `systemd-detect-virt` is not available.
                'xen\nxen-domU\n',  # `virt-what` example output.
                FileNotFoundError()  # `dmidecode` will fail.
            ]
            getuid_mock.return_value = 0

            self.assertEqual(
                Model._fetch_virtual_env_info(model_mock),  # pylint: disable=protected-access
                DEFAULT_CONFIG['default_strings']['virtual_environment'] +
                ' (xen, xen-domU)')

        with self.subTest('Virtual environment with systemd only.'):
            check_output_mock.reset_mock()
            getuid_mock.reset_mock()
            check_output_mock.side_effect = [
                'systemd-nspawn\n'  # `systemd-detect-virt` output.
            ]
            getuid_mock.return_value = 1000  # `virt-what` and `dmidecode` won't be called.

            self.assertEqual(
                Model._fetch_virtual_env_info(model_mock),  # pylint: disable=protected-access
                DEFAULT_CONFIG['default_strings']['virtual_environment'] +
                ' (systemd-nspawn)')

        with self.subTest('Virtual environment with systemd and `dmidecode`.'):
            check_output_mock.reset_mock()
            getuid_mock.reset_mock()
            check_output_mock.side_effect = [
                'systemd-nspawn\n',  # `systemd-detect-virt` example output.
                # `virt-what` won't be called (systemd call succeeded).
                'HYPERVISOR-NAME\n'  # `dmidecode` example output.
            ]
            getuid_mock.return_value = 0

            self.assertEqual(
                Model._fetch_virtual_env_info(model_mock),  # pylint: disable=protected-access
                'HYPERVISOR-NAME (systemd-nspawn)')

        with self.subTest('Not a virtual environment (systemd).'):
            check_output_mock.reset_mock()
            getuid_mock.reset_mock()
            check_output_mock.side_effect = CalledProcessError(
                1, 'systemd-detect-virt', 'none\n')

            self.assertIsNone(
                Model._fetch_virtual_env_info(model_mock)  # pylint: disable=protected-access
            )

        with self.subTest('Not a virtual environment (virt-what).'):
            check_output_mock.reset_mock()
            getuid_mock.reset_mock()
            check_output_mock.side_effect = [
                FileNotFoundError(
                ),  # `systemd-detect-virt` won't be available.
                '\n'  # `virt-what` won't detect anything.
                # `dmidecode` won't even be called.
            ]
            getuid_mock.return_value = 0

            self.assertIsNone(
                Model._fetch_virtual_env_info(model_mock)  # pylint: disable=protected-access
            )

        with self.subTest('Not a virtual environment (no tools, no root)'):
            check_output_mock.reset_mock()
            getuid_mock.reset_mock()
            check_output_mock.side_effect = [
                FileNotFoundError(
                )  # `systemd-detect-virt` won't be available.
            ]
            getuid_mock.return_value = 1000  # `virt-what` and `dmidecode` won't be called.

            self.assertIsNone(
                Model._fetch_virtual_env_info(model_mock)  # pylint: disable=protected-access
            )
예제 #10
0
 def setUp(self):
     """We use these mocks so often, it's worth defining them here."""
     self.disk_instance_mock = HelperMethods.entry_mock(Disk)
     self.output_mock = MagicMock()
예제 #11
0
 def setUp(self):
     self.temperature_mock = HelperMethods.entry_mock(Temperature)
     self.temperature_mock._temps = []  # pylint: disable=protected-access
예제 #12
0
    def test_parse_uptime_cmd(self, check_output_mock):
        """Test `_parse_uptime_cmd` static method"""
        # Create an uptime instance to perform testing.
        # It doesn't matter that its `__init__` will be called.
        uptime_instance_mock = HelperMethods.entry_mock(Uptime)

        # Keys: `uptime` outputs; values: expected `timedelta` instances.
        # We will test these with various time formats (and various numbers of users).
        # pylint: disable=line-too-long
        test_uptime_cases = {
            # Recently booted:
            '{time} up 0 sec, {user_loadavg}': timedelta(seconds=0),  # BSD, just booted
            '{time} up 1 sec, {user_loadavg}': timedelta(seconds=1),  # BSD, < 1 min uptime
            '{time} up 12 secs, {user_loadavg}': timedelta(seconds=12),  # BSD, < 1 min uptime
            '{time} up 0 min, {user_loadavg}': timedelta(minutes=0),  # Linux, < 1 min uptime
            '{time} up 1 min, {user_loadavg}': timedelta(minutes=1),
            # 1 min to 1 day
            '{time} up 12 mins, {user_loadavg}': timedelta(minutes=12),
            '{time} up 12 min, {user_loadavg}': timedelta(minutes=12),  # Variation without plural minutes
            '{time} up 1:00, {user_loadavg}': timedelta(hours=1),
            '{time} up 1:01, {user_loadavg}': timedelta(hours=1, minutes=1),
            '{time} up 1:23, {user_loadavg}': timedelta(hours=1, minutes=23),
            '{time} up 12:34, {user_loadavg}': timedelta(hours=12, minutes=34),
            # 1 day to 2 days
            '{time} up 1 day, 0 sec, {user_loadavg}': timedelta(days=1),  # BSD
            '{time} up 1 day, 1 sec, {user_loadavg}': timedelta(days=1, seconds=1),  # BSD
            '{time} up 1 day, 12 secs, {user_loadavg}': timedelta(days=1, seconds=12),  # BSD
            '{time} up 1 day, 0 min, {user_loadavg}': timedelta(days=1),  # Linux
            '{time} up 1 day, 1 min, {user_loadavg}': timedelta(days=1, minutes=1),
            '{time} up 1 day, 12 mins, {user_loadavg}': timedelta(days=1, minutes=12),
            '{time} up 1 day, 12 min, {user_loadavg}': timedelta(days=1, minutes=12),  # Variation without plural minutes
            '{time} up 1 day, 1:00, {user_loadavg}': timedelta(days=1, hours=1),
            '{time} up 1 day, 1:01, {user_loadavg}': timedelta(days=1, hours=1, minutes=1),
            '{time} up 1 day, 1:23, {user_loadavg}': timedelta(days=1, hours=1, minutes=23),
            '{time} up 1 day, 12:34, {user_loadavg}': timedelta(days=1, hours=12, minutes=34),
            # 2 days onwards
            '{time} up 12 days, 0 sec, {user_loadavg}': timedelta(days=12),  # BSD
            '{time} up 12 days, 1 sec, {user_loadavg}': timedelta(days=12, seconds=1),  # BSD
            '{time} up 12 days, 12 secs, {user_loadavg}': timedelta(days=12, seconds=12),  # BSD
            '{time} up 12 days, 0 min, {user_loadavg}': timedelta(days=12),  # Linux
            '{time} up 12 days, 1 min, {user_loadavg}': timedelta(days=12, minutes=1),
            '{time} up 12 days, 12 mins, {user_loadavg}': timedelta(days=12, minutes=12),
            '{time} up 12 day, 12 min, {user_loadavg}': timedelta(days=12, minutes=12),  # Variation without plural minutes
            '{time} up 12 days, 1:00, {user_loadavg}': timedelta(days=12, hours=1),
            '{time} up 12 days, 1:01, {user_loadavg}': timedelta(days=12, hours=1, minutes=1),
            '{time} up 12 days, 1:23, {user_loadavg}': timedelta(days=12, hours=1, minutes=23),
            '{time} up 12 days, 12:34, {user_loadavg}': timedelta(days=12, hours=12, minutes=34),
            # Very long uptimes - sanity check :)
            '{time} up 500 days, 0 sec, {user_loadavg}': timedelta(days=500),  # BSD
            '{time} up 500 days, 1 sec, {user_loadavg}': timedelta(days=500, seconds=1),  # BSD
            '{time} up 500 days, 12 secs, {user_loadavg}': timedelta(days=500, seconds=12),  # BSD
            '{time} up 500 days, 0 min, {user_loadavg}': timedelta(days=500),  # Linux
            '{time} up 500 days, 1 min, {user_loadavg}': timedelta(days=500, minutes=1),
            '{time} up 500 days, 12 mins, {user_loadavg}': timedelta(days=500, minutes=12),
            '{time} up 500 day, 12 min, {user_loadavg}': timedelta(days=500, minutes=12),  # Variation without plural minutes
            '{time} up 500 days, 1:00, {user_loadavg}': timedelta(days=500, hours=1),
            '{time} up 500 days, 1:01, {user_loadavg}': timedelta(days=500, hours=1, minutes=1),
            '{time} up 500 days, 1:23, {user_loadavg}': timedelta(days=500, hours=1, minutes=23),
            '{time} up 500 days, 12:34, {user_loadavg}': timedelta(days=500, hours=12, minutes=34)
        }
        # pylint: enable=line-too-long

        # Variations of the time in the `{time}` section.
        # These _should_ be avoided when we set the locale in `check_output`,
        # however let's check we can handle them anyway, just in case.
        time_variations = (
            '0:00', '9:43 ', '11:37  ', '19:21', '23:59',
            '12:00am', '1:10am', '1:10pm ', '6:43pm ', '8:26am ',
            '03:14:15', '09:26:12 ', '23:19:20  ',
            'nonsense_time  ', 'hopefully_works_anyway ',
            '  even with strange spacing!'
        )

        # Variations of the user count and load average section.
        # For this, we'll just combine user variations with a few load average variations.
        user_variations = (
            '1 user ', '1 user  ', ' 1 user, ', ' 1 user,  ',
            '2 users ', '2 users  ', '  2 users, ', '  2 users,  ',
            '15 users ', '15 users  ', ' 15 users, ', ' 15 users,  ',
            '150 users ', '150 users  ', '150 users, ', '150 users,  '
        )
        loadavg_variations = (
            'load averages: 1.95 1.28 2.10',
            'load average: 0.13, 0.17, 0.13',
            'we never match this part so the content here',
            '  should not affect our parsing'
        )
        user_loadavg_variations = [
            user + loadavg
            for user in user_variations
            for loadavg in loadavg_variations
        ]

        for uptime_output, expected_delta in test_uptime_cases.items():
            # We use `itertools.product` to get the permutations of our variations
            # since there are a lot of them! (a list comprehension would be slower)
            for variations in product(time_variations, user_loadavg_variations):
                check_output_mock.return_value = uptime_output.format(
                    time=variations[0],
                    user_loadavg=variations[1]
                ).encode()
                self.assertEqual(
                    uptime_instance_mock._parse_uptime_cmd(),  # pylint: disable=protected-access
                    expected_delta,
                    msg='`uptime` output: "{}"'.format(
                        uptime_output.format(
                            time=variations[0],
                            user_loadavg=variations[1]
                        )
                    )
                )

        # Check that our internal exception is correctly raised when `uptime` is not available.
        check_output_mock.side_effect = FileNotFoundError()
        self.assertRaises(
            ArcheyException,
            uptime_instance_mock._parse_uptime_cmd  # pylint: disable=protected-access
        )
예제 #13
0
    def test_various_output_cases(self):
        """Test when the device has just been started..."""
        uptime_instance_mock = HelperMethods.entry_mock(Uptime)
        output_mock = MagicMock()

        with self.subTest('Output in case of hours and minutes.'):
            uptime_instance_mock.value = {
                'days': 0,
                'hours': 2,
                'minutes': 1,
                'seconds': 0
            }
            Uptime.output(uptime_instance_mock, output_mock)
            self.assertEqual(
                output_mock.append.call_args[0][1],
                '2 hours and 1 minute'
            )

        output_mock.reset_mock()

        with self.subTest('Output in case of days, hours and minutes.'):
            uptime_instance_mock.value = {
                'days': 1,
                'hours': 1,
                'minutes': 2,
                'seconds': 0
            }
            Uptime.output(uptime_instance_mock, output_mock)
            self.assertEqual(
                output_mock.append.call_args[0][1],
                '1 day, 1 hour and 2 minutes'
            )

        output_mock.reset_mock()

        with self.subTest('Output in case of days and minutes.'):
            uptime_instance_mock.value = {
                'days': 3,
                'hours': 0,
                'minutes': 3,
                'seconds': 0
            }
            Uptime.output(uptime_instance_mock, output_mock)
            self.assertEqual(
                output_mock.append.call_args[0][1],
                '3 days and 3 minutes'
            )

        output_mock.reset_mock()

        with self.subTest('Output in case of very early execution.'):
            uptime_instance_mock.value = {
                'days': 0,
                'hours': 0,
                'minutes': 0,
                'seconds': 0
            }
            Uptime.output(uptime_instance_mock, output_mock)
            self.assertEqual(
                output_mock.append.call_args[0][1],
                '< 1 minute'
            )