def test_process_identity(self): host_uid = os.getuid() host_gid = os.getgid() host_supplementary_gids = set(os.getgroups()) # Retrieve ids from container util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) output = util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["id", "-u"]) container_uid = int(output[0]) output = util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["id", "-g"]) container_gid = int(output[0]) output = util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["id", "-G"]) container_supplementary_gids = { int(group) for group in output[0].split() } # Checks self.assertEqual(host_uid, container_uid) self.assertEqual(host_gid, container_gid) self.assertEqual(host_supplementary_gids, container_supplementary_gids)
def test_preserve_fds(self): test_file = open("/tmp/test1", "w+") test_fd = test_file.fileno() # Test preservation of PMI_FD inside the container host_environment = os.environ.copy() host_environment["PMI_FD"] = str(test_fd) util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) command = ["bash", "-c", "echo fd-preservation-test >&${PMI_FD}"] sarus_options = ["--mount=type=bind,source=/tmp,destination=/tmp"] util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=command, options_of_run_command=sarus_options, env=host_environment, pass_fds=(test_fd, )) try: test_file.seek(0) self.assertEqual(test_file.readline()[:-1], "fd-preservation-test") finally: test_file.close()
def _run_sarus(self): util.generate_ssh_keys() util.remove_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["true"])
def test_entrypoint_with_option_arguments(self): util.pull_image_if_necessary(is_centralized_repository=True, image="alpine:3.8") out = util.run_command_in_container(is_centralized_repository=False, image="alpine:3.8", command=["--option", "arg"], options_of_run_command=["--entrypoint=echo"]) self.assertEqual(out, ["--option arg"])
def _test_command_pull(self, image, is_centralized_repository): util.remove_image_if_necessary(is_centralized_repository, image) actual_images = util.list_images(is_centralized_repository) self.assertEqual(actual_images.count(image), 0) util.pull_image_if_necessary(is_centralized_repository, image) actual_images = util.list_images(is_centralized_repository) self.assertEqual(actual_images.count(image), 1)
def _test_command_rmi(self, is_centralized_repository): image = "alpine:latest" util.pull_image_if_necessary(is_centralized_repository, image) actual_images = set(util.list_images(is_centralized_repository)) self.assertTrue(image in actual_images) util.remove_image_if_necessary(is_centralized_repository, image) actual_images = set(util.list_images(is_centralized_repository)) self.assertTrue(image not in actual_images)
def test_image_with_non_ascii_characters(self): util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) output = util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["ls", "/földèr"]) # the command's output might also contain escape sequences (e.g. color codes), let's ignore # the escape characters and let's just check that the output contains the expected string self.assertTrue(output[0].find("filé") != -1) self.assertTrue(output[1].find("ファイル") != -1)
def test_image_with_symlink_over_directory(self): util.remove_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) output = util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["ls", "/usr/local/test".encode('utf-8')]) assert output[0] == "file" output = util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["realpath", "/usr/local/test".encode('utf-8')]) assert output[0] == "/opt/test"
def test_ssh_hook(self): util.pull_image_if_necessary(is_centralized_repository=False, image=self.image) util.generate_ssh_keys() # check SSH from node0 to node1 hostname_node1 = self._get_hostname_of_node1() hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh(hostname_node1) self.assertEqual(hostname_node1, hostname_node1_through_ssh) # check SSH goes into container (not host) prettyname = self._get_prettyname_of_node1_through_ssh(hostname_node1) self.assertEqual(prettyname, "Debian GNU/Linux 9 (stretch)")
def _test_command_run(self, is_centralized_repository): util.pull_image_if_necessary(is_centralized_repository, "library/alpine:3.8") util.pull_image_if_necessary(is_centralized_repository, "library/debian:jessie") util.pull_image_if_necessary(is_centralized_repository, "library/debian:stretch") util.pull_image_if_necessary(is_centralized_repository, "library/centos:7") self.assertEqual( util.run_image_and_get_prettyname(is_centralized_repository, "library/alpine:3.8"), "Alpine Linux") self.assertEqual( util.run_image_and_get_prettyname(is_centralized_repository, "library/debian:jessie"), "Debian GNU/Linux 8 (jessie)") self.assertEqual( util.run_image_and_get_prettyname(is_centralized_repository, "library/debian:stretch"), "Debian GNU/Linux 9 (stretch)") self.assertEqual( util.run_image_and_get_prettyname(is_centralized_repository, "library/centos:7"), "CentOS Linux")
def test_image_with_max_path_length(self): util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["touch", "/file"]) util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["touch", "/etc/file"]) util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["touch", "/bin/file"]) util.run_command_in_container(is_centralized_repository=False, image=self._IMAGE_NAME, command=["touch", "/sbin/file"])
def _test_command_pull(self, is_centralized_repository): image = "alpine:latest" util.remove_image_if_necessary(is_centralized_repository, image) actual_images = util.list_images(is_centralized_repository) self.assertEqual(actual_images.count(image), 0) util.pull_image_if_necessary(is_centralized_repository, image) actual_images = util.list_images(is_centralized_repository) self.assertEqual(actual_images.count(image), 1) # check that multiple pulls of the same image don't generate # multiple entries in the list of available images util.pull_image_if_necessary(is_centralized_repository, image) actual_images = util.list_images(is_centralized_repository) self.assertEqual(actual_images.count(image), 1)
def test_environment_variables(self): util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) host_environment = os.environ.copy() host_environment["HOST_ENV_VARIABLE"] = "host_env_variable_value" host_environment["HOST_ENV_VAR"] = "host_env_var_value" command=["bash", "-c", "echo $IMAGE_ENV_VARIABLE; echo $IMAGE_ENV_VAR; echo $HOST_ENV_VARIABLE; echo $HOST_ENV_VAR"] output = util.run_command_in_container( is_centralized_repository=False, image=self._IMAGE_NAME, command=command, environment=host_environment) self.assertEqual(output[0], "image_env_variable_value") self.assertEqual(output[1], "image_env_var_value") self.assertEqual(output[2], "host_env_variable_value") self.assertEqual(output[3], "host_env_var_value")
def _run_ps_in_container(self, with_init_process): util.pull_image_if_necessary(is_centralized_repository=False, image="alpine:3.8") if with_init_process: options = ["--init"] else: options = [] out = util.run_command_in_container(is_centralized_repository=False, image="alpine:3.8", command=["ps", "-o", "pid,comm"], options_of_run_command=options) processes = [] for line in out[1:]: pid, comm = line.split() processes.append({"pid": int(pid), "comm": comm}) processes.sort(key = lambda process: process["pid"]) # sort by pid in ascending order return processes
def _pull_docker_images(cls): util.pull_image_if_necessary(is_centralized_repository=False, image="alpine:3.8") # no glibc util.pull_image_if_necessary(is_centralized_repository=False, image="centos:6") # glibc 2.12 util.pull_image_if_necessary( is_centralized_repository=False, image="fedora:latest") # assumption: glibc >= host's glibc # based on fedora - assumption: glibc >= host's glibc util.pull_image_if_necessary( is_centralized_repository=False, image="ethcscs/sarus-integration-tests:nonexisting_ldcache_entry")
def test_workdir(self): util.pull_image_if_necessary(is_centralized_repository=True, image="alpine:3.8") # default workdir out = util.run_command_in_container(is_centralized_repository=False, image="alpine:3.8", command=["pwd"], options_of_run_command=None) self.assertEqual(out, ["/"]) # custom workdir out = util.run_command_in_container(is_centralized_repository=False, image="alpine:3.8", command=["pwd"], options_of_run_command=["--workdir=/etc"]) self.assertEqual(out, ["/etc"]) # custom non-exising workdir (sarus automatically creates it) out = util.run_command_in_container(is_centralized_repository=False, image="alpine:3.8", command=["pwd"], options_of_run_command=["--workdir=/non-exising-dir-2931"]) self.assertEqual(out, ["/non-exising-dir-2931"])
def test_cpu_affinity(self): image = "alpine:3.8" util.pull_image_if_necessary(is_centralized_repository=False, image=image) command = ["cat", "/proc/self/status"] out = util.command_output_without_trailing_new_lines(subprocess.check_output(command).decode()) host_cpus_allowed_list = self._parse_cpus_allowed_list(out) only_one_cpu_available = len(host_cpus_allowed_list) == 1 if only_one_cpu_available: print("WARNING: skipping CPU affinity test. Only one CPU" " is available, but at least two are required.") return cpu = self._parse_first_cpu(host_cpus_allowed_list) command = ["taskset", "--cpu-list", cpu, "sarus", "run", image, "cat", "/proc/self/status"] out = util.command_output_without_trailing_new_lines(subprocess.check_output(command).decode()) container_cpus_allowed_list = self._parse_cpus_allowed_list(out) self.assertEqual(container_cpus_allowed_list, cpu)
def _pull_docker_images(cls): util.pull_image_if_necessary(is_centralized_repository=False, image="alpine:3.8") # no glibc util.pull_image_if_necessary(is_centralized_repository=False, image="centos:6") # glibc 2.12 util.pull_image_if_necessary( is_centralized_repository=False, image="fedora:latest") # assumption: glibc >= host's glibc
def test_ssh_hook(self): util.pull_image_if_necessary(is_centralized_repository=False, image=self.image_with_musl) util.pull_image_if_necessary(is_centralized_repository=False, image=self.image_with_glibc) self._check_ssh_keys_generation() # check SSH from node0 to node1 hostname_node1 = self._get_hostname_of_node1(self.image_with_musl) hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh( self.image_with_musl, hostname_node1) self.assertEqual(hostname_node1, hostname_node1_through_ssh) hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh( self.image_with_glibc, hostname_node1) self.assertEqual(hostname_node1, hostname_node1_through_ssh) # check SSH from node0 to node1 with non-standard $HOME # in some systems the home from the passwd file (copied from the host) # might not be present in the container. The hook has to deduce it from # the passwd file and create it. self._set_home_in_sarus_passwd_file("/users/test") hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh( self.image_with_musl, hostname_node1) self.assertEqual(hostname_node1, hostname_node1_through_ssh) hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh( self.image_with_glibc, hostname_node1) self.assertEqual(hostname_node1, hostname_node1_through_ssh) self._restore_sarus_passwd_file() # check SSH goes into container (not host) prettyname = self._get_prettyname_of_node1_through_ssh( self.image_with_musl, hostname_node1) self.assertEqual(prettyname, "Alpine Linux v3.8") prettyname = self._get_prettyname_of_node1_through_ssh( self.image_with_glibc, hostname_node1) self.assertEqual(prettyname, "Debian GNU/Linux 9 (stretch)")
def test_ssh_hook(self): util.pull_image_if_necessary(is_centralized_repository=False, image=self.image_with_musl) util.pull_image_if_necessary(is_centralized_repository=False, image=self.image_with_glibc) self._check_ssh_keys_generation() # check SSH from node0 to node1 hostname_node1 = self._get_hostname_of_node1(self.image_with_musl) hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh( self.image_with_musl, hostname_node1) self.assertEqual(hostname_node1, hostname_node1_through_ssh) hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh( self.image_with_glibc, hostname_node1) self.assertEqual(hostname_node1, hostname_node1_through_ssh) # check SSH goes into container (not host) prettyname = self._get_prettyname_of_node1_through_ssh( self.image_with_musl, hostname_node1) self.assertEqual(prettyname, "Alpine Linux v3.8") prettyname = self._get_prettyname_of_node1_through_ssh( self.image_with_glibc, hostname_node1) self.assertEqual(prettyname, "Debian GNU/Linux 9 (stretch)")
def _pull_docker_images(cls): util.pull_image_if_necessary( is_centralized_repository=False, image="ethcscs/dockerfiles:sarus_mpi_support_test-mpich_compatible" ) util.pull_image_if_necessary( is_centralized_repository=False, image= "ethcscs/dockerfiles:sarus_mpi_support_test-mpich_major_incompatible" ) util.pull_image_if_necessary( is_centralized_repository=False, image= "ethcscs/dockerfiles:sarus_mpi_support_test-mpich_minor_incompatible" ) util.pull_image_if_necessary( is_centralized_repository=False, image="ethcscs/dockerfiles:sarus_mpi_support_test-no_mpi_libraries" )
def _pull_docker_images(cls): util.pull_image_if_necessary(is_centralized_repository=False, image="ethcscs/dockerfiles:sarus_mpi_support_test-mpich_compatible") util.pull_image_if_necessary(is_centralized_repository=False, image="ethcscs/dockerfiles:sarus_mpi_support_test-mpich_compatible_symlink") util.pull_image_if_necessary(is_centralized_repository=False, image="ethcscs/dockerfiles:sarus_mpi_support_test-mpich_major_incompatible") util.pull_image_if_necessary(is_centralized_repository=False, image="ethcscs/dockerfiles:sarus_mpi_support_test-mpich_minor_incompatible") util.pull_image_if_necessary(is_centralized_repository=False, image="ethcscs/dockerfiles:sarus_mpi_support_test-no_mpi_libraries") util.pull_image_if_necessary(is_centralized_repository=False, image="ethcscs/sarus-integration-tests:nonexisting_ldcache_entry")
def setUpClass(cls): util.pull_image_if_necessary(is_centralized_repository=False, image=cls._CONTAINER_IMAGE) cls._modify_bundle_config()
def setUpClass(cls): util.pull_image_if_necessary(is_centralized_repository=False, image=cls._CONTAINER_IMAGE) cls._enable_hook()
def setUpClass(cls): util.pull_image_if_necessary(is_centralized_repository=False, image="alpine:latest") cls._enable_hook()
def _pull_docker_images(cls): # note: host is ubuntu 18.04 (glibc 2.27) util.pull_image_if_necessary(is_centralized_repository=False, image="centos:7") # glibc 2.17 util.pull_image_if_necessary(is_centralized_repository=False, image="ubuntu:18.04") # glibc 2.27
def setUpClass(cls): cls._create_source_directories() cls._modify_sarusjson_file() cls.container_image = "ubuntu:16.04" util.pull_image_if_necessary(is_centralized_repository=False, image=cls.container_image)
def setUpClass(cls): util.pull_image_if_necessary(is_centralized_repository=False, image="alpine")
def test_image_with_max_path_length(self): util.pull_image_if_necessary(is_centralized_repository=False, image=self._IMAGE_NAME) prettyname = util.run_image_and_get_prettyname(is_centralized_repository=False, image=self._IMAGE_NAME) assert prettyname == "Alpine Linux"