Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
moreati committed Oct 10, 2024
1 parent c45b13b commit f97d7d3
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 142 deletions.
11 changes: 6 additions & 5 deletions .ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ for doing `setup.py install` while pulling a Docker container, for example.

### Environment Variables

* `DISTRO`: the `mitogen_` tests need a target Docker container distro. This
name comes from the Docker Hub `mitogen` user, i.e. `mitogen/$DISTRO-test`
* `DISTROS`: the `ansible_` tests can run against multiple targets
simultaneously, which speeds things up. This is a space-separated list of
DISTRO names, but additionally, supports:
* `MITOGEN_TEST_DISTRO_SPECS`: a space delimited list of distro specs to run
the tests against. (e.g. `centos6 ubuntu2004-py3*4`). Each spec determines
the Linux distribution, target Python interepreter & number of instances.
Only distributions with a pre-built Linux container image can be used.
* `debian-py3`: when generating Ansible inventory file, set
`ansible_python_interpreter` to `python3`, i.e. run a test where the
target interpreter is Python 3.
* `debian*16`: generate 16 Docker containers running Debian. Also works
with -py3.

* `MITOGEN_TEST_IMAGE_TEMPLATE`: specifies the Linux container image name,
and hence the container registry used for test targets.
2 changes: 1 addition & 1 deletion .ci/ansible_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def pause_if_interactive():


with ci_lib.Fold('docker_setup'):
containers = ci_lib.container_specs(ci_lib.DISTROS)
containers = ci_lib.container_specs(ci_lib.DISTRO_SPECS.split())
ci_lib.start_containers(containers)


Expand Down
8 changes: 4 additions & 4 deletions .ci/ci_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
)


DISTRO_SPECS = os.environ.get(
'MITOGEN_TEST_DISTRO_SPECS',
'centos6 centos8 debian9 debian11 ubuntu1604 ubuntu2004',
)
IMAGE_TEMPLATE = os.environ.get(
'MITOGEN_TEST_IMAGE_TEMPLATE',
'public.ecr.aws/n5z0e8q9/%(distro)s-test',
Expand Down Expand Up @@ -196,10 +200,6 @@ def __exit__(self, _1, _2, _3): pass


GIT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
# Used only when MODE=mitogen
DISTRO = os.environ.get('DISTRO', 'debian9')
# Used only when MODE=ansible
DISTROS = os.environ.get('DISTROS', 'centos6 centos8 debian9 debian11 ubuntu1604 ubuntu2004').split()
TMP = TempDir().path


Expand Down
2 changes: 0 additions & 2 deletions .ci/mitogen_py24_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
os.environ.update({
'NOCOVERAGE': '1',
'UNIT2': '/usr/local/python2.4.6/bin/unit2',

'MITOGEN_TEST_DISTRO': ci_lib.DISTRO,
'MITOGEN_LOG_LEVEL': 'debug',
'SKIP_ANSIBLE': '1',
})
Expand Down
1 change: 0 additions & 1 deletion .ci/mitogen_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import ci_lib

os.environ.update({
'MITOGEN_TEST_DISTRO': ci_lib.DISTRO,
'MITOGEN_LOG_LEVEL': 'debug',
'SKIP_ANSIBLE': '1',
})
Expand Down
78 changes: 6 additions & 72 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,80 +67,14 @@ jobs:
python_version: '3.13'
tox_env: py313-mode_ansible-ansible10-strategy_linear

- name: Mito_27_centos6
tox_env: py27-mode_mitogen-distro_centos6
- name: Mito_27_centos7
tox_env: py27-mode_mitogen-distro_centos7
- name: Mito_27_centos8
tox_env: py27-mode_mitogen-distro_centos8
- name: Mito_27_debian9
tox_env: py27-mode_mitogen-distro_debian9
- name: Mito_27_debian10
tox_env: py27-mode_mitogen-distro_debian10
- name: Mito_27_debian11
tox_env: py27-mode_mitogen-distro_debian11
- name: Mito_27_ubuntu1604
tox_env: py27-mode_mitogen-distro_ubuntu1604
- name: Mito_27_ubuntu1804
tox_env: py27-mode_mitogen-distro_ubuntu1804
- name: Mito_27_ubuntu2004
tox_env: py27-mode_mitogen-distro_ubuntu2004

- name: Mito_36_centos6
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_centos6
- name: Mito_36_centos7
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_centos7
- name: Mito_36_centos8
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_centos8
- name: Mito_36_debian9
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_debian9
- name: Mito_36_debian10
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_debian10
- name: Mito_36_debian11
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_debian11
- name: Mito_36_ubuntu1604
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_ubuntu1604
- name: Mito_36_ubuntu1804
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_ubuntu1804
- name: Mito_36_ubuntu2004
- name: Mito_27
tox_env: py27-mode_mitogen
- name: Mito_36
python_version: '3.6'
tox_env: py36-mode_mitogen-distro_ubuntu2004

- name: Mito_313_centos6
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_centos6
- name: Mito_313_centos7
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_centos7
- name: Mito_313_centos8
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_centos8
- name: Mito_313_debian9
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_debian9
- name: Mito_313_debian10
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_debian10
- name: Mito_313_debian11
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_debian11
- name: Mito_313_ubuntu1604
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_ubuntu1604
- name: Mito_313_ubuntu1804
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_ubuntu1804
- name: Mito_313_ubuntu2004
tox_env: py36-mode_mitogen
- name: Mito_313
python_version: '3.13'
tox_env: py313-mode_mitogen-distro_ubuntu2004
tox_env: py313-mode_mitogen

steps:
- uses: actions/checkout@v4
Expand Down
3 changes: 1 addition & 2 deletions tests/fakessh_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import testlib


@unittest.skip('broken')
class RsyncTest(testlib.DockerMixin, testlib.TestCase):
@unittest.skip('broken')
def test_rsync_from_master(self):
context = self.docker_ssh_any()

Expand All @@ -24,7 +24,6 @@ def test_rsync_from_master(self):
self.assertTrue(context.call(os.path.exists, '/tmp/data'))
self.assertTrue(context.call(os.path.exists, '/tmp/data/simple_pkg/a.py'))

@unittest.skip('broken')
def test_rsync_between_direct_children(self):
# master -> SSH -> mitogen__has_sudo_pubkey -> rsync(.ssh) -> master ->
# mitogen__has_sudo -> rsync
Expand Down
30 changes: 26 additions & 4 deletions tests/ssh_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_okay(self):
self.assertEqual(3, context.call(plain_old_module.add, 1, 2))


class SshTest(testlib.DockerMixin, testlib.TestCase):
class SshMixin(testlib.DockerMixin):
def test_debug_decoding(self):
# ensure filter_debug_logs() decodes the logged string.
capture = testlib.LogCapturer()
Expand Down Expand Up @@ -68,7 +68,7 @@ def test_stream_name(self):
password='has_sudo_password',
)
name = 'ssh.%s:%s' % (
self.dockerized_ssh.get_host(),
self.dockerized_ssh.host,
self.dockerized_ssh.port,
)
self.assertEqual(name, context.name)
Expand Down Expand Up @@ -176,7 +176,18 @@ def test_accept_enforce_host_keys(self):
fp.close()


class BannerTest(testlib.DockerMixin, testlib.TestCase):
for distro_spec in testlib.DISTRO_SPECS.split():
dockerized_ssh = testlib.DockerizedSshDaemon(distro_spec)
klass_name = 'SshTest%s' % (dockerized_ssh.distro.capitalize(),)
klass = type(
klass_name,
(SshMixin, testlib.TestCase),
{'dockerized_ssh': dockerized_ssh},
)
globals()[klass_name] = klass


class BannerMixin(testlib.DockerMixin):
# Verify the ability to disambiguate random spam appearing in the SSHd's
# login banner from a legitimate password prompt.
def test_verbose_enabled(self):
Expand All @@ -186,13 +197,24 @@ def test_verbose_enabled(self):
ssh_debug_level=3,
)
name = 'ssh.%s:%s' % (
self.dockerized_ssh.get_host(),
self.dockerized_ssh.host,
self.dockerized_ssh.port,
)
self.assertEqual(name, context.name)
context.shutdown(wait=True)


for distro_spec in testlib.DISTRO_SPECS.split():
dockerized_ssh = testlib.DockerizedSshDaemon(distro_spec)
klass_name = 'BannerTest%s' % (dockerized_ssh.distro.capitalize(),)
klass = type(
klass_name,
(BannerMixin, testlib.TestCase),
{'dockerized_ssh': dockerized_ssh},
)
globals()[klass_name] = klass


class StubPermissionDeniedTest(StubSshMixin, testlib.TestCase):
def test_classic_prompt(self):
self.assertRaises(mitogen.ssh.PasswordError,
Expand Down
13 changes: 12 additions & 1 deletion tests/su_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_basic(self):
self.assertEqual(argv[2], '-c')


class SuTest(testlib.DockerMixin, testlib.TestCase):
class SuMixin(testlib.DockerMixin):
stub_su_path = testlib.data_path('stubs/stub-su.py')

def test_slow_auth_failure(self):
Expand Down Expand Up @@ -64,3 +64,14 @@ def test_password_okay(self):
)
context = self.router.su(via=ssh, password='rootpassword')
self.assertEqual(0, context.call(os.getuid))


for distro_spec in testlib.DISTRO_SPECS.split():
dockerized_ssh = testlib.DockerizedSshDaemon(distro_spec)
klass_name = 'SuTest%s' % (dockerized_ssh.distro.capitalize(),)
klass = type(
klass_name,
(SuMixin, testlib.TestCase),
{'dockerized_ssh': dockerized_ssh},
)
globals()[klass_name] = klass
34 changes: 17 additions & 17 deletions tests/testlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@

LOG = logging.getLogger(__name__)

DISTRO = os.environ.get('MITOGEN_TEST_DISTRO', 'debian9')
DISTRO_SPECS = os.environ.get(
'MITOGEN_TEST_DISTRO_SPECS',
'centos6 centos8 debian9 debian11 ubuntu1604 ubuntu2004',
)
IMAGE_TEMPLATE = os.environ.get(
'MITOGEN_TEST_IMAGE_TEMPLATE',
'public.ecr.aws/n5z0e8q9/%(distro)s-test',
Expand Down Expand Up @@ -544,7 +547,6 @@ def start_container(self):
except Exception:
raise unittest.SkipTest('Docker binary is unavailable')

self.container_name = 'mitogen-test-%08x' % (random.getrandbits(64),)
args = [
'docker',
'run',
Expand All @@ -555,8 +557,9 @@ def start_container(self):
self.image,
]
subprocess.check_output(args)
self.port = self.get_port(self.container_name)

def __init__(self, distro=DISTRO, image_template=IMAGE_TEMPLATE):
def __init__(self, distro_spec, image_template=IMAGE_TEMPLATE):
# Code duplicated in ci_lib.py, both should be updated together
distro_pattern = re.compile(r'''
(?P<distro>(?P<family>[a-z]+)[0-9]+)
Expand All @@ -565,23 +568,22 @@ def __init__(self, distro=DISTRO, image_template=IMAGE_TEMPLATE):
''',
re.VERBOSE,
)
d = distro_pattern.match(distro).groupdict(default=None)
d = distro_pattern.match(distro_spec).groupdict(default=None)

self.distro = d['distro']
self.family = d['family']

if d.pop('py') == 'py3':
self.python_path = '/usr/bin/python3'
else:
self.python_path = '/usr/bin/python'

self.image = image_template % d
self.start_container()
self.host = self.get_host()
self.port = self.get_port(self.container_name)

def get_host(self):
return get_docker_host()
self.container_name = 'mitogen-test-%08x' % (random.getrandbits(64),)
self.host = get_docker_host()

def wait_for_sshd(self):
wait_for_port(self.get_host(), self.port, pattern='OpenSSH')
wait_for_port(self.port, self.port, pattern='OpenSSH')

def check_processes(self):
# Get Accounting name (ucomm) & command line (args) of each process
Expand Down Expand Up @@ -651,12 +653,10 @@ def setUpClass(cls):
if os.environ.get('SKIP_DOCKER_TESTS'):
raise unittest.SkipTest('SKIP_DOCKER_TESTS is set')

# we want to be able to override test distro for some tests that need a different container spun up
daemon_args = {}
if hasattr(cls, 'mitogen_test_distro'):
daemon_args['mitogen_test_distro'] = cls.mitogen_test_distro

cls.dockerized_ssh = DockerizedSshDaemon(**daemon_args)
# cls.dockerized_ssh is injected by dynamically generating TestCase
# subclasses.
# TODO Bite the bullet, switch to e.g. pytest
cls.dockerized_ssh.start_container()
cls.dockerized_ssh.wait_for_sshd()

@classmethod
Expand Down
Loading

0 comments on commit f97d7d3

Please sign in to comment.