Skip to content

Commit

Permalink
time dependent tests parametrized relatively
Browse files Browse the repository at this point in the history
  • Loading branch information
aamotharald committed Nov 18, 2024
1 parent 46ab5c3 commit 989c0ac
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,28 @@
import com.sap.oss.phosphor.fosstars.model.qa.TestVectors;
import com.sap.oss.phosphor.fosstars.model.qa.VerificationFailedException;
import com.sap.oss.phosphor.fosstars.model.rating.oss.OssSecurityRating;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;

public class ScoreVerificationTest {

public static final String TEST_VECTORS_FILE_NAME_TEMPLATE_DEFAULT = "%sTestVectors.yml";

public static final String TEST_VECTORS_FILE_NAME_TEMPLATE_TIMEDEPENDENT = "%sTestVectorsTimeDependent.yml";
public static final String TEST_VECTORS_FILE_NAME_TEMPLATE_TIME_DEPENDENT =
"%sTestVectorsTimeDependent.yml";

@Test
public void testVerification() {
Expand All @@ -34,51 +47,124 @@ public void testVerification() {

for (Score score : collector.scores()) {
if (!failingScores.contains(score.getClass().getSimpleName())) {
scoreVerification(score, TEST_VECTORS_FILE_NAME_TEMPLATE_DEFAULT);
scoreVerification(score);
}
}
}

@Test
public void testVulnerabilityDiscoveryAndSecurityTestingScoreTimeIndependent() {
scoreVerification(
new VulnerabilityDiscoveryAndSecurityTestingScore(new ProjectSecurityTestingScore()), TEST_VECTORS_FILE_NAME_TEMPLATE_DEFAULT);
new VulnerabilityDiscoveryAndSecurityTestingScore(new ProjectSecurityTestingScore()));
}

@Test
public void testVulnerabilityDiscoveryAndSecurityTestingScoreTimeDependent() {
scoreVerification(
new VulnerabilityDiscoveryAndSecurityTestingScore(new ProjectSecurityTestingScore()), TEST_VECTORS_FILE_NAME_TEMPLATE_TIMEDEPENDENT);
public void testVulnerabilityDiscoveryAndSecurityTestingScoreTimeDependent() throws IOException {
scoreVerificationWithTimeDependentValuesSubstituted(
new VulnerabilityDiscoveryAndSecurityTestingScore(new ProjectSecurityTestingScore()));
}

@Test
public void testSecurityReviewScoreTimeIndependent() {
scoreVerification(new SecurityReviewScore(), TEST_VECTORS_FILE_NAME_TEMPLATE_DEFAULT);
scoreVerification(new SecurityReviewScore());
}

@Test
public void testSecurityReviewScoreTimeDependent() {
scoreVerification(new SecurityReviewScore(), TEST_VECTORS_FILE_NAME_TEMPLATE_TIMEDEPENDENT);
public void testSecurityReviewScoreTimeDependent() throws IOException {
scoreVerificationWithTimeDependentValuesSubstituted(new SecurityReviewScore());
}

protected void scoreVerificationWithTimeDependentValuesSubstituted(Score score)
throws IOException {
String testVectorsFileName = String.format(TEST_VECTORS_FILE_NAME_TEMPLATE_TIME_DEPENDENT,
score.getClass().getSimpleName());
URL url = score.getClass().getResource(testVectorsFileName);
File testYamlFile = FileUtils.getFile(url.getFile());
String yamlString = FileUtils.readFileToString(testYamlFile, StandardCharsets.UTF_8);
String output = substituteYearsAndDaysPlaceholder(yamlString);
// Write the output to a temporary file
Path tempFile = Files.createTempFile("", ".yml");
Files.writeString(tempFile, output);
System.out.println(tempFile + " created for time-dependent test.");
scoreVerification(score, tempFile.toFile());
Files.delete(tempFile);
System.out.println(tempFile + " deleted for time-dependent test.");
}

protected void scoreVerification(Score score) {
String testVectorsFileName =
String.format(TEST_VECTORS_FILE_NAME_TEMPLATE_DEFAULT, score.getClass().getSimpleName());
URL url = score.getClass().getResource(testVectorsFileName);
File testYamlFile = FileUtils.getFile(url.getFile());
scoreVerification(score, testYamlFile);
}

protected void scoreVerification(Score score, String testVectorsFileNameTemplate) {
String className = score.getClass().getSimpleName();
String testVectorsFileName = String.format(testVectorsFileNameTemplate, className);
try (InputStream is = score.getClass().getResourceAsStream(testVectorsFileName)) {
protected void scoreVerification(Score score, File file) {
try (InputStream is = new FileInputStream(file)) {
TestVectors testVectors = TestVectors.loadFromYaml(is);
if (testVectors.isEmpty()) {
System.out.printf("No test vectors for %s%n", className);
System.out.printf("No test vectors for %s%n", score.getClass().getSimpleName());
fail("Verification failed");
}
System.out.printf("Verify %s with %d test vectors%n", className, testVectors.size());
System.out.printf("Verify %s with %d test vectors%n", score.getClass().getSimpleName(),
testVectors.size());
new ScoreVerification(score, testVectors).run();
} catch (VerificationFailedException e) {
System.out.printf("Verification failed for %s%n", className);
System.out.printf("Verification failed for %s%n", score.getClass().getSimpleName());
fail("Verification failed");
} catch (Exception e) {
System.out.printf("Couldn't verify %s%n", className);
System.out.printf("Couldn't verify %s%n", score.getClass().getSimpleName());
e.printStackTrace(System.out);
fail("Verification failed");
}
}

protected String substituteYearsAndDaysPlaceholder(String input) {
String output = substitutePlaceholder(input, TimeUnit.YEARS);
output = substitutePlaceholder(output, TimeUnit.DAYS);
return output;
}

protected String substitutePlaceholder(String input, TimeUnit timeUnit) {
Pattern pattern = Pattern.compile(timeUnit.getRegex());
Matcher matcher = pattern.matcher(input);

LocalDate currentDate = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

StringBuilder buf = new StringBuilder();
while (matcher.find()) {
LocalDate newDate = currentDate;
int timeUnitToSubtract = Integer.parseInt(matcher.group(1));
switch (timeUnit) {
case DAYS:
newDate = currentDate.minusDays(timeUnitToSubtract);
break;
case YEARS:
newDate = currentDate.minusYears(timeUnitToSubtract);
break;
default:
break;
}
String replacement = newDate.format(formatter);
matcher.appendReplacement(buf, replacement);
}
matcher.appendTail(buf);
return buf.toString();
}

public enum TimeUnit {
DAYS("\\$CURDATE\\{MINUS_DAYS\\((\\d+)\\)\\}"),
YEARS("\\$CURDATE\\{MINUS_YEARS\\((\\d+)\\)\\}");

private final String regex;

TimeUnit(String regex) {
this.regex = regex;
}

public String getRegex() {
return regex;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ elements:
organization:
type: "GitHubOrganization"
name: "org"
date: "2024-01-01"
date: "$CURDATE{MINUS_DAYS(100)}"
expectedScore:
type: "DoubleInterval"
from: 9.5
Expand All @@ -40,7 +40,7 @@ elements:
organization:
type: "GitHubOrganization"
name: "org"
date: "2023-01-01"
date: "$CURDATE{MINUS_YEARS(2)}"
expectedScore:
type: "DoubleInterval"
from: 2.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ elements:
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2018-03-03"
published: "$CURDATE{MINUS_YEARS(6)}"
- id: "CVE-02"
cvss: null
references: [ ]
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2020-10-28"
published: "$CURDATE{MINUS_YEARS(4)}"
feature:
type: "VulnerabilitiesFeature"
name: "Info about vulnerabilities in open-source project"
Expand Down Expand Up @@ -156,14 +156,14 @@ elements:
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2018-03-03"
published: "$CURDATE{MINUS_YEARS(6)}"
- id: "CVE-02"
cvss: null
references: [ ]
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2020-10-28"
published: "$CURDATE{MINUS_YEARS(4)}"
feature:
type: "VulnerabilitiesFeature"
name: "Info about vulnerabilities in open-source project"
Expand All @@ -188,14 +188,14 @@ elements:
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2021-03-03"
published: "$CURDATE{MINUS_YEARS(3)}"
- id: "CVE-02"
cvss: null
references: [ ]
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2024-10-28"
published: "$CURDATE{MINUS_DAYS(100)}"
feature:
type: "VulnerabilitiesFeature"
name: "Info about vulnerabilities in open-source project"
Expand Down Expand Up @@ -227,7 +227,7 @@ elements:
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2018-03-03"
published: "$CURDATE{MINUS_YEARS(6)}"
feature:
type: "VulnerabilitiesFeature"
name: "Info about vulnerabilities in open-source project"
Expand Down Expand Up @@ -259,14 +259,14 @@ elements:
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2020-03-03"
published: "$CURDATE{MINUS_YEARS(4)}"
- id: "CVE-02"
cvss: null
references: [ ]
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2024-10-28"
published: "$CURDATE{MINUS_DAYS(100)}"
feature:
type: "VulnerabilitiesFeature"
name: "Info about vulnerabilities in open-source project"
Expand Down Expand Up @@ -298,7 +298,7 @@ elements:
resolution: "UNKNOWN"
introduced: null
fixed: null
published: "2018-03-03"
published: "$CURDATE{MINUS_YEARS(6)}"
feature:
type: "VulnerabilitiesFeature"
name: "Info about vulnerabilities in open-source project"
Expand Down

0 comments on commit 989c0ac

Please sign in to comment.