Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhauled the end to end tests and added the test code from progpedia #1279

Merged
merged 22 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
fa9e0ce
Overhauled the end to end tests and added the test code from progpedia.
TwoOfTwelve Sep 5, 2023
cc8d9fd
Added missing result files for end to end tests
TwoOfTwelve Sep 5, 2023
04f2e87
Merge branch 'develop' into feature/endToEndTests-Rework
dfuchss Sep 13, 2023
9428119
Fixed test results
TwoOfTwelve Sep 14, 2023
a4a7cca
Reduced epsilon value for end to end tests.
TwoOfTwelve Sep 27, 2023
3a496fe
Generate expected test values for the progpedia dataset.
tsaglam Oct 4, 2023
4190ccc
Merge branch 'develop' into feature/endToEndTests-Rework
tsaglam Oct 4, 2023
fd9d1b1
Added token output for end to end tests.
TwoOfTwelve Oct 10, 2023
6a2745b
Improved end to end test output.
TwoOfTwelve Oct 10, 2023
5407b18
Added strict order for submissions in comparison.
TwoOfTwelve Oct 10, 2023
f6a07ba
Fixed sonarcloud issues.
TwoOfTwelve Oct 10, 2023
659e7c7
Implemented timurs suggestions.
TwoOfTwelve Oct 25, 2023
7774c0c
Moved progpedia data into a zip file.
TwoOfTwelve Oct 31, 2023
cc6e49f
Fixed spotless issues concerning zips.
TwoOfTwelve Oct 31, 2023
58c62fc
spotless.
TwoOfTwelve Oct 31, 2023
bbf8e06
Merge branch 'develop' into feature/endToEndTests-Rework
TwoOfTwelve Oct 31, 2023
0f86c4b
Fixed sonarcloud issues.
TwoOfTwelve Oct 31, 2023
8d26824
Improved language in test descriptions.
TwoOfTwelve Oct 31, 2023
510aef3
Improved handling of io streams in end to end tests.
TwoOfTwelve Oct 31, 2023
038d8e3
Added logging when permissions cannot be set on temp directory.
TwoOfTwelve Nov 13, 2023
4667032
Spotless
TwoOfTwelve Nov 18, 2023
0c41141
Fixed sonarcloud issues.
TwoOfTwelve Nov 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions core/src/main/java/de/jplag/GreedyStringTiling.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public class GreedyStringTiling {

private final int minimumMatchLength;
private final int minimumNeighborLength;
private JPlagOptions options;
private ConcurrentMap<TokenType, Integer> tokenTypeValues;
private final JPlagOptions options;
private final ConcurrentMap<TokenType, Integer> tokenTypeValues;
private final Map<Submission, Set<Token>> baseCodeMarkings = new IdentityHashMap<>();

private final Map<Submission, int[]> cachedTokenValueLists = new IdentityHashMap<>();
Expand Down Expand Up @@ -81,9 +81,17 @@ public final JPlagComparison compare(Submission firstSubmission, Submission seco
if (firstSubmission.getTokenList().size() > secondSubmission.getTokenList().size()) {
smallerSubmission = secondSubmission;
largerSubmission = firstSubmission;
} else {
} else if (firstSubmission.getTokenList().size() < secondSubmission.getTokenList().size()) {
smallerSubmission = firstSubmission;
largerSubmission = secondSubmission;
} else {
if (firstSubmission.getName().compareTo(secondSubmission.getName()) < 0) {
smallerSubmission = firstSubmission;
largerSubmission = secondSubmission;
} else {
smallerSubmission = secondSubmission;
largerSubmission = firstSubmission;
}
}
return compareInternal(smallerSubmission, largerSubmission);
}
Expand Down
1 change: 0 additions & 1 deletion endtoend-testing/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
<groupId>de.jplag</groupId>
<artifactId>cli</artifactId>
<version>${revision}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.jplag</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@ private TestDirectoryConstants() {
}

/**
* Base path to the saved results
* Base path to the resources directory
*/
public static final Path BASE_PATH_TO_RESULT_JSON = Path.of("src", "test", "resources", "results");
public static final Path BASE_PATH_TO_RESOURCES = Path.of("src", "test", "resources");

/**
* Base path to the endToEnd testing resources
* Base path to the saved results
*/
public static final Path BASE_PATH_TO_LANGUAGE_RESOURCES = Path.of("src", "test", "resources", "languageTestFiles");
public static final Path BASE_PATH_TO_RESULT_JSON = BASE_PATH_TO_RESOURCES.resolve(Path.of("results"));

/**
* Create the complete path to the submission files. Here the temporary system path is extended with the
* "SUBMISSION_DIRECTORY_NAME", which is predefined in this class.
* Base path to the data set descriptors
*/
public static final Path TEMPORARY_SUBMISSION_DIRECTORY_NAME = Path.of("target", "testing-directory-submission");
public static final Path BASE_PATH_TO_DATA_SET_DESCRIPTORS = BASE_PATH_TO_RESOURCES.resolve(Path.of("dataSets"));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package de.jplag.endtoend.helper;
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved

/**
* Helper to calculate the average of multiple numbers.
*/
public class AverageCalculator {
private double sum;
private int count;

/**
* Creates a new empty calculator
*/
public AverageCalculator() {
this.sum = 0;
this.count = 0;
}

/**
* Adds a new value to the calculation
* @param value The value
*/
public void add(double value) {
this.sum += value;
this.count++;
}

/**
* Calculates and returns the average of all added values.
* @return The result
*/
public double calculate() {
return this.sum / count;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.jplag.endtoend.helper;

import java.io.IOException;

import de.jplag.Language;
import de.jplag.cli.LanguageLoader;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

/**
* Deserialized a language from a json file
*/
public class LanguageDeserializer extends JsonDeserializer<Language> {
@Override
public Language deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String name = jsonParser.getText();
return LanguageLoader.getLanguage(name).orElseThrow(() -> new IllegalStateException(String.format("Language %s not found.", name)));
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package de.jplag.endtoend.helper;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import de.jplag.JPlagComparison;
import de.jplag.Language;
import de.jplag.Submission;
import de.jplag.endtoend.constants.TestDirectoryConstants;

/**
* Helper class to perform all necessary additional functions for the endToEnd tests.
Expand All @@ -28,30 +25,8 @@ private TestSuiteHelper() {
* @return unique identifier for test case recognition
*/
public static String getTestIdentifier(JPlagComparison jPlagComparison) {
return List.of(jPlagComparison.firstSubmission(), jPlagComparison.secondSubmission()).stream().map(Submission::getRoot)
return Stream.of(jPlagComparison.firstSubmission(), jPlagComparison.secondSubmission()).map(Submission::getRoot)
.map(FileHelper::getFileNameWithoutFileExtension).sorted().collect(Collectors.joining("-"));

}

/**
* Returns the file pointing to the directory of the submissions for the given language and result json. The result
* json's name is expected to be equal to the test suite identifier.
* @param language is the language for the tests
* @param resultJSON is the json containing the expected values
* @return returns the directory of the submissions
*/
public static File getSubmissionDirectory(Language language, File resultJSON) {
return getSubmissionDirectory(language, FileHelper.getFileNameWithoutFileExtension(resultJSON));
}

/**
* Returns the file pointing to the directory of the submissions for the given language and test suite identifier as
* described in the Readme.md.
* @param language is the langauge for the tests
* @param testSuiteIdentifier is the test suite identifier of the tests
* @return returns the directory of the submissions
*/
public static File getSubmissionDirectory(Language language, String testSuiteIdentifier) {
return TestDirectoryConstants.BASE_PATH_TO_LANGUAGE_RESOURCES.resolve(language.getIdentifier()).resolve(testSuiteIdentifier).toFile();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package de.jplag.endtoend.model;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

/**
* Identifier for a comparison. The order of the names does not matter
* @param firstName The first name
* @param secondName The second name
*/
public record ComparisonIdentifier(String firstName, String secondName) {
@Override
public boolean equals(Object o) {
if (!(o instanceof ComparisonIdentifier other)) {
return false;
}

return (firstName.equals(other.firstName) && secondName.equals(other.secondName))
|| (secondName.equals(other.firstName) && firstName.equals(other.secondName));
}

@Override
public int hashCode() {
return firstName.hashCode() + secondName.hashCode();
}

/**
* Loads the identifiers stored in a csv (semicolon separated) file.
* @param file The file to load
* @return The comparisons in the file
*/
public static Set<ComparisonIdentifier> loadIdentifiersFromFile(File file) {
try (Scanner scanner = new Scanner(file)) {
Set<ComparisonIdentifier> identifiers = new HashSet<>();
while (scanner.hasNextLine()) {
String[] parts = scanner.nextLine().split(";");
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
identifiers.add(new ComparisonIdentifier(parts[0], parts[1]));
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
}
return identifiers;
} catch (FileNotFoundException e) {
throw new IllegalStateException(String.format("Comparisons could not be loaded for %s.", file.getName()), e);
}
}

@Override
public String toString() {
return firstName + " - " + secondName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package de.jplag.endtoend.model;

import java.io.File;
import java.util.Set;
import java.util.stream.Collectors;

import de.jplag.Language;
import de.jplag.endtoend.constants.TestDirectoryConstants;
import de.jplag.endtoend.helper.LanguageDeserializer;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

/**
* Represents a data set for the endToEnd test suite.
* @param name The name of the data set
* @param language The language
* @param format The format
* @param sourceDirectory The source directory, may be null
* @param resultFile The result file name, may be null
* @param goldStandardFile The gold standard file, may be null
* @param options The options for the jplag runs, may be null
*/
public record DataSet(@JsonProperty(required = true) String name,
@JsonDeserialize(using = LanguageDeserializer.class) @JsonProperty(required = true) Language language,
@JsonProperty(required = true) DataSetFormat format, @JsonProperty String sourceDirectory, @JsonProperty String resultFile,
@JsonProperty String goldStandardFile, @JsonProperty Options options) {

/**
* Gets the source directories
* @return The source directories
*/
public Set<File> getSourceDirectories() {
return format.getSourceDirectories(this).stream()
.map(file -> new File(TestDirectoryConstants.BASE_PATH_TO_RESOURCES.toFile(), file.getPath())).collect(Collectors.toSet());
}

/**
* Helper function replacing null by the default value
* @return The source directory
*/
String actualSourceDirectory() {
if (sourceDirectory == null) {
return "data/" + name;
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
}
return sourceDirectory;
}

/**
* Helper function replacing null by the default value
* @return The result file
*/
public File getResultFile() {
if (resultFile == null) {
return new File(TestDirectoryConstants.BASE_PATH_TO_RESULT_JSON.toFile(), name + ".json");
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved
} else {
return new File(TestDirectoryConstants.BASE_PATH_TO_RESULT_JSON.toFile(), resultFile);
}
}

/**
* @return The gold standard file. Can be null.
*/
public File getGoldStandardFile() {
if (goldStandardFile == null) {
return null;
}
TwoOfTwelve marked this conversation as resolved.
Show resolved Hide resolved

return new File(TestDirectoryConstants.BASE_PATH_TO_RESOURCES.toFile(), goldStandardFile);
}

/**
* Helper function replacing null by the default value.
* @return The options
*/
public Options getOptions() {
if (this.options != null) {
return this.options;
} else {
return new Options(null, null);
}
}
tsaglam marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package de.jplag.endtoend.model;

import java.io.File;
import java.util.Collections;
import java.util.Set;

/**
* The available formats for data sets.
*/
@SuppressWarnings("unused") // The formats only referred to from the data set configuration
public enum DataSetFormat {
/**
* The progpedia format
*/
PROGPEDIA {
@Override
public Set<File> getSourceDirectories(DataSet dataSet) {
return Collections.singleton(new File(dataSet.actualSourceDirectory(), "ACCEPTED"));
}

@Override
public File getBaseCodeDirectory(DataSet dataSet, String directoryName) {
return new File(dataSet.actualSourceDirectory(), directoryName);
}
},
/**
* Plain format where the submissions are flat within the source directory.
*/
PLAIN {
@Override
public Set<File> getSourceDirectories(DataSet dataSet) {
return Collections.singleton(new File(dataSet.actualSourceDirectory()));
}

@Override
public File getBaseCodeDirectory(DataSet dataSet, String directoryName) {
throw new IllegalStateException("Plain formatted data sets cannot include base code.");
}
};

/**
* Resolved the source directories for jplag
* @param dataSet The data set
* @return The source directories
*/
public abstract Set<File> getSourceDirectories(DataSet dataSet);

/**
* Resolves the base code directory
* @param dataSet The data set
* @param directoryName The name of the base code directory
* @return The base code directory
*/
public abstract File getBaseCodeDirectory(DataSet dataSet, String directoryName);
}
Loading
Loading