diff --git a/pom.xml b/pom.xml
index b384ead7..224a62bc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,12 @@
junit-platform-launcher
${junit-platform-version}
+
+ org.mockito
+ mockito-inline
+ 5.2.0
+ test
+
ch.qos.logback
diff --git a/src/main/java/de/tum/cit/ase/ares/api/architecture/java/FileHandlerConstants.java b/src/main/java/de/tum/cit/ase/ares/api/architecture/java/FileHandlerConstants.java
index ddc9776e..c33a667d 100644
--- a/src/main/java/de/tum/cit/ase/ares/api/architecture/java/FileHandlerConstants.java
+++ b/src/main/java/de/tum/cit/ase/ares/api/architecture/java/FileHandlerConstants.java
@@ -21,6 +21,7 @@ public class FileHandlerConstants {
public static final Path ARCHUNIT_COMMAND_EXECUTION_METHODS = FileTools.resolveOnResources("templates", "architecture" , "java", "archunit", "methods", "command-execution-methods.txt");
public static final Path ARCHUNIT_THREAD_MANIPULATION_METHODS = FileTools.resolveOnResources("templates", "architecture" , "java", "archunit", "methods", "thread-manipulation-methods.txt");
public static final Path ARCHUNIT_SERIALIZATION_METHODS = FileTools.resolveOnResources("templates", "architecture" , "java", "archunit", "methods", "serializable-methods.txt");
+ public static final Path ARCHUNIT_CLASSLOADER_METHODS = FileTools.resolveOnResources("templates", "architecture" , "java", "archunit", "methods", "classloader-methods.txt");
//
//
diff --git a/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitSecurityTestCase.java b/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitSecurityTestCase.java
index 4950e19c..0895fb98 100644
--- a/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitSecurityTestCase.java
+++ b/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitSecurityTestCase.java
@@ -1,7 +1,6 @@
package de.tum.cit.ase.ares.api.architecture.java.archunit;
//
-
import com.tngtech.archunit.core.domain.JavaClasses;
import de.tum.cit.ase.ares.api.architecture.java.JavaArchitecturalTestCaseSupported;
import de.tum.cit.ase.ares.api.policy.SecurityPolicy.PackagePermission;
@@ -51,7 +50,6 @@ private JavaArchUnitSecurityTestCase(@Nonnull Builder builder) {
this.javaArchitectureTestCaseSupported = builder.javaArchitectureTestCaseSupported;
this.allowedPackages = builder.allowedPackages;
}
-
//
//
diff --git a/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitTestCaseCollection.java b/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitTestCaseCollection.java
index 7b681d9a..7d331ab1 100644
--- a/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitTestCaseCollection.java
+++ b/src/main/java/de/tum/cit/ase/ares/api/architecture/java/archunit/JavaArchUnitTestCaseCollection.java
@@ -158,4 +158,11 @@ public boolean test(JavaClass javaClass) {
FileHandlerConstants.ARCHUNIT_SERIALIZATION_METHODS
);
//
+
+ //
+ public static final ArchRule NO_CLASSES_SHOULD_USE_CLASSLOADERS = createNoClassShouldHaveMethodRule(
+ "uses ClassLoaders",
+ FileHandlerConstants.ARCHUNIT_CLASSLOADER_METHODS
+ );
+ //
}
\ No newline at end of file
diff --git a/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/classloader-methods.txt b/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/classloader-methods.txt
new file mode 100644
index 00000000..4407c211
--- /dev/null
+++ b/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/classloader-methods.txt
@@ -0,0 +1 @@
+java.lang.ClassLoader
\ No newline at end of file
diff --git a/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/reflection-methods.txt b/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/reflection-methods.txt
index 2cbb0495..1be946ce 100644
--- a/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/reflection-methods.txt
+++ b/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/reflection-methods.txt
@@ -74,6 +74,7 @@ java.lang.Class.getDeclaringClass()
java.lang.ClassLoader.getParent()
java.lang.ClassLoader.getSystemClassLoader()
java.lang.ClassLoader.getPlatformClassLoader()
+java.lang.ClassLoader
java.lang.Module.addReads(java.lang.Module)
java.lang.Module.getResourceAsStream(java.lang.String)
java.lang.Module.addExports(java.lang.String, java.lang.Module)
diff --git a/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/thread-manipulation-methods.txt b/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/thread-manipulation-methods.txt
index f0d9c7a4..776cf9bc 100644
--- a/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/thread-manipulation-methods.txt
+++ b/src/main/resources/de/tum/cit/ase/ares/api/templates/architecture/java/archunit/methods/thread-manipulation-methods.txt
@@ -149,6 +149,7 @@ java.util.concurrent.DelayQueue.take()
java.util.concurrent.ExecutorService.close()
java.util.concurrent.ForkJoinPool.managedBlock(java.util.concurrent.ForkJoinPool$ManagedBlocker)
java.util.concurrent.ForkJoinPool.close()
+java.util.concurrent.ForkJoinPool
java.util.concurrent.ForkJoinTask.inForkJoinPool()
java.util.concurrent.ForkJoinTask.fork()
java.util.concurrent.ForkJoinTask.getPool()
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/JavaAOPModeTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/JavaAOPModeTest.java
new file mode 100644
index 00000000..5a71d37d
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/JavaAOPModeTest.java
@@ -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 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 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 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 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());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseSettingsTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseSettingsTest.java
new file mode 100644
index 00000000..9a35c700
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseSettingsTest.java
@@ -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 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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseTest.java
new file mode 100644
index 00000000..9474cbda
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/JavaSecurityTestCaseTest.java
@@ -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 allowedListedClasses = List.of("TestClass");
+ List 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 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 filePaths = (List) 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());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationAdviceToolboxTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationAdviceToolboxTest.java
new file mode 100644
index 00000000..2cd54466
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationAdviceToolboxTest.java
@@ -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 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);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationDeletePathConstructorAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationDeletePathConstructorAdviceTest.java
new file mode 100644
index 00000000..c32d3520
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationDeletePathConstructorAdviceTest.java
@@ -0,0 +1,49 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationDeletePathConstructorAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationDeletePathConstructorAdviceTest {
+
+ private static final String OPERATION = "delete";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationDeletePathConstructorAdvice";
+ private static final String METHOD_NAME = "";
+ private static final String METHOD_SIGNATURE = "";
+ private static final Object[] ATTRIBUTES = new Object[0];
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+
+ @Test
+ void testOnEnterVerifiesFileSystemInteractionForDelete() {
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationDeletePathConstructorAdvice.onEnter(
+ CLASS_NAME,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationDeletePathMethodAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationDeletePathMethodAdviceTest.java
new file mode 100644
index 00000000..f67a3feb
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationDeletePathMethodAdviceTest.java
@@ -0,0 +1,56 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationDeletePathMethodAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationDeletePathMethodAdviceTest {
+
+ private static final String OPERATION = "delete";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationDeletePathMethodAdvice";
+ private static final String METHOD_NAME = "methodName";
+ private static final String METHOD_SIGNATURE = "methodSignature";
+ private static final Object[] ATTRIBUTES = new Object[]{"attrib1", "attrib2"};
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+ private static final Object INSTANCE = new Object() {
+ public final String attrib1 = "attrib1";
+ public final String attrib2 = "attrib2";
+ };
+
+ @Test
+ void shouldCheckFileSystemInteraction_whenDeletingPath() {
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationDeletePathMethodAdvice.onEnter(
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ INSTANCE,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationExecutePathConstructorAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationExecutePathConstructorAdviceTest.java
new file mode 100644
index 00000000..5e3bd230
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationExecutePathConstructorAdviceTest.java
@@ -0,0 +1,49 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationExecutePathConstructorAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationExecutePathConstructorAdviceTest {
+
+ private static final String OPERATION = "execute";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationExecutePathConstructorAdvice";
+ private static final String METHOD_NAME = "";
+ private static final String METHOD_SIGNATURE = "";
+ private static final Object[] ATTRIBUTES = new Object[0];
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+
+ @Test
+ void testOnEnter() {
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationExecutePathConstructorAdvice.onEnter(
+ CLASS_NAME,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationExecutePathMethodAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationExecutePathMethodAdviceTest.java
new file mode 100644
index 00000000..c2f321ca
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationExecutePathMethodAdviceTest.java
@@ -0,0 +1,59 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationExecutePathMethodAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.lang.reflect.Field;
+
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationExecutePathMethodAdviceTest {
+
+ private static final String OPERATION = "execute";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationExecutePathMethodAdvice";
+ private static final String METHOD_NAME = "methodName";
+ private static final String METHOD_SIGNATURE = "methodSignature";
+ private static final Object[] ATTRIBUTES = new Object[]{"attrib1", "attrib2"};
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+ private static final Object INSTANCE = new Object() {
+ public final String attrib1 = "attrib1";
+ public final String attrib2 = "attrib2";
+ };
+
+ @Test
+ void testOnEnter() throws IllegalAccessException {
+
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationExecutePathMethodAdvice.onEnter(
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ INSTANCE,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationOverwritePathConstructorAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationOverwritePathConstructorAdviceTest.java
new file mode 100644
index 00000000..55028c18
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationOverwritePathConstructorAdviceTest.java
@@ -0,0 +1,49 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationOverwritePathConstructorAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationOverwritePathConstructorAdviceTest {
+
+ private static final String OPERATION = "overwrite";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationOverwritePathConstructorAdvice";
+ private static final String METHOD_NAME = "";
+ private static final String METHOD_SIGNATURE = "";
+ private static final Object[] ATTRIBUTES = new Object[0];
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+
+ @Test
+ void testOnEnter() {
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationOverwritePathConstructorAdvice.onEnter(
+ CLASS_NAME,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationOverwritePathMethodAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationOverwritePathMethodAdviceTest.java
new file mode 100644
index 00000000..e4834e10
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationOverwritePathMethodAdviceTest.java
@@ -0,0 +1,60 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationOverwritePathMethodAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.lang.reflect.Field;
+
+import static org.mockito.AdditionalMatchers.aryEq;
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationOverwritePathMethodAdviceTest {
+
+ private static final String OPERATION = "overwrite";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationOverwritePathMethodAdvice";
+ private static final String METHOD_NAME = "methodName";
+ private static final String METHOD_SIGNATURE = "methodSignature";
+ private static final Object[] ATTRIBUTES = new Object[]{"attrib1", "attrib2"};
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+ private static final Object INSTANCE = new Object() {
+ public final String attrib1 = "attrib1";
+ public final String attrib2 = "attrib2";
+ };
+
+ @Test
+ void testOnEnter() throws Exception {
+
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationOverwritePathMethodAdvice.onEnter(
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ INSTANCE,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationReadPathConstructorAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationReadPathConstructorAdviceTest.java
new file mode 100644
index 00000000..dfb6f052
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationReadPathConstructorAdviceTest.java
@@ -0,0 +1,50 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationReadPathConstructorAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import static org.mockito.AdditionalMatchers.aryEq;
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationReadPathConstructorAdviceTest {
+
+ private static final String OPERATION = "read";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationReadPathConstructorAdvice";
+ private static final String METHOD_NAME = "";
+ private static final String METHOD_SIGNATURE = "";
+ private static final Object[] ATTRIBUTES = new Object[0];
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+
+ @Test
+ void testOnEnter() {
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationReadPathConstructorAdvice.onEnter(
+ CLASS_NAME,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
diff --git a/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationReadPathMethodAdviceTest.java b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationReadPathMethodAdviceTest.java
new file mode 100644
index 00000000..24cbaf68
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/aop/instrumentation/advice/JavaInstrumentationReadPathMethodAdviceTest.java
@@ -0,0 +1,60 @@
+package de.tum.cit.ase.ares.api.aop.instrumentation.advice;
+
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationAdviceToolbox;
+import de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationReadPathMethodAdvice;
+import org.junit.jupiter.api.Test;
+import org.mockito.MockedStatic;
+
+import java.lang.reflect.Field;
+
+import static org.mockito.AdditionalMatchers.aryEq;
+import static org.mockito.Mockito.*;
+
+class JavaInstrumentationReadPathMethodAdviceTest {
+
+ private static final String OPERATION = "read";
+ private static final String CLASS_NAME = "de.tum.cit.ase.ares.api.aop.java.instrumentation.advice.JavaInstrumentationReadPathMethodAdvice";
+ private static final String METHOD_NAME = "methodName";
+ private static final String METHOD_SIGNATURE = "methodSignature";
+ private static final Object[] ATTRIBUTES = new Object[]{"attrib1", "attrib2"};
+ private static final Object[] PARAMETERS = new Object[]{"param1", "param2"};
+ private static final Object INSTANCE = new Object() {
+ public final String attrib1 = "attrib1";
+ public final String attrib2 = "attrib2";
+ };
+
+ @Test
+ void testOnEnter() throws Exception {
+
+ try (MockedStatic mockedToolbox = mockStatic(JavaInstrumentationAdviceToolbox.class)) {
+ // Arrange
+ mockedToolbox.when(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ )).thenAnswer(invocation -> null);
+
+ // Act
+ JavaInstrumentationReadPathMethodAdvice.onEnter(
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ INSTANCE,
+ PARAMETERS
+ );
+
+ // Assert
+ mockedToolbox.verify(() -> JavaInstrumentationAdviceToolbox.checkFileSystemInteraction(
+ OPERATION,
+ CLASS_NAME,
+ METHOD_NAME,
+ METHOD_SIGNATURE,
+ ATTRIBUTES,
+ PARAMETERS
+ ));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/tum/cit/ase/ares/api/architecture/JavaArchUnitSecurityTestCaseTest.java b/src/test/java/de/tum/cit/ase/ares/api/architecture/JavaArchUnitSecurityTestCaseTest.java
new file mode 100644
index 00000000..68e85e30
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/architecture/JavaArchUnitSecurityTestCaseTest.java
@@ -0,0 +1,101 @@
+package de.tum.cit.ase.ares.api.architecture;
+
+import com.tngtech.archunit.core.domain.JavaClasses;
+import com.tngtech.archunit.core.importer.ClassFileImporter;
+import de.tum.cit.ase.ares.api.architecture.java.archunit.JavaArchUnitSecurityTestCase;
+import de.tum.cit.ase.ares.api.architecture.java.JavaArchitecturalTestCaseSupported;
+import de.tum.cit.ase.ares.api.policy.SecurityPolicy.PackagePermission;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class JavaArchUnitSecurityTestCaseTest {
+
+ private JavaArchUnitSecurityTestCase testCase;
+ private JavaClasses classes;
+
+ @BeforeEach
+ void setUp() {
+ classes = new ClassFileImporter().importPackages("com.example");
+ }
+
+ @Test
+ void testConstructorWithSingleParameter() {
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.FILESYSTEM_INTERACTION)
+ .build();
+ assertNotNull(testCase);
+ }
+
+ @Test
+ void testConstructorWithTwoParameters() {
+ Set packagePermissions = Set.of(new PackagePermission("com.example"));
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.PACKAGE_IMPORT)
+ .allowedPackages(packagePermissions)
+ .build();
+ assertNotNull(testCase);
+ }
+
+ @Test
+ void testWriteArchitectureTestCase() {
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.FILESYSTEM_INTERACTION)
+ .build();
+ String content = testCase.writeArchitectureTestCase();
+ assertNotNull(content);
+ }
+
+ @Test
+ void testExecuteArchitectureTestCaseFilesystemInteraction() {
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.FILESYSTEM_INTERACTION)
+ .build();
+ assertDoesNotThrow(() -> testCase.executeArchitectureTestCase(classes));
+ }
+
+ @Test
+ void testExecuteArchitectureTestCaseNetworkConnection() {
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.NETWORK_CONNECTION)
+ .build();
+ assertDoesNotThrow(() -> testCase.executeArchitectureTestCase(classes));
+ }
+
+ @Test
+ void testExecuteArchitectureTestCaseThreadCreation() {
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.THREAD_CREATION)
+ .build();
+ assertDoesNotThrow(() -> testCase.executeArchitectureTestCase(classes));
+ }
+
+ @Test
+ void testExecuteArchitectureTestCaseCommandExecution() {
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.COMMAND_EXECUTION)
+ .build();
+ assertDoesNotThrow(() -> testCase.executeArchitectureTestCase(classes));
+ }
+
+ @Test
+ void testExecuteArchitectureTestCasePackageImport() {
+ Set packagePermissions = Set.of(new PackagePermission("com.example"));
+ testCase = JavaArchUnitSecurityTestCase
+ .builder()
+ .javaArchitecturalTestCaseSupported(JavaArchitecturalTestCaseSupported.PACKAGE_IMPORT)
+ .allowedPackages(packagePermissions)
+ .build();
+ assertDoesNotThrow(() -> testCase.executeArchitectureTestCase(classes));
+ }
+}
diff --git a/src/test/java/de/tum/cit/ase/ares/api/architecture/JavaArchUnitTestCaseSupportedTest.java b/src/test/java/de/tum/cit/ase/ares/api/architecture/JavaArchUnitTestCaseSupportedTest.java
new file mode 100644
index 00000000..1e851b45
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/architecture/JavaArchUnitTestCaseSupportedTest.java
@@ -0,0 +1,42 @@
+package de.tum.cit.ase.ares.api.architecture;
+
+import de.tum.cit.ase.ares.api.architecture.java.JavaArchitecturalTestCaseSupported;
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+
+class JavaArchUnitTestCaseSupportedTest {
+
+ @Test
+ void testEnumValues() {
+ JavaArchitecturalTestCaseSupported[] values = JavaArchitecturalTestCaseSupported.values();
+ assertEquals(9, values.length);
+ assertEquals(JavaArchitecturalTestCaseSupported.FILESYSTEM_INTERACTION, values[0]);
+ assertEquals(JavaArchitecturalTestCaseSupported.NETWORK_CONNECTION, values[1]);
+ assertEquals(JavaArchitecturalTestCaseSupported.COMMAND_EXECUTION, values[2]);
+ assertEquals(JavaArchitecturalTestCaseSupported.THREAD_CREATION, values[3]);
+ assertEquals(JavaArchitecturalTestCaseSupported.PACKAGE_IMPORT, values[4]);
+ assertEquals(JavaArchitecturalTestCaseSupported.TERMINATE_JVM, values[5]);
+ assertEquals(JavaArchitecturalTestCaseSupported.REFLECTION, values[6]);
+ assertEquals(JavaArchitecturalTestCaseSupported.SERIALIZATION, values[7]);
+ assertEquals(JavaArchitecturalTestCaseSupported.CLASS_LOADING, values[8]);
+ }
+
+ @Test
+ void testEnumValueOf() {
+ assertEquals(JavaArchitecturalTestCaseSupported.FILESYSTEM_INTERACTION, JavaArchitecturalTestCaseSupported.valueOf("FILESYSTEM_INTERACTION"));
+ assertEquals(JavaArchitecturalTestCaseSupported.NETWORK_CONNECTION, JavaArchitecturalTestCaseSupported.valueOf("NETWORK_CONNECTION"));
+ assertEquals(JavaArchitecturalTestCaseSupported.COMMAND_EXECUTION, JavaArchitecturalTestCaseSupported.valueOf("COMMAND_EXECUTION"));
+ assertEquals(JavaArchitecturalTestCaseSupported.THREAD_CREATION, JavaArchitecturalTestCaseSupported.valueOf("THREAD_CREATION"));
+ assertEquals(JavaArchitecturalTestCaseSupported.PACKAGE_IMPORT, JavaArchitecturalTestCaseSupported.valueOf("PACKAGE_IMPORT"));
+ assertEquals(JavaArchitecturalTestCaseSupported.TERMINATE_JVM, JavaArchitecturalTestCaseSupported.valueOf("TERMINATE_JVM"));
+ assertEquals(JavaArchitecturalTestCaseSupported.REFLECTION, JavaArchitecturalTestCaseSupported.valueOf("REFLECTION"));
+ assertEquals(JavaArchitecturalTestCaseSupported.SERIALIZATION, JavaArchitecturalTestCaseSupported.valueOf("SERIALIZATION"));
+ assertEquals(JavaArchitecturalTestCaseSupported.CLASS_LOADING, JavaArchitecturalTestCaseSupported.valueOf("CLASS_LOADING"));
+ }
+
+ @Test
+ void testEnumValueOfInvalid() {
+ assertThrows(IllegalArgumentException.class,
+ () -> JavaArchitecturalTestCaseSupported.valueOf("INVALID_VALUE"));
+ }
+}
diff --git a/src/test/java/de/tum/cit/ase/ares/api/architecture/com/example/EmptyClass.java b/src/test/java/de/tum/cit/ase/ares/api/architecture/com/example/EmptyClass.java
new file mode 100644
index 00000000..820822eb
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/architecture/com/example/EmptyClass.java
@@ -0,0 +1,4 @@
+package de.tum.cit.ase.ares.api.architecture.com.example;
+
+public class EmptyClass {
+}
diff --git a/src/test/java/de/tum/cit/ase/ares/api/architecture/com/example/ExampleClass.java b/src/test/java/de/tum/cit/ase/ares/api/architecture/com/example/ExampleClass.java
new file mode 100644
index 00000000..d8c2a15c
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/api/architecture/com/example/ExampleClass.java
@@ -0,0 +1,10 @@
+package de.tum.cit.ase.ares.api.architecture.com.example;
+
+import de.tum.cit.ase.ares.integration.testuser.subject.SecurityPenguin;
+
+public class ExampleClass {
+
+ void someMethod() {
+ SecurityPenguin.trySetSystemOut();
+ }
+}
diff --git a/src/test/java/de/tum/cit/ase/ares/integration/ArchitectureSecurityTest.java b/src/test/java/de/tum/cit/ase/ares/integration/ArchitectureSecurityTest.java
index 1ac45de8..e0af1b8c 100644
--- a/src/test/java/de/tum/cit/ase/ares/integration/ArchitectureSecurityTest.java
+++ b/src/test/java/de/tum/cit/ase/ares/integration/ArchitectureSecurityTest.java
@@ -62,12 +62,6 @@ void testArchUnitThreadCreation() {
tests.assertThatEvents().haveExactly(1,
testFailedWith("testArchUnitThreadCreation", SecurityException.class));
}
-
- @TestTest
- void testWalaThreadCreation() {
- tests.assertThatEvents().haveExactly(1,
- testFailedWith("testWaLaThreadCreation", SecurityException.class));
- }
//
//
diff --git a/src/test/java/de/tum/cit/ase/ares/integration/FileSystemAccessTest.java b/src/test/java/de/tum/cit/ase/ares/integration/FileSystemAccessTest.java
index add760f0..442426c6 100644
--- a/src/test/java/de/tum/cit/ase/ares/integration/FileSystemAccessTest.java
+++ b/src/test/java/de/tum/cit/ase/ares/integration/FileSystemAccessTest.java
@@ -116,11 +116,6 @@ void test_accessPathTest() {
// void test_weAccessPath() {
// tests.assertThatEvents().haveExactly(1, finishedSuccessfully(weAccessPath));
// }
-
- @TestTest
- void test_accessFileSystem() {
- tests.assertThatEvents().haveExactly(1, testFailedWith("accessFileSystem", SecurityException.class));
- }
//
//TODO Markus: Look into why we are catching Runtime Exceptions and not Security Exceptions
diff --git a/src/test/java/de/tum/cit/ase/ares/integration/testuser/ThreadUser.java b/src/test/java/de/tum/cit/ase/ares/integration/testuser/ThreadUser.java
index 8d3d940a..1d11952c 100644
--- a/src/test/java/de/tum/cit/ase/ares/integration/testuser/ThreadUser.java
+++ b/src/test/java/de/tum/cit/ase/ares/integration/testuser/ThreadUser.java
@@ -1,7 +1,6 @@
package de.tum.cit.ase.ares.integration.testuser;
import static org.junit.Assert.assertEquals;
-import static org.junit.jupiter.api.Assertions.*;
import java.nio.file.Path;
import java.util.concurrent.*;
@@ -15,7 +14,10 @@
import de.tum.cit.ase.ares.api.jupiter.PublicTest;
import de.tum.cit.ase.ares.api.localization.UseLocale;
//REMOVED: Import of ArtemisSecurityManager
-import de.tum.cit.ase.ares.integration.testuser.subject.ThreadPenguin;
+import de.tum.cit.ase.ares.integration.testuser.subject.threads.ThreadPenguin;
+
+import static org.assertj.core.api.Fail.fail;
+import static org.junit.jupiter.api.Assertions.assertFalse;
@UseLocale("en")
@AllowThreads(maxActiveCount = 100)
@@ -27,6 +29,10 @@
@SuppressWarnings("static-method")
public class ThreadUser {
+ @PublicTest
+ @Policy(value = "src/test/resources/de/tum/cit/ase/ares/integration/testuser/securitypolicies/EverythingForbiddenPolicy.yaml", withinPath = "test-classes/de/tum/cit/ase/ares/integration/testuser/subject/threads")
+ void threadAccessTest() {}
+
@PublicTest
void commonPoolInterruptable() throws InterruptedException, ExecutionException {
// check functionality
diff --git a/src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/ThreadPenguin.java b/src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/threads/ThreadPenguin.java
similarity index 54%
rename from src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/ThreadPenguin.java
rename to src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/threads/ThreadPenguin.java
index 9c3ad579..9f8553c9 100644
--- a/src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/ThreadPenguin.java
+++ b/src/test/java/de/tum/cit/ase/ares/integration/testuser/subject/threads/ThreadPenguin.java
@@ -1,8 +1,9 @@
-package de.tum.cit.ase.ares.integration.testuser.subject;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+package de.tum.cit.ase.ares.integration.testuser.subject.threads;
import java.nio.file.Path;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
//REMOVED: Import of ArtemisSecurityManager
@@ -29,9 +30,7 @@ public static void tryStartTwoThreads() {
// ignore
}
});
- assertDoesNotThrow(() -> {
- t1.start();
- });
+ t1.start();
new Thread().start();
}
@@ -61,14 +60,47 @@ public static void spawnEndlessThreads() {
}
}
- public static void tryThreadWhitelisting() throws Throwable {
+ private static void verifyThreadWhitelisting(String message) throws Throwable {
AtomicReference failure = new AtomicReference<>();
- Thread t = new Thread(() -> Path.of("pom.xml").toFile().canWrite());
- //REMOVED: Thread-whitelisting-request to ArtemisSecurityManager
+ Thread t = new Thread(() -> failure.set(new SecurityException(message)));
t.setUncaughtExceptionHandler((t1, e) -> failure.set(e));
t.start();
t.join();
if (failure.get() != null)
throw failure.get();
}
+
+ public static void tryThreadWhitelisting() throws Throwable {
+ verifyThreadWhitelisting("Thread not whitelisted");
+ }
+
+ void threadWhitelistingWithPathFail() throws Throwable {
+ verifyThreadWhitelisting("Thread not whitelisted");
+ }
+
+ void commonPoolInterruptable() throws InterruptedException, ExecutionException {
+ // check functionality
+ var res = ForkJoinPool.commonPool().submit(() -> "A").get();
+ // submit long-running task
+ var task = ForkJoinPool.commonPool().submit(() -> {
+ ThreadPenguin.sleepInCurrentThread(5_000);
+ });
+ // check that the task is still running after 100 ms
+ try {
+ Thread.sleep(100);
+ } catch (@SuppressWarnings("unused") InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ // wait for task end
+ ForkJoinPool.commonPool().awaitQuiescence(5, TimeUnit.SECONDS);
+ }
+
+ public static void something() {
+ new ThreadPenguin().start();
+ }
+
+ @Override
+ public void start() {
+ super.start();
+ }
}
diff --git a/src/test/java/de/tum/cit/ase/ares/testutilities/CustomConditionEvents.java b/src/test/java/de/tum/cit/ase/ares/testutilities/CustomConditionEvents.java
new file mode 100644
index 00000000..fcd813f8
--- /dev/null
+++ b/src/test/java/de/tum/cit/ase/ares/testutilities/CustomConditionEvents.java
@@ -0,0 +1,50 @@
+package de.tum.cit.ase.ares.testutilities;
+
+import com.google.common.collect.ImmutableList;
+import com.tngtech.archunit.lang.ConditionEvent;
+import com.tngtech.archunit.lang.ConditionEvents;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Custom condition events used in ArchUnit tests
+ */
+public class CustomConditionEvents implements ConditionEvents {
+ private final List violations = new ArrayList<>();
+ private Optional informationAboutNumberOfViolations = Optional.empty();
+
+ @Override
+ public void add(ConditionEvent event) {
+ if (!event.isViolation()) {
+ violations.add(event);
+ }
+ }
+
+ @Override
+ public Optional getInformationAboutNumberOfViolations() {
+ return informationAboutNumberOfViolations;
+ }
+
+ @Override
+ public void setInformationAboutNumberOfViolations(String informationAboutNumberOfViolations) {
+ this.informationAboutNumberOfViolations = Optional.of(informationAboutNumberOfViolations);
+ }
+
+ @Override
+ public Collection getViolating() {
+ return ImmutableList.copyOf(violations);
+ }
+
+ @Override
+ public boolean containViolation() {
+ return !violations.isEmpty();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{" + violations + '}';
+ }
+}