Add scope name to metadata (#13531)
This commit is contained in:
parent
511a9c93ea
commit
786512b792
File diff suppressed because it is too large
Load Diff
|
@ -8,6 +8,7 @@ otelJava {
|
|||
|
||||
dependencies {
|
||||
implementation("org.yaml:snakeyaml:2.4")
|
||||
implementation("io.opentelemetry:opentelemetry-sdk-common")
|
||||
|
||||
testImplementation(enforcedPlatform("org.junit:junit-bom:5.12.1"))
|
||||
testImplementation("org.assertj:assertj-core:3.27.3")
|
||||
|
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
Runs analysis on instrumentation modules in order to generate documentation.
|
||||
|
||||
## How to use
|
||||
|
||||
Run the doc generator:
|
||||
|
||||
`./gradlew :instrumentation-docs:generateDocs`
|
||||
|
||||
## Instrumentation Hierarchy
|
||||
|
||||
An "InstrumentationEntity" represents a module that that targets specific code in a framework/library/technology.
|
||||
|
@ -46,10 +52,15 @@ public class SpringWebInstrumentationModule extends InstrumentationModule
|
|||
* Configured in `InstrumentationModule` code for each module
|
||||
* srcPath
|
||||
* Path to the source code of the instrumentation module
|
||||
* minimumJavaVersion
|
||||
* Minimum Java version required by the instrumentation module. If not specified, it is assumed to
|
||||
be Java 8
|
||||
* description
|
||||
* Short description of what the instrumentation does
|
||||
* target_versions
|
||||
* List of supported versions by the module, broken down by `library` or `javaagent` support
|
||||
* scope
|
||||
* Name: The scope name of the instrumentation, `io.opentelemetry.{instrumentation name}`
|
||||
|
||||
## Methodology
|
||||
|
||||
|
@ -62,12 +73,25 @@ As of now, the following fields are supported:
|
|||
|
||||
```yaml
|
||||
description: "Description of what the instrumentation does."
|
||||
|
||||
# used to mark modules that do not instrument traditional libraries (e.g. methods, annotations)
|
||||
# defaults to true
|
||||
isLibraryInstrumentation: false
|
||||
```
|
||||
|
||||
### Versions targeted
|
||||
### Gradle File Derived Information
|
||||
|
||||
We parse gradle files in order to determine the target versions.
|
||||
We parse gradle files in order to determine several pieces of metadata:
|
||||
|
||||
- Javaagent versions are determined by the `muzzle` plugin configurations
|
||||
- Library versions are determined by the library dependency versions
|
||||
- when available, latestDepTestLibrary is used to determine the latest supported version
|
||||
- Minimum Java version is determined by the `otelJava` configurations
|
||||
|
||||
### Scope
|
||||
|
||||
For now, the scope name is the only value that is implemented in our instrumentations. The scope
|
||||
name is determined by the instrumentation module name: `io.opentelemetry.{instrumentation name}`
|
||||
|
||||
We will implement gatherers for the schemaUrl and scope attributes when instrumentations start
|
||||
implementing them.
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.docs;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationEntity;
|
||||
import io.opentelemetry.instrumentation.docs.utils.FileManager;
|
||||
import io.opentelemetry.instrumentation.docs.utils.YamlHelper;
|
||||
import java.io.BufferedWriter;
|
||||
|
@ -26,6 +27,10 @@ public class DocGeneratorApplication {
|
|||
try (BufferedWriter writer =
|
||||
Files.newBufferedWriter(
|
||||
Paths.get("docs/instrumentation-list.yaml"), Charset.defaultCharset())) {
|
||||
writer.write("# This file is generated and should not be manually edited.\n");
|
||||
writer.write("# The structure and contents are a work in progress and subject to change.\n");
|
||||
writer.write(
|
||||
"# For more information see: https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/13468\n\n");
|
||||
YamlHelper.printInstrumentationList(entities, writer);
|
||||
} catch (IOException e) {
|
||||
logger.severe("Error writing instrumentation list: " + e.getMessage());
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.docs;
|
||||
|
||||
import static io.opentelemetry.instrumentation.docs.GradleParser.parseGradleFile;
|
||||
import static io.opentelemetry.instrumentation.docs.parsers.GradleParser.parseGradleFile;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.internal.DependencyInfo;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationEntity;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
|
||||
import io.opentelemetry.instrumentation.docs.utils.FileManager;
|
||||
import io.opentelemetry.instrumentation.docs.utils.InstrumentationPath;
|
||||
import io.opentelemetry.instrumentation.docs.utils.YamlHelper;
|
||||
|
@ -42,11 +45,12 @@ class InstrumentationAnalyzer {
|
|||
if (!entityMap.containsKey(key)) {
|
||||
entityMap.put(
|
||||
key,
|
||||
new InstrumentationEntity(
|
||||
path.srcPath().replace("/javaagent", "").replace("/library", ""),
|
||||
path.instrumentationName(),
|
||||
path.namespace(),
|
||||
path.group()));
|
||||
new InstrumentationEntity.Builder()
|
||||
.srcPath(path.srcPath().replace("/javaagent", "").replace("/library", ""))
|
||||
.instrumentationName(path.instrumentationName())
|
||||
.namespace(path.namespace())
|
||||
.group(path.group())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,15 +84,21 @@ class InstrumentationAnalyzer {
|
|||
Map<InstrumentationType, Set<String>> versions = new HashMap<>();
|
||||
for (String file : files) {
|
||||
String fileContents = fileSearch.readFileToString(file);
|
||||
DependencyInfo results = null;
|
||||
|
||||
if (file.contains("/javaagent/")) {
|
||||
Set<String> results = parseGradleFile(fileContents, InstrumentationType.JAVAAGENT);
|
||||
results = parseGradleFile(fileContents, InstrumentationType.JAVAAGENT);
|
||||
versions
|
||||
.computeIfAbsent(InstrumentationType.JAVAAGENT, k -> new HashSet<>())
|
||||
.addAll(results);
|
||||
.addAll(results.versions());
|
||||
} else if (file.contains("/library/")) {
|
||||
Set<String> results = parseGradleFile(fileContents, InstrumentationType.LIBRARY);
|
||||
versions.computeIfAbsent(InstrumentationType.LIBRARY, k -> new HashSet<>()).addAll(results);
|
||||
results = parseGradleFile(fileContents, InstrumentationType.LIBRARY);
|
||||
versions
|
||||
.computeIfAbsent(InstrumentationType.LIBRARY, k -> new HashSet<>())
|
||||
.addAll(results.versions());
|
||||
}
|
||||
if (results != null && results.minJavaVersionSupported() != null) {
|
||||
entity.setMinJavaVersion(results.minJavaVersionSupported());
|
||||
}
|
||||
}
|
||||
entity.setTargetVersions(versions);
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class InstrumentationEntity {
|
||||
private final String srcPath;
|
||||
private final String instrumentationName;
|
||||
private final String namespace;
|
||||
private final String group;
|
||||
|
||||
private InstrumentationMetaData metadata;
|
||||
private Map<InstrumentationType, Set<String>> targetVersions;
|
||||
|
||||
public InstrumentationEntity(
|
||||
String srcPath, String instrumentationName, String namespace, String group) {
|
||||
this.srcPath = srcPath;
|
||||
this.instrumentationName = instrumentationName;
|
||||
this.namespace = namespace;
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public InstrumentationEntity(
|
||||
String srcPath,
|
||||
String instrumentationName,
|
||||
String namespace,
|
||||
String group,
|
||||
Map<InstrumentationType, Set<String>> targetVersions,
|
||||
InstrumentationMetaData metadata) {
|
||||
this.srcPath = srcPath;
|
||||
this.instrumentationName = instrumentationName;
|
||||
this.namespace = namespace;
|
||||
this.group = group;
|
||||
this.targetVersions = targetVersions;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public void setMetadata(InstrumentationMetaData metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public InstrumentationMetaData getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public String getSrcPath() {
|
||||
return srcPath;
|
||||
}
|
||||
|
||||
public String getInstrumentationName() {
|
||||
return instrumentationName;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public Map<InstrumentationType, Set<String>> getTargetVersions() {
|
||||
return targetVersions;
|
||||
}
|
||||
|
||||
public void setTargetVersions(Map<InstrumentationType, Set<String>> targetVersions) {
|
||||
this.targetVersions = targetVersions;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs;
|
||||
|
||||
public class InstrumentationMetaData {
|
||||
|
||||
public InstrumentationMetaData() {}
|
||||
|
||||
public InstrumentationMetaData(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
private String description;
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs.internal;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public record DependencyInfo(Set<String> versions, Integer minJavaVersionSupported) {}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs.internal;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class InstrumentationEntity {
|
||||
private final String srcPath;
|
||||
private final String instrumentationName;
|
||||
private final String namespace;
|
||||
private final String group;
|
||||
private final InstrumentationScopeInfo scopeInfo;
|
||||
|
||||
@Nullable private Map<InstrumentationType, Set<String>> targetVersions;
|
||||
|
||||
@Nullable private Integer minJavaVersion;
|
||||
|
||||
@Nullable private InstrumentationMetaData metadata;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public InstrumentationEntity(Builder builder) {
|
||||
requireNonNull(builder.srcPath, "srcPath required");
|
||||
requireNonNull(builder.instrumentationName, "instrumentationName required");
|
||||
requireNonNull(builder.namespace, "namespace required");
|
||||
requireNonNull(builder.group, "group required");
|
||||
|
||||
this.srcPath = builder.srcPath;
|
||||
this.instrumentationName = builder.instrumentationName;
|
||||
this.namespace = builder.namespace;
|
||||
this.group = builder.group;
|
||||
this.metadata = builder.metadata;
|
||||
this.targetVersions = builder.targetVersions;
|
||||
this.minJavaVersion = builder.minJavaVersion;
|
||||
this.scopeInfo = InstrumentationScopeInfo.create("io.opentelemetry." + instrumentationName);
|
||||
}
|
||||
|
||||
public String getSrcPath() {
|
||||
return srcPath;
|
||||
}
|
||||
|
||||
public String getInstrumentationName() {
|
||||
return instrumentationName;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return namespace;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public InstrumentationScopeInfo getScopeInfo() {
|
||||
return scopeInfo;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InstrumentationMetaData getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Map<InstrumentationType, Set<String>> getTargetVersions() {
|
||||
return targetVersions;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getMinJavaVersion() {
|
||||
return minJavaVersion;
|
||||
}
|
||||
|
||||
public void setTargetVersions(Map<InstrumentationType, Set<String>> targetVersions) {
|
||||
this.targetVersions = targetVersions;
|
||||
}
|
||||
|
||||
public void setMetadata(InstrumentationMetaData metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public void setMinJavaVersion(Integer minJavaVersion) {
|
||||
this.minJavaVersion = minJavaVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public static class Builder {
|
||||
private String srcPath;
|
||||
private String instrumentationName;
|
||||
private String namespace;
|
||||
private String group;
|
||||
private Integer minJavaVersion;
|
||||
private InstrumentationMetaData metadata;
|
||||
private Map<InstrumentationType, Set<String>> targetVersions;
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public Builder srcPath(String srcPath) {
|
||||
this.srcPath = srcPath;
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public Builder instrumentationName(String instrumentationName) {
|
||||
this.instrumentationName = instrumentationName;
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public Builder namespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public Builder minJavaVersion(Integer minJavaVersion) {
|
||||
this.minJavaVersion = minJavaVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public Builder group(String group) {
|
||||
this.group = group;
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public Builder metadata(InstrumentationMetaData metadata) {
|
||||
this.metadata = metadata;
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public Builder targetVersions(Map<InstrumentationType, Set<String>> targetVersions) {
|
||||
this.targetVersions = targetVersions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstrumentationEntity build() {
|
||||
return new InstrumentationEntity(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs.internal;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public class InstrumentationMetaData {
|
||||
|
||||
public InstrumentationMetaData() {}
|
||||
|
||||
public InstrumentationMetaData(String description) {
|
||||
this.description = description;
|
||||
this.isLibraryInstrumentation = true;
|
||||
}
|
||||
|
||||
public InstrumentationMetaData(String description, Boolean isLibraryInstrumentation) {
|
||||
this.isLibraryInstrumentation = isLibraryInstrumentation;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Nullable private String description;
|
||||
|
||||
private Boolean isLibraryInstrumentation;
|
||||
|
||||
@Nullable
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Boolean getIsLibraryInstrumentation() {
|
||||
if (isLibraryInstrumentation == null) {
|
||||
return true;
|
||||
}
|
||||
return isLibraryInstrumentation;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setIsLibraryInstrumentation(Boolean libraryInstrumentation) {
|
||||
isLibraryInstrumentation = libraryInstrumentation;
|
||||
}
|
||||
}
|
|
@ -3,10 +3,14 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs;
|
||||
package io.opentelemetry.instrumentation.docs.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
|
||||
* any time.
|
||||
*/
|
||||
public enum InstrumentationType {
|
||||
JAVAAGENT,
|
||||
LIBRARY;
|
|
@ -3,16 +3,20 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs;
|
||||
package io.opentelemetry.instrumentation.docs.parsers;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.internal.DependencyInfo;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
class GradleParser {
|
||||
public class GradleParser {
|
||||
|
||||
private static final Pattern variablePattern =
|
||||
Pattern.compile("val\\s+(\\w+)\\s*=\\s*\"([^\"]+)\"");
|
||||
|
@ -31,20 +35,32 @@ class GradleParser {
|
|||
private static final Pattern latestDepTestLibraryPattern =
|
||||
Pattern.compile("latestDepTestLibrary\\(\"([^\"]+:[^\"]+):([^\"]+)\"\\)");
|
||||
|
||||
private static final Pattern coreJdkPattern = Pattern.compile("coreJdk\\(\\)");
|
||||
|
||||
private static final Pattern ifBlockPattern =
|
||||
Pattern.compile("if\\s*\\([^)]*\\)\\s*\\{.*?}", Pattern.DOTALL);
|
||||
|
||||
private static final Pattern otelJavaBlockPattern =
|
||||
Pattern.compile("otelJava\\s*\\{.*?}", Pattern.DOTALL);
|
||||
|
||||
private static final Pattern minJavaVersionPattern =
|
||||
Pattern.compile("minJavaVersionSupported\\.set\\(JavaVersion\\.VERSION_(\\d+)\\)");
|
||||
|
||||
/**
|
||||
* Parses gradle files for muzzle and dependency information
|
||||
*
|
||||
* @param gradleFileContents Contents of a Gradle build file as a String
|
||||
* @return A set of strings summarizing the group, module, and version ranges
|
||||
*/
|
||||
public static Set<String> parseGradleFile(String gradleFileContents, InstrumentationType type) {
|
||||
Set<String> results = new HashSet<>();
|
||||
public static DependencyInfo parseGradleFile(
|
||||
String gradleFileContents, InstrumentationType type) {
|
||||
DependencyInfo results;
|
||||
Map<String, String> variables = extractVariables(gradleFileContents);
|
||||
|
||||
if (type.equals(InstrumentationType.JAVAAGENT)) {
|
||||
results.addAll(parseMuzzle(gradleFileContents, variables));
|
||||
results = parseMuzzle(gradleFileContents, variables);
|
||||
} else {
|
||||
results.addAll(parseLibraryDependencies(gradleFileContents, variables));
|
||||
results = parseLibraryDependencies(gradleFileContents, variables);
|
||||
}
|
||||
|
||||
return results;
|
||||
|
@ -58,13 +74,24 @@ class GradleParser {
|
|||
* @param variables Map of variable names to their values
|
||||
* @return A set of strings summarizing the group, module, and version ranges
|
||||
*/
|
||||
private static Set<String> parseMuzzle(String gradleFileContents, Map<String, String> variables) {
|
||||
private static DependencyInfo parseMuzzle(
|
||||
String gradleFileContents, Map<String, String> variables) {
|
||||
Set<String> results = new HashSet<>();
|
||||
Matcher passBlockMatcher = muzzlePassBlockPattern.matcher(gradleFileContents);
|
||||
|
||||
Integer minJavaVersion = parseMinJavaVersion(gradleFileContents);
|
||||
|
||||
while (passBlockMatcher.find()) {
|
||||
String passBlock = passBlockMatcher.group(1);
|
||||
|
||||
if (coreJdkPattern.matcher(passBlock).find()) {
|
||||
if (minJavaVersion != null) {
|
||||
results.add("Java " + minJavaVersion + "+");
|
||||
} else {
|
||||
results.add("Java 8+");
|
||||
}
|
||||
}
|
||||
|
||||
String group = extractValue(passBlock, "group\\.set\\(\"([^\"]+)\"\\)");
|
||||
String module = extractValue(passBlock, "module\\.set\\(\"([^\"]+)\"\\)");
|
||||
String versionRange = extractValue(passBlock, "versions\\.set\\(\"([^\"]+)\"\\)");
|
||||
|
@ -74,7 +101,7 @@ class GradleParser {
|
|||
results.add(summary);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
return new DependencyInfo(results, minJavaVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,7 +113,7 @@ class GradleParser {
|
|||
* @param variables Map of variable names to their values
|
||||
* @return A set of strings summarizing the group, module, and versions
|
||||
*/
|
||||
private static Set<String> parseLibraryDependencies(
|
||||
private static DependencyInfo parseLibraryDependencies(
|
||||
String gradleFileContents, Map<String, String> variables) {
|
||||
Map<String, String> versions = new HashMap<>();
|
||||
|
||||
|
@ -123,7 +150,45 @@ class GradleParser {
|
|||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
Integer minJavaVersion = parseMinJavaVersion(gradleFileContents);
|
||||
|
||||
return new DependencyInfo(results, minJavaVersion);
|
||||
}
|
||||
|
||||
public static Integer parseMinJavaVersion(String gradleFileContents) {
|
||||
List<int[]> excludedRanges = new ArrayList<>();
|
||||
|
||||
// Identify all if-block ranges so we can exclude them
|
||||
Matcher ifBlockMatcher = ifBlockPattern.matcher(gradleFileContents);
|
||||
while (ifBlockMatcher.find()) {
|
||||
excludedRanges.add(new int[] {ifBlockMatcher.start(), ifBlockMatcher.end()});
|
||||
}
|
||||
|
||||
Matcher otelJavaMatcher = otelJavaBlockPattern.matcher(gradleFileContents);
|
||||
while (otelJavaMatcher.find()) {
|
||||
int blockStart = otelJavaMatcher.start();
|
||||
|
||||
if (isInExcludedRange(blockStart, excludedRanges)) {
|
||||
continue; // Skip blocks inside 'if' statements
|
||||
}
|
||||
|
||||
String otelJavaBlock = otelJavaMatcher.group();
|
||||
Matcher versionMatcher = minJavaVersionPattern.matcher(otelJavaBlock);
|
||||
if (versionMatcher.find()) {
|
||||
return Integer.parseInt(versionMatcher.group(1));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isInExcludedRange(int position, List<int[]> ranges) {
|
||||
for (int[] range : ranges) {
|
||||
if (position >= range[0] && position <= range[1]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.docs.utils;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.InstrumentationType;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -29,7 +29,6 @@ public class FileManager {
|
|||
|
||||
try (Stream<Path> walk = Files.walk(rootPath)) {
|
||||
return walk.filter(Files::isDirectory)
|
||||
.filter(dir -> !dir.toString().contains("/build"))
|
||||
.filter(dir -> isValidInstrumentationPath(dir.toString()))
|
||||
.map(dir -> parseInstrumentationPath(dir.toString()))
|
||||
.collect(Collectors.toList());
|
||||
|
@ -77,7 +76,9 @@ public class FileManager {
|
|||
|
||||
if (filePath.contains("/test/")
|
||||
|| filePath.contains("/testing")
|
||||
|| filePath.contains("/build/")
|
||||
|| filePath.contains("-common/")
|
||||
|| filePath.contains("-common-")
|
||||
|| filePath.contains("bootstrap/src")) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.docs.utils;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.InstrumentationType;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
|
||||
|
||||
public record InstrumentationPath(
|
||||
String instrumentationName,
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.docs.utils;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.InstrumentationEntity;
|
||||
import io.opentelemetry.instrumentation.docs.InstrumentationMetaData;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationEntity;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationMetaData;
|
||||
import java.io.BufferedWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -16,7 +16,6 @@ import java.util.TreeMap;
|
|||
import java.util.stream.Collectors;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
public class YamlHelper {
|
||||
|
||||
|
@ -24,6 +23,7 @@ public class YamlHelper {
|
|||
List<InstrumentationEntity> list, BufferedWriter writer) {
|
||||
Map<String, List<InstrumentationEntity>> groupedByGroup =
|
||||
list.stream()
|
||||
.filter(entity -> isLibraryInstrumentation(entity.getMetadata()))
|
||||
.collect(
|
||||
Collectors.groupingBy(
|
||||
InstrumentationEntity::getGroup, TreeMap::new, Collectors.toList()));
|
||||
|
@ -43,6 +43,13 @@ public class YamlHelper {
|
|||
|
||||
entityMap.put("srcPath", entity.getSrcPath());
|
||||
|
||||
if (entity.getMinJavaVersion() != null) {
|
||||
entityMap.put("minimumJavaVersion", entity.getMinJavaVersion());
|
||||
}
|
||||
|
||||
Map<String, Object> scopeMap = getScopeMap(entity);
|
||||
entityMap.put("scope", scopeMap);
|
||||
|
||||
Map<String, Object> targetVersions = new TreeMap<>();
|
||||
if (entity.getTargetVersions() != null && !entity.getTargetVersions().isEmpty()) {
|
||||
entity
|
||||
|
@ -52,6 +59,7 @@ public class YamlHelper {
|
|||
targetVersions.put(type.toString(), new ArrayList<>(versions)));
|
||||
}
|
||||
entityMap.put("target_versions", targetVersions);
|
||||
|
||||
instrumentations.add(entityMap);
|
||||
}
|
||||
groupMap.put("instrumentations", instrumentations);
|
||||
|
@ -60,12 +68,25 @@ public class YamlHelper {
|
|||
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
Representer representer = new Representer(options);
|
||||
representer.getPropertyUtils().setSkipMissingProperties(true);
|
||||
Yaml yaml = new Yaml(representer, options);
|
||||
|
||||
Yaml yaml = new Yaml(options);
|
||||
yaml.dump(output, writer);
|
||||
}
|
||||
|
||||
// We assume true unless explicitly overridden
|
||||
private static Boolean isLibraryInstrumentation(InstrumentationMetaData metadata) {
|
||||
if (metadata == null) {
|
||||
return true;
|
||||
}
|
||||
return metadata.getIsLibraryInstrumentation();
|
||||
}
|
||||
|
||||
private static Map<String, Object> getScopeMap(InstrumentationEntity entity) {
|
||||
Map<String, Object> scopeMap = new LinkedHashMap<>();
|
||||
scopeMap.put("name", entity.getScopeInfo().getName());
|
||||
return scopeMap;
|
||||
}
|
||||
|
||||
public static InstrumentationMetaData metaDataParser(String input) {
|
||||
return new Yaml().loadAs(input, InstrumentationMetaData.class);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ package io.opentelemetry.instrumentation.docs;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationEntity;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
|
||||
import io.opentelemetry.instrumentation.docs.utils.InstrumentationPath;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -50,6 +52,8 @@ class InstrumentationAnalyzerTest {
|
|||
assertThat(log4jEntity.getNamespace()).isEqualTo("log4j");
|
||||
assertThat(log4jEntity.getGroup()).isEqualTo("log4j");
|
||||
assertThat(log4jEntity.getSrcPath()).isEqualTo("instrumentation/log4j/log4j-appender-2.17");
|
||||
assertThat(log4jEntity.getScopeInfo().getName())
|
||||
.isEqualTo("io.opentelemetry.log4j-appender-2.17");
|
||||
|
||||
InstrumentationEntity springEntity =
|
||||
entities.stream()
|
||||
|
@ -61,5 +65,6 @@ class InstrumentationAnalyzerTest {
|
|||
assertThat(springEntity.getNamespace()).isEqualTo("spring");
|
||||
assertThat(springEntity.getGroup()).isEqualTo("spring");
|
||||
assertThat(springEntity.getSrcPath()).isEqualTo("instrumentation/spring/spring-web");
|
||||
assertThat(springEntity.getScopeInfo().getName()).isEqualTo("io.opentelemetry.spring-web");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.docs;
|
||||
package io.opentelemetry.instrumentation.docs.parsers;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.Set;
|
||||
import io.opentelemetry.instrumentation.docs.internal.DependencyInfo;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class GradleParserTest {
|
||||
|
@ -22,10 +23,10 @@ class GradleParserTest {
|
|||
+ " versions.set(\"[5.0,6.4)\")\n"
|
||||
+ " }\n"
|
||||
+ "}";
|
||||
Set<String> versions =
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.JAVAAGENT);
|
||||
assertThat(versions.size()).isEqualTo(1);
|
||||
assertThat(versions.stream().findFirst().get())
|
||||
assertThat(info.versions().size()).isEqualTo(1);
|
||||
assertThat(info.versions().stream().findFirst().get())
|
||||
.isEqualTo("org.elasticsearch.client:rest:[5.0,6.4)");
|
||||
}
|
||||
|
||||
|
@ -33,10 +34,10 @@ class GradleParserTest {
|
|||
void testExtractLibraryVersion() {
|
||||
String gradleBuildFileContent =
|
||||
"dependencies {\n" + " library(\"org.apache.httpcomponents:httpclient:4.3\")\n" + "}";
|
||||
Set<String> versions =
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.LIBRARY);
|
||||
assertThat(versions.size()).isEqualTo(1);
|
||||
assertThat(versions.stream().findFirst().get())
|
||||
assertThat(info.versions().size()).isEqualTo(1);
|
||||
assertThat(info.versions().stream().findFirst().get())
|
||||
.isEqualTo("org.apache.httpcomponents:httpclient:4.3");
|
||||
}
|
||||
|
||||
|
@ -49,13 +50,75 @@ class GradleParserTest {
|
|||
+ " latestDepTestLibrary(\"org.apache.httpcomponents:httpclient:4.+\") // see apache-httpclient-5.0 module\n"
|
||||
+ "}";
|
||||
|
||||
Set<String> versions =
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.LIBRARY);
|
||||
assertThat(versions.size()).isEqualTo(1);
|
||||
assertThat(versions.stream().findFirst().get())
|
||||
assertThat(info.versions().size()).isEqualTo(1);
|
||||
assertThat(info.versions().stream().findFirst().get())
|
||||
.isEqualTo("org.apache.httpcomponents:httpclient:[4.3,4.+)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractCoreJdk() {
|
||||
String gradleBuildFileContent =
|
||||
"""
|
||||
muzzle {
|
||||
pass {
|
||||
coreJdk()
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.JAVAAGENT);
|
||||
assertThat(info.versions().size()).isEqualTo(1);
|
||||
assertThat(info.versions().stream().findFirst().get()).isEqualTo("Java 8+");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractMinimumJavaVersion() {
|
||||
String gradleBuildFileContent =
|
||||
"""
|
||||
muzzle {
|
||||
pass {
|
||||
coreJdk()
|
||||
}
|
||||
}
|
||||
|
||||
otelJava {
|
||||
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
||||
}
|
||||
""";
|
||||
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.JAVAAGENT);
|
||||
assertThat(info.versions().size()).isEqualTo(1);
|
||||
assertThat(info.minJavaVersionSupported()).isEqualTo(11);
|
||||
assertThat(info.versions().stream().findFirst().get()).isEqualTo("Java 11+");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractMinimumJavaVersionIgnoredWithinIfCondition() {
|
||||
String gradleBuildFileContent =
|
||||
"""
|
||||
muzzle {
|
||||
pass {
|
||||
coreJdk()
|
||||
}
|
||||
}
|
||||
|
||||
if (latestDepTest) {
|
||||
otelJava {
|
||||
minJavaVersionSupported.set(JavaVersion.VERSION_11)
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.JAVAAGENT);
|
||||
assertThat(info.versions().size()).isEqualTo(1);
|
||||
assertThat(info.versions().stream().findFirst().get()).isEqualTo("Java 8+");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExtractMuzzleVersions_MultiplePassBlocks() {
|
||||
String gradleBuildFileContent =
|
||||
|
@ -89,9 +152,9 @@ class GradleParserTest {
|
|||
+ " }\n"
|
||||
+ "}\n";
|
||||
|
||||
Set<String> versions =
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.JAVAAGENT);
|
||||
assertThat(versions)
|
||||
assertThat(info.versions())
|
||||
.containsExactlyInAnyOrder(
|
||||
"dev.zio:zio_2.12:[2.0.0,)", "dev.zio:zio_2.13:[2.0.0,)", "dev.zio:zio_3:[2.0.0,)");
|
||||
}
|
||||
|
@ -117,9 +180,9 @@ class GradleParserTest {
|
|||
+ " }\n"
|
||||
+ "}\n";
|
||||
|
||||
Set<String> versions =
|
||||
DependencyInfo info =
|
||||
GradleParser.parseGradleFile(gradleBuildFileContent, InstrumentationType.LIBRARY);
|
||||
assertThat(versions)
|
||||
assertThat(info.versions())
|
||||
.containsExactlyInAnyOrder(
|
||||
"ch.qos.logback:logback-classic:1.3.0",
|
||||
"org.slf4j:slf4j-api:2.0.0",
|
|
@ -44,6 +44,14 @@ class FileManagerTest {
|
|||
assertThat(FileManager.isValidInstrumentationPath("/instrumentation/test/javaagent")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExcludesCommonModules() {
|
||||
assertThat(
|
||||
FileManager.isValidInstrumentationPath(
|
||||
"instrumentation/elasticsearch/elasticsearch-rest-common-5.0"))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindBuildGradleFiles() throws IOException {
|
||||
Path gradleFile = Files.createFile(tempDir.resolve("build.gradle.kts"));
|
||||
|
|
|
@ -7,9 +7,9 @@ package io.opentelemetry.instrumentation.docs.utils;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.instrumentation.docs.InstrumentationEntity;
|
||||
import io.opentelemetry.instrumentation.docs.InstrumentationMetaData;
|
||||
import io.opentelemetry.instrumentation.docs.InstrumentationType;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationEntity;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationMetaData;
|
||||
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
|
@ -33,26 +33,29 @@ class YamlHelperTest {
|
|||
new InstrumentationMetaData("Spring Web 6.0 instrumentation");
|
||||
|
||||
entities.add(
|
||||
new InstrumentationEntity(
|
||||
"instrumentation/spring/spring-web/spring-web-6.0",
|
||||
"spring-web-6.0",
|
||||
"spring",
|
||||
"spring",
|
||||
targetVersions1,
|
||||
metadata1));
|
||||
new InstrumentationEntity.Builder()
|
||||
.srcPath("instrumentation/spring/spring-web/spring-web-6.0")
|
||||
.instrumentationName("spring-web-6.0")
|
||||
.namespace("spring")
|
||||
.group("spring")
|
||||
.targetVersions(targetVersions1)
|
||||
.metadata(metadata1)
|
||||
.minJavaVersion(11)
|
||||
.build());
|
||||
|
||||
Map<InstrumentationType, Set<String>> targetVersions2 = new HashMap<>();
|
||||
|
||||
targetVersions2.put(
|
||||
InstrumentationType.LIBRARY,
|
||||
new HashSet<>(List.of("org.apache.struts:struts2-core:2.1.0")));
|
||||
entities.add(
|
||||
new InstrumentationEntity(
|
||||
"instrumentation/struts/struts-2.3",
|
||||
"struts-2.3",
|
||||
"struts",
|
||||
"struts",
|
||||
targetVersions2,
|
||||
null));
|
||||
new InstrumentationEntity.Builder()
|
||||
.srcPath("instrumentation/struts/struts-2.3")
|
||||
.instrumentationName("struts-2.3")
|
||||
.namespace("struts")
|
||||
.group("struts")
|
||||
.targetVersions(targetVersions2)
|
||||
.build());
|
||||
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
BufferedWriter writer = new BufferedWriter(stringWriter);
|
||||
|
@ -61,22 +64,115 @@ class YamlHelperTest {
|
|||
writer.flush();
|
||||
|
||||
String expectedYaml =
|
||||
"spring:\n"
|
||||
+ " instrumentations:\n"
|
||||
+ " - name: spring-web-6.0\n"
|
||||
+ " description: Spring Web 6.0 instrumentation\n"
|
||||
+ " srcPath: instrumentation/spring/spring-web/spring-web-6.0\n"
|
||||
+ " target_versions:\n"
|
||||
+ " javaagent:\n"
|
||||
+ " - org.springframework:spring-web:[6.0.0,)\n"
|
||||
+ "struts:\n"
|
||||
+ " instrumentations:\n"
|
||||
+ " - name: struts-2.3\n"
|
||||
+ " srcPath: instrumentation/struts/struts-2.3\n"
|
||||
+ " target_versions:\n"
|
||||
+ " library:\n"
|
||||
+ " - org.apache.struts:struts2-core:2.1.0\n";
|
||||
"""
|
||||
spring:
|
||||
instrumentations:
|
||||
- name: spring-web-6.0
|
||||
description: Spring Web 6.0 instrumentation
|
||||
srcPath: instrumentation/spring/spring-web/spring-web-6.0
|
||||
minimumJavaVersion: 11
|
||||
scope:
|
||||
name: io.opentelemetry.spring-web-6.0
|
||||
target_versions:
|
||||
javaagent:
|
||||
- org.springframework:spring-web:[6.0.0,)
|
||||
struts:
|
||||
instrumentations:
|
||||
- name: struts-2.3
|
||||
srcPath: instrumentation/struts/struts-2.3
|
||||
scope:
|
||||
name: io.opentelemetry.struts-2.3
|
||||
target_versions:
|
||||
library:
|
||||
- org.apache.struts:struts2-core:2.1.0
|
||||
""";
|
||||
|
||||
assertThat(expectedYaml).isEqualTo(stringWriter.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPrintInstrumentationListIgnoresNonLibraryInstrumentation() throws Exception {
|
||||
List<InstrumentationEntity> entities = new ArrayList<>();
|
||||
Map<InstrumentationType, Set<String>> targetVersions1 = new HashMap<>();
|
||||
targetVersions1.put(
|
||||
InstrumentationType.JAVAAGENT,
|
||||
new HashSet<>(List.of("org.springframework:spring-web:[6.0.0,)")));
|
||||
|
||||
InstrumentationMetaData metadata1 =
|
||||
new InstrumentationMetaData("Spring Web 6.0 instrumentation");
|
||||
|
||||
entities.add(
|
||||
new InstrumentationEntity.Builder()
|
||||
.srcPath("instrumentation/spring/spring-web/spring-web-6.0")
|
||||
.instrumentationName("spring-web-6.0")
|
||||
.namespace("spring")
|
||||
.group("spring")
|
||||
.targetVersions(targetVersions1)
|
||||
.metadata(metadata1)
|
||||
.minJavaVersion(11)
|
||||
.build());
|
||||
|
||||
InstrumentationMetaData metadata2 = new InstrumentationMetaData(null, false);
|
||||
|
||||
entities.add(
|
||||
new InstrumentationEntity.Builder()
|
||||
.srcPath("instrumentation/internal/internal-application-logger")
|
||||
.instrumentationName("internal-application-logger")
|
||||
.namespace("internal")
|
||||
.group("internal")
|
||||
.metadata(metadata2)
|
||||
.targetVersions(new HashMap<>())
|
||||
.build());
|
||||
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
BufferedWriter writer = new BufferedWriter(stringWriter);
|
||||
|
||||
YamlHelper.printInstrumentationList(entities, writer);
|
||||
writer.flush();
|
||||
|
||||
String expectedYaml =
|
||||
"""
|
||||
spring:
|
||||
instrumentations:
|
||||
- name: spring-web-6.0
|
||||
description: Spring Web 6.0 instrumentation
|
||||
srcPath: instrumentation/spring/spring-web/spring-web-6.0
|
||||
minimumJavaVersion: 11
|
||||
scope:
|
||||
name: io.opentelemetry.spring-web-6.0
|
||||
target_versions:
|
||||
javaagent:
|
||||
- org.springframework:spring-web:[6.0.0,)
|
||||
""";
|
||||
|
||||
assertThat(expectedYaml).isEqualTo(stringWriter.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMetadataParser() {
|
||||
String input =
|
||||
"""
|
||||
description: test description
|
||||
isLibraryInstrumentation: false
|
||||
""";
|
||||
|
||||
InstrumentationMetaData metadata = YamlHelper.metaDataParser(input);
|
||||
assertThat(metadata.getIsLibraryInstrumentation()).isFalse();
|
||||
assertThat(metadata.getDescription()).isEqualTo("test description");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMetadataParserWithOnlyLibraryEntry() {
|
||||
String input = "isLibraryInstrumentation: false";
|
||||
InstrumentationMetaData metadata = YamlHelper.metaDataParser(input);
|
||||
assertThat(metadata.getIsLibraryInstrumentation()).isFalse();
|
||||
assertThat(metadata.getDescription()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMetadataParserWithOnlyDescription() {
|
||||
String input = "description: false";
|
||||
InstrumentationMetaData metadata = YamlHelper.metaDataParser(input);
|
||||
assertThat(metadata.getIsLibraryInstrumentation()).isTrue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
|
@ -0,0 +1 @@
|
|||
isLibraryInstrumentation: false
|
Loading…
Reference in New Issue