-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from ls1intum/chore/add-tests
`Chore`: Add unit tests for architectural and AOP analysis
- Loading branch information
Showing
28 changed files
with
1,020 additions
and
24 deletions.
There are no files selected for viewing
This file contains 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 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 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 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
1 change: 1 addition & 0 deletions
1
...tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/classloader-methods.txt
This file contains 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 @@ | ||
java.lang.ClassLoader |
This file contains 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 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
124 changes: 124 additions & 0 deletions
124
src/test/java/de/tum/cit/ase/ares/api/aop/JavaAOPModeTest.java
This file contains 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,124 @@ | ||
package de.tum.cit.ase.ares.api.aop; | ||
|
||
import de.tum.cit.ase.ares.api.aop.java.JavaAOPMode; | ||
import de.tum.cit.ase.ares.api.util.FileTools; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.MockedStatic; | ||
|
||
import java.lang.reflect.Method; | ||
import java.nio.file.Path; | ||
import java.util.Arrays; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
class JavaAOPModeTest { | ||
|
||
private static final int SETUP_OPTIONS_COUNT = 2; | ||
/** | ||
* Expected number of files to copy for instrumentation mode. | ||
* This includes: | ||
* - [List the specific files or types of files expected] | ||
*/ | ||
private static final int INSTRUMENTATION_FILES_COUNT = 13; | ||
private static final int INSTRUMENTATION_VALUES_COUNT = 12; | ||
|
||
/** | ||
* Expected number of files to copy for AspectJ mode. | ||
* This includes: | ||
* - [List the specific files or types of files expected] | ||
*/ | ||
private static final int ASPECTJ_FILES_COUNT = 2; | ||
private static final int ASPECTJ_VALUES_COUNT = 2; | ||
|
||
private static String TEST_PACKAGE = "com.example"; | ||
private static String TEST_MAIN_CLASS = "MainClass"; | ||
private static String[] EXPECTED_ARRAY = {"mocked", "array"}; | ||
|
||
private JavaAOPMode instrumentationMode; | ||
private JavaAOPMode aspectjMode; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
instrumentationMode = JavaAOPMode.INSTRUMENTATION; | ||
aspectjMode = JavaAOPMode.ASPECTJ; | ||
} | ||
|
||
@Test | ||
void testEnumValues() { | ||
JavaAOPMode[] modes = JavaAOPMode.values(); | ||
assertEquals(SETUP_OPTIONS_COUNT, modes.length); | ||
assertTrue(Arrays.asList(modes).contains(JavaAOPMode.INSTRUMENTATION)); | ||
assertTrue(Arrays.asList(modes).contains(JavaAOPMode.ASPECTJ)); | ||
} | ||
|
||
@Test | ||
void testFilesToCopy_InstrumentationMode() { | ||
try (MockedStatic<FileTools> mockedFileTools = mockStatic(FileTools.class)) { | ||
mockedFileTools | ||
.when(() -> FileTools.resolveOnResources(any(String[].class))) | ||
.thenReturn(mock(Path.class)); | ||
instrumentationMode.filesToCopy(); | ||
mockedFileTools | ||
.verify(() -> FileTools.resolveOnResources(any(String[].class)), | ||
times(INSTRUMENTATION_FILES_COUNT) | ||
); | ||
} | ||
} | ||
|
||
@Test | ||
void testFilesToCopy_AspectJMode() { | ||
try (MockedStatic<FileTools> mockedFileTools = mockStatic(FileTools.class)) { | ||
mockedFileTools | ||
.when(() -> FileTools.resolveOnResources(any(String[].class))) | ||
.thenReturn(mock(Path.class)); | ||
aspectjMode.filesToCopy(); | ||
mockedFileTools | ||
.verify(() -> FileTools.resolveOnResources(any(String[].class)), | ||
times(ASPECTJ_FILES_COUNT) | ||
); | ||
} | ||
} | ||
|
||
@Test | ||
void testFileValues_InstrumentationMode() { | ||
try (MockedStatic<FileTools> mockedFileTools = mockStatic(FileTools.class)) { | ||
mockedFileTools | ||
.when(() -> FileTools.generatePackageNameArray(anyString(), anyInt())) | ||
.thenReturn(EXPECTED_ARRAY); | ||
instrumentationMode.fileValues(TEST_PACKAGE, TEST_MAIN_CLASS); | ||
mockedFileTools | ||
.verify(() -> FileTools.generatePackageNameArray(anyString(), anyInt()), | ||
times(INSTRUMENTATION_VALUES_COUNT) | ||
); | ||
} | ||
} | ||
|
||
@Test | ||
void testFileValues_AspectJMode() { | ||
try (MockedStatic<FileTools> mockedFileTools = mockStatic(FileTools.class)) { | ||
mockedFileTools | ||
.when(() -> FileTools.generatePackageNameArray(anyString(), anyInt())) | ||
.thenReturn(EXPECTED_ARRAY); | ||
aspectjMode.fileValues(TEST_PACKAGE, TEST_MAIN_CLASS); | ||
mockedFileTools | ||
.verify(() -> FileTools.generatePackageNameArray(anyString(), anyInt()), | ||
times(ASPECTJ_VALUES_COUNT) | ||
); | ||
} | ||
} | ||
|
||
@Test | ||
void testReset() { | ||
try { | ||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); | ||
Class<?> settingsClass = Class.forName("de.tum.cit.ase.ares.api.aop.java.JavaSecurityTestCaseSettings", true, classLoader); | ||
Method resetMethod = settingsClass.getDeclaredMethod("reset"); | ||
resetMethod.setAccessible(true); | ||
resetMethod.invoke(null); | ||
} catch (Exception e) { | ||
fail("Exception should not have been thrown: " + e.getMessage()); | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseSettingsTest.java
This file contains 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,65 @@ | ||
package de.tum.cit.ase.ares.api.aop; | ||
|
||
import de.tum.cit.ase.ares.api.aop.java.JavaSecurityTestCaseSettings; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.lang.reflect.Constructor; | ||
import java.lang.reflect.Field; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
class JavaSecurityTestCaseSettingsTest { | ||
|
||
@Test | ||
void testConstructorThrowsException() { | ||
try { | ||
Constructor<JavaSecurityTestCaseSettings> constructor = JavaSecurityTestCaseSettings.class.getDeclaredConstructor(); | ||
constructor.setAccessible(true); | ||
constructor.newInstance(); | ||
fail("Expected SecurityException to be thrown"); | ||
} catch (InvocationTargetException e) { | ||
assertInstanceOf(SecurityException.class, e.getCause()); | ||
assertEquals("Ares Security Error (Reason: Ares-Code; Stage: Creation): JavaSecurityTestCaseSettings is a utility class and should not be instantiated.", e.getCause().getMessage()); | ||
} catch (Exception e) { | ||
fail("Unexpected exception: " + e); | ||
} | ||
} | ||
|
||
@Test | ||
void testResetMethod() { | ||
try { | ||
Field aopModeField = JavaSecurityTestCaseSettings.class.getDeclaredField("aopMode"); | ||
Field allowedListedClassesField = JavaSecurityTestCaseSettings.class.getDeclaredField("allowedListedClasses"); | ||
Field portsAllowedToBeConnectedToField = JavaSecurityTestCaseSettings.class.getDeclaredField("portsAllowedToBeConnectedTo"); | ||
|
||
aopModeField.setAccessible(true); | ||
allowedListedClassesField.setAccessible(true); | ||
portsAllowedToBeConnectedToField.setAccessible(true); | ||
|
||
aopModeField.set(null, "test"); | ||
allowedListedClassesField.set(null, new String[]{"testClass"}); | ||
portsAllowedToBeConnectedToField.set(null, new int[]{8080}); | ||
|
||
Method resetMethod = JavaSecurityTestCaseSettings.class.getDeclaredMethod("reset"); | ||
resetMethod.setAccessible(true); | ||
resetMethod.invoke(null); | ||
|
||
assertNull(aopModeField.get(null)); | ||
assertNull(allowedListedClassesField.get(null)); | ||
assertNull(portsAllowedToBeConnectedToField.get(null)); | ||
|
||
Field pathsAllowedToBeReadField = JavaSecurityTestCaseSettings.class.getDeclaredField("pathsAllowedToBeRead"); | ||
pathsAllowedToBeReadField.setAccessible(true); | ||
assertNull(pathsAllowedToBeReadField.get(null)); | ||
|
||
Field pathsAllowedToBeOverwrittenField = JavaSecurityTestCaseSettings.class.getDeclaredField("pathsAllowedToBeOverwritten"); | ||
pathsAllowedToBeOverwrittenField.setAccessible(true); | ||
assertNull(pathsAllowedToBeOverwrittenField.get(null)); | ||
|
||
} catch (Exception e) { | ||
fail("Unexpected exception: " + e); | ||
} | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseTest.java
This file contains 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,80 @@ | ||
package de.tum.cit.ase.ares.api.aop; | ||
|
||
import de.tum.cit.ase.ares.api.aop.java.JavaSecurityTestCase; | ||
import de.tum.cit.ase.ares.api.aop.java.JavaSecurityTestCaseSupported; | ||
import de.tum.cit.ase.ares.api.policy.SecurityPolicy.ResourceAccesses; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.MockedStatic; | ||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.util.List; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
class JavaSecurityTestCaseTest { | ||
|
||
private JavaSecurityTestCase javaSecurityTestCase; | ||
private ResourceAccesses resourceAccesses; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
JavaSecurityTestCaseSupported supported = JavaSecurityTestCaseSupported.FILESYSTEM_INTERACTION; | ||
resourceAccesses = mock(ResourceAccesses.class); | ||
javaSecurityTestCase = new JavaSecurityTestCase(supported, resourceAccesses); | ||
} | ||
|
||
@Test | ||
void testWriteAOPSecurityTestCase() { | ||
String result = javaSecurityTestCase.writeAOPSecurityTestCase("INSTRUMENTATION"); | ||
assertEquals("", result); | ||
} | ||
|
||
@Test | ||
void testWriteAOPSecurityTestCaseFile() { | ||
List<String> allowedListedClasses = List.of("TestClass"); | ||
List<JavaSecurityTestCase> javaSecurityTestCases = List.of(javaSecurityTestCase); | ||
|
||
String result = JavaSecurityTestCase.writeAOPSecurityTestCaseFile( | ||
"INSTRUMENTATION", | ||
"de.tum.cit", | ||
allowedListedClasses, | ||
javaSecurityTestCases | ||
); | ||
|
||
assertTrue(result.contains("private static String aopMode")); | ||
assertTrue(result.contains("private static String restrictedPackage")); | ||
assertTrue(result.contains("private static String[] allowedListedClasses")); | ||
} | ||
|
||
@Test | ||
void testExecuteAOPSecurityTestCase() { | ||
try (MockedStatic<JavaSecurityTestCase> mockedStatic = mockStatic(JavaSecurityTestCase.class)) { | ||
javaSecurityTestCase.executeAOPSecurityTestCase("INSTRUMENTATION"); | ||
mockedStatic.verify(() -> JavaSecurityTestCase.setJavaAdviceSettingValue(anyString(), any(), eq("INSTRUMENTATION")), atLeastOnce()); | ||
} | ||
} | ||
|
||
@Test | ||
void testGetPermittedFilePaths() throws Exception { | ||
Method method = JavaSecurityTestCase.class.getDeclaredMethod("getPermittedFilePaths", String.class); | ||
method.setAccessible(true); | ||
List<String> filePaths = (List<String>) method.invoke(javaSecurityTestCase, "read"); | ||
assertEquals(filePaths.size(), 0); | ||
} | ||
|
||
@Test | ||
void testGenerateAdviceSettingValue() throws Exception { | ||
Method method = JavaSecurityTestCase.class.getDeclaredMethod("generateAdviceSettingValue", String.class, String.class, Object.class); | ||
method.setAccessible(true); | ||
String result = (String) method.invoke(null, "String", "testAdvice", "testValue"); | ||
assertEquals("private static String testAdvice = \"testValue\";\n", result); | ||
result = (String) method.invoke(null, "String[]", "testAdviceArray", List.of("value1", "value2")); | ||
assertEquals("private static String[] testAdviceArray = new String[] {\"value1\", \"value2\"};\n", result); | ||
InvocationTargetException thrown = assertThrows(InvocationTargetException.class, () -> { | ||
method.invoke(null, "UnknownType", "testAdvice", "value"); | ||
}); | ||
assertEquals(SecurityException.class, thrown.getCause().getClass()); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
...tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationAdviceToolboxTest.java
This file contains 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,46 @@ | ||
package de.tum.cit.ase.ares.api.aop.instrumentation.advice; | ||
|
||
import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.MockedStatic; | ||
|
||
import java.lang.reflect.Method; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
class JavaInstrumentationAdviceToolboxTest { | ||
|
||
|
||
@Test | ||
void testCheckFileSystemInteraction_AllowedInteraction() { | ||
try (MockedStatic<JavaInstrumentationAdviceToolbox> mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) { | ||
Method getValueFromSettings = JavaInstrumentationAdviceToolbox.class.getDeclaredMethod("getValueFromSettings", String.class); | ||
getValueFromSettings.setAccessible(true); | ||
|
||
mockedToolbox.when(() -> getValueFromSettings.invoke(null, "aopMode")).thenReturn("INSTRUMENTATION"); | ||
mockedToolbox.when(() -> getValueFromSettings.invoke(null, "restrictedPackage")).thenReturn("de.tum.cit.ase"); | ||
mockedToolbox.when(() -> getValueFromSettings.invoke(null, "allowedListedClasses")).thenReturn(new String[]{"de.tum.cit.ase.safe"}); | ||
mockedToolbox.when(() -> getValueFromSettings.invoke(null, "pathsAllowedToBeRead")).thenReturn(new String[]{"/allowed/path"}); | ||
|
||
assertDoesNotThrow(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction( | ||
"read", | ||
"de.tum.cit.ase.safe.FileReader", | ||
"readFile", | ||
"(Ljava/lang/String;)V", | ||
null, | ||
new Object[]{"/allowed/path"} | ||
)); | ||
} catch (Exception e) { | ||
fail("Exception should not have been thrown: " + e.getMessage()); | ||
} | ||
} | ||
|
||
@Test | ||
void testLocalizeFallback() { | ||
String key = "security.advice.test.key"; | ||
String result = JavaInstrumentationAdviceToolbox.localize(key, "arg1", "arg2"); | ||
key = "!security.advice.test.key!"; | ||
assertEquals(key, result); | ||
} | ||
} |
Oops, something went wrong.