Skip to content
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

Fix: API tool reports fictitious changes to execution environment #1302

Merged
merged 1 commit into from
Jul 7, 2024

Conversation

ptziegler
Copy link
Contributor

@ptziegler ptziegler commented Jun 14, 2024

The API tool only checks the Bundle-RequiredExecutionEnvironment header when comparing the baseline with the workspace bundle. If the EE of the baseline bundle is described via the Require-Capability header, an empty string is compared to the workspace EE, which is treated as an incompatibility.

This also adds a simple test case where the execution environment of two bundles is checked. One bundle uses the Require-Capability, the other one the Bundle-RequiredExecutionEnvironment header.

Resolves #1301

@ptziegler
Copy link
Contributor Author

ptziegler commented Jun 14, 2024

Argh... this test setup is way too confusing.

The new bundle doesn't seem to be registered properly, though the issue still shows up when changing the manifest file of "bundle.a".

@ptziegler
Copy link
Contributor Author

There we go... the expected error is now:

Unable to find BREE for bundle using 'Require-Capability': array lengths differed, expected.length=1 actual.length=0; arrays first differed at element [0]; expected:<JavaSE-17> but was:<end of array>
	at org.junit.internal.ComparisonCriteria.arrayEquals(ComparisonCriteria.java:89)
	at org.junit.internal.ComparisonCriteria.arrayEquals(ComparisonCriteria.java:28)
	at org.junit.Assert.internalArrayEquals(Assert.java:534)
	at org.junit.Assert.assertArrayEquals(Assert.java:285)
	at org.eclipse.pde.api.tools.builder.tests.compatibility.ProjectTypeContainerTests.testExecutionEnvironment(ProjectTypeContainerTests.java:170)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at junit.framework.TestCase.runTest(TestCase.java:177)
	at org.eclipse.jdt.core.tests.junit.extension.TestCase.runTest(TestCase.java:972)
	at junit.framework.TestCase.runBare(TestCase.java:142)
	at junit.framework.TestResult$1.protect(TestResult.java:122)
	at junit.framework.TestResult.runProtected(TestResult.java:142)
	at junit.framework.TestResult.run(TestResult.java:125)
	at junit.framework.TestCase.run(TestCase.java:130)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:757)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
	at org.eclipse.pde.internal.junit.runtime.RemotePluginTestRunner.main(RemotePluginTestRunner.java:83)
	at org.eclipse.pde.internal.junit.runtime.PlatformUITestHarness.lambda$0(PlatformUITestHarness.java:45)
	at org.eclipse.e4.ui.internal.workbench.swt.E4Testable.lambda$1(E4Testable.java:127)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:5040)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4520)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:152)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:639)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:546)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152)
	at org.eclipse.pde.internal.junit.runtime.NonUIThreadTestApplication.start(NonUIThreadTestApplication.java:58)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:143)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:109)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:439)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:271)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1481)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1454)
Caused by: java.lang.AssertionError: expected:<JavaSE-17> but was:<end of array>
	at org.junit.Assert.fail(Assert.java:89)
	at org.junit.Assert.failNotEquals(Assert.java:835)
	at org.junit.Assert.assertEquals(Assert.java:120)
	at org.junit.Assert.assertEquals(Assert.java:146)
	at org.junit.internal.ComparisonCriteria.arrayEquals(ComparisonCriteria.java:87)
	... 50 more


Copy link

github-actions bot commented Jun 14, 2024

Test Results

   291 files  ±0     291 suites  ±0   55m 52s ⏱️ - 1m 13s
 3 580 tests +1   3 504 ✅ +1   76 💤 ±0  0 ❌ ±0 
11 037 runs  +3  10 806 ✅ +3  231 💤 ±0  0 ❌ ±0 

Results for commit be7a44b. ± Comparison against base commit 1b1b92a.

♻️ This comment has been updated with latest results.

@laeubi
Copy link
Contributor

laeubi commented Jun 14, 2024

@ptziegler great work in reproducing the issue!

@ptziegler
Copy link
Contributor Author

Let's just hope that this time, less than all the tests crash... I forgot to push the .project and .classpath files, which is why it worked locally.

@ptziegler ptziegler force-pushed the issue1301 branch 2 times, most recently from 5be7308 to 1a30591 Compare June 20, 2024 21:32
@ptziegler
Copy link
Contributor Author

@HannesWell This is effectively the same fix I applied in the Equinox PR. The important part is to not use getExecutionEnvironments() as this method only supports the Bundle-RequireExecutionEnvironment header.

@HannesWell
Copy link
Member

@HannesWell This is effectively the same fix I applied in the Equinox PR. The important part is to not use getExecutionEnvironments() as this method only supports the Bundle-RequireExecutionEnvironment header.

Thanks for that. I'll try my best to have a look at this tomorrow (Sorry was a busy weekend).

Copy link
Member

@HannesWell HannesWell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ptziegler thanks for this. The general idea is correct and the tests are good.

But the algorithm to extract the BREE id from the EE filter only works for the simple, but very common case of filters like (&(osgi.ee=JavaSE)(version=17). Still other cases should be supported too.
Therefore I have now completed the work I started a while ago for the mentioned other use-cases and added it as a separate commit to this PR.
That commits add a re-usable method ManifestUtils.getRequiredExecutionEnvironments() to returns all required EE ids, regardless if they are defined via BREE header or EE requirement.
Internally this method provides a fast path for the common case, but also a complete path, where all available EEs in the runtime are matched against the filter and the matching ones are collected. Basically what has been suggested in #1301 (comment).

I also changed your commit to use the new method and force pushed the result to this PR's branch, I hope that's fine for you. If you want to keep the old code, you should make sure to make a local copy of the branch.

In general this PR would then be ready for me. I just would like to resolver the comment below.
@laeubi or @merks do you want to have a look at this as well?

Comment on lines 356 to 357
Method getOSGiEENameVersion = OSGiManifestBuilderFactory.class
.getDeclaredMethod("getOSGiEENameVersion", String.class); //$NON-NLS-1$
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tjwatson can this be made available to PDE in some way since I would like to avoid to duplicate the logic in PDE.
It does not have to be an API, some internals that are accessible should be fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In its current form it would have to be internal since returning a String[] is rather strange. Would something like this help as possible API:

public static Map<String, String> getOSGiEERequirementDirectives(String bree)

Where the directives just have the osgi.ee filter directive?
Or maybe just a method to create the filter:

public static String getOSGiEERequirementFilter(String bree)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes the former would be helpful. But I have now solved that by simply 'hard-coding' the filter attributes of the old EEs CDC-1.0/Foundation-1.0 and CDC-1.1/Foundation-1.1. For all other resent EE ids the simple method to split the version and name at the last dash is sufficient and hopefully for all future ones as well.
So I think it is not necessary to introduce a new API method for that.

@HannesWell HannesWell changed the title Create test case checking execution environment of project bundles Fix: API tool reports fictitious changes to execution environment Jun 27, 2024
@laeubi
Copy link
Contributor

laeubi commented Jun 28, 2024

Still other cases should be supported too.

As I have written elsewhere this is a tough case and probably can only be solved by matching the filter against a list of available EEs. I would just postpone that to the time where it is really needed.

@ptziegler
Copy link
Contributor Author

I also changed your commit to use the new method and force pushed the result to this PR's branch, I hope that's fine for you. If you want to keep the old code, you should make sure to make a local of the branch.

That's more than fine by me. I'm not overly familiar with all possible combinations with which one could describe the EE, so I appreciate you taking the time and cleaning up those edge cases.

@HannesWell HannesWell force-pushed the issue1301 branch 4 times, most recently from 99c29a2 to 5e8ac63 Compare June 29, 2024 09:29
@HannesWell
Copy link
Member

This change itself is ready, but I'm currently investigating other use-cases for the new method, e.g. in #1318.
I would therefore like to keep this open to bring that in a more general shape, but I'll complete this in the next days and then submit this.
@ptziegler from your issue assume this is not urgent for you and a few days more or less do not matter?

@ptziegler
Copy link
Contributor Author

@HannesWell That is correct. The problem only shows up at the start of a release cycle, so it'll only come up again at the start of 2024-09.

The API tool only checks the Bundle-RequiredExecutionEnvironment header
when comparing the baseline with the workspace bundle. If the EE of the
baseline bundle is described via the Require-Capability header, an empty
string is compared to the workspace EE, which is treated as an
incompatibility.

This also adds a simple test case where the execution environment of two
bundles is checked. One bundle uses the  Require-Capability, the other
one the Bundle-RequiredExecutionEnvironment header.

Resolves eclipse-pde#1301
Copy link
Member

@HannesWell HannesWell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have now added the new utility method via #1325 (the other PR that will use it takes some more time) and rebased this PR on that.
So this is now ready.
Thanks again.

@HannesWell HannesWell merged commit 7c27f5c into eclipse-pde:master Jul 7, 2024
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

API tool reports ficticious changes to execution environment
4 participants