UnitTestUpload.java 4.74 KB
Newer Older
Dominik Vayhinger's avatar
Dominik Vayhinger committed
1
2
3
4
5
package de.hftstuttgart.rest.v1.unittest;

import de.hftstuttgart.utils.JGitUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
6
7
import org.springframework.core.env.Environment;
import org.springframework.util.FileSystemUtils;
Dominik Vayhinger's avatar
Dominik Vayhinger committed
8
9
10
11
12
13
14
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 javax.servlet.annotation.MultipartConfig;
15
16
17
18
19
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Dominik Vayhinger's avatar
Dominik Vayhinger committed
20
21
22
23
24
25
26
27
28
29

/**
 * 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);
Lukas Wiest's avatar
Lukas Wiest committed
30
31
    public final static String modocotTestConfigRegex = "^dtt::(.*)::(.*|none)::(.*|none)::(.*)$";
    public final static String modocotDueConfigRegex = "^dtt::(.*)::(.*|none)::(.*|none)$";
Dominik Vayhinger's avatar
Dominik Vayhinger committed
32
33
34
35

    private final JGitUtil jGitUtil;
    private final String assignmentBasePath;

36
    public UnitTestUpload(Environment env, JGitUtil jGitUtil) {
Dominik Vayhinger's avatar
Dominik Vayhinger committed
37
        this.jGitUtil = jGitUtil;
38
39
40

        Path p = Paths.get(env.getProperty("modocot.dir"), env.getProperty("modocot.dir.test.folder.name"));
        this.assignmentBasePath = p.toAbsolutePath().toString();
Dominik Vayhinger's avatar
Dominik Vayhinger committed
41
42
43
44
45
46
    }

    /**
     * Create a subfolder for the specific assignment.
     * This is called when the teacher creates an assignment and uploads the JUnit test files
     *
47
     * @param unitTestFileRef The text file which contains the JUnit tests meta data
Dominik Vayhinger's avatar
Dominik Vayhinger committed
48
49
50
     * @param assignmentId    ID of the created assignment. Generated by Moodle
     */
    @RequestMapping(method = RequestMethod.POST)
51
52
53
54
55
56
57
58
59
60
61
62
63
    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
Dominik Vayhinger's avatar
Dominik Vayhinger committed
64
        unitTestFileRef.transferTo(file);
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
        LOG.debug(String.format("saved config file to: %s", file.getAbsolutePath()));

        Pattern pattern = Pattern.compile(this.modocotTestConfigRegex);
        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 modocot 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 modocot test line: %s", line));
                    config = matcher;
                }
            }
        } catch (IOException e) {
            LOG.error("Error while reading repo config", e);
Kammleiter's avatar
Kammleiter committed
87
        }
88
89
90
        finally {
            if (config == null) {
                throw new RuntimeException("couldn't find repo config for unittest clone");
Dominik Vayhinger's avatar
Dominik Vayhinger committed
91
92
93
            }
        }

94
95
96
97
98
99
100
        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()));
Dominik Vayhinger's avatar
Dominik Vayhinger committed
101
102
103
104
105
106
107
108
109
110
111
112
    }

    /**
     * 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) {
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
        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));
Dominik Vayhinger's avatar
Dominik Vayhinger committed
129
130
    }
}