UnitTestUpload.java 4.86 KB
Newer Older
Lückemeyer's avatar
Lückemeyer committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package de.hftstuttgart.dtabackend.rest.v1.unittest;

import de.hftstuttgart.dtabackend.utils.JGitUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.core.env.Environment;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.annotation.MultipartConfig;

import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Rest controller for anything related to the TEST files.
 */
@RestController
@RequestMapping("/v1/unittest")
@MultipartConfig
public class UnitTestUpload {

    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 String assignmentBasePath;

    public UnitTestUpload(Environment env, JGitUtil jGitUtil) {
        this.jGitUtil = jGitUtil;

        Path p = Paths.get(env.getProperty("data.dir"), env.getProperty("data.dir.test.folder.name"));
        this.assignmentBasePath = p.toAbsolutePath().toString();
    }

    /**
     * Create a subfolder for the specific assignment.
     * This is called when the teacher creates an assignment and uploads the JUnit test files
     *
     * @param unitTestFileRef The text file which contains the JUnit tests meta data
     * @param assignmentId    ID of the created assignment. Generated by Moodle
     */
    @RequestMapping(method = RequestMethod.POST)
    public void uploadUnitTestFile(
        @RequestParam("unitTestFile") MultipartFile unitTestFileRef,
        @RequestParam("assignmentId") String assignmentId
    ) throws IOException {
        LOG.info("received new assignment");

        File file = Paths.get(
                this.assignmentBasePath,
                assignmentId + ".txt")
            .toFile();
        file.mkdirs();

        // save assignment config
        unitTestFileRef.transferTo(file);
        LOG.debug(String.format("saved config file to: %s", file.getAbsolutePath()));

        Pattern pattern = Pattern.compile(TESTCONFIGREGEX);
        Matcher config = null;

        LOG.debug("reading test configuration file");
        // open saved config in a try-with
        try (BufferedReader br = new BufferedReader(
            new InputStreamReader(
                new FileInputStream(file)))) {
            String line;

            // 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 {
            if (config == null) {
                throw new RuntimeException("couldn't find repo config for unittest clone");
            }
        }

        LOG.debug("calling test repo clone");
        // cloning assignment repo to persistent space
        jGitUtil.cloneRepository(
            config,
            Paths.get(this.assignmentBasePath, assignmentId).toAbsolutePath().toString());

        LOG.info(String.format("stored new assignment: %s", file.getAbsolutePath()));
    }

    /**
     * Delete the folder for the assignment.
     * Called when the teacher deletes the JUnitTest assignment
     * <p>
     * {{url}}:8080/v1/unittest?assignmentId=111
     *
     * @param assignmentId ID of the assignment to delete. Generated by Moodle
     */
    @RequestMapping(method = RequestMethod.DELETE)
    public void deleteUnitTestFiles(@RequestParam("assignmentId") String assignmentId) {
        LOG.info(String.format("received deletion order for assignment %s", assignmentId));

        // deleting config file
        File file = Paths.get(
            this.assignmentBasePath,
            assignmentId + ".txt")
            .toFile();
        file.delete();

        // deleting local copy of repository
        file = Paths.get(
            this.assignmentBasePath,
            assignmentId).toFile();
        FileSystemUtils.deleteRecursively(file);

        LOG.info(String.format("assignment %s deletion complete", assignmentId));
    }
}