Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit 60df3db

Browse files
authored
test: dependency convergence check on gRPC and GAX (#595)
* ci: adding dependency convergence check * test: try bad gRPC version * ci: fixed description of the check * test: reverted gRPC version * renaming to gRPC convergence test
1 parent aa2cfec commit 60df3db

File tree

5 files changed

+234
-23
lines changed

5 files changed

+234
-23
lines changed

.github/workflows/upper-bound-check.yaml

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
pull_request:
6+
name: version-check
7+
jobs:
8+
upper-bound-check:
9+
name: Upper-bound check
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- uses: stCarolas/setup-maven@v4
14+
with:
15+
maven-version: 3.8.1
16+
- uses: actions/setup-java@v1
17+
with:
18+
java-version: 8
19+
- run: java -version
20+
- name: Install the BOM to local Maven repository
21+
run: .kokoro/build.sh
22+
- name: Check the BOM content satisfies the upper-bound-check test case
23+
run: mvn -B -V -ntp verify -Dcheckstyle.skip
24+
working-directory: upper-bound-check
25+
grpc-convergence-check:
26+
name: gRPC dependency convergence check
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v2
30+
- uses: stCarolas/setup-maven@v4
31+
with:
32+
maven-version: 3.8.1
33+
- uses: actions/setup-java@v1
34+
with:
35+
java-version: 8
36+
- run: java -version
37+
- name: Install the BOM to local Maven repository
38+
run: .kokoro/build.sh
39+
- name: Check the BOM content satisfies the dependency-convergence-check test
40+
run: mvn -B -V -ntp verify -Dcheckstyle.skip
41+
working-directory: dependency-convergence-check
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Dependency Convergence Check
2+
3+
This project includes a test case for dependency convergence for some (not all)
4+
artifacts in the Google Cloud Shared Dependencies BOM.
5+
6+
This project is not meant to be used by end-users or published to Maven Central.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>com.google.cloud</groupId>
5+
<artifactId>shared-dependencies-dependency-convergence-test</artifactId>
6+
<version>2.7.0</version><!-- {x-version-update:google-cloud-shared-dependencies:current} -->
7+
<name>Dependency convergence test for certain artifacts in Google Cloud Shared Dependencies</name>
8+
<url>https://github.com/googleapis/java-shared-dependencies</url>
9+
<description>
10+
An dependency convergence test case for the shared dependencies BOM. A failure of this test case means
11+
the shared dependencies BOM has outdated dependencies; there are newer version of artifacts
12+
appearing in the dependency tree.
13+
</description>
14+
15+
<organization>
16+
<name>Google LLC</name>
17+
</organization>
18+
19+
<scm>
20+
<connection>scm:git:git@github.com:googleapis/java-shared-dependencies.git</connection>
21+
<developerConnection>scm:git:git@github.com:googleapis/java-shared-dependencies.git</developerConnection>
22+
<url>https://github.com/googleapis/java-shared-dependencies</url>
23+
<tag>HEAD</tag>
24+
</scm>
25+
26+
<issueManagement>
27+
<url>https://github.com/googleapis/java-shared-dependencies/issues</url>
28+
<system>GitHub Issues</system>
29+
</issueManagement>
30+
31+
<licenses>
32+
<license>
33+
<name>Apache-2.0</name>
34+
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
35+
</license>
36+
</licenses>
37+
38+
<properties>
39+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
40+
<maven.compiler.source>1.8</maven.compiler.source>
41+
<maven.compiler.target>1.8</maven.compiler.target>
42+
</properties>
43+
44+
<dependencyManagement>
45+
<dependencies>
46+
<dependency>
47+
<groupId>com.google.cloud</groupId>
48+
<artifactId>google-cloud-shared-dependencies</artifactId>
49+
<version>2.7.0</version><!-- {x-version-update:google-cloud-shared-dependencies:current} -->
50+
<type>pom</type>
51+
<scope>import</scope>
52+
</dependency>
53+
</dependencies>
54+
</dependencyManagement>
55+
56+
<dependencies>
57+
<dependency>
58+
<groupId>com.google.guava</groupId>
59+
<artifactId>guava</artifactId>
60+
<version>31.0.1-jre</version>
61+
<scope>test</scope>
62+
</dependency>
63+
<dependency>
64+
<groupId>com.google.cloud.tools</groupId>
65+
<artifactId>dependencies</artifactId>
66+
<version>1.5.12</version>
67+
<scope>test</scope>
68+
</dependency>
69+
<dependency>
70+
<groupId>junit</groupId>
71+
<artifactId>junit</artifactId>
72+
<version>4.13.1</version>
73+
<scope>test</scope>
74+
</dependency>
75+
</dependencies>
76+
</project>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright 2022 Google LLC.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud;
18+
19+
import static org.junit.Assert.assertTrue;
20+
21+
import com.google.cloud.tools.opensource.classpath.ClassPathBuilder;
22+
import com.google.cloud.tools.opensource.classpath.ClassPathEntry;
23+
import com.google.cloud.tools.opensource.classpath.ClassPathResult;
24+
import com.google.cloud.tools.opensource.classpath.DependencyMediation;
25+
import com.google.cloud.tools.opensource.dependencies.Bom;
26+
import com.google.cloud.tools.opensource.dependencies.DependencyPath;
27+
import com.google.common.base.Joiner;
28+
import com.google.common.collect.ImmutableList;
29+
import com.google.common.collect.ImmutableSet;
30+
import java.nio.file.Paths;
31+
import java.util.HashSet;
32+
import java.util.Set;
33+
import org.eclipse.aether.artifact.Artifact;
34+
import org.junit.Test;
35+
36+
/**
37+
* Test to ensure that certain artifacts in the dependency tree of each entry of the shared
38+
* dependencies BOM have the same version.
39+
*/
40+
public class DependencyConvergenceTest {
41+
42+
@Test
43+
public void testGrpcConvergence() throws Exception {
44+
// There were cases where the gRPC version set in the shared dependencies BOM and the gRPC
45+
// version declared in gax-grpc's dependency broke the build of downstream projects. Two
46+
// artifacts were using version range to specify exact gRPC versions.
47+
// https://github.com/googleapis/java-shared-dependencies/pull/595
48+
Bom bom = Bom.readBom(Paths.get("../pom.xml"));
49+
assertConvergence(
50+
bom,
51+
"io.grpc",
52+
"grpc-netty-shaded",
53+
ImmutableSet.of(
54+
// Because OpenCensus's gRPC version does not use version range notation, it does not
55+
// break downstream build
56+
"opencensus-exporter-trace-stackdriver",
57+
"opencensus-exporter-stats-stackdriver",
58+
// Because grpc-gcp's gRPC version does not use version range notation, it does not
59+
// break downstream build
60+
"grpc-gcp"));
61+
}
62+
63+
/**
64+
* Asserts the artifact specified at {@code groupId} and {@code artifactId} have the same version
65+
* across the dependency trees of the managed dependencies of {@code bom}.
66+
*
67+
* <p>Use {@code excludingArtifactIds} to ignore certain artifacts.
68+
*/
69+
private void assertConvergence(
70+
Bom bom, String groupId, String artifactId, Set<String> excludingArtifactIds)
71+
throws Exception {
72+
ImmutableList<Artifact> managedDependencies = bom.getManagedDependencies();
73+
74+
Set<DependencyPath> foundPaths = new HashSet<>();
75+
Set<String> foundVersions = new HashSet<>();
76+
for (Artifact managedDependency : managedDependencies) {
77+
if (excludingArtifactIds.contains(managedDependency.getArtifactId())) {
78+
continue;
79+
}
80+
81+
ClassPathBuilder classPathBuilder = new ClassPathBuilder();
82+
ClassPathResult result =
83+
classPathBuilder.resolve(
84+
ImmutableList.of(managedDependency), false, DependencyMediation.MAVEN);
85+
ImmutableList<ClassPathEntry> classPath = result.getClassPath();
86+
for (ClassPathEntry entry : classPath) {
87+
Artifact artifact = entry.getArtifact();
88+
if (artifactId.equals(artifact.getArtifactId()) && groupId.equals(artifact.getGroupId())) {
89+
ImmutableList<DependencyPath> dependencyPaths = result.getDependencyPaths(entry);
90+
foundPaths.add(dependencyPaths.get(0));
91+
foundVersions.add(artifact.getVersion());
92+
}
93+
}
94+
}
95+
96+
assertTrue(
97+
"There should be at least one version in the graph but empty; "
98+
+ "please check the assertion is using correct groupID and artifactID.",
99+
foundVersions.size() >= 1);
100+
101+
// Duplicate versions found in the dependency trees
102+
assertTrue(
103+
"The version for "
104+
+ groupId
105+
+ ":"
106+
+ artifactId
107+
+ " should be one but there are multiple of them: "
108+
+ Joiner.on(", ").join(foundPaths),
109+
foundVersions.size() <= 1);
110+
}
111+
}

0 commit comments

Comments
 (0)