diff --git a/examples/osgi-test-example-pde/README.md b/examples/osgi-test-example-pde/README.md new file mode 100644 index 00000000..2222afa9 --- /dev/null +++ b/examples/osgi-test-example-pde/README.md @@ -0,0 +1,8 @@ +# osgi-test-example-pde +An example project demonstrating OSGi testing capabilities using [Eclipse PDE](https://www.eclipse.org/pde/). + +To execute it do the following: + +- make sure you are using a recent Eclipse for RCP/RAP Developers edition (minimum 2022-03) +- open the 'example.target' and set it as your active target +- import the projects, right click on PlayerTest.java and choose `Run As` > `Junit Plugin Test` diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.classpath b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.classpath new file mode 100644 index 00000000..e801ebfb --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.project b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.project new file mode 100644 index 00000000..b43f5861 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.project @@ -0,0 +1,28 @@ + + + example.api + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.settings/org.eclipse.jdt.core.prefs b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..c9545f06 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/META-INF/MANIFEST.MF b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/META-INF/MANIFEST.MF new file mode 100644 index 00000000..500357b0 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/META-INF/MANIFEST.MF @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: API +Bundle-SymbolicName: org.osgi.test.example.api +Bundle-Version: 1.0.0.qualifier +Automatic-Module-Name: org.osgi.test.example.api +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Export-Package: org.osgi.test.example.api;version="1.0.0" diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/build.properties b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/build.properties new file mode 100644 index 00000000..34d2e4d2 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/src/org/osgi/test/example/api/Ball.java b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/src/org/osgi/test/example/api/Ball.java new file mode 100644 index 00000000..5238fadd --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/src/org/osgi/test/example/api/Ball.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package org.osgi.test.example.api; + +public interface Ball { + + void inflate(); + + void kick(); + +} diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/src/org/osgi/test/example/api/Player.java b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/src/org/osgi/test/example/api/Player.java new file mode 100644 index 00000000..eb1f5559 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.api/src/org/osgi/test/example/api/Player.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package org.osgi.test.example.api; + +public interface Player { + + Ball getBall(); + + void kickBall(); +} diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.classpath b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.classpath new file mode 100644 index 00000000..37b3b397 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.project b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.project new file mode 100644 index 00000000..d1e77883 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.project @@ -0,0 +1,33 @@ + + + example.player.impl + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.settings/org.eclipse.jdt.core.prefs b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..c9545f06 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.settings/org.eclipse.pde.ds.annotations.prefs b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.settings/org.eclipse.pde.ds.annotations.prefs new file mode 100644 index 00000000..73a356b6 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/.settings/org.eclipse.pde.ds.annotations.prefs @@ -0,0 +1,8 @@ +classpath=true +dsVersion=V1_3 +eclipse.preferences.version=1 +enabled=true +generateBundleActivationPolicyLazy=true +path=OSGI-INF +validationErrorLevel=error +validationErrorLevel.missingImplicitUnbindMethod=error diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/META-INF/MANIFEST.MF b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/META-INF/MANIFEST.MF new file mode 100644 index 00000000..1734013d --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Player Impl +Bundle-SymbolicName: org.osgi.test.example.player.impl +Bundle-Version: 1.0.0.qualifier +Automatic-Module-Name: org.osgi.test.example.player.impl +Bundle-RequiredExecutionEnvironment: JavaSE-11 +Import-Package: org.osgi.framework;version="1.10.0", + org.osgi.service.component.annotations;version="1.3.0", + org.osgi.test.example.api;version="[1.0.0,1.1.0)" +Bundle-ActivationPolicy: lazy +Require-Bundle: org.junit, + org.osgi.test.common;resolution:=optional, + assertj-core;resolution:=optional, + org.osgi.test.assertj.framework;resolution:=optional, + org.mockito.mockito-core;resolution:=optional, + org.osgi.test.junit5;bundle-version="1.1.0";resolution:=optional, + org.junit.jupiter.api;bundle-version="5.8.1";resolution:=optional +Export-Package: org.osgi.test.example.player.test +Service-Component: OSGI-INF/org.osgi.test.example.player.impl.PlayerImpl.xml diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/OSGI-INF/org.osgi.test.example.player.impl.PlayerImpl.xml b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/OSGI-INF/org.osgi.test.example.player.impl.PlayerImpl.xml new file mode 100644 index 00000000..238aa0ca --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/OSGI-INF/org.osgi.test.example.player.impl.PlayerImpl.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/build.properties b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/build.properties new file mode 100644 index 00000000..4974816f --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/org.osgi.test.example.player.impl.PlayerImpl.xml diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/src/org/osgi/test/example/player/impl/PlayerImpl.java b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/src/org/osgi/test/example/player/impl/PlayerImpl.java new file mode 100644 index 00000000..e8bc6d07 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/src/org/osgi/test/example/player/impl/PlayerImpl.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package org.osgi.test.example.player.impl; + +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.test.example.api.Ball; +import org.osgi.test.example.api.Player; + +@Component +public class PlayerImpl implements Player { + + @Reference + Ball ball; + + @Override + public void kickBall() { + ball.kick(); + } + + @Override + public Ball getBall() { + return ball; + } +} diff --git a/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/src_test/org/osgi/test/example/player/test/PlayerTest.java b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/src_test/org/osgi/test/example/player/test/PlayerTest.java new file mode 100644 index 00000000..9a733f28 --- /dev/null +++ b/examples/osgi-test-example-pde/bundles/org.osgi.test.example.player.impl/src_test/org/osgi/test/example/player/test/PlayerTest.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + *******************************************************************************/ + +package org.osgi.test.example.player.test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; + +import java.util.Dictionary; +import java.util.List; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.junit.jupiter.api.extension.ExtendWith; +import org.osgi.framework.BundleContext; +import org.osgi.test.assertj.dictionary.DictionaryAssert; +import org.osgi.test.common.annotation.InjectBundleContext; +import org.osgi.test.common.annotation.InjectService; +import org.osgi.test.common.dictionary.Dictionaries; +import org.osgi.test.common.service.ServiceAware; +import org.osgi.test.example.api.Ball; +import org.osgi.test.example.api.Player; +import org.osgi.test.junit5.context.BundleContextExtension; +import org.osgi.test.junit5.service.ServiceExtension; + +@ExtendWith(BundleContextExtension.class) +@ExtendWith(ServiceExtension.class) +public class PlayerTest { + + static Ball b; + + @InjectBundleContext + BundleContext bc; + + public PlayerTest() { + System.out.println(); + } + + @BeforeAll + static void beforeAll(@InjectBundleContext BundleContext staticBC) { + b = mock(Ball.class); + Dictionary props = Dictionaries.dictionaryOf("test", "testball"); + staticBC.registerService(Ball.class, b, props); + + } + + @InjectService + Player p; + + @Test + void myTest() { + assertThat(p).isNotNull(); + assertThat(p.getBall()).isSameAs(b); + verifyNoInteractions(b); + p.kickBall(); + verify(b).kick(); + } + + static class DummyBall implements Ball { + + @Override + public void inflate() { + } + + @Override + public void kick() { + } + } + + @Test + void myServiceAwareTest(@InjectService(cardinality = 0) ServiceAware ball) { + assertThat(ball.getServices()).hasSize(1); + DictionaryAssert.assertThat(ball.getServiceReference().getProperties()).containsEntry("test", "testball"); + bc.registerService(Ball.class, new DummyBall(), null); + assertThat(ball.getServices()).hasSize(2); + bc.registerService(Ball.class, new DummyBall(), null); + assertThat(ball.getServices()).hasSize(3); + } + + @Nested + @TestInstance(Lifecycle.PER_CLASS) + class TwoBalls { + Ball b2; + + @BeforeAll + void beforeAll(@InjectBundleContext BundleContext bc) { + b2 = mock(Ball.class); + bc.registerService(Ball.class, b2, null); + } + + @Test + void twoBallTest(@InjectService(cardinality = 2) List services) { + assertThat(services).containsExactlyInAnyOrder(b, b2); + } + } + + // This test should fail - proves that the second ball registered + // in the nested test gets cleaned up. +// @Test +// void myDoubleTest(@InjectService(cardinality = 2) List balls) { +// } +} diff --git a/examples/osgi-test-example-pde/example.target b/examples/osgi-test-example-pde/example.target new file mode 100644 index 00000000..d1de5ce9 --- /dev/null +++ b/examples/osgi-test-example-pde/example.target @@ -0,0 +1,66 @@ + + + + + + + + + + + + org.mockito + mockito-core + 3.8.0 + jar + + + + + + + org.osgi + org.osgi.test.assertj.framework + 1.1.0 + jar + + + org.osgi + org.osgi.test.assertj.log + 1.1.0 + jar + + + org.osgi + org.osgi.test.assertj.promise + 1.1.0 + jar + + + org.osgi + org.osgi.test.common + 1.1.0 + jar + + + org.osgi + org.osgi.test.junit5.cm + 1.1.0 + jar + + + org.osgi + org.osgi.test.junit5.listeners.log.osgi + 1.1.0 + jar + + + org.osgi + org.osgi.test.junit5 + 1.1.0 + jar + + + + + \ No newline at end of file