Skip to content
Open
Changes from all commits
Commits
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
98 changes: 86 additions & 12 deletions maven_plugin/src/test/java/it/IntegrationTestsIT.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package it;

import static com.soebes.itf.extension.assertj.MavenITAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

Expand Down Expand Up @@ -28,6 +29,49 @@

@MavenJupiterExtension
public class IntegrationTestsIT {

@SuppressWarnings("null")
public void assertDependencyNode(DependencyNode node) {
assertThat(node.getChecksum())
.as(
"%s:%s:%s checksum",
node.getGroupId().getValue(),
node.getArtifactId().getValue(),
node.getVersion().getValue())
.isNotEmpty();
assertThat(node.getChecksumAlgorithm())
.as(
"%s:%s:%s checksum algorithm",
node.getGroupId().getValue(),
node.getArtifactId().getValue(),
node.getVersion().getValue())
.isNotEmpty();
assertThat(node.getResolved())
.as(
"%s:%s:%s resolved url",
node.getGroupId().getValue(),
node.getArtifactId().getValue(),
node.getVersion().getValue())
.isNotEqualTo(ResolvedUrl.Unresolved());
assertThat(node.getRepositoryId())
.as(
"%s:%s:%s repository id",
node.getGroupId().getValue(),
node.getArtifactId().getValue(),
node.getVersion().getValue())
.isNotEqualTo(RepositoryId.None());
}

public void assertAllDependencies(LockFile lockFile) {
lockFile.getDependencies().stream()
.flatMap(d -> flattenDependencies(d).stream())
.forEach(node -> assertDependencyNode(node));
lockFile.getMavenPlugins().stream()
.flatMap(plugin -> plugin.getDependencies().stream())
.flatMap(dep -> flattenDependencies(dep).stream())
.forEach(node -> assertDependencyNode(node));
}

@MavenTest
public void simpleProject(MavenExecutionResult result) throws Exception {
// contract: an empty project should generate an empty lock file
Expand All @@ -41,19 +85,20 @@ public void simpleProject(MavenExecutionResult result) throws Exception {

@MavenTest
public void singleDependency(MavenExecutionResult result) throws Exception {
// contract: an empty project should generate an empty lock file
// contract: a project with a single dependency should generate a lockfile with the dependency data
System.out.println("Running 'singleDependency' integration test.");
assertThat(result).isSuccessful();
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getEnvironment()).isNotNull();
assertThat(lockFile.getDependencies()).hasSize(1);
var junitDep = lockFile.getDependencies().toArray(DependencyNode[]::new)[0];
assertThat(junitDep.getArtifactId()).extracting(ArtifactId::getValue).isEqualTo("spoon-core");
assertThat(junitDep.getGroupId()).extracting(GroupId::getValue).isEqualTo("fr.inria.gforge.spoon");
assertThat(junitDep.getVersion()).extracting(VersionNumber::getValue).isEqualTo("10.3.0");
assertThat(junitDep.getChecksum())
var spoonDep = lockFile.getDependencies().toArray(DependencyNode[]::new)[0];
assertThat(spoonDep.getArtifactId()).extracting(ArtifactId::getValue).isEqualTo("spoon-core");
assertThat(spoonDep.getGroupId()).extracting(GroupId::getValue).isEqualTo("fr.inria.gforge.spoon");
assertThat(spoonDep.getVersion()).extracting(VersionNumber::getValue).isEqualTo("10.3.0");
assertThat(spoonDep.getChecksum())
.isEqualTo("37a43de039cf9a6701777106e3c5921e7131e5417fa707709abf791d3d8d9174");
}

Expand All @@ -65,6 +110,7 @@ public void singleDependencyCheckCorrect(MavenExecutionResult result) throws Exc
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getDependencies()).hasSize(1);
var junitDep = lockFile.getDependencies().toArray(DependencyNode[]::new)[0];
assertThat(junitDep.getArtifactId()).extracting(ArtifactId::getValue).isEqualTo("junit-jupiter-api");
Expand Down Expand Up @@ -123,6 +169,7 @@ public void pluginProject(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getMavenPlugins()).isNotEmpty();
assertThat(lockFile.getMavenPlugins())
.allMatch(v -> !v.getChecksum().isBlank()
Expand Down Expand Up @@ -169,6 +216,7 @@ public void pluginUserDependency(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getMavenPlugins()).isNotEmpty();
assertThat(lockFile.getMavenPlugins())
.allMatch(v -> !v.getChecksum().isBlank()
Expand Down Expand Up @@ -311,6 +359,7 @@ void reduceLog4jAffected(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getDependencies().stream().flatMap(v -> flattenDependencies(v).stream()))
.anyMatch(v -> v.getArtifactId().getValue().equals("log4j-core")
&& v.getVersion().getValue().equals("2.0"));
Expand All @@ -323,6 +372,7 @@ void reduceLog4jNotAffected(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getDependencies().stream().flatMap(v -> flattenDependencies(v).stream()))
.noneMatch(v -> v.getArtifactId().getValue().equals("log4j-core")
&& v.getVersion().getValue().equals("2.0"));
Expand Down Expand Up @@ -359,6 +409,7 @@ private void classifier(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getDependencies()).hasSize(3);

var junitSourceDep = lockFile.getDependencies().toArray(DependencyNode[]::new)[0];
Expand Down Expand Up @@ -475,6 +526,7 @@ public void orderedLockfile(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
var dependencyList = lockFile.getDependencies().stream()
.map(it -> it.getComparatorString())
.collect(Collectors.toList());
Expand Down Expand Up @@ -543,6 +595,10 @@ public void checksumModeRemote(MavenExecutionResult result) throws Exception {
assertThat(lockfilePath).exists();
var lockfile = LockFile.readLockFile(lockfilePath);

// Fails due to bug in parallel downloader for remote checksums
// See https://github.com/chains-project/maven-lockfile/issues/1561
// assertAllDependencies(lockfile);

// Verify: atlassian-bandana:0.2.0 is hosted on packages.atlassian.com which doesn't provide SHA-256, SHA-256
// has
// to be calculated
Expand All @@ -551,27 +607,36 @@ public void checksumModeRemote(MavenExecutionResult result) throws Exception {
.getChecksum()
.equals("12357e6d5c5eb6b5ed80bbb98f4ef7b70fcb08520a9f306c4af086c37d6ebc11"))
.findAny();
assertThat(dep1Checksum).isNotNull();
assertThat(dep1Checksum.isPresent()).isTrue();
result.getMavenLog();

// Verify: jsap:2.1 is hosted on repo.maven.apache.org which doesn't provide SHA-256, and who's SHA-1 has a
// different format (providing `checksum path` instead of `checksum`). SHA-1 should still succeed as the
// `checksum` is verified aganist up until the first space, thus excluding the path of the file when the
// SHA-1 was generated. SHA-256 has to be calculated.
var dep2Checksum = lockfile.getDependencies().stream()
.flatMap(d -> flattenDependencies(d).stream())
.filter(dependency -> dependency
.getChecksum()
.equals("331746fa62cfbc3368260c5a2e660936ad11be612308c120a044e120361d474e"))
.findAny();
// BUG: dep2Checksum is an Optional, so it will always be non-null
assertThat(dep2Checksum).isNotNull();
// With parallel download feature, this check consistently fails, potentially due to rate limiting on Maven
// Central.
// assertThat(dep2Checksum.isPresent()).isTrue();

// Verify: spoon-core:11.1.0 is hosted on maven central and directly provides SHA-256 checksums
var dep3Checksum = lockfile.getDependencies().stream()
.filter(dependency -> dependency
.getChecksum()
.equals("a8ae41ae0a1578a7ef9ce4f8d562813a99e6cc015e8cb3b0482b5470d53f1c6b"))
.findAny();
// BUG: dep3Checksum is an Optional, so it will always be non-null
assertThat(dep3Checksum).isNotNull();
// With parallel download feature, this check consistently fails, potentially due to rate limiting on Maven
// Central.
// assertThat(dep3Checksum.isPresent()).isTrue();
}

@MavenTest
Expand All @@ -582,6 +647,7 @@ public void resolvedFieldShouldResolve(MavenExecutionResult result) throws Excep
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
var atlassianResolved = lockFile.getDependencies().stream()
.filter(
dependency -> dependency
Expand All @@ -590,7 +656,7 @@ public void resolvedFieldShouldResolve(MavenExecutionResult result) throws Excep
ResolvedUrl.of(
"https://packages.atlassian.com/maven-public/atlassian-bandana/atlassian-bandana/0.2.0/atlassian-bandana-0.2.0.jar")))
.findAny();
assertThat(atlassianResolved).isNotNull();
assertThat(atlassianResolved.isPresent()).isTrue();
var mavenCentralResolved = lockFile.getDependencies().stream()
.filter(
dependency -> dependency
Expand All @@ -599,27 +665,28 @@ public void resolvedFieldShouldResolve(MavenExecutionResult result) throws Excep
ResolvedUrl.of(
"https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar")))
.findAny();
assertThat(mavenCentralResolved).isNotNull();
assertThat(mavenCentralResolved.isPresent()).isTrue();
// Ensure dependencies with classifiers have correctly resolved urls.
// sisu-guice with classifier noaop is a direct dependency of org.sonatype.sisu:sisu-inject-bean.
var dependencyWithClassifierResolved = lockFile.getDependencies().stream()
.flatMap(d -> flattenDependencies(d).stream())
.filter(
dependency -> dependency
.getResolved()
.equals(
ResolvedUrl.of(
"https://repo.maven.apache.org/maven2/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar")))
.findAny();
assertThat(dependencyWithClassifierResolved).isNotNull();
assertThat(dependencyWithClassifierResolved.isPresent()).isTrue();
// Ensure repository ids are resolved.
var atlassianRepositoryId = lockFile.getDependencies().stream()
.filter(dependency -> dependency.getRepositoryId().equals(RepositoryId.of("maven-atlassian-all")))
.findAny();
assertThat(atlassianRepositoryId).isNotNull();
assertThat(atlassianRepositoryId.isPresent()).isTrue();
var mavenCentralRepositoryId = lockFile.getDependencies().stream()
.filter(dependency -> dependency.getRepositoryId().equals(RepositoryId.of("central")))
.findAny();
assertThat(mavenCentralRepositoryId).isNotNull();
assertThat(mavenCentralRepositoryId.isPresent()).isTrue();
}

@MavenTest
Expand Down Expand Up @@ -670,6 +737,7 @@ public void externalParentPom(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);

// Verify pom is present
var pom = lockFile.getPom();
Expand Down Expand Up @@ -718,6 +786,7 @@ public void relativeParentPom(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);

// Verify pom is present
var pom = lockFile.getPom();
Expand Down Expand Up @@ -748,6 +817,7 @@ public void artifactTypeProject(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getDependencies()).isNotEmpty();
// Verify at least one dependency has a non-null type (the pom-type dependency)
assertThat(lockFile.getDependencies())
Expand Down Expand Up @@ -787,6 +857,7 @@ public void buildExtensionsMultiple(MavenExecutionResult result) throws Exceptio
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getMavenExtensions()).isNotEmpty();
// wagon-ftp has no explicit version but is resolved from Maven's extensionArtifactMap — all 3 are recorded
assertThat(lockFile.getMavenExtensions()).hasSize(3);
Expand Down Expand Up @@ -849,6 +920,7 @@ public void buildExtensionVersionFromParent(MavenExecutionResult result) throws
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);
assertThat(lockFile.getMavenExtensions()).hasSize(3);
assertThat(new ArrayList<>(lockFile.getMavenExtensions()))
.extracting(ext ->
Expand Down Expand Up @@ -882,6 +954,7 @@ public void bomPom(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);

var junitDep = lockFile.getDependencies().stream()
.filter(dep -> dep.getGroupId().getValue().equals("org.junit.jupiter")
Expand All @@ -905,6 +978,7 @@ public void bomPomWithParent(MavenExecutionResult result) throws Exception {
Path lockFilePath = findFile(result, "lockfile.json");
assertThat(lockFilePath).exists();
var lockFile = LockFile.readLockFile(lockFilePath);
assertAllDependencies(lockFile);

var foundBom = lockFile.getBoms().stream()
.filter(bom -> bom.getGroupId().getValue().equals("io.netty")
Expand Down
Loading