Skip to content

Commit c02aadd

Browse files
ptzieglerlaeubi
authored andcommitted
Add reproducer for cyclic bundle dependencies caused by #2218
1 parent 693ecb5 commit c02aadd

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/core/tests/internal/classpath/ClasspathResolutionTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2020, 2023 Red Hat Inc. and others.
2+
* Copyright (c) 2020, 2026 Red Hat Inc. and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -19,6 +19,7 @@
1919

2020
import java.util.Arrays;
2121
import java.util.List;
22+
import java.util.Map;
2223
import java.util.Properties;
2324
import java.util.Set;
2425
import java.util.function.Predicate;
@@ -40,6 +41,7 @@
4041
import org.eclipse.pde.internal.core.MinimalState;
4142
import org.eclipse.pde.internal.core.PDECore;
4243
import org.eclipse.pde.internal.core.TargetPlatformHelper;
44+
import org.eclipse.pde.ui.tests.runtime.TestUtils;
4345
import org.eclipse.pde.ui.tests.util.ProjectUtils;
4446
import org.eclipse.pde.ui.tests.util.TargetPlatformUtil;
4547
import org.junit.BeforeClass;
@@ -49,6 +51,7 @@
4951
import org.junit.rules.TestRule;
5052
import org.mockito.Mockito;
5153
import org.osgi.framework.Bundle;
54+
import org.osgi.framework.Constants;
5255
import org.osgi.framework.FrameworkUtil;
5356

5457
public class ClasspathResolutionTest {
@@ -146,6 +149,21 @@ public void testImportSystemPackageDoesntAddExtraBundleJava8_osgiEERequirement()
146149
}
147150
}
148151

152+
@Test
153+
public void testRequiredPluginsViaCapabilityForFragment() throws CoreException {
154+
ProjectUtils.createPluginProject("A", "1.0.0");
155+
ProjectUtils.createPluginProject("capabilities.provider", "1.0.0",
156+
Map.of(Constants.PROVIDE_CAPABILITY, "some.test.capability", Constants.REQUIRE_BUNDLE, "A"));
157+
IProject projectConsumer = ProjectUtils.createPluginProject("capabilities.consumer", "1.0.0",
158+
Map.of(Constants.REQUIRE_CAPABILITY, "some.test.capability", Constants.FRAGMENT_HOST, "A"));
159+
160+
TestUtils.waitForJobs("ClasspathResolutionTest.testRequiredPluginsViaCapabilityForFragment", 200, 30_000);
161+
162+
List<String> requiredPluginContainers = getRequiredPluginContainerEntries(projectConsumer);
163+
assertThat(requiredPluginContainers).contains("A1_0_0");
164+
assertThat(requiredPluginContainers).noneMatch(containerName -> containerName.contains("capabilities.provider"));
165+
}
166+
149167
// --- utilitiy methods ---
150168

151169
private List<String> getRequiredPluginContainerEntries(IProject project) throws CoreException {

ui/org.eclipse.pde.ui.tests/src/org/eclipse/pde/ui/tests/util/ProjectUtils.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2008, 2022 IBM Corporation and others.
2+
* Copyright (c) 2008, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -217,6 +217,9 @@ public static IProject createPluginProject(String bundleSymbolicName, String ver
217217
case Constants.EXPORT_PACKAGE -> setPackageExports(description, projectService, value);
218218
case Constants.IMPORT_PACKAGE -> setPackageImports(description, projectService, value);
219219
case Constants.REQUIRE_BUNDLE -> setRequiredBundles(description, projectService, value);
220+
case Constants.FRAGMENT_HOST -> setFragmentHost(description, projectService, value);
221+
case Constants.REQUIRE_CAPABILITY -> setRequiredCapability(description, projectService, value);
222+
case Constants.PROVIDE_CAPABILITY -> setProvidedCapability(description, projectService, value);
220223
default -> throw new IllegalArgumentException("Unsupported header: " + header);
221224
}
222225
});
@@ -256,6 +259,26 @@ private static void setRequiredBundles(IBundleProjectDescription project, IBundl
256259
project.setRequiredBundles(imports);
257260
}
258261

262+
private static void setFragmentHost(IBundleProjectDescription project, IBundleProjectService projectService,
263+
String value) {
264+
var host = parseHeader(Constants.REQUIRE_BUNDLE, value, h -> {
265+
VersionRange bundleVersion = Optional.ofNullable(h.getAttribute(Constants.BUNDLE_VERSION))
266+
.map(VersionRange::valueOf).orElse(null);
267+
return projectService.newHost(h.getValue(), bundleVersion);
268+
}).findFirst().orElse(null);
269+
project.setHost(host);
270+
}
271+
272+
private static void setRequiredCapability(IBundleProjectDescription project, IBundleProjectService projectService,
273+
String value) {
274+
project.setHeader(Constants.REQUIRE_CAPABILITY, value);
275+
}
276+
277+
private static void setProvidedCapability(IBundleProjectDescription project, IBundleProjectService projectService,
278+
String value) {
279+
project.setHeader(Constants.PROVIDE_CAPABILITY, value);
280+
}
281+
259282
private static <T> Stream<T> parseHeader(String header, String value, Function<ManifestElement, T> parser) {
260283
try {
261284
return Arrays.stream(ManifestElement.parseHeader(header, value)).map(parser);

0 commit comments

Comments
 (0)