Repository: exasol/integration-test-docker-environment (language: python)

Issue:
TestContainer doesn't get rebuild with force_rebuild set
# Background

- When we set `force_rebuild` to `true`, we would expect that build steps such as `AnalyzeTestContainer` would get rebuilt
- However, the `AnalyzeTestContainer` implements the  `is_rebuild_requested` method with a simple `false`, it needs to check the `build_config().force_rebuild config`

https://github.com/exasol/integration-test-docker-environment/blob/f9698db94e5a533c3b50ea44beffc1aa6c33c291/exasol_integration_test_docker_environment/lib/test_environment/analyze_test_container.py#L44

# Acceptance Criteria

- Check `build_config().force_rebuild config` in `is_rebuild_requested` 


Discussion / hints:

Fix patch:
diff --git a/doc/changes/changes_1.6.0.md b/doc/changes/changes_1.6.0.md
index 4e0d994ea..e179a80b5 100644
--- a/doc/changes/changes_1.6.0.md
+++ b/doc/changes/changes_1.6.0.md
@@ -20,3 +20,4 @@ If you need further versions, please open an issue.
  - #294: Fixed that the client logging config gets overwritten
  - #295: Fixed that the test_container_content parameter pollutes the logs
  - #300: Fixed BucketFS uploads during reusing of an environment
+ - #291: Fixed that test container gets rebuild when force_rebuild is true
\ No newline at end of file


Test patch:
diff --git a/exasol_integration_test_docker_environment/lib/test_environment/analyze_test_container.py b/exasol_integration_test_docker_environment/lib/test_environment/analyze_test_container.py
index a017607d3..5c570bf04 100644
--- a/exasol_integration_test_docker_environment/lib/test_environment/analyze_test_container.py
+++ b/exasol_integration_test_docker_environment/lib/test_environment/analyze_test_container.py
@@ -1,12 +1,8 @@
 from typing import Set, Dict
 
-from luigi.parameter import ParameterVisibility
-
-from exasol_integration_test_docker_environment.lib.base.json_pickle_parameter import JsonPickleParameter
+from exasol_integration_test_docker_environment.lib.config.build_config import build_config
 from exasol_integration_test_docker_environment.lib.config.docker_config import target_docker_repository_config, \
     source_docker_repository_config
-from exasol_integration_test_docker_environment.lib.data.test_container_content_description import \
-    TestContainerContentDescription
 from exasol_integration_test_docker_environment.lib.docker.images.create.docker_build_base import DockerBuildBase
 from exasol_integration_test_docker_environment.lib.docker.images.create.docker_image_analyze_task import \
     DockerAnalyzeImageTask
@@ -45,7 +41,8 @@ def get_dockerfile(self):
         return str(self.test_container_content.docker_file)
 
     def is_rebuild_requested(self) -> bool:
-        return False
+        config = build_config()
+        return config.force_rebuild
 
 
 class DockerTestContainerBuildBase(DockerBuildBase, TestContainerParameter):
diff --git a/exasol_integration_test_docker_environment/test/get_test_container_content.py b/exasol_integration_test_docker_environment/test/get_test_container_content.py
index 9ff2bd549..85c0ef561 100644
--- a/exasol_integration_test_docker_environment/test/get_test_container_content.py
+++ b/exasol_integration_test_docker_environment/test/get_test_container_content.py
@@ -4,14 +4,18 @@
 from exasol_integration_test_docker_environment.lib.data.test_container_content_description import \
     TestContainerContentDescription, TestContainerBuildMapping, TestContainerRuntimeMapping
 
-TEST_CONTAINER_PATH = Path(__file__).parent / "resources" / "test_container"
+TEST_CONTAINER_ROOT_PATH = Path(__file__).parent / "resources" / "test_container"
 
+FULL_TEST_CONTAINER_PATH = TEST_CONTAINER_ROOT_PATH / "full"
+MOCK_TEST_CONTAINER_PATH = TEST_CONTAINER_ROOT_PATH / "mock"
 
-def get_test_container_content(runtime_mapping: Tuple[TestContainerRuntimeMapping] = tuple()) \
+
+def get_test_container_content(test_container_path: Path = FULL_TEST_CONTAINER_PATH,
+                               runtime_mapping: Tuple[TestContainerRuntimeMapping] = tuple()) \
         -> TestContainerContentDescription:
     return TestContainerContentDescription(
-        docker_file=f"{TEST_CONTAINER_PATH}/Dockerfile",
-        build_files_and_directories=[TestContainerBuildMapping(source=TEST_CONTAINER_PATH / "test.txt",
+        docker_file=str(test_container_path / "Dockerfile"),
+        build_files_and_directories=[TestContainerBuildMapping(source=test_container_path / "test.txt",
                                                                target="test.text")],
         runtime_mappings=list(runtime_mapping)
     )
diff --git a/exasol_integration_test_docker_environment/test/resources/test_container/Dockerfile b/exasol_integration_test_docker_environment/test/resources/test_container/full/Dockerfile
similarity index 100%
rename from exasol_integration_test_docker_environment/test/resources/test_container/Dockerfile
rename to exasol_integration_test_docker_environment/test/resources/test_container/full/Dockerfile
diff --git a/exasol_integration_test_docker_environment/test/resources/test_container/test.txt b/exasol_integration_test_docker_environment/test/resources/test_container/full/test.txt
similarity index 100%
rename from exasol_integration_test_docker_environment/test/resources/test_container/test.txt
rename to exasol_integration_test_docker_environment/test/resources/test_container/full/test.txt
diff --git a/exasol_integration_test_docker_environment/test/resources/test_container/mock/Dockerfile b/exasol_integration_test_docker_environment/test/resources/test_container/mock/Dockerfile
new file mode 100644
index 000000000..fa602f573
--- /dev/null
+++ b/exasol_integration_test_docker_environment/test/resources/test_container/mock/Dockerfile
@@ -0,0 +1,3 @@
+FROM ubuntu:20.04
+
+COPY test.text /test.text
\ No newline at end of file
diff --git a/exasol_integration_test_docker_environment/test/resources/test_container/mock/test.txt b/exasol_integration_test_docker_environment/test/resources/test_container/mock/test.txt
new file mode 100644
index 000000000..037869c9e
--- /dev/null
+++ b/exasol_integration_test_docker_environment/test/resources/test_container/mock/test.txt
@@ -0,0 +1,1 @@
+Empty File
\ No newline at end of file
diff --git a/exasol_integration_test_docker_environment/test/test_api_build_test_container.py b/exasol_integration_test_docker_environment/test/test_api_build_test_container.py
index a3e0fa56e..63b7c403a 100644
--- a/exasol_integration_test_docker_environment/test/test_api_build_test_container.py
+++ b/exasol_integration_test_docker_environment/test/test_api_build_test_container.py
@@ -3,10 +3,15 @@
 
 from exasol_integration_test_docker_environment.lib import api
 from exasol_integration_test_docker_environment.lib.docker import ContextDockerClient
-from exasol_integration_test_docker_environment.test.get_test_container_content import get_test_container_content
+from exasol_integration_test_docker_environment.lib.docker.images.image_info import ImageState
+from exasol_integration_test_docker_environment.test.get_test_container_content import get_test_container_content, \
+    MOCK_TEST_CONTAINER_PATH
+
 from exasol_integration_test_docker_environment.testing import luigi_utils
 from exasol_integration_test_docker_environment.testing.api_test_environment import ApiTestEnvironment
 
+TEST_CONTAINER_CONTENT = get_test_container_content(MOCK_TEST_CONTAINER_PATH)
+
 
 class APIBuildTestContainerTest(unittest.TestCase):
 
@@ -21,11 +26,31 @@ def tearDown(self):
     def test_build_test_container(self):
         docker_repository_name = self.test_environment.docker_repository_name
         image_info = api.build_test_container(target_docker_repository_name=docker_repository_name,
-                                              test_container_content=get_test_container_content())
+                                              test_container_content=TEST_CONTAINER_CONTENT)
         with ContextDockerClient() as docker_client:
             image = docker_client.images.get(image_info.get_target_complete_name())
-            assert len(image.tags) == 1
-            assert image.tags[0] == image_info.get_target_complete_name()
+            self.assertEqual(len(image.tags), 1)
+            self.assertEqual(image.tags[0], image_info.get_target_complete_name())
+            self.assertEqual(image_info.image_state, ImageState.WAS_BUILD.name)
+
+    def test_build_test_container_use_cached(self):
+        docker_repository_name = self.test_environment.docker_repository_name
+        image_info1 = api.build_test_container(target_docker_repository_name=docker_repository_name,
+                                               test_container_content=TEST_CONTAINER_CONTENT)
+        self.assertEqual(image_info1.image_state, ImageState.WAS_BUILD.name)
+        image_info2 = api.build_test_container(target_docker_repository_name=docker_repository_name,
+                                               test_container_content=TEST_CONTAINER_CONTENT)
+        self.assertEqual(image_info2.image_state, ImageState.USED_LOCAL.name)
+
+    def test_build_test_container_force_rebuild(self):
+        docker_repository_name = self.test_environment.docker_repository_name
+        image_info1 = api.build_test_container(target_docker_repository_name=docker_repository_name,
+                                               test_container_content=TEST_CONTAINER_CONTENT)
+        self.assertEqual(image_info1.image_state, ImageState.WAS_BUILD.name)
+        image_info2 = api.build_test_container(target_docker_repository_name=docker_repository_name,
+                                               test_container_content=TEST_CONTAINER_CONTENT,
+                                               force_rebuild=True)
+        self.assertEqual(image_info2.image_state, ImageState.WAS_BUILD.name)
 
 
 if __name__ == '__main__':
diff --git a/exasol_integration_test_docker_environment/test/test_api_test_environment.py b/exasol_integration_test_docker_environment/test/test_api_test_environment.py
index 762cd6e0f..f62d1c3d1 100644
--- a/exasol_integration_test_docker_environment/test/test_api_test_environment.py
+++ b/exasol_integration_test_docker_environment/test/test_api_test_environment.py
@@ -111,7 +111,7 @@ def _assert_deployment_available(self, environment_info: EnvironmentInfo) -> Non
             self.assertEqual(exit_code, 0)
             self.assertEqual(output.decode("utf-8"), "test")
 
-    def _assert_deployment_not_shared(self, environment_info: EnvironmentInfo, temp_path: Path) -> bool:
+    def _assert_deployment_not_shared(self, environment_info: EnvironmentInfo, temp_path: Path):
         with ContextDockerClient() as docker_client:
             test_container = docker_client.containers.get(environment_info.test_container_info.container_name)
             exit_code, output = test_container.exec_run("touch /test_target/test_new.txt")
@@ -131,7 +131,7 @@ def test_runtime_mapping_without_deployment(self):
                 environment = \
                     self.test_environment.spawn_docker_test_environment_with_test_container(
                         name=self.docker_environment_name,
-                        test_container_content=get_test_container_content((mapping,))
+                        test_container_content=get_test_container_content(runtime_mapping=(mapping,))
                     )
                 environment_info = environment.environment_info
                 self._assert_deployment_available(environment_info)
@@ -146,7 +146,7 @@ def test_runtime_mapping_deployment(self):
                 environment = \
                     self.test_environment.spawn_docker_test_environment_with_test_container(
                         name=self.docker_environment_name,
-                        test_container_content=get_test_container_content((mapping,))
+                        test_container_content=get_test_container_content(runtime_mapping=(mapping,))
                     )
                 environment_info = environment.environment_info
                 self._assert_deployment_available(environment_info)
diff --git a/exasol_integration_test_docker_environment/test/test_populate_data.py b/exasol_integration_test_docker_environment/test/test_populate_data.py
index 3e2f7d120..12ca020a7 100644
--- a/exasol_integration_test_docker_environment/test/test_populate_data.py
+++ b/exasol_integration_test_docker_environment/test/test_populate_data.py
@@ -33,7 +33,7 @@ def setUpClass(cls):
         cls.docker_environment_name = cls.__name__
         test_data_folder = Path(__file__).parent / "resources" / "test_data"
         test_container_runtime_mapping = TestContainerRuntimeMapping(source=test_data_folder, target="/test_data")
-        test_container_content = get_test_container_content((test_container_runtime_mapping,))
+        test_container_content = get_test_container_content(runtime_mapping=(test_container_runtime_mapping,))
         cls.environment = \
             cls.test_environment.spawn_docker_test_environment_with_test_container(
                 name=cls.docker_environment_name,