import json from pathlib import Path import tempfile import unittest from unittest.mock import patch from samsara.collectors.linux import (collect_local_linux, parse_connections, parse_units, run_command, CollectionCancelled) from samsara.collectors.demo import collect_demo, LINUX_DEMO_HOST from samsara.analyzers.assessment import assess from samsara.reporting.export import export_html class LinuxTests(unittest.TestCase): def test_service_states_and_startup(self): rows = parse_units('nginx.service loaded active running Web server\nexample.service loaded inactive dead Example\n', 'nginx.service enabled enabled\nexample.service disabled disabled\n') self.assertEqual(rows[0]['state'], 'Running') self.assertEqual(rows[0]['startup'], 'enabled') self.assertEqual(rows[1]['state'], 'inactive/dead') def test_ipv4_ipv6_and_unprivileged_connections(self): rows = parse_connections('LISTEN 0 128 0.0.0.0:22 0.0.0.0:*\nESTAB 0 0 [::1]:443 [::1]:51234 users:(("nginx",pid=123,fd=7))\n') self.assertEqual(rows[0]['remote_port'], 0) self.assertIsNone(rows[0]['pid']) self.assertEqual(rows[1]['local_address'], '::1') self.assertEqual(rows[1]['state'], 'Established') self.assertEqual(rows[1]['process'], 'nginx') self.assertEqual(rows[1]['direction'], 'Unknown') @patch('samsara.collectors.linux.platform.system', return_value='Windows') def test_wrong_execution_platform(self, system): with self.assertRaises(ValueError): collect_local_linux() @patch('samsara.collectors.linux.platform.system', return_value='Linux') def test_partial_failures_never_use_demo(self, system): def unavailable(args, **kwargs): raise RuntimeError('SECRET diagnostics must not be reported') data = collect_local_linux(runner=unavailable) self.assertFalse(data['synthetic']) self.assertEqual(data['checks']['services']['status'], 'failed') self.assertEqual(data['checks']['network']['status'], 'failed') self.assertEqual(data['checks']['software']['status'], 'failed') self.assertEqual(data['inventory']['services'], []) self.assertNotIn('SECRET', json.dumps(data)) self.assertEqual(data['checks']['certificates']['status'], 'not_collected') @patch('samsara.collectors.linux.platform.system', return_value='Linux') def test_cancel(self, system): with self.assertRaises(CollectionCancelled): collect_local_linux(cancelled=lambda: True) def test_mint_and_rhel_package_parsing(self): for rpm in [False, True]: def command(args, **kwargs): if args[0] == 'ip': return '[]' if args[0] == 'rpm': return 'nginx\t1.2-1\tExample vendor\n' if args[0] == 'dpkg-query': return 'installed\tnginx:amd64\t1.2\nconfig-files\tremoved\t1.0\n' return '' with self.subTest(rpm=rpm), patch('samsara.collectors.linux.platform.system', return_value='Linux'), patch('samsara.collectors.linux.Path.is_file', return_value=rpm): data = collect_local_linux(runner=command) self.assertEqual(len(data['inventory']['software']), 1) self.assertIn('nginx', data['inventory']['software'][0]['name']) self.assertEqual(data['checks']['software']['status'], 'partial') def test_local_report_source_and_unclassified_services(self): data = collect_demo(LINUX_DEMO_HOST) data['synthetic'] = False data['server']['collection_source'] = 'Local Linux read-only collection' data['inventory']['services'] = [{'name': 'desktop-example.service', 'state': 'Running'}] result = assess(data) self.assertFalse(any(f['category'] == 'Active service' for f in result['findings'])) self.assertTrue(any(f['category'] == 'Unclassified services' for f in result['findings'])) with tempfile.TemporaryDirectory() as folder: path = Path(folder) / 'report.html' export_html(path, data, result) self.assertIn('LOCAL LINUX INVENTORY', path.read_text()) self.assertNotIn('IMPORTED INVENTORY', path.read_text()) @unittest.skipUnless(__import__('sys').platform.startswith('linux'), 'Linux command test') def test_command_timeout_and_cancellation(self): with self.assertRaisesRegex(RuntimeError, 'timed out'): run_command(['sleep', '1'], timeout=.05) with self.assertRaises(CollectionCancelled): run_command(['sleep', '1'], cancelled=lambda: True)