51 lines
3.6 KiB
Python
51 lines
3.6 KiB
Python
import json
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
from unittest.mock import patch,Mock
|
|
from docker_support import DockerSupport
|
|
from deploy.docker_helper import Manager,MANAGED_LABEL,ROLE_LABEL,PACKAGES
|
|
|
|
class DockerTests(unittest.TestCase):
|
|
def test_absent_helper_is_not_reported_as_absent_docker(self):
|
|
with patch.object(DockerSupport,'call',side_effect=OSError()):
|
|
value=DockerSupport().status();self.assertIsNone(value['installed']);self.assertFalse(value['helper_available']);self.assertEqual(value['services'],[])
|
|
def test_inventory_requires_both_exact_labels_and_exposes_no_inspect_data(self):
|
|
with tempfile.TemporaryDirectory() as d,patch('deploy.docker_helper.run',return_value=Mock(returncode=0,stdout='a'*64+'\tstudio\timage:v1\trunning\tUp 1 minute\n')) as run:
|
|
rows=Manager(d).inventory();args=run.call_args.args[0]
|
|
self.assertIn('label='+MANAGED_LABEL,args);self.assertIn('label='+ROLE_LABEL,args)
|
|
self.assertEqual(set(rows[0]),{'id','name','image','state','status'})
|
|
self.assertNotIn('inspect',args)
|
|
def test_arbitrary_helper_actions_are_rejected(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
manager=Manager(d)
|
|
for data in ({'action':'exec','command':'id'},{'action':'stop'},[],{'action':'install','args':['--privileged']}):
|
|
with self.assertRaises(ValueError):manager.dispatch(data)
|
|
def test_existing_docker_is_never_reinstalled(self):
|
|
with tempfile.TemporaryDirectory() as d,patch('deploy.docker_helper.release',return_value={'ID':'debian','VERSION_ID':'13'}),patch('deploy.docker_helper.Path.exists',return_value=True),patch('deploy.docker_helper.threading.Thread') as thread:
|
|
manager=Manager.__new__(Manager);manager.allow_install=True;manager.lock=__import__('threading').RLock();manager.job=None
|
|
with self.assertRaises(ValueError):manager.install()
|
|
thread.assert_not_called()
|
|
def test_missing_authorization_prevents_install(self):
|
|
with tempfile.TemporaryDirectory() as d,patch('deploy.docker_helper.release',return_value={'ID':'debian','VERSION_ID':'13'}),patch('deploy.docker_helper.Path.exists',return_value=False):
|
|
manager=Manager(d);self.assertFalse(manager.preflight()[0])
|
|
with self.assertRaises(ValueError):manager.install()
|
|
def test_install_uses_fixed_official_packages_and_checks_compose(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
root=Path(d);(root/'etc/apt/sources.list.d').mkdir(parents=True)
|
|
manager=Manager(root/'state',True);manager.job={'state':'running'};commands=[]
|
|
def path(value):return root/str(value).lstrip('/')
|
|
def checked(args):
|
|
commands.append(args)
|
|
if args[0]=='/usr/bin/curl':Path(args[-1]).touch()
|
|
with patch('deploy.docker_helper.release',return_value={'ID':'debian','VERSION_ID':'13'}),patch('deploy.docker_helper.run',return_value=Mock(stdout='amd64\n')),patch('deploy.docker_helper.Path',side_effect=path),patch.object(manager,'_checked',side_effect=checked):manager._install()
|
|
self.assertEqual(manager.job['state'],'complete')
|
|
self.assertIn(['/usr/bin/apt-get','install','-y','--no-remove',*PACKAGES],commands)
|
|
self.assertIn(['/usr/bin/docker','compose','version','--short'],commands)
|
|
self.assertFalse(any('restart' in c or 'reboot' in c for c in commands))
|
|
def test_package_failure_does_not_claim_success_or_reboot(self):
|
|
with tempfile.TemporaryDirectory() as d:
|
|
manager=Manager(d,True);manager.job={'state':'running'}
|
|
with patch('deploy.docker_helper.release',return_value={'VERSION_ID':'13'}),patch('deploy.docker_helper.run',return_value=Mock(stdout='amd64')),patch.object(manager,'_checked',side_effect=ValueError('failed')):manager._install()
|
|
self.assertEqual(manager.job['state'],'failed')
|