"""Integration tests for the CLI shell plugins and runners.""" import collections import os import string import subprocess import sys import tempfile import unittest from galaxy_test.base.populators import skip_without_tool from galaxy_test.base.ssh_util import generate_ssh_keys from galaxy_test.driver import integration_util from .test_job_environments import BaseJobEnvironmentIntegrationTestCase RemoteConnection = collections.namedtuple('remote_connection', ['hostname', 'username', 'port', 'private_key', 'public_key']) def start_ssh_docker(container_name, jobs_directory, port=10022, image='agaveapi/slurm'): ssh_keys = generate_ssh_keys() START_SLURM_DOCKER = ['docker', 'run', '-h', 'localhost', '-p', f'{port}:22', '-d', '--name', container_name, '--rm', '--privileged', # for torque '-v', "{jobs_directory}:{jobs_directory}".format(jobs_directory=jobs_directory), "-v", f"{ssh_keys.public_key_file}:/home/testuser/.ssh/authorized_keys", '--ulimit', 'nofile=2048:2048', image] subprocess.check_call(START_SLURM_DOCKER) if sys.platform != 'darwin': subprocess.check_call(['docker', 'exec', container_name, 'usermod', '-u', str(os.getuid()), 'testuser']) return RemoteConnection('localhost', 'testuser', port, ssh_keys.private_key_file, ssh_keys.public_key_file) def stop_ssh_docker(container_name, remote_connection): subprocess.check_call(['docker', 'rm', '-f', container_name]) os.remove(remote_connection.private_key) os.remove(remote_connection.public_key) def cli_job_config(remote_connection, shell_plugin='ParamikoShell', job_plugin='Slurm'): job_conf_template = string.Template(""" $shell_plugin $job_plugin $username $private_key $hostname $port False False 42 """) job_conf_str = job_conf_template.substitute(shell_plugin=shell_plugin, job_plugin=job_plugin, **remote_connection._asdict()) with tempfile.NamedTemporaryFile(suffix="_slurm_integration_job_conf.xml", mode="w", delete=False) as job_conf: job_conf.write(job_conf_str) return job_conf.name @integration_util.skip_unless_docker() class BaseCliIntegrationTestCase(BaseJobEnvironmentIntegrationTestCase): @classmethod def setUpClass(cls): if cls is BaseCliIntegrationTestCase: raise unittest.SkipTest("Base class") cls.container_name = "%s_container" % cls.__name__ cls.jobs_directory = tempfile.mkdtemp() cls.remote_connection = start_ssh_docker(container_name=cls.container_name, jobs_directory=cls.jobs_directory, image=cls.image) super().setUpClass() @classmethod def tearDownClass(cls): stop_ssh_docker(cls.container_name, cls.remote_connection) super().tearDownClass() @classmethod def handle_galaxy_config_kwds(cls, config): config["jobs_directory"] = cls.jobs_directory config["file_path"] = cls.jobs_directory config["job_config_file"] = cli_job_config(remote_connection=cls.remote_connection, shell_plugin=cls.shell_plugin, job_plugin=cls.job_plugin) @skip_without_tool("job_environment_default") def test_running_cli_job(self): job_env = self._run_and_get_environment_properties() assert job_env.some_env == '42' class TorqueSetup: job_plugin = 'Torque' image = 'mvdbeek/galaxy-integration-docker-images:torque_latest' class SlurmSetup: job_plugin = 'Slurm' image = 'mvdbeek/galaxy-integration-docker-images:slurm_latest' class ParamikoShell: shell_plugin = 'ParamikoShell' class SecureShell: shell_plugin = 'SecureShell' class ParamikoCliSlurmIntegrationTestCase(SlurmSetup, ParamikoShell, BaseCliIntegrationTestCase): pass class ShellJobCliSlurmIntegrationTestCase(SlurmSetup, SecureShell, BaseCliIntegrationTestCase): pass class ParamikoCliTorqueIntegrationTestCase(TorqueSetup, ParamikoShell, BaseCliIntegrationTestCase): pass class ShellJobCliTorqueIntegrationTestCase(TorqueSetup, SecureShell, BaseCliIntegrationTestCase): pass