Closed JanWittler closed 1 year ago
It seems that the issue is local to some test package. When running an entire suite, subsequent tests only fail for test cases within the same package of the problematic test. When entering another package later, tests succeed again.
The issue is caused by how Eclipse resolves pathmap
URIs. When the resource to which the pathmap points is not yet loaded in the local resource set, the URI is resolved by asking the URIMappingRegistryImpl.INSTANCE
. All paths to loaded resources are backed up there.
In my case the issue was caused because in the second test case I was loading a resource that referenced another resource. That referenced resource was not yet loaded in the second test thus there was no entry in the mapping registry with the correct path. However, in the first test a resource with the same name was loaded. Thus the mapping registry contained an entry with the path pointing to the test output of the first test which was then loaded in the second test and caused the crash.
For my test suite I was able to solve the test by manually loading the incorrectly resolved resource before loading the resource that has the reference. However, in general there should never be a dependency on the order in which tests are executed. I am not completely sure whether the resolving error is an issue of Eclipse or rather JaMoPP (as this is known to have loading issues Vitruv-Domains#97).
Thus the mapping registry contained an entry with the path pointing to the test output of the first test
In other places of Vitruv, we assume that pathmap
resources are effectively read-only. What kind of reference was using a pathmap
URI to reference a not read-only resource?
You get that behaviour by loading a Java class that references another custom Java class (i.e. as a field type or method argument type). When loading such a class, JaMoPP uses pathmap
to reference those classes.
Thus the mapping registry contained an entry with the path pointing to the test output of the first test
To be more precise: it contained an entry pointing to the Java class file at [test_dir]/src/...
Since JaMoPP caches classes and thus may resolve classes created in other tests, we usually reset the classpath for each test case (see, for example, the Java to PCM tests. Potentially, it would be more reasonable to cleanup after the test rather than before, but the effect should be the same. Can you try whether that cleanup resolves the issue in your tests?
Thanks for the hint. However, the linked code does not change the behaviour since the problem is not the JaMoPP cache but the URIMappingRegistryImpl.INSTANCE
cache.
I actually expected every registry caching some of the JaMoPP classpath elements to be cleaned up when resetting the classpath, but that does not seem to be the case :-/
Would it be possible to cleanup the URIMappingRegistryImpl.INSTANCE
cache by hand as well?
I did not know about that behavior, which also seems to restrict the productive usability of JaMoPP, because having multiple projects with the same classes in the same packages would be problematic.
I tried completely resetting the URIMappingRegistryImpl.INSTANCE
but this resulted in a failure since no pathmaps at all could be resolved anymore. We could try to create some filter to only reset pathmaps created by the test case but I assume this to be very error-prone.
The pathmap resolving is based on some delegation mechanism, i.e. if the current resolver does not know the pathmap, the parent is asked until eventually the root, which is the URIMappingRegistryImpl.INSTANCE
, is asked. I guess it was possible to insert some custom resolver in that chain which gets reset after each test run. However, I did not test this.
I am currently experiencing test failures depending on the order in which I execute tests. In particular, if a certain test is executed, all tests after it are failing. If those tests are executed independently, they succeed. It seems that the
ResourceRepository
is not correctly cleaned up. Attached you can see the stack trace. The critical test propagates changes whereInterface.java
is created. This class is not present in the other tests, however the test fails because of a pathmap to it thus it must be an artifact of the previous test. The correct behaviour should be that the entire VSUM state is reset before a new test is executed.Stacktrace
java.lang.IllegalStateException: Could not delete URI pathmap:/javaclass/basic.config.Interface.java at tools.vitruv.framework.vsum.ModelInstance.delete(ModelInstance.java:106) at tools.vitruv.framework.vsum.repositories.ResourceRepositoryImpl.saveOrDeleteModels(ResourceRepositoryImpl.java:160) at tools.vitruv.framework.vsum.VirtualModelImpl.save(VirtualModelImpl.java:86) at tools.vitruv.framework.vsum.VirtualModelImpl.propagateChange(VirtualModelImpl.java:98) at tools.vitruv.testutils.ChangePublishingTestView.lambda$0(ChangePublishingTestView.java:89) at tools.vitruv.testutils.ChangePublishingTestView.lambda$5(ChangePublishingTestView.java:156) at edu.kit.ipd.sdq.commons.util.java.lang.IterableUtil.flatMapFixedTo(IterableUtil.java:60) at edu.kit.ipd.sdq.commons.util.java.lang.IterableUtil.flatMapFixed(IterableUtil.java:55) at tools.vitruv.testutils.ChangePublishingTestView.propagateChanges(ChangePublishingTestView.java:158) at tools.vitruv.testutils.ChangePublishingTestView.propagate(ChangePublishingTestView.java:121) at tools.vitruv.testutils.VitruvApplicationTest.propagate(VitruvApplicationTest.java:132) at tools.vitruv.applications.external.umljava.tests.uml2java.advancedsuite.AdvancedSuiteTest.enrichJavaModel(AdvancedSuiteTest.java:144) at tools.vitruv.applications.external.umljava.tests.uml2java.Uml2JavaStateBasedChangeTest.preloadModel(Uml2JavaStateBasedChangeTest.java:51) at tools.vitruv.applications.external.umljava.tests.uml2java.advancedsuite.AdvancedSuiteTest.preloadModel(AdvancedSuiteTest.java:49) at tools.vitruv.applications.external.umljava.tests.uml2java.StateBasedChangeTest.setup(StateBasedChangeTest.java:98) at tools.vitruv.applications.external.umljava.tests.uml2java.StateBasedChangeDifferencesTest.setup(StateBasedChangeDifferencesTest.java:46) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeEachMethod(TimeoutExtension.java:76) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeMethodInExtensionContext(ClassBasedTestDescriptor.java:490) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$synthesizeBeforeEachMethodAdapter$19(ClassBasedTestDescriptor.java:475) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeEachMethods$2(TestMethodTestDescriptor.java:167) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeBeforeMethodsOrCallbacksUntilExceptionOccurs$5(TestMethodTestDescriptor.java:195) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeMethodsOrCallbacksUntilExceptionOccurs(TestMethodTestDescriptor.java:195) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeBeforeEachMethods(TestMethodTestDescriptor.java:164) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84) at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464) at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:117) at org.eclipse.pde.internal.junit.runtime.PlatformUITestHarness.lambda$0(PlatformUITestHarness.java:45) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:185) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4181) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3841) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1157) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1046) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152) at org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.runApp(NonUIThreadTestApplication.java:53) at org.eclipse.pde.internal.junit.runtime.UITestApplication.runApp(UITestApplication.java:47) at org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.start(NonUIThreadTestApplication.java:48) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) at org.eclipse.equinox.launcher.Main.run(Main.java:1461) at org.eclipse.equinox.launcher.Main.main(Main.java:1434) Caused by: java.net.MalformedURLException: unknown protocol: pathmap at java.base/java.net.URL.