Commit b6f6e1ad authored by Lückemeyer's avatar Lückemeyer
Browse files

added directory support for unittests and student submissions. kept legacy mode.

parent 8aabe7e6
Pipeline #9077 passed with stage
...@@ -18,6 +18,8 @@ import java.nio.file.Files; ...@@ -18,6 +18,8 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jakarta.servlet.annotation.MultipartConfig; import jakarta.servlet.annotation.MultipartConfig;
/** /**
...@@ -63,10 +65,20 @@ public class TaskUpload { ...@@ -63,10 +65,20 @@ public class TaskUpload {
case "text/plain": case "text/plain":
LOG.debug("textfile uploaded, searching for dta config"); LOG.debug("textfile uploaded, searching for dta config");
// find URI in config file // find URI in config file
Matcher config = RegexUtil.findStudentConfig(taskFileRef.getInputStream()); String subDir="";
Matcher config = RegexUtil.extractConfig(taskFileRef.getInputStream(), Pattern.compile(RegexUtil.DTA_SUBMISSIONCONFIGREGEX));
if(config==null) {
config = RegexUtil.extractConfig(taskFileRef.getInputStream(), Pattern.compile(RegexUtil.SUBMISSIONCONFIGREGEX));
if(config==null)
{
throw new RuntimeException("couldn't find repo config for student submission clone");
}
}
else {
subDir=config.group(4);
}
LOG.debug("calling repo clone"); LOG.debug("calling repo clone");
jGitUtil.cloneRepository(config, srcPath.toAbsolutePath().toString()); jGitUtil.cloneRepository(config, srcPath.toAbsolutePath().toString(), subDir);
break; break;
case "application/zip": case "application/zip":
......
package de.hftstuttgart.dtabackend.rest.v1.unittest; package de.hftstuttgart.dtabackend.rest.v1.unittest;
import de.hftstuttgart.dtabackend.utils.JGitUtil; import de.hftstuttgart.dtabackend.utils.JGitUtil;
import de.hftstuttgart.dtabackend.utils.RegexUtil;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
...@@ -28,9 +30,6 @@ import java.util.regex.Pattern; ...@@ -28,9 +30,6 @@ import java.util.regex.Pattern;
public class UnitTestUpload { public class UnitTestUpload {
private static final Logger LOG = LogManager.getLogger(UnitTestUpload.class); private static final Logger LOG = LogManager.getLogger(UnitTestUpload.class);
public final static String TESTCONFIGREGEX = "^dtt::(.*)::(.*|none)::(.*|none)::(.*)$";
public final static String SUBMISSIONCONFIGREGEX = "^dtt::(.*)::(.*|none)::(.*|none)$";
private final JGitUtil jGitUtil; private final JGitUtil jGitUtil;
private final String assignmentBasePath; private final String assignmentBasePath;
...@@ -55,48 +54,31 @@ public class UnitTestUpload { ...@@ -55,48 +54,31 @@ public class UnitTestUpload {
) throws IOException { ) throws IOException {
LOG.info("received new assignment"); LOG.info("received new assignment");
File file = Paths.get( File file = Paths.get(this.assignmentBasePath, assignmentId + ".txt").toFile();
this.assignmentBasePath,
assignmentId + ".txt")
.toFile();
file.mkdirs(); file.mkdirs();
// save assignment config // save assignment config
unitTestFileRef.transferTo(file); unitTestFileRef.transferTo(file);
LOG.debug(String.format("saved config file to: %s", file.getAbsolutePath())); LOG.debug(String.format("saved config file to: %s", file.getAbsolutePath()));
Pattern pattern = Pattern.compile(TESTCONFIGREGEX); String subDir="";
Matcher config = null; Pattern pattern = Pattern.compile(RegexUtil.DTA_TESTCONFIGREGEX);
LOG.debug("reading test configuration file"); Matcher config = RegexUtil.extractConfig(new FileInputStream(file), pattern);
// open saved config in a try-with if (config == null) {
try (BufferedReader br = new BufferedReader( pattern=Pattern.compile(RegexUtil.TESTCONFIGREGEX);
new InputStreamReader( config = RegexUtil.extractConfig(new FileInputStream(file), pattern);
new FileInputStream(file)))) { if(config==null)
String line; {
throw new RuntimeException("couldn't find repo config for unittest clone");
// search for a URI while none is found and there are lines left }
while (config == null && (line = br.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
LOG.debug(String.format("found dta test line: %s", line));
config = matcher;
}
}
} catch (IOException e) {
LOG.error("Error while reading repo config", e);
} }
finally { else {
if (config == null) { subDir=config.group(4);
throw new RuntimeException("couldn't find repo config for unittest clone");
}
} }
LOG.debug("calling test repo clone"); LOG.debug("calling test repo clone");
// cloning assignment repo to persistent space // cloning assignment repo to persistent space
jGitUtil.cloneRepository( jGitUtil.cloneRepository(config, Paths.get(this.assignmentBasePath, assignmentId).toAbsolutePath().toString(), subDir);
config,
Paths.get(this.assignmentBasePath, assignmentId).toAbsolutePath().toString());
LOG.info(String.format("stored new assignment: %s", file.getAbsolutePath())); LOG.info(String.format("stored new assignment: %s", file.getAbsolutePath()));
} }
......
...@@ -20,6 +20,7 @@ import java.nio.file.Path; ...@@ -20,6 +20,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component @Component
public class ExecuteTestUtil { public class ExecuteTestUtil {
...@@ -60,31 +61,34 @@ public class ExecuteTestUtil { ...@@ -60,31 +61,34 @@ public class ExecuteTestUtil {
// clone stored test to tmpdir // clone stored test to tmpdir
LOG.debug("copying pre-downloaded unitttest repo"); LOG.debug("copying pre-downloaded unitttest repo");
FileUtil.copyFolder( FileUtil.copyFolder(
Paths.get( Paths.get(assignmentBasePath, assignmentId),
assignmentBasePath, testPath);
assignmentId
),
testPath
);
LOG.debug("copy test config"); LOG.debug("copy test config");
Files.copy( Files.copy(
Paths.get( Paths.get(assignmentBasePath, assignmentId + ".txt"),
assignmentBasePath, Paths.get(workDirectory.toAbsolutePath().toString(), "config.txt"));
assignmentId + ".txt"
),
Paths.get(
workDirectory.toAbsolutePath().toString(),
"config.txt"
)
);
Files.createDirectory(resultPath); Files.createDirectory(resultPath);
LOG.info("reading test config"); LOG.info("reading test config");
Matcher config = RegexUtil.findProfessorConfig( Matcher config = RegexUtil.extractConfig(
new FileInputStream(Paths.get(workDirectory.toAbsolutePath().toString(), "config.txt").toFile())); new FileInputStream(Paths.get(workDirectory.toAbsolutePath().toString(), "config.txt").toFile()), Pattern.compile(RegexUtil.DTA_TESTCONFIGREGEX));
String image="";
if(config==null)
{
config = RegexUtil.extractConfig(
new FileInputStream(Paths.get(workDirectory.toAbsolutePath().toString(), "config.txt").toFile()), Pattern.compile(RegexUtil.TESTCONFIGREGEX));
if(config==null)
{
throw new RuntimeException("couldn't find repo config for unittest image extraction");
}
image=config.group(4);
}
else
{
image=config.group(5);
}
// define the paths to mount as Binds from Host to the test-container // define the paths to mount as Binds from Host to the test-container
Path testPathHost = Paths.get( Path testPathHost = Paths.get(
testTmpPathHost.toAbsolutePath().toString(), testTmpPathHost.toAbsolutePath().toString(),
...@@ -104,7 +108,7 @@ public class ExecuteTestUtil { ...@@ -104,7 +108,7 @@ public class ExecuteTestUtil {
// start test-container with professor given image and bind mounts for test, submission and result // start test-container with professor given image and bind mounts for test, submission and result
dockerUtil.runContainer( dockerUtil.runContainer(
config.group(4), image,
new Bind(testPathHost.toAbsolutePath().toString(), new Volume("/data/test")), new Bind(testPathHost.toAbsolutePath().toString(), new Volume("/data/test")),
new Bind(srcPathHost.toAbsolutePath().toString(), new Volume("/data/src")), new Bind(srcPathHost.toAbsolutePath().toString(), new Volume("/data/src")),
new Bind(resultPathHost.toAbsolutePath().toString(), new Volume("/data/result")) new Bind(resultPathHost.toAbsolutePath().toString(), new Volume("/data/result"))
......
...@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component; ...@@ -10,6 +10,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.FileSystemUtils; import org.springframework.util.FileSystemUtils;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@Component @Component
...@@ -19,7 +20,7 @@ public class JGitUtil { ...@@ -19,7 +20,7 @@ public class JGitUtil {
public JGitUtil() {} public JGitUtil() {}
public void cloneRepository(Matcher config, String targetPath) { public void cloneRepository(Matcher config, String targetPath, String subDir) {
LOG.debug(String.format("cloning repository: %s", config.group(1))); LOG.debug(String.format("cloning repository: %s", config.group(1)));
File targetDirectory = new File(targetPath); File targetDirectory = new File(targetPath);
...@@ -28,46 +29,44 @@ public class JGitUtil { ...@@ -28,46 +29,44 @@ public class JGitUtil {
FileSystemUtils.deleteRecursively(targetDirectory); FileSystemUtils.deleteRecursively(targetDirectory);
} }
//create companion checkout dir "targetPath"+"_checkout" File checkoutDirectory = targetDirectory;
File checkoutDirectory = new File(targetPath+"_checkout"); //if an optional directory parameter was given
if (targetDirectory.exists()) { if(subDir!="")
LOG.debug("clone checkout directory existing yet, deleting now"); {
FileSystemUtils.deleteRecursively(checkoutDirectory); //create companion checkout dir "targetPath"+"_checkout"
checkoutDirectory = new File(targetPath+"_checkout");
if (targetDirectory.exists()) {
LOG.debug("clone checkout directory existing yet, deleting now");
FileSystemUtils.deleteRecursively(checkoutDirectory);
}
} }
try { try {
//check group(1) for possible directory
//if(!config.group(1).endsWith(".git"))
//cut off the directory part
//pos=instr(".git/")
//cloneURI=config.group(1).substr(1, pos+3)
//else
//cloneURI=config.group(1)
LOG.debug("preparing clone"); LOG.debug("preparing clone");
CloneCommand cloneCommand = Git.cloneRepository() CloneCommand cloneCommand = Git.cloneRepository()
.setDirectory(checkoutDirectory) .setDirectory(checkoutDirectory)
//.setURI(cloneURI)
.setURI(config.group(1)); .setURI(config.group(1));
if (!config.group(2).equals("none") && !config.group(3).equals("none")) { if (!config.group(2).equals("none") && !config.group(3).equals("none")) {
LOG.debug("setting credentials"); LOG.debug("setting credentials");
cloneCommand.setCredentialsProvider( cloneCommand.setCredentialsProvider(new UsernamePasswordCredentialsProvider(config.group(2), config.group(3)));
new UsernamePasswordCredentialsProvider(config.group(2), config.group(3)));
} }
LOG.debug("cloning..."); LOG.debug("cloning...");
cloneCommand.call() cloneCommand.call().close();
.close();
//copy appropriate path from checkout directory to target directory
//if(!config.group(1).endsWith(".git"))
//copy checkout+config.group(1).substr(pos+4) to target directory
//else
//copy checkout directory to target directory directly
//if an optional directory parameter was given
if(subDir!="")
{
//copy appropriate path from checkout directory to target directory
FileSystemUtils.copyRecursively(targetDirectory, new File(checkoutDirectory+subDir));
}
}
catch (IOException e) {
LOG.error(String.format("Error while cloning from %s: could not copy to unit test dir", config.group(1)), e);
} }
catch (GitAPIException e) { catch (GitAPIException e) {
LOG.error(String.format("Error while cloning from %s", config.group(1)), e); LOG.error(String.format("Error while cloning from %s: could not read from Git", config.group(1)), e);
} }
LOG.debug(String.format("cloned from %s to %s", config.group(1), targetDirectory)); LOG.debug(String.format("cloned from %s to %s", config.group(1), targetDirectory));
......
...@@ -3,9 +3,9 @@ package de.hftstuttgart.dtabackend.utils; ...@@ -3,9 +3,9 @@ package de.hftstuttgart.dtabackend.utils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import de.hftstuttgart.dtabackend.rest.v1.unittest.UnitTestUpload;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
...@@ -14,6 +14,11 @@ import java.util.regex.Pattern; ...@@ -14,6 +14,11 @@ import java.util.regex.Pattern;
public class RegexUtil { public class RegexUtil {
public final static String DTA_TESTCONFIGREGEX = "^dtt::(.*)::(.*|none)::(.*|none)::(.*)::(.*)$";
public final static String DTA_SUBMISSIONCONFIGREGEX = "^dtt::(.*)::(.*|none)::(.*|none)::(.*)$";
public final static String TESTCONFIGREGEX = "^dtt::(.*)::(.*|none)::(.*|none)::(.*)$";
public final static String SUBMISSIONCONFIGREGEX = "^dtt::(.*)::(.*|none)::(.*|none)$";
public enum ConfigType { public enum ConfigType {
TEACHER, TEACHER,
STUDENT, STUDENT,
...@@ -33,11 +38,11 @@ public class RegexUtil { ...@@ -33,11 +38,11 @@ public class RegexUtil {
Pattern pattern; Pattern pattern;
switch (configType) { switch (configType) {
case TEACHER: case TEACHER:
pattern = Pattern.compile(UnitTestUpload.TESTCONFIGREGEX); pattern = Pattern.compile(RegexUtil.TESTCONFIGREGEX);
break; break;
case STUDENT: case STUDENT:
pattern = Pattern.compile(UnitTestUpload.SUBMISSIONCONFIGREGEX); pattern = Pattern.compile(RegexUtil.SUBMISSIONCONFIGREGEX);
break; break;
default: default:
...@@ -46,33 +51,31 @@ public class RegexUtil { ...@@ -46,33 +51,31 @@ public class RegexUtil {
throw new RuntimeException(msg); throw new RuntimeException(msg);
} }
Matcher config = null; Matcher config = extractConfig(is, pattern);
LOG.debug("reading config file"); return config;
// open received file in a try-with }
try (BufferedReader br = new BufferedReader(
new InputStreamReader( public static Matcher extractConfig(InputStream configFileStream, Pattern pattern) {
is))) { LOG.debug("reading configuration file");
Matcher configItems=null;
// open saved config in a try-with
try (BufferedReader br = new BufferedReader(new InputStreamReader(configFileStream))) {
String line; String line;
// as long as we haven't found a configuration and have lines left, search // search for a URI while none is found and there are lines left
while (config == null && (line = br.readLine()) != null) { while (configItems == null && (line = br.readLine()) != null) {
Matcher matcher = pattern.matcher(line); Matcher matcher = pattern.matcher(line);
if (matcher.matches()) { if (matcher.matches()) {
LOG.debug(String.format("found dta line: %s", line)); LOG.debug(String.format("found valid config line: %s", line));
config = matcher; configItems = matcher;
} }
} }
} catch (IOException e) { } catch (IOException e) {
LOG.error("Error while reading repo config", e); LOG.error("Error while reading repo config", e);
} }
finally { finally {
if (config == null) {
throw new RuntimeException("couldn't find repo config for clone");
}
} }
return configItems;
return config; }
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment