def test_format_to_json(self, print_mock, _, __): """Test how the `output` method handles JSON preferred formatting of entries""" output = Output(format_to_json=True) # We can't set the `name` attribute of a mock on its creation, # so this is a little bit messy... mocked_entries = [ Mock(value='test'), Mock(value=0xDEAD) ] mocked_entries[0].name = 'test' mocked_entries[1].name = 'name' output._entries = mocked_entries # pylint: disable=protected-access output.output() # Check that `print` output is properly formatted as JSON, with expected results. output_json_data = json.loads(print_mock.call_args[0][0])['data'] self.assertEqual( output_json_data['test'], 'test' ) self.assertEqual( output_json_data['name'], 0xDEAD )
def test_line_wrapping(self, print_mock, termsize_mock, _, __): """Test how the `output` method handles wrapping lines that are too long""" output = Output() # We only need a column value for the terminal size termsize_tuple = namedtuple('termsize_tuple', 'columns') termsize_mock.return_value = termsize_tuple(10) output._results = [ # pylint: disable=protected-access 'short', # no truncation - too short 'looooooong', # truncation - too long 'tenchars', # no truncation - exactly the right width '\x1b[0;31mshort\x1b[0m', # no truncation - too short '\x1b[0;31mlooooooong\x1b[0m' # truncation - too long, long word truncated ] output.output() print_mock.assert_called_with("""\ W short O \x1b[0m... O tenchars O \x1b[0;31mshort\x1b[0m O \x1b[0;31m\x1b[0m...\x1b[0m\ """) # Check that `print` has been called only once. # `unittest.mock.Mock.assert_called_once` is not available against Python < 3.6. self.assertEqual(print_mock.call_count, 1)
def test_line_wrapping(self, print_mock, termsize_mock, _, __, ___, ____): """Test how the `output` method handles wrapping lines that are too long""" output = Output() # We only need a column value for the terminal size termsize_tuple = namedtuple('termsize_tuple', 'columns') termsize_mock.return_value = termsize_tuple(13) output._results = [ # pylint: disable=protected-access 'short', # no truncation - too short 'looooooong', # truncation - too long 'adjusted', # no truncation - exactly the right width '\x1b[0;31mshort\x1b[0m', # no truncation - too short '\x1b[0;31mlooooooong\x1b[0m' # truncation - too long, long word truncated ] output.output() print_mock.assert_called_with("""\ W short O \x1b[0m... O adjusted O \x1b[0;31mshort\x1b[0m O \x1b[0;31m\x1b[0m...\x1b[0m\ """) # Check that `print` has been called only once. self.assertTrue(print_mock.assert_called_once)
def test_append_custom_entries_color(self, _, __): """Check that `Output` honor `ANSI_COLOR` as required""" output = Output() output.append("key", "value") self.assertListEqual( output._results, # pylint: disable=protected-access [f"\x1b[5;31;47mkey:{Colors.CLEAR} value"])
def test_append_regular(self, _, __): """Test the `append` method, for new entries""" output = Output() output.append('KEY', 'VALUE') self.assertListEqual( output._results, # pylint: disable=protected-access ['COLOR_0KEY:{clear} VALUE'.format(clear=Colors.CLEAR)])
def test_append(self): """Test the `append` method, for new entries""" output = Output() # Let's manually set the distribution for the test case... output.distribution = Distributions.DEBIAN output.append('KEY', 'VALUE') self.assertEqual(output.results, ['COLOR_1KEY:CLEAR VALUE'])
def test_append_ansi_color(self, _, __): """Check that `Output` honor `ANSI_COLOR` as required""" output = Output() output.append("key", "value") # Slackware logo got three colors, so let's check they have been correctly replaced. self.assertTrue( all('ANSI_COLOR' in str(color) for color in output._colors) # pylint: disable=protected-access ) self.assertEqual( len(output._colors), # pylint: disable=protected-access 3 # Slackware's logo got 3 defined colors. ) self.assertListEqual( output._results, # pylint: disable=protected-access [f"\x1b[ANSI_COLORmkey:{Colors.CLEAR} value"])
def test_init_windows_subsystem(self, _, __): """Test output for Windows Subsystem Linux""" output = Output() self.assertEqual( output.distribution, Distributions.WINDOWS )
def test_init_unknown_distro(self, _, __): """Test unknown distribution output""" output = Output() self.assertEqual( output.distribution, Distributions.LINUX )
def test_init_known_distro(self, _, __): """Test known distribution output""" output = Output() self.assertEqual( output.distribution, Distributions.DEBIAN )
def test_init_distro_like_first(self, _, __, ___, ____): """Test distribution matching from the `os-release`'s `ID_LIKE` option (multiple entries)""" output = Output() self.assertEqual( output._distribution, # pylint: disable=protected-access Distributions.LINUX_MINT )
def test_init_distro_like(self, _, __, ___, ____): """Test distribution matching from the `os-release`'s `ID_LIKE` option""" output = Output() self.assertEqual( output._distribution, # pylint: disable=protected-access Distributions.UBUNTU )
def test_init_both_distro_calls_fail(self, _, __, ___, ____): """Test distribution fall-back when `distro` soft-fail two times""" output = Output() self.assertEqual( output._distribution, # pylint: disable=protected-access Distributions.LINUX )
def test_init_unknown_distro(self, _, __, ___, ____): """Test unknown distribution output""" output = Output() self.assertEqual( output._distribution, # pylint: disable=protected-access Distributions.LINUX )
def test_init_windows_subsystem(self, _, __): """Test output for Windows Subsystem Linux""" output = Output() self.assertEqual( output._distribution, # pylint: disable=protected-access Distributions.WINDOWS )
def test_init_distro_like_second(self, _, __, ___, ____): """Test distribution matching from the `os-release`'s `ID_LIKE` option (second candidate)""" output = Output() self.assertEqual( output._distribution, # pylint: disable=protected-access Distributions.ARCH_LINUX )
def test_preferred_distribution(self, _, run_detection_mock): """Simple test checking behavior when `preferred_distribution` is passed at instantiation""" output = Output(preferred_distribution='rhel') self.assertEqual( output._distribution, # pylint: disable=protected-access Distributions.RED_HAT) # Check `Distributions.run_detection` method has not been called at all. self.assertFalse(run_detection_mock.called)
def test_append_no_ansi_color(self, _, __): """Check that `Output` DOES NOT honor `ANSI_COLOR` when specified""" output = Output() output.append("key", "value") # Check that NO colors have been replaced (actually, that the list is the same as before). self.assertFalse( any('ANSI_COLOR' in str(color) for color in output._colors) # pylint: disable=protected-access ) self.assertListEqual( output._colors, # pylint: disable=protected-access [ # Windows' colors palettes, unmodified. Colors.BLUE_BRIGHT, Colors.RED_BRIGHT, Colors.GREEN_BRIGHT, Colors.YELLOW_NORMAL ]) self.assertListEqual( output._results, # pylint: disable=protected-access [f"{Colors.BLUE_BRIGHT}key:{Colors.CLEAR} value"])
def test_append_no_ansi_color(self, _, __, ___): """Check that `Output` DOES NOT honor `ANSI_COLOR` when specified""" output = Output() # Check that NO colors have been replaced (actually, that the list is the same as before). self.assertFalse( any('ANSI_COLOR' in str(color) for color in output._colors_palette) # pylint: disable=protected-access ) self.assertListEqual( output._colors_palette, # pylint: disable=protected-access COLORS_DICT[Distributions.WINDOWS])
def test_append_ansi_color(self, _, __, ___): """Check that `Output` honor `ANSI_COLOR` as required""" output = Output() # Slackware logo got three colors, so let's check they have been correctly replaced. self.assertTrue( all('ANSI_COLOR' in str(color) for color in output._colors_palette) # pylint: disable=protected-access ) self.assertEqual( len(output._colors_palette), # pylint: disable=protected-access len(COLORS_DICT[Distributions.SLACKWARE]))
def test_append_ansi_color(self, _, __, ___): """Check that `Output` honor `ANSI_COLOR` as required""" output = Output() # Slackware logo got three colors, so let's check they have been correctly replaced. self.assertTrue( all('ANSI_COLOR' in str(color) for color in output._colors) # pylint: disable=protected-access ) self.assertEqual( len(output._colors), # pylint: disable=protected-access 3 # Slackware's logo got 3 defined colors. )
def main(): """Simple entry point""" # `Processes` is a singleton, let's populate the internal list here. Processes() # `Configuration` is a singleton, let's populate the internal object here. configuration = Configuration() output = Output() for entry in Entries: if configuration.get('entries', {}).get(entry.name, True): output.append(entry.name, entry.value().value) output.output()
def main(): """Simple entry point""" args = args_parsing() # `Processes` is a singleton, let's populate the internal list here. Processes() # `Configuration` is a singleton, let's populate the internal object here. configuration = Configuration(config_path=args.config_path) # From configuration, gather the entries user-enabled. enabled_entries = [ (entry.value, entry.name) for entry in Entries if configuration.get('entries', {}).get(entry.name, True) ] output = Output(preferred_distribution=args.distribution, format_to_json=args.json) # We will map this function onto our enabled entries to instantiate them. def _entry_instantiator(entry_tuple): return entry_tuple[0](name=entry_tuple[1]) # Let's use a context manager stack to manage conditional use of `TheadPoolExecutor`. with ExitStack() as cm_stack: if not configuration.get('parallel_loading'): mapper = map else: # Instantiate a threads pool to load our enabled entries in parallel. # We use threads (and not processes) since most work done by our entries is IO-bound. # `max_workers` is manually computed to mimic Python 3.8+ behaviour, but for our needs. # See <https://github.com/python/cpython/pull/13618>. executor = cm_stack.enter_context( ThreadPoolExecutor(max_workers=min( len(enabled_entries) or 1, (os.cpu_count() or 1) + 4))) mapper = executor.map for entry_instance in mapper(_entry_instantiator, enabled_entries): output.add_entry(entry_instance) output.output() # Has the screenshot flag been specified ? if args.screenshot is not None: # If so, but still _falsy_, pass `None` as no output file has been specified by the user. take_screenshot((args.screenshot or None))
def main(): """Simple entry point""" parser = argparse.ArgumentParser(prog='archey') parser.add_argument('-v', '--version', action='version', version=__version__) parser.parse_args() # `Processes` is a singleton, let's populate the internal list here. Processes() # `Configuration` is a singleton, let's populate the internal object here. configuration = Configuration() output = Output() for entry in Entries: if configuration.get('entries', {}).get(entry.name, True): output.append(entry.name, entry.value().value) output.output()
def test_centered_output(self, print_mock, _, __): """Test how the `output` method handles centering operations""" output = Output() # # ODD ENTRIES NUMBER # # # Entries smaller than logo output._results = [ # pylint: disable=protected-access '1', '2', '3' ] # Let's run the algorithm ! output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '1', '2', '3', '', '', '', '', '', '', '', '' ]) # Entries bigger than logo output._results = [ # pylint: disable=protected-access '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21' ] output.output() print_mock.assert_called_with("""\ FAKE_COLOR 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 FAKE_COLOR 20 FAKE_COLOR 21\x1b[0m\ """) # # EVEN ENTRIES NUMBER # # # Entries smaller than logo output._results = [ # pylint: disable=protected-access '1', '2', '3', '4' ] output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '1', '2', '3', '4', '', '', '', '', '', '', '' ]) # Entries bigger than logo output._results = [ # pylint: disable=protected-access '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22' ] output.output() print_mock.assert_called_with("""\ FAKE_COLOR 1 FAKE_COLOR 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 FAKE_COLOR 21 FAKE_COLOR 22\x1b[0m\ """) # # FULL ENTRIES # # output._results = [ # pylint: disable=protected-access '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ] output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ]) # # NO ENTRY # # output._results = [] # pylint: disable=protected-access output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ])
def test_centered_output(self, _): """Test how the `output` method handle centering operations""" output = Output() # Let's manually set the distribution for the test case... output.distribution = Distributions.DEBIAN # # ODD ENTRIES NUMBER # # output.results = [ '1', '2', '3' ] # Let's run the algorithm ! output.output() self.assertListEqual( output.results, [ '', '', '', '', '', '', '', '1', '2', '3', '', '', '', '', '', '', '', '' ] ) # # EVEN ENTRIES NUMBER # # output.results = [ '1', '2', '3', '4' ] output.output() self.assertListEqual( output.results, [ '', '', '', '', '', '', '', '1', '2', '3', '4', '', '', '', '', '', '', '' ] ) # # FULL ENTRIES # # output.results = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ] output.output() self.assertListEqual( output.results, [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ] ) # # NO ENTRY # # output.results = [] output.output() self.assertListEqual( output.results, [ '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ] )
def test_centered_output(self, _, __, ___, ____): """Test how the `output` method handles centering operations""" output = Output() # # ODD ENTRIES NUMBER # # output._results = [ # pylint: disable=protected-access '1', '2', '3' ] # Let's run the algorithm ! output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '1', '2', '3', '', '', '', '', '', '', '', '' ] ) # # EVEN ENTRIES NUMBER # # output._results = [ # pylint: disable=protected-access '1', '2', '3', '4' ] output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '1', '2', '3', '4', '', '', '', '', '', '', '' ] ) # # FULL ENTRIES # # output._results = [ # pylint: disable=protected-access '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ] output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ] ) # # NO ENTRY # # output._results = [] # pylint: disable=protected-access output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ] )
def test_centered_output(self, print_mock, _, __, ___): """Test how the `output` method handles centering operations""" output = Output() with self.subTest( 'Odd number of entries (entries smaller than logo).'): output._results = [ # pylint: disable=protected-access '1', '2', '3' ] output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '1', '2', '3', '', '', '', '', '', '', '', '' ]) with self.subTest('Odd number of entries (entries bigger than logo).'): output._results = [ # pylint: disable=protected-access '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21' ] output.output() print_mock.assert_called_with("""\ FAKE_COLOR 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 FAKE_COLOR 20 FAKE_COLOR 21\x1b[0m\ """) output = Output() with self.subTest( 'Even number of entries (entries smaller than logo).'): output._results = [ # pylint: disable=protected-access '1', '2', '3', '4' ] output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '1', '2', '3', '4', '', '', '', '', '', '', '' ]) with self.subTest( 'Even number of entries (entries bigger than logo).'): output._results = [ # pylint: disable=protected-access '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22' ] output.output() print_mock.assert_called_with("""\ FAKE_COLOR 1 FAKE_COLOR 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 FAKE_COLOR 21 FAKE_COLOR 22\x1b[0m\ """) output = Output() with self.subTest('Full entries.'): output._results = [ # pylint: disable=protected-access '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ] output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18' ]) output = Output() with self.subTest('No entry.'): output._results = [] # pylint: disable=protected-access output.output() self.assertListEqual( output._results, # pylint: disable=protected-access [ '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ])
def main(): """Simple entry point""" args = args_parsing() # Setup logging. logging.basicConfig(format='%(levelname)s: %(message)s') # Populate our internal singletons once and for all. Processes() Environment() configuration = Configuration(config_path=args.config_path) # From configuration, gather the entries user-configured. available_entries = configuration.get('entries') if available_entries is None: # If none were specified, lazy-mimic a full-enabled entries list without any configuration. available_entries = [{'type': entry_name} for entry_name in Entries.__members__.keys()] output = Output( preferred_logo_style=args.logo_style, preferred_distribution=args.distribution, format_to_json=args.json ) # We will map this function onto our enabled entries to instantiate them. def _entry_instantiator(entry: dict) -> Optional[Entry]: # Based on **required** `type` field, instantiate the corresponding `Entry` object. try: return Entries[entry.pop('type')].value( name=entry.pop('name', None), # `name` is fully-optional. options=entry # Remaining fields should be propagated as options. ) except KeyError as key_error: logging.warning( 'One entry (misses or) uses an invalid `type` field (%s).', key_error ) return None # Let's use a context manager stack to manage conditional use of `TheadPoolExecutor`. with ExitStack() as cm_stack: if not configuration.get('parallel_loading'): mapper = map else: # Instantiate a threads pool to load our enabled entries in parallel. # We use threads (and not processes) since most work done by our entries is IO-bound. # `max_workers` is manually computed to mimic Python 3.8+ behaviour, but for our needs. # See <https://github.com/python/cpython/pull/13618>. executor = cm_stack.enter_context(ThreadPoolExecutor( max_workers=min(len(available_entries) or 1, (os.cpu_count() or 1) + 4) )) mapper = executor.map for entry_instance in mapper(_entry_instantiator, available_entries): if not entry_instance: continue output.add_entry(entry_instance) output.output() # Has the screenshot flag been specified ? if args.screenshot is not None: # If so, but still _falsy_, pass `None` as no output file has been specified by the user. try: screenshot_taken = take_screenshot((args.screenshot or None)) except KeyboardInterrupt: screenshot_taken = False print() finally: sys.exit((not screenshot_taken))