Skip to content

Commit

Permalink
Add a test for AgentMain which verifies that all classes from the s…
Browse files Browse the repository at this point in the history
…pec are actually instrumented
  • Loading branch information
centic9 authored and basil committed Mar 8, 2022
1 parent df85b90 commit 3b40c0c
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 3 deletions.
12 changes: 9 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
</includes>
<excludes>
<exclude>**/TransformerTest.java</exclude>
<exclude>**/AgentMainTest.java</exclude>
</excludes>
<argLine>
-javaagent:"${project.build.directory}/file-leak-detector-${project.version}-jar-with-dependencies.jar"
Expand All @@ -60,9 +61,8 @@
</goals>
<configuration>
<includes>
<include>
**/TransformerTest.java
</include>
<include>**/TransformerTest.java</include>
<include>**/AgentMainTest.java</include>
</includes>
<excludes>
<exclude>**/instrumented/*.java</exclude>
Expand Down Expand Up @@ -142,6 +142,12 @@
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.2.4</version>
<scope>test</scope>
</dependency>
</dependencies>

<profiles>
Expand Down
74 changes: 74 additions & 0 deletions src/test/java/org/kohsuke/file_leak_detector/AgentMainTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.kohsuke.file_leak_detector;

import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Test;
import org.kohsuke.file_leak_detector.transform.ClassTransformSpec;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class AgentMainTest {
@Test
public void noDuplicateSpecs() {
final List<ClassTransformSpec> specs = AgentMain.createSpec();

Set<String> seenClasses = new HashSet<>();
for (ClassTransformSpec spec : specs) {
assertTrue("Did have duplicate spec for class " + spec.name, seenClasses.add(spec.name));
}
}

@Test
public void testPreMain() throws Exception {
final List<ClassTransformSpec> specs = AgentMain.createSpec();

final Set<String> seenClasses = new HashSet<>();
for (ClassTransformSpec spec : specs) {
seenClasses.add(spec.name);
}

Instrumentation instrumentation = mock(Instrumentation.class);
Mockito.doAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
for (Object obj : invocationOnMock.getArguments()) {
Class<?> clazz = (Class<?>) obj;
String name = clazz.getName().replace(".", "/");
assertTrue(
"Tried to transform a class wihch is not contained in the specs: "
+ name
+ " ("
+ clazz
+ "), having remaining classes: "
+ seenClasses,
seenClasses.remove(name));
}
return null;
}
}).when(instrumentation).retransformClasses((Class<?>) any());

AgentMain.premain(null, instrumentation);

verify(instrumentation, times(1)).addTransformer((ClassFileTransformer) any(), anyBoolean());
verify(instrumentation, times(1)).retransformClasses((Class<?>) any());

// the following are not available in all JVMs
seenClasses.remove("sun/nio/ch/SocketChannelImpl");
seenClasses.remove("java/net/AbstractPlainSocketImpl");

assertTrue(
"Had classes in the spec which were not instrumented: " + seenClasses,
seenClasses.isEmpty());
}
}

0 comments on commit 3b40c0c

Please sign in to comment.