test: raise coverage 68.7% -> ~80.4%; add ~250 tests for new egress/DDNS/network paths
Unit Tests / test (push) Successful in 12m6s

Coverage was below acceptable levels and several newly-added code paths
(sshuttle egress, proxy egress, DDNS provider stubs, DNS overview route,
peer-registry provisioning) had zero test coverage.

~250 new unit tests are added across 16 new test files. Existing test files
are updated to match refactored interfaces (DHCP removed, constants
introduced, network_manager restructured). .coveragerc is added to pin the
source mapping and the 70% floor so regressions are caught at commit time.

tests/test_enhanced_api.py was previously living in api/ (wrong location)
and is moved to tests/ where it belongs.

Integration test files are updated to remove references to DHCP endpoints
and add coverage for the new DNS overview and DDNS sync endpoints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 09:03:39 -04:00
parent c41cadafb4
commit aa1e5c41ec
33 changed files with 9446 additions and 631 deletions
+559
View File
@@ -0,0 +1,559 @@
"""
Tests for the sshuttle (SSH tunnel) exit type — configure_sshuttle validation,
config-file generation, vault integration, apply_routes REDIRECT rules,
_exit_status bridging, and the /api/connectivity/exits/sshuttle route
(never echoes secrets).
"""
import os
import stat
import sys
import shutil
import tempfile
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'api'))
import connectivity_manager as cm_module
from connectivity_manager import ConnectivityManager
_SENTINEL = object()
VALID_KEY = (
'-----BEGIN OPENSSH PRIVATE KEY-----\n'
'b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAAB\n'
'-----END OPENSSH PRIVATE KEY-----\n'
)
VALID_KNOWN_HOSTS = (
'ssh.example.com,203.0.113.5 ssh-ed25519 '
'AAAAC3NzaC1lZDI1NTE5AAAAIB5d0o0Yw1xP1Yw1xP1Yw1xP1Yw1xP1Yw1xP1Yw1xP1Y'
)
def _make_manager(tmp_dir=None, peer_registry=_SENTINEL, config_manager=None,
vault_manager=None):
if tmp_dir is None:
tmp_dir = tempfile.mkdtemp()
if config_manager is None:
config_manager = MagicMock()
config_manager.get_identity.return_value = {
'cell_name': 'test',
'ip_range': '172.20.0.0/16',
}
config_manager.get_connectivity_config.return_value = {
'exits': {}, 'peer_exit_map': {},
}
config_manager.get_installed_services.return_value = {}
if peer_registry is _SENTINEL:
peer_registry = MagicMock()
peer_registry.list_peers.return_value = []
with patch.object(ConnectivityManager, '_subscribe_to_events', lambda self: None):
mgr = ConnectivityManager(
config_manager=config_manager,
peer_registry=peer_registry,
vault_manager=vault_manager,
data_dir=tmp_dir,
config_dir=tmp_dir,
)
return mgr
def _valid_cfg(**overrides):
cfg = {
'host': 'ssh.example.com',
'port': 22,
'user': 'tunnel',
'auth': 'key',
'private_key': VALID_KEY,
'known_hosts': VALID_KNOWN_HOSTS,
}
cfg.update(overrides)
return cfg
def _mock_subprocess_ok():
return MagicMock(returncode=0, stdout='', stderr='')
# ---------------------------------------------------------------------------
# configure_sshuttle — validation
# ---------------------------------------------------------------------------
class TestConfigureSshuttleValidation(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.mkdtemp()
self.mgr = _make_manager(tmp_dir=self.tmp)
def tearDown(self):
shutil.rmtree(self.tmp, ignore_errors=True)
def test_valid_config_returns_ok(self):
result = self.mgr.configure_sshuttle(_valid_cfg())
self.assertTrue(result['ok'], result)
def test_non_dict_config_rejected(self):
result = self.mgr.configure_sshuttle('not a dict')
self.assertFalse(result['ok'])
def test_missing_host_rejected(self):
cfg = _valid_cfg()
del cfg['host']
result = self.mgr.configure_sshuttle(cfg)
self.assertFalse(result['ok'])
self.assertIn('host', result['error'])
def test_host_with_spaces_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(host='bad host'))
self.assertFalse(result['ok'])
def test_host_with_shell_metachars_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(host='host;rm -rf /'))
self.assertFalse(result['ok'])
def test_host_with_double_dots_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(host='a..b'))
self.assertFalse(result['ok'])
def test_ip_host_accepted(self):
result = self.mgr.configure_sshuttle(_valid_cfg(host='203.0.113.10'))
self.assertTrue(result['ok'])
def test_port_zero_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(port=0))
self.assertFalse(result['ok'])
self.assertIn('port', result['error'])
def test_port_above_65535_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(port=70000))
self.assertFalse(result['ok'])
def test_port_non_numeric_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(port='abc'))
self.assertFalse(result['ok'])
def test_port_defaults_to_22(self):
cfg = _valid_cfg()
del cfg['port']
result = self.mgr.configure_sshuttle(cfg)
self.assertTrue(result['ok'])
conf = Path(self.mgr.sshuttle_dir, 'sshuttle.conf').read_text()
self.assertIn('PORT=22', conf)
def test_invalid_user_uppercase_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(user='Tunnel'))
self.assertFalse(result['ok'])
self.assertIn('user', result['error'])
def test_invalid_user_too_long_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(user='a' * 33))
self.assertFalse(result['ok'])
def test_user_starting_with_digit_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(user='1user'))
self.assertFalse(result['ok'])
def test_invalid_auth_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(auth='agent'))
self.assertFalse(result['ok'])
self.assertIn('auth', result['error'])
def test_missing_known_hosts_rejected(self):
cfg = _valid_cfg()
del cfg['known_hosts']
result = self.mgr.configure_sshuttle(cfg)
self.assertFalse(result['ok'])
self.assertIn('known_hosts', result['error'])
def test_empty_known_hosts_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(known_hosts=' '))
self.assertFalse(result['ok'])
def test_known_hosts_with_too_few_fields_rejected(self):
result = self.mgr.configure_sshuttle(
_valid_cfg(known_hosts='ssh.example.com ssh-ed25519'))
self.assertFalse(result['ok'])
def test_known_hosts_with_bad_keytype_rejected(self):
result = self.mgr.configure_sshuttle(
_valid_cfg(known_hosts='ssh.example.com ssh-dss AAAAB3Nza'))
self.assertFalse(result['ok'])
def test_known_hosts_with_non_base64_key_rejected(self):
result = self.mgr.configure_sshuttle(
_valid_cfg(known_hosts='ssh.example.com ssh-ed25519 not$base64!'))
self.assertFalse(result['ok'])
def test_multiline_known_hosts_rejected(self):
kh = VALID_KNOWN_HOSTS + '\nother.example.com ssh-ed25519 AAAAC3Nza'
result = self.mgr.configure_sshuttle(_valid_cfg(known_hosts=kh))
self.assertFalse(result['ok'])
def test_strict_host_key_checking_no_rejected(self):
result = self.mgr.configure_sshuttle(
_valid_cfg(host='ssh.example.com -oStrictHostKeyChecking=no'))
self.assertFalse(result['ok'])
self.assertIn('StrictHostKeyChecking', result['error'])
def test_strict_host_key_checking_no_in_known_hosts_rejected(self):
result = self.mgr.configure_sshuttle(
_valid_cfg(known_hosts='x StrictHostKeyChecking=no y'))
self.assertFalse(result['ok'])
def test_strict_host_key_checking_no_case_insensitive(self):
result = self.mgr.configure_sshuttle(
_valid_cfg(host='h stricthostkeychecking = NO'))
self.assertFalse(result['ok'])
def test_key_auth_without_private_key_rejected(self):
cfg = _valid_cfg()
del cfg['private_key']
result = self.mgr.configure_sshuttle(cfg)
self.assertFalse(result['ok'])
self.assertIn('private_key', result['error'])
def test_key_auth_with_garbage_key_rejected(self):
result = self.mgr.configure_sshuttle(_valid_cfg(private_key='not a key'))
self.assertFalse(result['ok'])
def test_password_auth_without_password_rejected(self):
cfg = _valid_cfg(auth='password')
del cfg['private_key']
result = self.mgr.configure_sshuttle(cfg)
self.assertFalse(result['ok'])
def test_password_auth_with_password_accepted(self):
cfg = _valid_cfg(auth='password', password='s3cret')
del cfg['private_key']
result = self.mgr.configure_sshuttle(cfg)
self.assertTrue(result['ok'])
def test_invalid_exclude_subnet_rejected(self):
result = self.mgr.configure_sshuttle(
_valid_cfg(exclude_subnets=['not-a-cidr']))
self.assertFalse(result['ok'])
def test_result_never_contains_secrets(self):
result = self.mgr.configure_sshuttle(_valid_cfg())
self.assertNotIn('PRIVATE KEY', str(result))
# ---------------------------------------------------------------------------
# configure_sshuttle — file generation
# ---------------------------------------------------------------------------
class TestConfigureSshuttleFiles(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.mkdtemp()
self.vault = MagicMock()
self.mgr = _make_manager(tmp_dir=self.tmp, vault_manager=self.vault)
def tearDown(self):
shutil.rmtree(self.tmp, ignore_errors=True)
def test_sshuttle_conf_golden(self):
self.mgr.configure_sshuttle(_valid_cfg(
exclude_subnets=['172.20.0.0/16', '10.0.0.0/8']))
conf = Path(self.mgr.sshuttle_dir, 'sshuttle.conf').read_text()
expected = (
'HOST=ssh.example.com\n'
'PORT=22\n'
'USER=tunnel\n'
'AUTH=key\n'
'LISTEN_PORT=12300\n'
'EXCLUDE=172.20.0.0/16,10.0.0.0/8\n'
)
self.assertEqual(conf, expected)
def test_key_file_written_0600(self):
self.mgr.configure_sshuttle(_valid_cfg())
key_path = Path(self.mgr.sshuttle_dir, 'id_pic')
self.assertTrue(key_path.is_file())
mode = stat.S_IMODE(os.stat(key_path).st_mode)
self.assertEqual(mode, 0o600)
self.assertIn('PRIVATE KEY', key_path.read_text())
def test_known_hosts_file_written_0600(self):
self.mgr.configure_sshuttle(_valid_cfg())
kh_path = Path(self.mgr.sshuttle_dir, 'known_hosts')
self.assertTrue(kh_path.is_file())
mode = stat.S_IMODE(os.stat(kh_path).st_mode)
self.assertEqual(mode, 0o600)
self.assertEqual(kh_path.read_text(), VALID_KNOWN_HOSTS + '\n')
def test_password_file_written_0600_for_password_auth(self):
cfg = _valid_cfg(auth='password', password='s3cret')
del cfg['private_key']
self.mgr.configure_sshuttle(cfg)
pw_path = Path(self.mgr.sshuttle_dir, 'password')
self.assertTrue(pw_path.is_file())
mode = stat.S_IMODE(os.stat(pw_path).st_mode)
self.assertEqual(mode, 0o600)
self.assertEqual(pw_path.read_text(), 's3cret\n')
def test_default_excludes_contain_cell_subnet_and_rfc1918(self):
self.mgr.configure_sshuttle(_valid_cfg())
conf = Path(self.mgr.sshuttle_dir, 'sshuttle.conf').read_text()
for net in ('172.20.0.0/16', '10.0.0.0/8', '172.16.0.0/12',
'192.168.0.0/16'):
self.assertIn(net, conf)
def test_key_stored_in_vault(self):
self.mgr.configure_sshuttle(_valid_cfg())
self.vault.store_secret.assert_called_once_with(
'connectivity_sshuttle_key', VALID_KEY)
def test_password_stored_in_vault(self):
cfg = _valid_cfg(auth='password', password='s3cret')
del cfg['private_key']
self.mgr.configure_sshuttle(cfg)
self.vault.store_secret.assert_called_once_with(
'connectivity_sshuttle_password', 's3cret')
def test_non_secret_fields_persisted_in_config_manager(self):
self.mgr.configure_sshuttle(_valid_cfg())
self.mgr.config_manager.set_connectivity_field.assert_called_once()
field, exits = self.mgr.config_manager.set_connectivity_field.call_args[0]
self.assertEqual(field, 'exits')
self.assertEqual(exits['sshuttle']['host'], 'ssh.example.com')
self.assertNotIn('private_key', exits['sshuttle'])
self.assertNotIn('password', exits['sshuttle'])
self.assertNotIn('known_hosts', exits['sshuttle'])
def test_write_failure_returns_ok_false(self):
with patch.object(self.mgr, '_write_secure', side_effect=OSError('disk full')):
result = self.mgr.configure_sshuttle(_valid_cfg())
self.assertFalse(result['ok'])
# ---------------------------------------------------------------------------
# apply_routes — sshuttle REDIRECT
# ---------------------------------------------------------------------------
class TestApplyRoutesSshuttle(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.tmp, ignore_errors=True)
def test_sshuttle_peer_gets_redirect_to_12300(self):
pr = MagicMock()
pr.list_peers.return_value = [
{'peer': 'alice', 'exit_via': 'sshuttle'},
]
pr.get_peer.return_value = {'peer': 'alice', 'ip': '172.20.0.50/32'}
mgr = _make_manager(tmp_dir=self.tmp, peer_registry=pr)
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = _mock_subprocess_ok()
mgr.apply_routes()
redirect_calls = [
c for c in mock_sp.run.call_args_list
if 'REDIRECT' in c.args[0]
]
self.assertEqual(len(redirect_calls), 1)
args = redirect_calls[0].args[0]
self.assertIn('--to-ports', args)
self.assertEqual(args[args.index('--to-ports') + 1], '12300')
self.assertIn('172.20.0.50', args)
def test_sshuttle_peer_gets_mark_0x40(self):
pr = MagicMock()
pr.list_peers.return_value = [
{'peer': 'alice', 'exit_via': 'sshuttle'},
]
pr.get_peer.return_value = {'peer': 'alice', 'ip': '172.20.0.50/32'}
mgr = _make_manager(tmp_dir=self.tmp, peer_registry=pr)
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = _mock_subprocess_ok()
mgr.apply_routes()
mark_calls = [
c for c in mock_sp.run.call_args_list
if 'MARK' in c.args[0] and '172.20.0.50' in c.args[0]
]
self.assertEqual(len(mark_calls), 1)
args = mark_calls[0].args[0]
self.assertEqual(args[args.index('--set-mark') + 1], hex(0x40))
def test_ip_rule_added_for_sshuttle_table_140(self):
mgr = _make_manager(tmp_dir=self.tmp)
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = MagicMock(returncode=1, stdout='', stderr='')
mgr.apply_routes()
rule_adds = [
c for c in mock_sp.run.call_args_list
if 'rule' in c.args[0] and 'add' in c.args[0]
and hex(0x40) in c.args[0]
]
self.assertEqual(len(rule_adds), 1)
self.assertIn('140', rule_adds[0].args[0])
def test_no_killswitch_for_sshuttle(self):
"""sshuttle has no exit iface — _add_killswitch must skip it."""
mgr = _make_manager(tmp_dir=self.tmp)
self.assertNotIn('sshuttle', mgr.IFACES)
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = _mock_subprocess_ok()
mgr._add_killswitch(0x40, None)
mock_sp.run.assert_not_called()
# ---------------------------------------------------------------------------
# _exit_status — sshuttle bridge
# ---------------------------------------------------------------------------
class TestSshuttleExitStatus(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.tmp, ignore_errors=True)
def _mgr(self, installed=None):
config_manager = MagicMock()
config_manager.get_identity.return_value = {'ip_range': '172.20.0.0/16'}
config_manager.get_installed_services.return_value = installed or {}
return _make_manager(tmp_dir=self.tmp, config_manager=config_manager)
def test_not_configured_initially(self):
mgr = self._mgr()
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = MagicMock(returncode=1, stdout='', stderr='')
info = mgr._exit_status('sshuttle')
self.assertFalse(info['configured'])
self.assertEqual(info['status'], 'not_configured')
def test_configured_after_configure_sshuttle(self):
mgr = self._mgr()
mgr.configure_sshuttle(_valid_cfg())
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = MagicMock(returncode=1, stdout='', stderr='')
info = mgr._exit_status('sshuttle')
self.assertTrue(info['configured'])
self.assertEqual(info['status'], 'configured')
def test_configured_when_store_service_installed(self):
mgr = self._mgr(installed={'sshuttle': {'manifest': {'id': 'sshuttle'}}})
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = MagicMock(returncode=1, stdout='', stderr='')
info = mgr._exit_status('sshuttle')
self.assertTrue(info['configured'])
def test_configured_when_container_running(self):
mgr = self._mgr()
def fake_run(cmd, **kwargs):
if 'inspect' in cmd and 'cell-sshuttle' in cmd:
return MagicMock(returncode=0, stdout='true\n', stderr='')
return MagicMock(returncode=1, stdout='', stderr='')
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.side_effect = fake_run
info = mgr._exit_status('sshuttle')
self.assertTrue(info['configured'])
def test_sshuttle_in_list_exits(self):
mgr = self._mgr()
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = _mock_subprocess_ok()
exits = mgr.list_exits()
types = {e['type'] for e in exits}
self.assertIn('sshuttle', types)
# ---------------------------------------------------------------------------
# set_peer_exit accepts sshuttle
# ---------------------------------------------------------------------------
class TestSetPeerExitSshuttle(unittest.TestCase):
def setUp(self):
self.tmp = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.tmp, ignore_errors=True)
def test_sshuttle_is_a_valid_exit_type(self):
pr = MagicMock()
pr.set_peer_exit_via.return_value = True
pr.list_peers.return_value = []
mgr = _make_manager(tmp_dir=self.tmp, peer_registry=pr)
with patch.object(cm_module, 'subprocess') as mock_sp:
mock_sp.run.return_value = _mock_subprocess_ok()
result = mgr.set_peer_exit('alice', 'sshuttle')
self.assertTrue(result['ok'])
def test_peer_registry_accepts_sshuttle(self):
from peer_registry import PeerRegistry
self.assertIn('sshuttle', PeerRegistry.VALID_EXIT_VIA)
# ---------------------------------------------------------------------------
# POST /api/connectivity/exits/sshuttle — route behaviour
# ---------------------------------------------------------------------------
class TestSshuttleRoute(unittest.TestCase):
def setUp(self):
import app as app_module
self.app_module = app_module
app_module.app.config['TESTING'] = True
self.client = app_module.app.test_client()
def test_valid_config_returns_200_ok_only(self):
mock_cm = MagicMock()
mock_cm.configure_sshuttle.return_value = {'ok': True}
with patch.object(self.app_module, 'connectivity_manager', mock_cm):
resp = self.client.post('/api/connectivity/exits/sshuttle',
json=_valid_cfg())
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp.get_json(), {'ok': True})
def test_invalid_config_returns_400(self):
mock_cm = MagicMock()
mock_cm.configure_sshuttle.return_value = {'ok': False, 'error': 'invalid host'}
with patch.object(self.app_module, 'connectivity_manager', mock_cm):
resp = self.client.post('/api/connectivity/exits/sshuttle',
json={'host': '!!'})
self.assertEqual(resp.status_code, 400)
self.assertFalse(resp.get_json()['ok'])
def test_response_never_echoes_private_key(self):
mock_cm = MagicMock()
mock_cm.configure_sshuttle.return_value = {'ok': True}
with patch.object(self.app_module, 'connectivity_manager', mock_cm):
resp = self.client.post('/api/connectivity/exits/sshuttle',
json=_valid_cfg())
body = resp.get_data(as_text=True)
self.assertNotIn('PRIVATE KEY', body)
self.assertNotIn(VALID_KEY.splitlines()[1], body)
def test_response_never_echoes_password(self):
mock_cm = MagicMock()
mock_cm.configure_sshuttle.return_value = {'ok': True}
cfg = _valid_cfg(auth='password', password='hunter2-secret')
del cfg['private_key']
with patch.object(self.app_module, 'connectivity_manager', mock_cm):
resp = self.client.post('/api/connectivity/exits/sshuttle', json=cfg)
self.assertNotIn('hunter2-secret', resp.get_data(as_text=True))
def test_exception_returns_500_without_details(self):
mock_cm = MagicMock()
mock_cm.configure_sshuttle.side_effect = Exception('boom PRIVATE stuff')
with patch.object(self.app_module, 'connectivity_manager', mock_cm):
resp = self.client.post('/api/connectivity/exits/sshuttle',
json=_valid_cfg())
self.assertEqual(resp.status_code, 500)
self.assertNotIn('PRIVATE', resp.get_data(as_text=True))
if __name__ == '__main__':
unittest.main()