java - 在 pax 考试测试阶段未创建配置管理和声明性服务

标签 java osgi declarative-services pax-exam

我在 DS 中编写了一个 @Component,它应该在多个实例中实例化和激活。为了测试我已经编写了一个 pax 考试测试,我启动了 karaf 并添加了 scr。一切工作正常,但是......直到测试方法运行之后它才会实例化服务,因此没有空间进行断言等。

@Test
public final void testing() throws Exception { 
props = createProperties(user, pass, host);
cfg = configurationAdmin.
     createFactoryConfiguration(CouchbaseConnectionProvider.SVC_NAME);
cfg.update(props);

final ServiceTracker tracker = new ServiceTracker(bundleContext, CouchbaseConnectionProvider.class, null);
tracker.open();

CouchbaseConnectionProvider svc = (CouchbaseConnectionProvider) tracker.waitForService(5000);
// It will wait 5s and after testing exits it will create the service
}

我在这里做错了什么? 因为当方法退出时,它将正确创建并激活具有所有属性的服务。

我可以补充一下,测试方法使用线程“ion(3)-127.0.0.1”,并且当 DS 实例化时使用线程“84-b6b23468b652)”。

干杯, 马里奥

更新3 实际上有两个错误,一个在我这边,一个在其他地方(在 felix CM 中?),因为一段时间后(当容器关闭时)我的接口(interface) impl 包可以访问配置,但它确实应该绑定(bind)到 pax 测试 bundle (当然还有 CM 本身)并且在容器关闭时从未“free:d”。我不知道那个错误在哪里 - 我将完成一个简约的 mvn 项目并尝试 felix cm 人员,然后我将在此处发布更新。

更新2 如果有人有兴趣跟踪进度(如果有错误;)),我已提交错误(https://ops4j1.jira.com/browse/PAXEXAM-725)

更新 1 这是我在测试类中的配置

package se.crossbreed.foundation.persistence.provider.couchbase;

@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class CouchbaseConnectionProviderTests extends CbTestBase {
  ...
}

这是测试类中的配置,它将使用基类 基本选项。

@org.ops4j.pax.exam.Configuration
public Option[] config() {
    List<Option> options = super.baseConfig();
    options.addAll(Arrays
            .asList(features(karafStandardRepo, "scr"),
                    mavenBundle()
                            .groupId("se.crossbreed.foundation.persistence")
                            .artifactId(
                                    "se.crossbreed.foundation.persistence.core")
                            .versionAsInProject(),
                    mavenBundle().groupId("io.reactivex")
                            .artifactId("rxjava").versionAsInProject(),
                    mavenBundle()
                            .groupId("se.crossbreed.ports.bundles")
                            .artifactId(
                                    "se.crossbreed.ports.bundles.couchbase.java-client")
                            .versionAsInProject(),
                    mavenBundle()
                            .groupId("se.crossbreed.foundation.persistence")
                            .artifactId(
                                    "se.crossbreed.foundation.persistence.provider.couchbase")
                            .versionAsInProject()));

    // above bundle is the one I'm trying to test and where
    // this test resides in (project wise)
    return options.toArray(new Option[] {});
}

基本配置是从基类获取的

protected List<Option> baseConfig() {
    return new ArrayList<Option>(
            Arrays.asList(new Option[] {
                    logLevel(LogLevel.INFO),
                    karafDistributionConfiguration().frameworkUrl(karafUrl)
                            .unpackDirectory(new File("target", "exam"))
                            .useDeployFolder(false),
                    configureConsole().ignoreLocalConsole(),
                    mavenBundle().groupId("biz.aQute.bnd")
                            .artifactId("bndlib").version("${version.bndlib}"),
                    mavenBundle()
                            .groupId("se.crossbreed.foundation")
                            .artifactId(
                                    "se.crossbreed.foundation.core.annotations")
                            .versionAsInProject(),
                    mavenBundle()
                            .groupId("se.crossbreed.foundation")
                            .artifactId(
                                    "se.crossbreed.foundation.core.interfaces")
                            .versionAsInProject() }));
}

测试的包是

package se.crossbreed.foundation.persistence.provider.couchbase;

并且 CouchbaseConnectionProvider 位于同一个包上

package se.crossbreed.foundation.persistence.provider.couchbase;

import se.crossbreed.foundation.persistence.core.CbDbConnectionProvider;

public interface CouchbaseConnectionProvider extends CbDbConnectionProvider {
    public final static String SVC_NAME = "couchbase.connection.provider";
}

实现:

package se.crossbreed.foundation.persistence.provider.couchbase.impl;

@Component(immediate = true, name = 
    CouchbaseConnectionProvider.SVC_NAME, provide = {
    CouchbaseConnectionProvider.class, CbDbConnectionProvider.class,
    CbService.class }, properties = { "providerType=DOCUMENT" }, 
    configurationPolicy = ConfigurationPolicy.require)
    public class CouchbaseConnectionProviderImpl implements
    CouchbaseConnectionProvider { ... }

这是 Couchbase Provider 的项目结构和我无法开始工作的测试(直到测试运行后;)。

Project Structure of the couchbase provider and the test

最佳答案

(我实际上没有发现您的代码有任何问题,ConfigurationAdmin 应该异步工作。测试后启动的新服务看起来仍然像是同步问题。在这种情况下,此设置可能会修复它。)

您可以使用 pax-exam-cm 使用其他选项创建工厂配置,而不是在测试方法中创建配置:

@org.ops4j.pax.exam.Configuration
public Option[] config() {
    List<Option> options = super.baseConfig();
    options.addAll(Arrays
        .asList(features(karafStandardRepo, "scr"),
        //missing conversion: putAll() needs a Map        
        ConfigurationAdminOptions.factoryConfiguration(CouchbaseConnectionProvider.SVC_NAME)
                        .putAll(createProperties(user, pass, host)).create(true).asOption(),
                mavenBundle()
                        .groupId("se.crossbreed.foundation.persistence")
                        .artifactId(
                                "se.crossbreed.foundation.persistence.core")
                        .versionAsInProject(),
                mavenBundle().groupId("io.reactivex")
                        .artifactId("rxjava").versionAsInProject(),
                mavenBundle()
                        .groupId("se.crossbreed.ports.bundles")
                        .artifactId(
                                   "se.crossbreed.ports.bundles.couchbase.java-client")
                        .versionAsInProject(),
                mavenBundle()
                        .groupId("se.crossbreed.foundation.persistence")
                        .artifactId(
                                "se.crossbreed.foundation.persistence.provider.couchbase")
                        .versionAsInProject()));

    // above bundle is the one I'm trying to test and where
    // this test resides in (project wise)
    return options.toArray(new Option[] {});
}

Maven 设置:

<dependency>
    <groupId>org.ops4j.pax.exam</groupId>
    <artifactId>pax-exam-cm</artifactId>
    <version>${exam.version}</version>                
</dependency>

然后,您还可以简单地使用 @Inject 注释来获取测试中的 CouchbaseConnectionProvider

@Inject
CouchbaseConnectionProvider svc;

关于java - 在 pax 考试测试阶段未创建配置管理和声明性服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31272051/

相关文章:

java - 使用 Jackson 从子元素开始反序列化 XML

java - 打印包含继承成员的数组?

osgi - Import-Package 分辨率 :=optional and no dependency at all 之间的区别

java - 戈戈 : BundleException: An error occurred trying to read the bundle in OSGi with Equinox

osgi - 如何声明对 SCR 扩展器能力的要求?

java - 人工智能(神经网络) - 实际输出永远不会接近正确输出

java 二维图形库

java - 无法解析标准 java 导入

java - 以编程方式使用 OSGi 中的组件