-
Notifications
You must be signed in to change notification settings - Fork 1
test: test for the agent added #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
cd5c678
tests: adding java agent tests
serenacofano 2bd0f54
tests on empty annotattion or sbom added
serenacofano f495caf
fix
serenacofano 129bff4
Update .gitignore
serenacofano 14cc500
Update classport-agent/pom.xml
serenacofano a26a2a2
cross-platform compatibility fixed
serenacofano 256daa7
Merge branch 'test-agent' of github.com:chains-project/classport into…
serenacofano 8fc6a6d
fix dependency issue
serenacofano cebf52f
made writeSBOM public
serenacofano c76b108
change name of getSBOM -> mockSBOM
serenacofano 293b05c
names refactoring
serenacofano 89ec35e
test Analyser
serenacofano 113eb57
test for static analyser completed
serenacofano 9bb454a
fix in boolean variable
serenacofano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
target/ | ||
*.class | ||
.DS_Store | ||
|
||
# jdtls/eclipse stuff | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.lang.annotation.Annotation; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.HashMap; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertAll; | ||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNull; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import io.github.chains_project.classport.agent.ClassportAgent; | ||
import io.github.chains_project.classport.commons.AnnotationReader; | ||
import io.github.chains_project.classport.commons.ClassportInfo; | ||
|
||
public class ClassportAgentTest { | ||
|
||
private static final Path CLASSPORT_TREE_PATH = Path.of("src/test/resources/classport-deps/classport-deps-tree"); | ||
private static final Path CLASSPORT_LIST_PATH = Path.of("src/test/resources/classport-deps/classport-deps-list"); | ||
private static final Path ANNOTATED_CLASS_PATH = Path.of("src/test/resources/annotated-classes/StringUtils.class"); | ||
private static final Path NOT_ANNOTATED_CLASS_PATH = Path.of("src/test/resources/not-annotated-classes/StringUtils.class"); | ||
|
||
@Test | ||
void shouldGenerateDependencyListAndTreeFiles() throws Exception { | ||
HashMap<String, ClassportInfo> sbom = mockSBOM(); | ||
|
||
ClassportAgent.writeSBOM(sbom); | ||
|
||
File actualTreeFile = new File(System.getProperty("user.dir"), "classport-deps-tree"); | ||
File actualListFile = new File(System.getProperty("user.dir"), "classport-deps-list"); | ||
|
||
assertAll( | ||
() -> assertTrue(actualTreeFile.exists(), "Tree output file should be created"), | ||
() -> assertTrue(actualListFile.exists(), "List output file should be created"), | ||
() -> assertEquals( | ||
Files.readString(CLASSPORT_TREE_PATH), | ||
Files.readString(actualTreeFile.toPath()), | ||
"Tree files should be identical"), | ||
() -> assertEquals( | ||
Files.readString(CLASSPORT_LIST_PATH), | ||
Files.readString(actualListFile.toPath()), | ||
"List files should be identical") | ||
); | ||
|
||
actualTreeFile.delete(); | ||
actualListFile.delete(); | ||
} | ||
|
||
|
||
@Test | ||
void shouldHandleEmptySBOM() throws Exception { | ||
HashMap<String, ClassportInfo> emptySBOM = new HashMap<>(); | ||
serenacofano marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
ClassportAgent.writeSBOM(emptySBOM); | ||
|
||
File treeFile = new File(System.getProperty("user.dir"), "classport-deps-tree"); | ||
File listFile = new File(System.getProperty("user.dir"), "classport-deps-list"); | ||
|
||
assertTrue(treeFile.exists(), "Tree output file should be created even if SBOM is empty"); | ||
assertTrue(listFile.exists(), "List output file should be created even if SBOM is empty"); | ||
|
||
String treeContent = new String(Files.readAllBytes(treeFile.toPath())); | ||
String expectedPlaceholder = "<Unknown> (parent-only artefact)"; | ||
|
||
assertTrue(treeContent.contains(expectedPlaceholder), "Tree file should contain placeholder text when SBOM is empty"); | ||
assertTrue(listFile.length() == 0, "List file should be empty when SBOM is empty"); | ||
|
||
// Clean up after the test | ||
treeFile.delete(); | ||
listFile.delete(); | ||
} | ||
|
||
@Test | ||
void shouldAnnotationBeCorrectlyRead() throws IOException { | ||
File classFile = ANNOTATED_CLASS_PATH.toFile(); | ||
byte[] buffer = loadClassFromFile(classFile); | ||
ClassportInfo actualAnnotation = AnnotationReader.getAnnotationValues(buffer); | ||
|
||
assertAll( | ||
() -> assertEquals("commons-lang3", actualAnnotation.artefact()), | ||
() -> assertEquals("org.apache.commons", actualAnnotation.group()), | ||
() -> assertEquals("org.apache.commons:commons-lang3:jar:3.17.0", actualAnnotation.id()), | ||
() -> assertTrue(actualAnnotation.isDirectDependency()), | ||
() -> assertEquals("com.example:test-agent-app:jar:1.0-SNAPSHOT", actualAnnotation.sourceProjectId()), | ||
() -> assertEquals("3.17.0", actualAnnotation.version()), | ||
() -> assertEquals("org.apache.commons:commons-text:jar:1.12.0", actualAnnotation.childIds()[0]) | ||
); | ||
} | ||
|
||
@Test | ||
void shouldReturnNonAnnotatedClassesNull() throws Exception { | ||
byte[] nonAnnotatedClassBytes = loadClassFromFile(NOT_ANNOTATED_CLASS_PATH.toFile()); | ||
ClassportInfo actualAnnotation = AnnotationReader.getAnnotationValues(nonAnnotatedClassBytes); | ||
assertNull(actualAnnotation); | ||
} | ||
|
||
|
||
private byte[] loadClassFromFile(File classFile) throws IOException { | ||
try (InputStream inputStream = new FileInputStream(classFile)) { | ||
return inputStream.readAllBytes(); | ||
} | ||
} | ||
|
||
|
||
private HashMap<String, ClassportInfo> mockSBOM() { | ||
HashMap<String, ClassportInfo> sbom = new HashMap<>(); | ||
sbom.put("com.example:test-agent-app:jar:1.0-SNAPSHOT", | ||
createClassportInfo("com.example", "1.0-SNAPSHOT", | ||
"com.example:test-agent-app:jar:1.0-SNAPSHOT", | ||
"test-agent-app", false, | ||
"com.example:test-agent-app:jar:1.0-SNAPSHOT", | ||
new String[]{"com.google.code.gson:gson:jar:2.11.0", | ||
"org.apache.commons:commons-lang3:jar:3.17.0"})); | ||
sbom.put("com.google.code.gson:gson:jar:2.11.0", | ||
createClassportInfo("com.google.code.gson", "2.11.0", | ||
"com.google.code.gson:gson:jar:2.11.0", | ||
"gson", true, | ||
"com.example:test-agent-app:jar:1.0-SNAPSHOT", | ||
new String[]{"com.google.errorprone:error_prone_annotations:jar:2.27.0"})); | ||
sbom.put("org.apache.commons:commons-lang3:jar:3.17.0", | ||
createClassportInfo("org.apache.commons", "3.17.0", | ||
"org.apache.commons:commons-lang3:jar:3.17.0", | ||
"commons-lang3", true, | ||
"com.example:test-agent-app:jar:1.0-SNAPSHOT", | ||
new String[]{"org.apache.commons:commons-text:jar:1.12.0"})); | ||
return sbom; | ||
} | ||
|
||
private ClassportInfo createClassportInfo(String group, String version, String id, | ||
String artefact, boolean isDirectDependency, | ||
String sourceProjectId, String[] childIds) { | ||
return new ClassportInfo() { | ||
@Override public String group() { return group; } | ||
@Override public String version() { return version; } | ||
@Override public String id() { return id; } | ||
@Override public String artefact() { return artefact; } | ||
@Override public boolean isDirectDependency() { return isDirectDependency; } | ||
@Override public String sourceProjectId() { return sourceProjectId; } | ||
@Override public String[] childIds() { return childIds; } | ||
@Override public Class<? extends Annotation> annotationType() { return ClassportInfo.class; } | ||
}; | ||
} | ||
} |
Binary file added
BIN
+62.8 KB
classport-agent/src/test/resources/annotated-classes/StringUtils.class
Binary file not shown.
2 changes: 2 additions & 0 deletions
2
classport-agent/src/test/resources/classport-deps/classport-deps-list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
com.google.code.gson:gson:jar:2.11.0 | ||
org.apache.commons:commons-lang3:jar:3.17.0 | ||
serenacofano marked this conversation as resolved.
Show resolved
Hide resolved
|
3 changes: 3 additions & 0 deletions
3
classport-agent/src/test/resources/classport-deps/classport-deps-tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
com.example:test-agent-app:jar:1.0-SNAPSHOT | ||
+- com.google.code.gson:gson:jar:2.11.0 | ||
\- org.apache.commons:commons-lang3:jar:3.17.0 |
Binary file added
BIN
+62.4 KB
classport-agent/src/test/resources/not-annotated-classes/StringUtils.class
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.PrintStream; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.HashMap; | ||
import java.util.jar.JarFile; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
import org.junit.jupiter.api.Test; | ||
import org.objectweb.asm.ClassReader; | ||
import org.objectweb.asm.ClassVisitor; | ||
import org.objectweb.asm.MethodVisitor; | ||
import org.objectweb.asm.Opcodes; | ||
|
||
import io.github.chains_project.classport.analyser.Analyser; | ||
import io.github.chains_project.classport.analyser.ClassLoadingAdder; | ||
import io.github.chains_project.classport.commons.ClassportInfo; | ||
|
||
class AnalyserTest { | ||
|
||
private final Path annotatedJarPath = Path.of("src/test/resources/annotated-classes/test-agent-app-1.0-SNAPSHOT.jar"); | ||
private final Path notAnnotatedJarPath = Path.of("src/test/resources/not-annotated-classes/test-agent-app-1.0-SNAPSHOT.jar"); | ||
private final String addedClassName = "__classportForceClassLoading"; | ||
private final String addedClassDescriptor = "()V"; | ||
private final Path annotatedClassPath = Path.of("src/test/resources/annotated-classes/Main.class"); | ||
private boolean methodPresent; | ||
private boolean methodInvoked; | ||
|
||
@Test | ||
void testGetSBOM_withAnnotatedClasses() throws IOException { | ||
JarFile jar = new JarFile(annotatedJarPath.toFile()); | ||
HashMap<String, ClassportInfo> actualSbom = Analyser.getSBOM(jar); | ||
|
||
assertTrue(!actualSbom.isEmpty()); | ||
assertEquals(4, actualSbom.size(), "SBOM should contain 4 annotated classes"); | ||
assertTrue(actualSbom.containsKey("com.example:test-agent-app:jar:1.0-SNAPSHOT"), "SBOM should contain class com.example:test-agent-app:jar:1.0-SNAPSHOT"); | ||
assertTrue(actualSbom.containsKey("com.google.errorprone:error_prone_annotations:jar:2.27.0"), "SBOM should contain class com.google.errorprone:error_prone_annotations:jar:2.27.0"); | ||
assertTrue(actualSbom.containsKey("com.google.code.gson:gson:jar:2.11.0"), "SBOM should contain class com.google.code.gson:gson:jar:2.11.0"); | ||
assertTrue(actualSbom.containsKey("org.apache.commons:commons-lang3:jar:3.17.0"), "SBOM should contain class org.apache.commons:commons-lang3:jar:3.17.0"); | ||
} | ||
|
||
@Test | ||
void testGetSBOM_withNonAnnotatedClasses() throws IOException { | ||
ByteArrayOutputStream errContent = new ByteArrayOutputStream(); | ||
System.setErr(new PrintStream(errContent)); | ||
|
||
JarFile jar = new JarFile(notAnnotatedJarPath.toFile()); | ||
HashMap<String, ClassportInfo> actualSbom = Analyser.getSBOM(jar); | ||
|
||
assertTrue(actualSbom.isEmpty(),"The sbom should be empty if the jar file does not contain annotated classes"); | ||
String actualMessage = errContent.toString(); | ||
assertTrue(actualMessage.contains("[Warning]"), "The warning message should match the expected pattern"); | ||
} | ||
|
||
@Test | ||
void testForceClassLoading_withAnnotation() throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { | ||
Path path = annotatedClassPath; | ||
byte[] originalMainClass = Files.readAllBytes(path); | ||
|
||
String[] classesToLoad = {"com/google/errorprone/annotations/MustBeClosed", "com/google/gson/ExclusionStrategy", "org/apache/commons/lang3/BooleanUtils"}; | ||
byte[] modifiedClass = ClassLoadingAdder.forceClassLoading(originalMainClass, classesToLoad); | ||
|
||
assertNotNull(modifiedClass, "Modified class byte array should not be null"); | ||
assertTrue(modifiedClass.length > 0, "Modified class should have content"); | ||
|
||
ClassReader classReader = new ClassReader(modifiedClass); | ||
assertTrue(isAdditionalMethodPresent(classReader), "The additional method __classportForceClassLoading should be present"); | ||
assertTrue(isAdditionalMethodInvoked(classReader), "The additional method __classportForceClassLoading should be invoked"); | ||
|
||
} | ||
|
||
private boolean isAdditionalMethodPresent(ClassReader classReader) { | ||
methodPresent = false; | ||
classReader.accept(new ClassVisitor(Opcodes.ASM9) { | ||
|
||
@Override | ||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { | ||
if (name.equals(addedClassName) && descriptor.equals(addedClassDescriptor)) { | ||
methodPresent = true; | ||
} | ||
return super.visitMethod(access, name, descriptor, signature, exceptions); | ||
} | ||
}, 0); | ||
return methodPresent; | ||
} | ||
|
||
private boolean isAdditionalMethodInvoked(ClassReader classReader) { | ||
methodInvoked = false; | ||
classReader.accept(new ClassVisitor(Opcodes.ASM9) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
@Override | ||
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { | ||
return new MethodVisitor(Opcodes.ASM9) { | ||
@Override | ||
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { | ||
if (name.equals(addedClassName) && descriptor.equals(addedClassDescriptor)) { | ||
methodInvoked = true; | ||
} | ||
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface); | ||
} | ||
}; | ||
} | ||
|
||
}, 0); | ||
return methodInvoked; | ||
} | ||
} | ||
|
Binary file not shown.
Binary file added
BIN
+1.09 MB
classport-analyser/src/test/resources/annotated-classes/test-agent-app-1.0-SNAPSHOT.jar
Binary file not shown.
Binary file added
BIN
+966 KB
classport-analyser/src/test/resources/not-annotated-classes/test-agent-app-1.0-SNAPSHOT.jar
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.