Преглед на файлове

tests: DockerComposer contextmanager improvements

-Improve the DockerComposer contextmanager to make sure teardown happens by using try except block.
-Move the self. declarations up so we are sure they are set even if an exception occurs.
-set self._networks
Niek преди 3 месеца
родител
ревизия
557069583d
променени са 1 файла, в които са добавени 30 реда и са изтрити 7 реда
  1. 30 7
      test/conftest.py

+ 30 - 7
test/conftest.py

@@ -471,34 +471,57 @@ def connect_to_all_networks() -> List[Network]:
 
 class DockerComposer(contextlib.AbstractContextManager):
     def __init__(self):
+        logging.debug("DockerComposer __init__")
         self._networks = None
         self._docker_compose_files = None
         self._project_name = None
 
     def __exit__(self, *exc_info):
+        logging.debug("DockerComposer __exit__")
         self._down()
 
     def _down(self):
+        logging.debug(f"DockerComposer _down {self._docker_compose_files} {self._project_name} {self._networks}")
         if self._docker_compose_files is None:
+            logging.debug("docker_compose_files is None, nothing to cleanup")
             return
-        for network in self._networks:
-            disconnect_from_network(network)
+        if self._networks:
+            for network in self._networks:
+                disconnect_from_network(network)
         docker_compose_down(self._docker_compose_files, self._project_name)
         self._docker_compose_file = None
         self._project_name = None
+        self._networks = []
 
     def compose(self, docker_compose_files: List[str], project_name: str):
         if docker_compose_files == self._docker_compose_files and project_name == self._project_name:
+            logging.info(f"Skipping compose: {docker_compose_files} (already running under project {project_name})")
             return
-        self._down()
         if docker_compose_files is None or project_name is None:
+            logging.info(f"Skipping compose: no compose file specified")
             return
-        docker_compose_up(docker_compose_files, project_name)
-        self._networks = connect_to_all_networks()
-        wait_for_nginxproxy_to_be_ready()
-        time.sleep(3)  # give time to containers to be ready
+        self._down()
         self._docker_compose_files = docker_compose_files
         self._project_name = project_name
+        logging.debug(f"DockerComposer compose {self._docker_compose_files} {self._project_name} {self._networks}")
+
+        try:
+            docker_compose_up(docker_compose_files, project_name)
+            self._networks = connect_to_all_networks()
+            wait_for_nginxproxy_to_be_ready()
+            time.sleep(3)  # give time to containers to be ready
+
+        except docker.errors.APIError as e:
+            logging.error(f"Docker API error ({e.status_code}): {e.explanation}")
+            logging.debug(f"Full error message: {str(e)}")
+            self._down()  # Ensure proper cleanup even on failure
+            pytest.fail(f"Docker Compose setup failed due to Docker API error: {e.explanation}")
+            
+        except RuntimeError as e:
+            logging.error(f"RuntimeEror encountered in: {project_name}")
+            logging.debug(f"Full error message: {str(e)}")
+            self._down()  # Ensure proper cleanup even on failure
+            pytest.fail(f"Docker Compose setup failed due to RuntimeError in: {project_name}")
 
 
 ###############################################################################