Example #1
0
 def test_connect_failed(self):
     thrown = False
     try:
         test = DockerEnvironmentDriver(
             self.temp_dir, ".datmo", docker_socket="unix:///var/run/fooo")
         test.connect()
     except EnvironmentConnectFailed:
         thrown = True
     assert thrown
Example #2
0
 def test_init_failed(self):
     thrown = False
     try:
         test = DockerEnvironmentDriver(
             self.temp_dir, docker_socket="unix:///var/run/fooo")
         test.init()
     except EnvironmentInitFailed:
         thrown = True
     assert thrown
Example #3
0
    def setup_method(self):
        self.temp_dir = tempfile.mkdtemp(dir=test_datmo_dir)
        # Test the default parameters
        self.docker_environment_driver = \
            DockerEnvironmentDriver(self.temp_dir)

        random_text = str(uuid.uuid1())
        with open(os.path.join(self.temp_dir, "Dockerfile"), "wb") as f:
            f.write(to_bytes("FROM python:3.5-alpine" + "\n"))
            f.write(to_bytes(str("RUN echo " + random_text)))
Example #4
0
 def setup_method(self):
     self.temp_dir = tempfile.mkdtemp(dir=test_datmo_dir)
     # Ensure the ".datmo" directory is there (this is ensured by higher level functions
     # in practice
     os.makedirs(os.path.join(self.temp_dir, ".datmo"))
     # Test the default parameters
     self.docker_environment_driver = \
         DockerEnvironmentDriver(self.temp_dir, ".datmo")
     self.image_name = str(uuid.uuid1())
     self.random_text = str(uuid.uuid1())
     self.dockerfile_path = os.path.join(self.temp_dir, "Dockerfile")
     with open(self.dockerfile_path, "wb") as f:
         f.write(to_bytes("FROM python:3.5-alpine" + os.linesep))
         f.write(to_bytes(str("RUN echo " + self.random_text)))
Example #5
0
 def setup_method(self):
     # provide mountable tmp directory for docker
     tempfile.tempdir = "/tmp" if not platform.system(
     ) == "Windows" else None
     test_datmo_dir = os.environ.get('TEST_DATMO_DIR',
                                     tempfile.gettempdir())
     self.temp_dir = tempfile.mkdtemp(dir=test_datmo_dir)
     # Test the default parameters
     self.docker_environment_manager = \
         DockerEnvironmentDriver(self.temp_dir)
     self.init_result = self.docker_environment_manager.init()
     random_text = str(uuid.uuid1())
     with open(os.path.join(self.temp_dir, "Dockerfile"), "a+") as f:
         f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
         f.write(to_unicode(str("RUN echo " + random_text)))
Example #6
0
 def test_instantiation_not_connected(self):
     thrown = False
     try:
         DockerEnvironmentDriver(self.temp_dir,
                                 docker_socket="unix:///var/run/fooo")
     except EnvironmentInitFailed:
         thrown = True
     assert thrown
Example #7
0
def check_docker_inactive(filepath):
    try:
        test = DockerEnvironmentDriver(filepath=filepath)
        test.init()
        definition_path = os.path.join(filepath, "Dockerfile")
        if platform.system() == "Windows":
            with open(definition_path, "wb") as f:
                f.write(to_bytes("FROM python:3.5-alpine" + "\n"))
                f.write(to_bytes(str("RUN echo hello")))
            test.build("docker-test", definition_path)
        return False
    except (EnvironmentInitFailed, EnvironmentExecutionError):
        return True
Example #8
0
class TestDockerEnv():
    # TODO: Add more cases for each test
    """
    Checks all functions of the DockerEnvironmentDriver
    """
    def setup_method(self):
        self.temp_dir = tempfile.mkdtemp(dir=test_datmo_dir)
        # Test the default parameters
        self.docker_environment_driver = \
            DockerEnvironmentDriver(self.temp_dir)
        self.image_name = str(uuid.uuid1())
        self.random_text = str(uuid.uuid1())
        self.dockerfile_path = os.path.join(self.temp_dir, "Dockerfile")
        with open(self.dockerfile_path, "wb") as f:
            f.write(to_bytes("FROM python:3.5-alpine" + os.linesep))
            f.write(to_bytes(str("RUN echo " + self.random_text)))

    def teardown_method(self):
        if not check_docker_inactive(test_datmo_dir):
            self.docker_environment_driver.remove(self.image_name, force=True)

    def test_instantiation(self):
        assert self.docker_environment_driver != None
        assert self.docker_environment_driver.docker_socket == None or "unix:///var/run/docker.sock"
        assert self.docker_environment_driver.docker_execpath == "docker"
        assert self.docker_environment_driver.client
        assert self.docker_environment_driver.prefix
        assert self.docker_environment_driver.type

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_init_success(self):
        init_result = self.docker_environment_driver.init()
        assert init_result and \
               self.docker_environment_driver.is_initialized == True

    def test_init_failed(self):
        thrown = False
        try:
            test = DockerEnvironmentDriver(
                self.temp_dir, docker_socket="unix:///var/run/fooo")
            test.init()
        except EnvironmentInitFailed:
            thrown = True
        assert thrown

    def test_get_current_type(self):
        result = self.docker_environment_driver.get_environment_types()
        assert result

    def test_get_current_name(self):
        environment_type = "cpu"
        result = self.docker_environment_driver.get_supported_frameworks(
            environment_type)
        assert result

    def test_get_supported_languages(self):
        environment_type = "cpu"
        environment_framework = "data-analytics"
        result = self.docker_environment_driver.get_supported_languages(
            environment_type, environment_framework)
        assert result

    def test_setup(self):
        save_definition_path = os.path.join(
            self.docker_environment_driver.filepath, "test")

        # Test setup failure if name it not present
        failed = False
        try:
            _ = self.docker_environment_driver.setup(
                options={}, definition_path=save_definition_path)
        except EnvironmentDoesNotExist:
            failed = True
        assert failed

        # Test setup failure if name is not a valid name
        failed = False
        try:
            _ = self.docker_environment_driver.setup(
                options={"name": "random"},
                definition_path=save_definition_path)
        except EnvironmentDoesNotExist:
            failed = True
        assert failed

        options = {
            "environment_framework": "data-analytics",
            "environment_type": "cpu",
            "environment_language": "py27"
        }

        # Test if failure if the path does not exist
        failed = False
        try:
            _ = self.docker_environment_driver.setup(
                options=options, definition_path=save_definition_path)
        except PathDoesNotExist:
            failed = True
        assert failed

        # Create definition path
        os.makedirs(save_definition_path)

        # Test by passing definition filepath and options
        result = self.docker_environment_driver.setup(
            options=options, definition_path=save_definition_path)
        definition_filepath = os.path.join(save_definition_path, "Dockerfile")
        assert result and os.path.isfile(definition_filepath) and \
               "datmo" in open(definition_filepath, "r").read()

    def test_create(self):
        input_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "Dockerfile")
        output_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "datmoDockerfile")
        # Test both default values
        success, path, output_path = \
            self.docker_environment_driver.create()

        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path

        open(output_dockerfile_path, "r").close()
        os.remove(output_dockerfile_path)

        # Test default values for output
        success, path, output_path = \
            self.docker_environment_driver.create(input_dockerfile_path)

        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path

        open(output_dockerfile_path, "r").close()
        os.remove(output_dockerfile_path)

        # Test both values given
        success, path, output_path = \
            self.docker_environment_driver.create(input_dockerfile_path,
                                                        output_dockerfile_path)
        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path

        # Test exception for output path already exists
        failed = False
        try:
            self.docker_environment_driver.create(
                output_path=output_dockerfile_path)
        except FileAlreadyExistsError:
            failed = True
        assert failed

        # Test exception for path does not exist
        os.remove(input_dockerfile_path)
        open(output_dockerfile_path, "r").close()
        os.remove(output_dockerfile_path)

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_build(self):
        result = self.docker_environment_driver.build(self.image_name,
                                                      self.dockerfile_path)
        assert result == True
        # teardown
        self.docker_environment_driver.remove(self.image_name, force=True)

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_run(self):
        # TODO: add more options for run w/ volumes etc
        # Keeping stdin_open and tty as either (True, True) or (False, False).
        # other combination are not used
        log_filepath = os.path.join(self.docker_environment_driver.filepath,
                                    "test.log")
        self.docker_environment_driver.build(self.image_name,
                                             self.dockerfile_path)
        # keeping stdin_open and tty as False
        run_options = {
            "command": ["sh", "-c", "echo yo"],
            "ports": ["8888:9999", "5000:5001"],
            "name": str(uuid.uuid1()),
            "volumes": {
                self.docker_environment_driver.filepath: {
                    'bind': '/home/',
                    'mode': 'rw'
                }
            },
            "mem_limit": "4g",
            "detach": True,
            "stdin_open": False,
            "tty": False,
            "api": False
        }
        return_code, run_id, logs = \
            self.docker_environment_driver.run(self.image_name, run_options, log_filepath)
        assert return_code == 0
        assert run_id
        assert logs
        assert isinstance(logs, str)

        # teardown
        self.docker_environment_driver.stop(run_id, force=True)

        # Test default values for run options
        run_options = {"command": ["sh", "-c", "echo yo"]}
        return_code, run_id, logs = \
            self.docker_environment_driver.run(self.image_name, run_options, log_filepath)
        assert return_code == 0
        assert run_id
        assert logs
        assert isinstance(logs, str)
        # teardown container
        self.docker_environment_driver.stop(run_id, force=True)

    # commenting due to test being unreliable
    # @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    # def test_interactive_run(self):
    #     # keeping stdin_open, tty as True
    #     log_filepath = os.path.join(self.docker_environment_driver.filepath,
    #                                 "test.log")
    #     self.docker_environment_driver.build(self.image_name,
    #                                          self.dockerfile_path)
    #
    #     @timeout_decorator.timeout(10, use_signals=False)
    #     def timed_run(container_name, timed_run_result):
    #         run_options = {
    #             "command": [],
    #             "ports": ["8888:9999", "5000:5001"],
    #             "name": container_name,
    #             "volumes": {
    #                 self.docker_environment_driver.filepath: {
    #                     'bind': '/home/',
    #                     'mode': 'rw'
    #                 }
    #             },
    #             "detach": True,
    #             "stdin_open": True,
    #             "tty": True,
    #             "api": False
    #         }
    #
    #         self.docker_environment_driver.run(self.image_name, run_options,
    #                                            log_filepath)
    #         return timed_run_result
    #
    #     container_name = str(uuid.uuid1())
    #     timed_run_result = False
    #     try:
    #         timed_run_result = timed_run(container_name, timed_run_result)
    #     except timeout_decorator.timeout_decorator.TimeoutError:
    #         timed_run_result = True
    #
    #     assert timed_run_result
    #
    #     # teardown
    #     self.docker_environment_driver.remove(self.image_name, force=True)
    #     # remove datmoDockerfile
    #     output_dockerfile_path = os.path.join(self.docker_environment_driver.filepath,
    #                                           "datmoDockerfile")
    #     os.remove(output_dockerfile_path)
    #
    #     # new jupyter dockerfile
    #     new_docker_filepath = os.path.join(
    #         self.docker_environment_driver.filepath, "Dockerfile")
    #     random_text = str(uuid.uuid1())
    #     with open(new_docker_filepath, "wb") as f:
    #         f.write(to_bytes("FROM nbgallery/jupyter-alpine:latest\n"))
    #         f.write(to_bytes(str("RUN echo " + random_text)))
    #     self.docker_environment_driver.build(self.image_name,
    #                                          new_docker_filepath)
    #
    #     @timeout_decorator.timeout(10, use_signals=False)
    #     def timed_run(container_name, timed_run_result):
    #         run_options = {
    #             "command": ["jupyter", "notebook", "--allow-root"],
    #             "ports": ["8888:8888"],
    #             "name": container_name,
    #             "volumes": {
    #                 self.docker_environment_driver.filepath: {
    #                     'bind': '/home/',
    #                     'mode': 'rw'
    #                 }
    #             },
    #             "detach": True,
    #             "stdin_open": False,
    #             "tty": False,
    #             "api": False
    #         }
    #
    #         self.docker_environment_driver.run(self.image_name, run_options,
    #                                            log_filepath)
    #         return timed_run_result
    #
    #     # teardown
    #     self.docker_environment_driver.remove(self.image_name, force=True)
    #     # remove datmoDockerfile
    #     output_dockerfile_path = os.path.join(self.docker_environment_driver.filepath,
    #                                           "datmoDockerfile")
    #     os.remove(output_dockerfile_path)
    #
    #     # new dockerfile
    #     new_docker_filepath = os.path.join(
    #         self.docker_environment_driver.filepath, "Dockerfile")
    #     random_text = str(uuid.uuid1())
    #     with open(new_docker_filepath, "wb") as f:
    #         f.write(to_bytes("FROM datmo/python-base:cpu-py27" + os.linesep))
    #         f.write(to_bytes(str("RUN echo " + random_text)))
    #     self.docker_environment_driver.build(self.image_name,
    #                                          new_docker_filepath,
    #                                          workspace='notebook')
    #
    #     @timeout_decorator.timeout(10, use_signals=False)
    #     def timed_run(container_name, timed_run_result):
    #         run_options = {
    #             "command": ["jupyter", "notebook", "--allow-root"],
    #             "ports": ["8888:8888"],
    #             "name": container_name,
    #             "volumes": {
    #                 self.docker_environment_driver.filepath: {
    #                     'bind': '/home/',
    #                     'mode': 'rw'
    #                 }
    #             },
    #             "detach": True,
    #             "stdin_open": False,
    #             "tty": False,
    #             "api": False
    #         }
    #
    #         self.docker_environment_driver.run(self.image_name, run_options,
    #                                            log_filepath)
    #         return timed_run_result
    #
    #     container_name = str(uuid.uuid1())
    #     timed_run_result = False
    #     try:
    #         timed_run_result = timed_run(container_name, timed_run_result)
    #     except timeout_decorator.timeout_decorator.TimeoutError:
    #         timed_run_result = True
    #     assert timed_run_result
    #
    #     # teardown container
    #     self.docker_environment_driver.stop(container_name, force=True)
    #
    #     # remove datmoDockerfile
    #     output_dockerfile_path = os.path.join(self.docker_environment_driver.filepath,
    #                                           "datmoDockerfile")
    #     os.remove(output_dockerfile_path)
    #
    #     # new dockerfile
    #     new_docker_filepath = os.path.join(
    #         self.docker_environment_driver.filepath, "Dockerfile")
    #     random_text = str(uuid.uuid1())
    #     with open(new_docker_filepath, "wb") as f:
    #         f.write(to_bytes("FROM datmo/python-base:cpu-py27" + os.linesep))
    #         f.write(to_bytes(str("RUN echo " + random_text)))
    #     self.docker_environment_driver.build(self.image_name,
    #                                          new_docker_filepath,
    #                                          workspace='notebook')
    #
    #     @timeout_decorator.timeout(10, use_signals=False)
    #     def timed_run(container_name, timed_run_result):
    #         run_options = {
    #             "command": ["jupyter", "notebook", "--allow-root"],
    #             "ports": ["8888:8888"],
    #             "name": container_name,
    #             "volumes": {
    #                 self.docker_environment_driver.filepath: {
    #                     'bind': '/home/',
    #                     'mode': 'rw'
    #                 }
    #             },
    #             "detach": True,
    #             "stdin_open": False,
    #             "tty": False,
    #             "api": False
    #         }
    #
    #         self.docker_environment_driver.run(self.image_name, run_options,
    #                                            log_filepath)
    #         return timed_run_result
    #
    #     container_name = str(uuid.uuid1())
    #     timed_run_result = False
    #     try:
    #         timed_run_result = timed_run(container_name, timed_run_result)
    #     except timeout_decorator.timeout_decorator.TimeoutError:
    #         timed_run_result = True
    #     assert timed_run_result
    #
    #     # teardown container
    #     self.docker_environment_driver.stop(container_name, force=True)
    #
    #     # remove datmoDockerfile
    #     output_dockerfile_path = os.path.join(self.docker_environment_driver.filepath,
    #                                           "datmoDockerfile")
    #     os.remove(output_dockerfile_path)
    #
    #     # new dockerfile
    #     new_docker_filepath = os.path.join(
    #         self.docker_environment_driver.filepath, "Dockerfile")
    #     random_text = str(uuid.uuid1())
    #     with open(new_docker_filepath, "wb") as f:
    #         f.write(to_bytes("FROM datmo/python-base:cpu-py27" + os.linesep))
    #         f.write(to_bytes(str("RUN echo " + random_text)))
    #     self.docker_environment_driver.build(self.image_name,
    #                                          new_docker_filepath,
    #                                          workspace='jupyterlab')
    #
    #     @timeout_decorator.timeout(10, use_signals=False)
    #     def timed_run(container_name, timed_run_result):
    #         run_options = {
    #             "command": ["jupyter", "lab", "--allow-root"],
    #             "ports": ["8888:8888"],
    #             "name": container_name,
    #             "volumes": {
    #                 self.docker_environment_driver.filepath: {
    #                     'bind': '/home/',
    #                     'mode': 'rw'
    #                 }
    #             },
    #             "detach": True,
    #             "stdin_open": False,
    #             "tty": False,
    #             "api": False
    #         }
    #
    #         self.docker_environment_driver.run(self.image_name, run_options,
    #                                            log_filepath)
    #         return timed_run_result
    #
    #     container_name = str(uuid.uuid1())
    #     timed_run_result = False
    #     try:
    #         timed_run_result = timed_run(container_name, timed_run_result)
    #     except timeout_decorator.timeout_decorator.TimeoutError:
    #         timed_run_result = True
    #     assert timed_run_result

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_stop(self):
        log_filepath = os.path.join(self.docker_environment_driver.filepath,
                                    "test.log")
        self.docker_environment_driver.build(self.image_name,
                                             self.dockerfile_path)

        run_options = {
            "command": ["sh", "-c", "echo yo"],
            "ports": ["8888:9999", "5000:5001"],
            "name": str(uuid.uuid1()),
            "volumes": None,
            "detach": False,
            "stdin_open": False,
            "tty": False,
            "api": False
        }
        _, run_id, _ = \
            self.docker_environment_driver.run(self.image_name, run_options, log_filepath)
        result = self.docker_environment_driver.stop(run_id, force=True)
        assert result

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_remove(self):
        # Test if no image present and no containers
        result = self.docker_environment_driver.remove(self.image_name)
        assert result == True

        # Without force
        self.docker_environment_driver.build(self.image_name,
                                             self.dockerfile_path)
        result = self.docker_environment_driver.remove(self.image_name)
        assert result == True
        # remove datmoDockerfile
        output_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "datmoDockerfile")
        os.remove(output_dockerfile_path)

        # With force
        self.docker_environment_driver.build(self.image_name,
                                             self.dockerfile_path)
        result = self.docker_environment_driver.remove(self.image_name,
                                                       force=True)
        assert result == True

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_get_tags_for_docker_repository(self):
        result = self.docker_environment_driver.get_tags_for_docker_repository(
            "hello-world")
        assert 'latest' in result

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_build_image(self):
        result = self.docker_environment_driver.build_image(
            self.image_name, self.dockerfile_path)
        assert result == True

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_get_image(self):
        failed = False
        try:
            self.docker_environment_driver.get_image("random")
        except EnvironmentImageNotFound:
            failed = True
        assert failed

        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)

        result = self.docker_environment_driver.get_image(self.image_name)
        tags = result.__dict__['attrs']['RepoTags']
        assert self.image_name + ":latest" in tags

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_list_images(self):
        # TODO: Test out all input permutations
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        # List images without all flag
        result = self.docker_environment_driver.list_images()
        group = [item.__dict__['attrs']['RepoTags'] for item in result]
        list_of_lists = [sublist for sublist in group if sublist]
        group_flat = [item for sublist in list_of_lists for item in sublist]
        assert self.image_name + ":latest" in group_flat
        # List images with all flag
        result = self.docker_environment_driver.list_images(all_images=True)
        group = [item.__dict__['attrs']['RepoTags'] for item in result]
        list_of_lists = [sublist for sublist in group if sublist]
        group_flat = [item for sublist in list_of_lists for item in sublist]
        assert self.image_name + ":latest" in group_flat

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_search_images(self):
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        result = self.docker_environment_driver.search_images(self.image_name)
        assert len(result) > 0

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_remove_image(self):
        # Failure without force
        failure = False
        try:
            _ = self.docker_environment_driver.remove_image("random")
        except EnvironmentExecutionError:
            failure = True
        assert failure == True
        # Failure with force
        failure = False
        try:
            _ = self.docker_environment_driver.remove_image("random",
                                                            force=True)
        except EnvironmentExecutionError:
            failure = True
        assert failure == True
        # Without force
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        result = self.docker_environment_driver.remove_image(self.image_name)
        assert result == True
        # remove datmoDockerfile
        output_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "datmoDockerfile")
        os.remove(output_dockerfile_path)
        # With force
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        result = self.docker_environment_driver.remove_image(self.image_name,
                                                             force=True)
        assert result == True
        # remove datmoDockerfile
        output_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "datmoDockerfile")
        os.remove(output_dockerfile_path)

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_remove_images(self):
        # TODO: Test out all input permutations
        # Without force
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        result = self.docker_environment_driver.remove_images(
            name=self.image_name)
        assert result == True
        # remove datmoDockerfile
        output_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "datmoDockerfile")
        os.remove(output_dockerfile_path)
        # With force
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        result = self.docker_environment_driver.remove_images(
            name=self.image_name, force=True)
        assert result == True

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_run_container(self):
        # TODO: test with all variables provided
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        # With default parameters
        return_code, container_id = \
            self.docker_environment_driver.run_container(self.image_name)
        assert return_code == 0 and \
            container_id
        # teardown container
        self.docker_environment_driver.stop(container_id, force=True)
        # With api=True, detach=False
        logs = self.docker_environment_driver.run_container(self.image_name,
                                                            api=True)
        assert logs == ""
        # With api=True, detach=True
        container_obj = self.docker_environment_driver.run_container(
            self.image_name, api=True, detach=True)
        assert container_obj

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_get_container(self):
        failed = False
        try:
            self.docker_environment_driver.get_container("random")
        except EnvironmentContainerNotFound:
            failed = True
        assert failed

        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        _, container_id = self.docker_environment_driver.run_container(
            self.image_name)
        result = self.docker_environment_driver.get_container(container_id)
        assert result

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_list_containers(self):
        # TODO: Test out all input permutations
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        _, container_id = self.docker_environment_driver.run_container(
            self.image_name, detach=True)
        result = self.docker_environment_driver.list_containers()
        assert container_id and len(result) > 0
        # teardown
        self.docker_environment_driver.remove(self.image_name, force=True)

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_stop_container(self):
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        _, container_id = self.docker_environment_driver.run_container(
            self.image_name)
        result = self.docker_environment_driver.stop_container(container_id)
        assert result == True
        result = self.docker_environment_driver.get_container(container_id)
        assert result.__dict__['attrs']['State']['Status'] == "exited"

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_remove_container(self):
        # Failure random container id (no force)
        failure = False
        try:
            _ = self.docker_environment_driver.remove_container("random")
        except EnvironmentExecutionError:
            failure = True
        assert failure == True
        # Failure random container id (force)
        failure = False
        try:
            _ = self.docker_environment_driver.remove_container("random",
                                                                force=True)
        except EnvironmentExecutionError:
            failure = True
        assert failure == True
        # Without force
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        _, container_id = self.docker_environment_driver.run_container(
            self.image_name)
        result = self.docker_environment_driver.remove_container(container_id)
        assert result == True
        # With force
        _, container_id = self.docker_environment_driver.run_container(
            self.image_name)
        result = self.docker_environment_driver.remove_container(container_id,
                                                                 force=True)
        assert result == True

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_log_container(self):
        # TODO: Do a more comprehensive test, test out optional variables
        # TODO: Test out more commands at the system level
        log_filepath = os.path.join(self.docker_environment_driver.filepath,
                                    "test.log")
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        _, container_id = \
            self.docker_environment_driver.run_container(self.image_name,
                                                          command=["sh", "-c", "echo yo"])
        return_code, logs = self.docker_environment_driver.log_container(
            container_id, log_filepath)
        assert return_code == 0
        assert logs and \
               os.path.exists(log_filepath)

        with open(log_filepath, "r") as f:
            assert f.readline() != ""

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_stop_remove_containers_by_term(self):
        # 1) Test with image_name (random container name), match with image_name
        # 2) Test with image_name and name given, match with name
        self.docker_environment_driver.build_image(self.image_name,
                                                   self.dockerfile_path)
        # 1) Test option 1

        # Test without force
        self.docker_environment_driver.run_container(self.image_name)
        result = self.docker_environment_driver.stop_remove_containers_by_term(
            self.image_name)
        assert result == True
        # Test with force
        self.docker_environment_driver.run_container(self.image_name)
        result = self.docker_environment_driver.stop_remove_containers_by_term(
            self.image_name, force=True)
        assert result == True

        # 2) Test option 2
        self.docker_environment_driver.run_container(self.image_name,
                                                     name="datmo_test")
        result = self.docker_environment_driver.stop_remove_containers_by_term(
            "datmo_test")
        assert result == True
        # Test with force
        self.docker_environment_driver.run_container(self.image_name,
                                                     name="datmo_test")
        result = self.docker_environment_driver.stop_remove_containers_by_term(
            "datmo_test", force=True)
        assert result == True

    def test_create_requirements_file(self):
        # 1) Test failure EnvironmentDoesNotExist
        # 2) Test success
        # 3) Test failure EnvironmentRequirementsCreateError
        # 1) Test option 1
        result = self.docker_environment_driver.create_requirements_file()
        assert os.path.isfile(result) and \
               "datmo" in open(result, "r").read()

        # 2) Test option 2
        # Since it uses pip as package manager, it doesn't extract any other package than what
        # has already been installed in local
        script_path = os.path.join(self.docker_environment_driver.filepath,
                                   "script.py")
        with open(script_path, "wb") as f:
            f.write(to_bytes("import numpy\n"))
            f.write(to_bytes("import sklearn\n"))
        # Test default
        result = self.docker_environment_driver.create_requirements_file()
        assert result
        assert os.path.isfile(result) and \
               "datmo" in open(result, "r").read()

        # 3) Test option 3
        exception_thrown = False
        try:
            _ = self.docker_environment_driver.\
                create_requirements_file(package_manager="does_not_work")
        except EnvironmentRequirementsCreateError:
            exception_thrown = True

        assert exception_thrown

    def test_create_default_dockerfile(self):
        # 1) Create default dockerfile for default script present

        # 1) Test option 1
        script_path = os.path.join(self.docker_environment_driver.filepath,
                                   "script.py")
        with open(script_path, "wb") as f:
            f.write(to_bytes("import numpy\n"))
            f.write(to_bytes("import sklearn\n"))

        result = self.docker_environment_driver.\
            create_default_definition(directory=self.docker_environment_driver.filepath)

        assert result
        assert os.path.isfile(result)
        output = open(result, "r").read()
        print(repr(output))
        assert "python" in output

    def test_create_datmo_definition(self):
        # Test 1
        input_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "Dockerfile")
        output_dockerfile_path = os.path.join(
            self.docker_environment_driver.filepath, "datmoDockerfile")
        result = self.docker_environment_driver.create_datmo_definition(
            input_dockerfile_path, output_dockerfile_path)
        assert result
        assert os.path.isfile(output_dockerfile_path)
        output = open(output_dockerfile_path, "r").read()
        print(repr(output))
        assert "datmo essential" in output

        # Test 2: With workspaces on datmo base image
        os.remove(output_dockerfile_path)
        with open(input_dockerfile_path, "wb") as f:
            f.write(to_bytes("FROM datmo/python-base:cpu-py27" + os.linesep))
            f.write(to_bytes(str("RUN echo " + self.random_text)))
        result = self.docker_environment_driver.create_datmo_definition(
            input_dockerfile_path,
            output_dockerfile_path,
            workspace="notebook")
        assert result
        assert os.path.isfile(output_dockerfile_path)
        output = open(output_dockerfile_path, "r").read()
        print(repr(output))
        assert "FROM datmo/python-base:cpu-py27-notebook" in output
        assert "datmo essential" in output

        # Test 3: With workspaces on datmo base image with jupyterlab
        os.remove(output_dockerfile_path)
        with open(input_dockerfile_path, "wb") as f:
            f.write(to_bytes("FROM datmo/python-base:cpu-py27" + "\n"))
            f.write(to_bytes(str("RUN echo " + self.random_text)))
        result = self.docker_environment_driver.create_datmo_definition(
            input_dockerfile_path,
            output_dockerfile_path,
            workspace="jupyterlab")
        assert result
        assert os.path.isfile(output_dockerfile_path)
        output = open(output_dockerfile_path, "r").read()
        print(repr(output))
        assert "FROM datmo/python-base:cpu-py27-jupyterlab" in output
        assert "datmo essential" in output

    @pytest_docker_environment_failed_instantiation(test_datmo_dir)
    def test_gpu_enabled(self):
        if not self.docker_environment_driver.gpu_enabled():
            print("GPU not available")
        else:
            log_filepath = os.path.join(
                self.docker_environment_driver.filepath, "test.log")
            return_code, run_id, logs = self.docker_environment_driver.run(
                "nvidia/cuda", {
                    "command": ["nvidia-smi"],
                    "name": str(uuid.uuid1()),
                    "detach": True,
                    "gpu": True
                }, log_filepath)
            assert return_code == 0
Example #9
0
class TestDockerEnv():
    # TODO: Add more cases for each test
    """
    Checks all functions of the DockerEnvironmentDriver
    """
    def setup_method(self):
        # provide mountable tmp directory for docker
        tempfile.tempdir = "/tmp" if not platform.system(
        ) == "Windows" else None
        test_datmo_dir = os.environ.get('TEST_DATMO_DIR',
                                        tempfile.gettempdir())
        self.temp_dir = tempfile.mkdtemp(dir=test_datmo_dir)
        # Test the default parameters
        self.docker_environment_manager = \
            DockerEnvironmentDriver(self.temp_dir)
        self.init_result = self.docker_environment_manager.init()
        random_text = str(uuid.uuid1())
        with open(os.path.join(self.temp_dir, "Dockerfile"), "a+") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))

    def teardown_method(self):
        pass

    def test_instantiation_and_connected(self):
        assert self.docker_environment_manager.is_connected
        assert self.docker_environment_manager != None

    def test_instantiation_not_connected(self):
        thrown = False
        try:
            DockerEnvironmentDriver(self.temp_dir,
                                    docker_socket="unix:///var/run/fooo")
        except EnvironmentInitFailed:
            thrown = True
        assert thrown

    def test_create(self):
        input_dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        output_dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "datmoDockerfile")
        # Test both default values
        success, path, output_path, requirements_filepath = \
            self.docker_environment_manager.create()

        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path
        assert requirements_filepath == None

        open(output_dockerfile_path, "r").close()
        os.remove(output_dockerfile_path)

        # Test default values for output
        success, path, output_path, requirements_filepath = \
            self.docker_environment_manager.create(input_dockerfile_path)

        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path
        assert requirements_filepath == None

        open(output_dockerfile_path, "r").close()
        os.remove(output_dockerfile_path)

        # Test both values given
        success, path, output_path, requirements_filepath = \
            self.docker_environment_manager.create(input_dockerfile_path,
                                                        output_dockerfile_path)
        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path
        assert requirements_filepath == None

        # Test for language being passed in
        os.remove(input_dockerfile_path)
        open(output_dockerfile_path, "r").close()
        os.remove(output_dockerfile_path)

        script_path = os.path.join(self.docker_environment_manager.filepath,
                                   "script.py")
        with open(script_path, "w") as f:
            f.write(to_unicode("import numpy\n"))
            f.write(to_unicode("import sklearn\n"))
        success, path, output_path, requirements_filepath = \
            self.docker_environment_manager.create(language="python3")
        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path
        assert requirements_filepath and os.path.isfile(requirements_filepath) and \
               "numpy" in open(requirements_filepath, "r").read()

        # Test exception for path does not exist
        os.remove(input_dockerfile_path)
        open(output_dockerfile_path, "r").close()
        os.remove(output_dockerfile_path)
        success, path, output_path, requirements_filepath =\
            self.docker_environment_manager.create()
        assert success and \
               os.path.isfile(output_dockerfile_path) and \
               "datmo" in open(output_dockerfile_path, "r").read()
        assert path == input_dockerfile_path
        assert output_path == output_dockerfile_path
        assert requirements_filepath

        # Test exception for output path already exists
        failed = False
        try:
            self.docker_environment_manager.create(
                output_path=output_dockerfile_path)
        except FileAlreadyExistsException:
            failed = True
        assert failed

    def test_build(self):
        name = str(uuid.uuid1())
        path = os.path.join(self.docker_environment_manager.filepath,
                            "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        result = self.docker_environment_manager.build(name, path)
        assert result == True
        # teardown
        self.docker_environment_manager.remove(name, force=True)

        # test
        os.remove(path)
        script_path = os.path.join(self.docker_environment_manager.filepath,
                                   "script.py")

        with open(script_path, "w") as f:
            f.write(to_unicode("import numpy\n"))
            f.write(to_unicode("import sklearn\n"))

        success, path, output_path, requirements_filepath = \
            self.docker_environment_manager.create(language="python3")

        assert success and \
               os.path.isfile(path) and \
               "datmo" in open(output_path, "r").read()
        assert requirements_filepath and os.path.isfile(requirements_filepath) and \
               "numpy" in open(requirements_filepath, "r").read()

        result = self.docker_environment_manager.build(name, path)
        assert result == True
        # teardown
        self.docker_environment_manager.remove(name, force=True)

    def test_run(self):
        # TODO: add more options for run w/ volumes etc
        image_name = str(uuid.uuid1())
        path = os.path.join(self.docker_environment_manager.filepath,
                            "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        log_filepath = os.path.join(self.docker_environment_manager.filepath,
                                    "test.log")
        self.docker_environment_manager.build(image_name, path)

        run_options = {
            "command": ["sh", "-c", "echo yo"],
            "ports": ["8888:9999", "5000:5001"],
            "name": "cooltest",
            "volumes": {
                self.docker_environment_manager.filepath: {
                    'bind': '/home/',
                    'mode': 'rw'
                }
            },
            "detach": True,
            "stdin_open": True,
            "tty": True,
            "gpu": True,
            "api": False
        }
        return_code, run_id, logs = \
            self.docker_environment_manager.run(image_name, run_options, log_filepath)

        assert return_code == 0
        assert run_id
        assert logs
        # teardown
        self.docker_environment_manager.stop(run_id, force=True)

        # Test default values for run options
        run_options = {"command": ["sh", "-c", "echo yo"]}
        return_code, run_id, logs = \
            self.docker_environment_manager.run(image_name, run_options, log_filepath)
        assert return_code == 0
        assert run_id
        assert logs
        # teardown container
        self.docker_environment_manager.stop(run_id, force=True)
        # teardown image
        self.docker_environment_manager.remove(image_name, force=True)

    def test_stop(self):
        name = str(uuid.uuid1())
        path = os.path.join(self.docker_environment_manager.filepath,
                            "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        log_filepath = os.path.join(self.docker_environment_manager.filepath,
                                    "test.log")
        self.docker_environment_manager.build(name, path)

        run_options = {
            "command": ["sh", "-c", "echo yo"],
            "ports": ["8888:9999", "5000:5001"],
            "name": "my_container_name_2",
            "volumes": None,
            "detach": False,
            "stdin_open": False,
            "tty": False,
            "gpu": False,
            "api": False
        }
        _, run_id, _ = \
            self.docker_environment_manager.run(name, run_options, log_filepath)
        result = self.docker_environment_manager.stop(run_id, force=True)
        assert result
        # teardown
        self.docker_environment_manager.remove(name, force=True)

    def test_remove(self):
        name = str(uuid.uuid1())
        path = os.path.join(self.docker_environment_manager.filepath,
                            "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        # Without force
        self.docker_environment_manager.build(name, path)
        result = self.docker_environment_manager.remove(name)
        assert result == True
        # With force
        self.docker_environment_manager.build(name, path)
        # teardown
        result = self.docker_environment_manager.remove(name, force=True)
        assert result == True

    def test_init(self):
        assert self.init_result and \
               self.docker_environment_manager.is_initialized == True

    def test_get_tags_for_docker_repository(self):
        result = self.docker_environment_manager.get_tags_for_docker_repository(
            "hello-world")
        assert 'latest' in result

    def test_build_image(self):
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        result = self.docker_environment_manager.build_image(
            image_name, dockerfile_path)
        assert result == True
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_get_image(self):
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)

        result = self.docker_environment_manager.get_image(image_name)
        tags = result.__dict__['attrs']['RepoTags']
        assert image_name + ":latest" in tags
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_list_images(self):
        # TODO: Test out all input permutations
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        # List images without all flag
        result = self.docker_environment_manager.list_images()
        group = [item.__dict__['attrs']['RepoTags'] for item in result]
        list_of_lists = [sublist for sublist in group if sublist]
        group_flat = [item for sublist in list_of_lists for item in sublist]
        assert image_name + ":latest" in group_flat
        # List images with all flag
        result = self.docker_environment_manager.list_images(all_images=True)
        group = [item.__dict__['attrs']['RepoTags'] for item in result]
        list_of_lists = [sublist for sublist in group if sublist]
        group_flat = [item for sublist in list_of_lists for item in sublist]
        assert image_name + ":latest" in group_flat
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_search_images(self):
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        result = self.docker_environment_manager.search_images(image_name)
        assert len(result) > 0
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_remove_image(self):
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        # Without force
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        result = self.docker_environment_manager.remove_image(image_name)
        assert result == True
        # With force
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        result = self.docker_environment_manager.remove_image(image_name,
                                                              force=True)
        assert result == True

    def test_remove_images(self):
        # TODO: Test out all input permutations
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        # Without force
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        result = self.docker_environment_manager.remove_images(name=image_name)
        assert result == True
        # With force
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        result = self.docker_environment_manager.remove_images(name=image_name,
                                                               force=True)
        assert result == True

    def test_run_container(self):
        # TODO: test with all variables provided
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        # With default parameters
        return_code, container_id = \
            self.docker_environment_manager.run_container(image_name)
        assert return_code == 0 and \
            container_id
        # teardown container
        self.docker_environment_manager.stop(container_id, force=True)
        # With api=True, detach=False
        logs = self.docker_environment_manager.run_container(image_name,
                                                             api=True)
        assert logs == ""
        # With api=True, detach=True
        container_obj = self.docker_environment_manager.run_container(
            image_name, api=True, detach=True)
        assert container_obj
        self.docker_environment_manager.stop(container_obj.id, force=True)
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_get_container(self):
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        _, container_id = self.docker_environment_manager.run_container(
            image_name)
        result = self.docker_environment_manager.get_container(container_id)
        assert result
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_list_containers(self):
        # TODO: Test out all input permutations
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        _, container_id = self.docker_environment_manager.run_container(
            image_name, detach=True)
        result = self.docker_environment_manager.list_containers()
        assert container_id and len(result) > 0
        self.docker_environment_manager.stop(container_id, force=True)
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_stop_container(self):
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        _, container_id = self.docker_environment_manager.run_container(
            image_name)
        result = self.docker_environment_manager.stop_container(container_id)
        assert result == True
        result = self.docker_environment_manager.get_container(container_id)
        assert result.__dict__['attrs']['State']['Status'] == "exited"
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_remove_container(self):
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        # Without force
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        _, container_id = self.docker_environment_manager.run_container(
            image_name)
        result = self.docker_environment_manager.remove_container(container_id)
        assert result == True
        # With force
        _, container_id = self.docker_environment_manager.run_container(
            image_name)
        result = self.docker_environment_manager.remove_container(container_id,
                                                                  force=True)
        assert result == True
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_log_container(self):
        # TODO: Do a more comprehensive test, test out optional variables
        # TODO: Test out more commands at the system level
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        log_filepath = os.path.join(self.docker_environment_manager.filepath,
                                    "test.log")
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        _, container_id = \
            self.docker_environment_manager.run_container(image_name,
                                                          command=["sh", "-c", "echo yo"])
        return_code, logs = self.docker_environment_manager.log_container(
            container_id, log_filepath)
        assert return_code == 0
        assert logs and \
               os.path.exists(log_filepath)

        with open(log_filepath, "r") as f:
            assert f.readline() != ""

        self.docker_environment_manager.stop_container(container_id)
        self.docker_environment_manager.remove_container(container_id,
                                                         force=True)
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_create_requirements_file(self):
        # 1) Test failure EnvironmentDoesNotExist
        # 2) Test success
        # 3) Test failure EnvironmentRequirementsCreateException

        # 1) Test option 1
        failed = False
        try:
            _ = self.docker_environment_manager.create_requirements_file()
        except EnvironmentDoesNotExist:
            failed = True
        assert failed

        # 2) Test option 2
        script_path = os.path.join(self.docker_environment_manager.filepath,
                                   "script.py")
        with open(script_path, "w") as f:
            f.write(to_unicode("import numpy\n"))
            f.write(to_unicode("import sklearn\n"))
        # Test default
        result = self.docker_environment_manager.create_requirements_file()
        assert result
        assert os.path.isfile(result) and \
               "numpy" in open(result, "r").read() and \
               "scikit_learn" in open(result, "r").read()

        # 3) Test option 3
        exception_thrown = False
        try:
            _ = self.docker_environment_manager.\
                create_requirements_file(execpath="does_not_work")
        except EnvironmentRequirementsCreateException:
            exception_thrown = True

        assert exception_thrown

    def test_create_default_dockerfile(self):
        script_path = os.path.join(self.docker_environment_manager.filepath,
                                   "script.py")
        with open(script_path, "w") as f:
            f.write(to_unicode("import numpy\n"))
            f.write(to_unicode("import sklearn\n"))
        requirements_filepath = \
            self.docker_environment_manager.create_requirements_file()
        result = self.docker_environment_manager.\
            create_default_dockerfile(requirements_filepath,
                                      language="python3")

        assert result
        assert os.path.isfile(result)
        assert "python" in open(result, "r").read()
        assert "requirements.txt" in open(result, "r").read()

    def test_stop_remove_containers_by_term(self):
        # TODO: add more robust tests
        image_name = str(uuid.uuid1())
        dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        random_text = str(uuid.uuid1())
        with open(dockerfile_path, "w") as f:
            f.write(to_unicode("FROM datmo/xgboost:cpu" + "\n"))
            f.write(to_unicode(str("RUN echo " + random_text)))
        self.docker_environment_manager.build_image(image_name,
                                                    dockerfile_path)
        # Test without force
        self.docker_environment_manager.run_container(image_name)
        result = self.docker_environment_manager.stop_remove_containers_by_term(
            image_name)
        assert result == True
        # Test with force
        self.docker_environment_manager.run_container(image_name)
        result = self.docker_environment_manager.stop_remove_containers_by_term(
            image_name, force=True)
        assert result == True
        self.docker_environment_manager.remove_image(image_name, force=True)

    def test_form_datmo_dockerfile(self):
        input_dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "Dockerfile")
        output_dockerfile_path = os.path.join(
            self.docker_environment_manager.filepath, "datmoDockerfile")
        result = self.docker_environment_manager.form_datmo_definition_file(
            input_dockerfile_path, output_dockerfile_path)
        assert result and \
            os.path.isfile(output_dockerfile_path) and \
            "datmo" in open(output_dockerfile_path, "r").read()