Merge pull request #112 from DataDog/tyler/version-verify
Add version scan verification and test in CI
This commit is contained in:
commit
59d1be4ea7
|
@ -14,7 +14,7 @@ jobs:
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Run Tests
|
name: Run Tests
|
||||||
command: ./gradlew clean check --parallel
|
command: ./gradlew clean check verifyVersionScan --parallel
|
||||||
|
|
||||||
- save_cache:
|
- save_cache:
|
||||||
paths:
|
paths:
|
||||||
|
|
|
@ -6,4 +6,6 @@ class VersionScanExtension {
|
||||||
boolean scanDependencies = false
|
boolean scanDependencies = false
|
||||||
String legacyGroup
|
String legacyGroup
|
||||||
String legacyModule
|
String legacyModule
|
||||||
|
Map<String, String> verifyPresent = Collections.emptyMap()
|
||||||
|
List<String> verifyMissing = Collections.emptyList()
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,19 +34,23 @@ class VersionScanPlugin implements Plugin<Project> {
|
||||||
RepositorySystemSession session = newRepositorySystemSession(system)
|
RepositorySystemSession session = newRepositorySystemSession(system)
|
||||||
|
|
||||||
project.extensions.create("versionScan", VersionScanExtension)
|
project.extensions.create("versionScan", VersionScanExtension)
|
||||||
project.task('scanVersions') {
|
def scanVersions = project.task('scanVersions') {
|
||||||
description = "Queries for all versions of configured modules and finds key classes"
|
description = "Queries for all versions of configured modules and finds key classes"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!project.gradle.startParameter.taskNames.contains('scanVersions')) {
|
def hasRelevantTask = project.gradle.startParameter.taskNames.contains('scanVersions')
|
||||||
|
hasRelevantTask |= project.gradle.startParameter.taskNames.contains('scanVersionsReport')
|
||||||
|
hasRelevantTask |= project.gradle.startParameter.taskNames.contains('verifyVersionScan')
|
||||||
|
if (!hasRelevantTask) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
println "Adding scan tasks for $project"
|
// println "Adding scan tasks for $project"
|
||||||
|
|
||||||
Set<String> allInclude = Sets.newConcurrentHashSet()
|
Set<String> allInclude = Sets.newConcurrentHashSet()
|
||||||
Set<String> allExclude = Sets.newConcurrentHashSet()
|
Set<String> allExclude = Sets.newConcurrentHashSet()
|
||||||
AtomicReference<Set<String>> keyPresent = new AtomicReference(Collections.emptySet())
|
AtomicReference<Set<String>> keyPresent = new AtomicReference(Collections.emptySet())
|
||||||
AtomicReference<Set<String>> keyMissing = new AtomicReference(Collections.emptySet())
|
AtomicReference<Set<String>> keyMissing = new AtomicReference(Collections.emptySet())
|
||||||
|
|
||||||
def scanVersionsReport = project.task('scanVersionsReport') {
|
def scanVersionsReport = project.task('scanVersionsReport') {
|
||||||
description = "Prints the result of the scanVersions task"
|
description = "Prints the result of the scanVersions task"
|
||||||
doLast {
|
doLast {
|
||||||
|
@ -67,7 +71,9 @@ class VersionScanPlugin implements Plugin<Project> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
project.tasks.scanVersions.finalizedBy(scanVersionsReport)
|
if (project.gradle.startParameter.taskNames.contains('scanVersions')) {
|
||||||
|
scanVersions.finalizedBy(scanVersionsReport)
|
||||||
|
}
|
||||||
|
|
||||||
project.repositories {
|
project.repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -118,6 +124,48 @@ class VersionScanPlugin implements Plugin<Project> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, String> verifyPresent = project.versionScan.verifyPresent
|
||||||
|
List<String> verifyMissing = project.versionScan.verifyMissing
|
||||||
|
|
||||||
|
if (!verifyPresent.isEmpty() || !verifyMissing.isEmpty()) {
|
||||||
|
def verifyVersionScan = project.task('verifyVersionScan') {
|
||||||
|
description = "Validates that the configured classes and methods are only present where expected."
|
||||||
|
doLast {
|
||||||
|
// This may already be done by the report task, but repeating for good measure.
|
||||||
|
keyPresent.get().removeAll(allExclude)
|
||||||
|
keyMissing.get().removeAll(allInclude)
|
||||||
|
|
||||||
|
assert keyPresent.get() != [] || keyMissing.get() != []
|
||||||
|
|
||||||
|
def errors = []
|
||||||
|
for (String className : verifyPresent.keySet()) {
|
||||||
|
String identifier = project.versionScan.scanMethods ? "$className|${verifyPresent.get(className)}" : className
|
||||||
|
if (!keyPresent.get().contains(identifier)) {
|
||||||
|
errors << "not a 'keyPresent' identifier: $identifier"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String className : verifyMissing) {
|
||||||
|
if (!keyMissing.get().contains(className)) {
|
||||||
|
errors << "not a 'keyMissing' identifier: $className"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errors.each {
|
||||||
|
System.err.println "Error for $group:$module - $it"
|
||||||
|
}
|
||||||
|
if (!errors.isEmpty()) {
|
||||||
|
throw new AssertionError("Version scan verification failed.\n" +
|
||||||
|
"Errors listed above are likely the result of a new module " +
|
||||||
|
"being published to Maven, not a code change in this repo.\n" +
|
||||||
|
"This does mean a fix should be made though to 'dd-trace-supported-framework.yaml'.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.gradle.startParameter.taskNames.contains('scanVersions')) {
|
||||||
|
scanVersions.finalizedBy(verifyVersionScan)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// println "Scanning ${includeVersionSet.size()} included and ${excludeVersionSet.size()} excluded versions. Included: ${includeVersionSet.collect { it.version }}}"
|
// println "Scanning ${includeVersionSet.size()} included and ${excludeVersionSet.size()} excluded versions. Included: ${includeVersionSet.collect { it.version }}}"
|
||||||
|
|
||||||
includeVersionSet.each { version ->
|
includeVersionSet.each { version ->
|
||||||
|
@ -144,12 +192,15 @@ class VersionScanPlugin implements Plugin<Project> {
|
||||||
def jar = new JarFile(jarFile)
|
def jar = new JarFile(jarFile)
|
||||||
for (jarEntry in jar.entries()) {
|
for (jarEntry in jar.entries()) {
|
||||||
if (jarEntry.name.endsWith(".class")) {
|
if (jarEntry.name.endsWith(".class")) {
|
||||||
|
def className = jarEntry.name
|
||||||
|
className = className.replaceAll("/", ".")
|
||||||
|
className = className.replace(".class", "")
|
||||||
if (project.versionScan.scanMethods) {
|
if (project.versionScan.scanMethods) {
|
||||||
findMethodNames(jar, jarEntry).each {
|
findMethodNames(jar, jarEntry).each {
|
||||||
contentSet.add("$jarEntry.name|$it")
|
contentSet.add("$className|$it".toString())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
contentSet.add("$jarEntry.name")
|
contentSet.add(className)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +214,10 @@ class VersionScanPlugin implements Plugin<Project> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
project.tasks.scanVersions.finalizedBy(task)
|
project.tasks.scanVersions.finalizedBy(task)
|
||||||
project.tasks.scanVersionsReport.mustRunAfter(task)
|
project.tasks.scanVersionsReport.dependsOn(task)
|
||||||
|
if (project.tasks.hasProperty("verifyVersionScan")) {
|
||||||
|
project.tasks.verifyVersionScan.dependsOn(task)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def filter(List<Version> list) {
|
def filter(List<Version> list) {
|
||||||
|
|
|
@ -6,4 +6,8 @@ versionScan {
|
||||||
versions = "[4.3,)"
|
versions = "[4.3,)"
|
||||||
legacyGroup = "commons-httpclient"
|
legacyGroup = "commons-httpclient"
|
||||||
legacyModule = "commons-httpclient"
|
legacyModule = "commons-httpclient"
|
||||||
|
verifyPresent = [
|
||||||
|
"org.apache.http.conn.SchemePortResolver": null,
|
||||||
|
"org.apache.http.conn.ssl.SSLContexts" : null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,4 +6,9 @@ versionScan {
|
||||||
group = "com.amazonaws"
|
group = "com.amazonaws"
|
||||||
module = "aws-java-sdk-core"
|
module = "aws-java-sdk-core"
|
||||||
versions = "[1.11.0,)"
|
versions = "[1.11.0,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"com.amazonaws.http.client.HttpClientFactory" : null,
|
||||||
|
"com.amazonaws.http.apache.utils.ApacheUtils" : null,
|
||||||
|
"com.amazonaws.http.request.HttpRequestFactory": null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,9 @@ versionScan {
|
||||||
group = "com.datastax.cassandra"
|
group = "com.datastax.cassandra"
|
||||||
module = "cassandra-driver-core"
|
module = "cassandra-driver-core"
|
||||||
versions = "[3.2,)"
|
versions = "[3.2,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"com.datastax.driver.core.utils.MoreObjects" : null,
|
||||||
|
"com.datastax.driver.core.RemoteEndpointAwareNettySSLOptions": null,
|
||||||
|
"com.datastax.driver.core.GuavaCompatibility" : null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,8 @@ versionScan {
|
||||||
module = "javax.jms-api"
|
module = "javax.jms-api"
|
||||||
versions = "[2,)"
|
versions = "[2,)"
|
||||||
legacyModule = "jms-api"
|
legacyModule = "jms-api"
|
||||||
|
verifyPresent = [
|
||||||
|
"javax.jms.JMSContext" : null,
|
||||||
|
"javax.jms.CompletionListener": null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,8 @@ versionScan {
|
||||||
group = "org.mongodb"
|
group = "org.mongodb"
|
||||||
module = "mongodb-driver-async"
|
module = "mongodb-driver-async"
|
||||||
versions = "[3.0,)"
|
versions = "[3.0,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"com.mongodb.operation.AsyncReadOperation": null,
|
||||||
|
"com.mongodb.client.model.MapReduceAction": null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,8 @@ versionScan {
|
||||||
group = "org.mongodb"
|
group = "org.mongodb"
|
||||||
module = "mongo-java-driver"
|
module = "mongo-java-driver"
|
||||||
versions = "[3.0,)"
|
versions = "[3.0,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"com.mongodb.operation.AsyncReadOperation": null,
|
||||||
|
"com.mongodb.client.model.MapReduceAction": null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,9 @@ versionScan {
|
||||||
module = "okhttp"
|
module = "okhttp"
|
||||||
versions = "[3.0,)"
|
versions = "[3.0,)"
|
||||||
legacyGroup = "com.squareup.okhttp"
|
legacyGroup = "com.squareup.okhttp"
|
||||||
|
verifyPresent = [
|
||||||
|
"okhttp3.Cookie" : null,
|
||||||
|
"okhttp3.ConnectionPool": null,
|
||||||
|
"okhttp3.Headers" : null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,9 @@ versionScan {
|
||||||
group = "org.apache.tomcat.embed"
|
group = "org.apache.tomcat.embed"
|
||||||
module = "tomcat-embed-core"
|
module = "tomcat-embed-core"
|
||||||
versions = "[8.0,)"
|
versions = "[8.0,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"org.apache.catalina.WebResource" : null,
|
||||||
|
"org.apache.catalina.webresources.TrackedInputStream" : null,
|
||||||
|
"org.apache.catalina.webresources.AbstractArchiveResource": null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,9 @@ versionScan {
|
||||||
group = "org.apache.tomcat"
|
group = "org.apache.tomcat"
|
||||||
module = "tomcat-catalina"
|
module = "tomcat-catalina"
|
||||||
versions = "[8.0,)"
|
versions = "[8.0,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"org.apache.catalina.WebResource" : null,
|
||||||
|
"org.apache.catalina.webresources.TrackedInputStream" : null,
|
||||||
|
"org.apache.catalina.webresources.AbstractArchiveResource": null,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ opentracing-apache-httpclient:
|
||||||
supported_version: 4\.[3|4|5]\..*
|
supported_version: 4\.[3|4|5]\..*
|
||||||
identifying_present_classes:
|
identifying_present_classes:
|
||||||
- org.apache.http.conn.SchemePortResolver
|
- org.apache.http.conn.SchemePortResolver
|
||||||
- org.apache.http.config.Lookup
|
|
||||||
- org.apache.http.conn.ssl.SSLContexts
|
- org.apache.http.conn.ssl.SSLContexts
|
||||||
|
|
||||||
- artifact: commons-httpclient
|
- artifact: commons-httpclient
|
||||||
|
|
Loading…
Reference in New Issue