From 6c7bc49f2c3807fbc849e476887b0e41876e6a1e Mon Sep 17 00:00:00 2001
From: mamunozgil <miguel.munoz-gil@hft-stuttgart.de>
Date: Fri, 10 Jan 2025 11:09:49 +0100
Subject: [PATCH] Modified paths

---
 .../dtabackend/utils/DockerUtil.java          | 126 ++++++++++--------
 .../dtabackend/utils/ExecuteTestUtil.java     |  20 +--
 2 files changed, 82 insertions(+), 64 deletions(-)

diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java
index 28510e0..b59d882 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/DockerUtil.java
@@ -19,6 +19,7 @@ import org.springframework.stereotype.Component;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.UUID;
 import java.util.stream.Collectors;
 
 @Component
@@ -94,60 +95,75 @@ public class DockerUtil {
     }
 
     public int runContainerWithVolumes(String image, Volume... volumes) throws InterruptedException, IOException {
-    LOG.debug(String.format("Pulling image: %s", image));
-    try {
-        dockerClient.pullImageCmd(image)
-            .start()
-            .awaitCompletion()
-            .close();
-    } catch (DockerException e) {
-        LOG.error(String.format(
-            "Pulling Docker image %s failed with %s, trying with local image",
-            image,
-            e.getMessage()));
-    }
-
-    LOG.debug("Creating container");
-    CreateContainerResponse containerResponse;
-    try {
-        // Prepare the host configuration with volumes
-        HostConfig hostConfig = HostConfig.newHostConfig()
-            .withMounts(
-                Arrays.stream(volumes)
-                    .map(volume -> new Mount().withTarget(volume.getPath()).withType(MountType.VOLUME))
-                    .collect(Collectors.toList())
-            );
-
-        // Create the container with the configured volumes
-        containerResponse = dockerClient.createContainerCmd("testcontainer")
-            .withImage(image)
-            .withHostConfig(hostConfig)
-            .exec();
-    } catch (DockerException e) {
-        LOG.error(String.format(
-            "Creating Docker Testrunner container failed with %s", e.getMessage()));
-        throw e;
-    }
-
-    LOG.debug(String.format("Container created: %s", containerResponse.getId()));
-
-    LOG.debug(String.format("Starting container %s", containerResponse.getId()));
-    dockerClient.startContainerCmd(containerResponse.getId()).exec();
-
-    LOG.debug(String.format("Waiting for completion of container %s", containerResponse.getId()));
-    int ret = dockerClient
-        .waitContainerCmd(containerResponse.getId())
-        .start()
-        .awaitCompletion()
-        .awaitStatusCode();
-    LOG.debug(String.format("Container completed with status %d", ret));
-
-    LOG.debug(String.format("Deleting container %s", containerResponse.getId()));
-    dockerClient.removeContainerCmd(containerResponse.getId())
-        .withRemoveVolumes(true)
-        .exec();
-
-    return ret;
-}
+        LOG.debug(String.format("Pulling image: %s", image));
+    
+        // Pull the Docker image or log and proceed with local image
+        try {
+            dockerClient.pullImageCmd(image).start().awaitCompletion();
+            LOG.debug(String.format("Image %s pulled successfully", image));
+        } catch (DockerException e) {
+            LOG.warn(String.format(
+                "Failed to pull image %s from remote: %s. Attempting to use local image.",
+                image, e.getMessage()));
+    
+            if (dockerClient.inspectImageCmd(image).exec() == null) {
+                LOG.error(String.format("Image %s not found locally. Aborting.", image));
+                throw new IOException("Image not available locally or remotely: " + image);
+            }
+        }
+    
+        String containerId = null;
+        try {
+            LOG.debug("Configuring container with volumes");
+    
+            // Prepare the host configuration for volumes
+            HostConfig hostConfig = HostConfig.newHostConfig()
+                .withMounts(Arrays.stream(volumes)
+                    .map(volume -> new Mount()
+                        .withTarget(volume.getPath())
+                        .withType(MountType.VOLUME))
+                    .collect(Collectors.toList()));
+    
+            // Create the container
+            LOG.debug("Creating container");
+            CreateContainerResponse containerResponse = dockerClient.createContainerCmd(image)
+                .withHostConfig(hostConfig)
+                .withName("testcontainer-" + UUID.randomUUID()) 
+                .exec();
+    
+            containerId = containerResponse.getId();
+            LOG.debug(String.format("Container created with ID: %s", containerId));
+    
+            // Start the container
+            LOG.debug(String.format("Starting container %s", containerId));
+            dockerClient.startContainerCmd(containerId).exec();
+    
+            // Wait for container completion
+            LOG.debug(String.format("Waiting for completion of container %s", containerId));
+            int statusCode = dockerClient.waitContainerCmd(containerId)
+                .start()
+                .awaitCompletion()
+                .awaitStatusCode();
+    
+            LOG.debug(String.format("Container %s completed with status code %d", containerId, statusCode));
+            return statusCode;
+    
+        } catch (DockerException | InterruptedException e) {
+            LOG.error(String.format("An error occurred: %s", e.getMessage()), e);
+            throw e;
+        } finally {
+            if (containerId != null) {
+                try {
+                    LOG.debug(String.format("Cleaning up container %s", containerId));
+                    dockerClient.removeContainerCmd(containerId).withRemoveVolumes(false).exec();
+                    LOG.debug(String.format("Container %s removed successfully", containerId));
+                } catch (DockerException cleanupException) {
+                    LOG.error(String.format(
+                        "Failed to clean up container %s: %s",
+                        containerId, cleanupException.getMessage()), cleanupException);
+                }
+            }
+        }
+    }    
 
 }
diff --git a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
index bc5e73b..61541db 100644
--- a/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
+++ b/src/main/java/de/hftstuttgart/dtabackend/utils/ExecuteTestUtil.java
@@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.github.dockerjava.api.model.Volume;
 
 import de.hftstuttgart.dtabackend.models.ExerciseCompetencyProfile;
-import de.hftstuttgart.dtabackend.models.ICompetencyProfile;
 import de.hftstuttgart.dtabackend.models.Recommendation;
 import de.hftstuttgart.dtabackend.models.ResultSummary;
 import de.hftstuttgart.dtabackend.models.TestCompetencyProfile;
@@ -35,6 +34,7 @@ public class ExecuteTestUtil {
 
     private final DockerUtil dockerUtil;
     private final String assignmentBasePath;
+    private final String containerTestDir;
 
     public ExecuteTestUtil(
         Environment env,
@@ -44,17 +44,19 @@ public class ExecuteTestUtil {
 
         // set base path for assignments to be stored
         Path p = Paths.get(
-            env.getProperty("data.dir"),
-            env.getProperty("data.dir.test.folder.name"));
+            env.getProperty("data.dir"), ///data
+            env.getProperty("data.dir.test.folder.name")); //UnitTests
         this.assignmentBasePath = p.toAbsolutePath().toString();
+        this.containerTestDir = env.getProperty( "data.dir");
     }
 
     public ResultSummary runTests(String assignmentId, Path workDirectory) throws IOException, InterruptedException {
 
         // Define paths for the test, the submission, and where the result is expected afterwards
-        Path testPath = Paths.get("/data/test");   // Volume mount path in the container
-        Path srcPath = Paths.get("/data/src");    // Volume mount path in the container
-        Path resultPath = Paths.get("/data/result"); // Volume mount path in the container
+        String containerTestDir = this.containerTestDir; 
+        Path resultPath = Paths.get(containerTestDir, "result"); 
+        Path testPath = Paths.get(containerTestDir, "test");    
+        Path srcPath = Paths.get(containerTestDir, "src");      
 
         // Clone stored test to testPath
         LOG.debug("Copying pre-downloaded unit test repo");
@@ -95,9 +97,9 @@ public class ExecuteTestUtil {
         // Start the test-container with professor-given image and volume mounts for test, submission, and result
         dockerUtil.runContainerWithVolumes(
             image,
-            new Volume("/data/test"),
-            new Volume("/data/src"),
-            new Volume("/data/result")
+            new Volume("test_volume: /data/test"),
+            new Volume("src_volume: /data/src"),
+            new Volume("result_volume: /data/result")
         );
 
         ResultSummary resultSummary = generateResult(assignmentId, resultPath, testPath);
-- 
GitLab