在 pax 考试测试阶段未创建配置管理和声明服务
Configuration Admin and Declarative Services not created during pax exam test phase
我在 DS 中写了一个@component,它应该在多个实例中被实例化和激活。为了测试我写了一个 pax 考试测试,我在其中启动 karaf 并添加了 scr。一切正常,但是......在测试方法具有 运行 之前它不会实例化服务,因此我没有 space 进行断言等
@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 中?),因为一段时间后(当容器正在关闭时)我的接口 impl bundle 可以访问配置,但它真的应该绑定到 pax 测试bundle(当然还有 CM 本身)并且在容器关闭时从来没有 "free:d"。我不知道那个错误在哪里 - 我将结束一个简约的 mvn 项目并尝试 felix cm 家伙,我将 post 更新在这里。
更新 2
我已经提交了一个错误 (https://ops4j1.jira.com/browse/PAXEXAM-725) 如果有人有兴趣关注进展(如果有错误 ;))
更新 1
这是我在测试中的配置class
package se.crossbreed.foundation.persistence.provider.couchbase;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class CouchbaseConnectionProviderTests extends CbTestBase {
...
}
这是测试class中的配置,它将使用基础class
基本选项。
@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[] {});
}
基础配置取自基础class
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 的项目结构和我无法开始工作的测试(直到测试有 运行 ;)。
我怀疑测试会自行部署 CouchbaseConnectionProvider 接口。因此,您尝试使用与实际服务提供的接口不同的接口来检索服务。
您应该尝试将导入和导出添加到 CouchbaseConnectionProvider 所在包的测试包中。
为此使用 ProbeBuilder
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
probe.setHeader(Constants.IMPORT_PACKAGE, "..");
probe.setHeader(Constants.EXPORT_PACKAGE, "..");
return probe;
}
(我实际上没有发现您的代码有任何问题,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;
感谢你们的意见 - 我选择自己回答这个问题,因为我的代码中有一个错误并得到了 Christoph 的帮助。
如果有人做了我做的,我在这里引用他的回答。
问题是我没有在 createFactoryConfiguration 中通过 (pid, null) 将配置所有权设置为匿名。相反,我使用了 createFactoryConfiguration(pid) 然后它绑定到当前正在执行的包而不是我正在测试的包。正如 Christoph 解释的那样,我可以获取服务包的包位置并明确设置它。
干杯,
马里奥
这是 Christoph Läubrich 的回答
“Christoph Läubrich 添加了评论 - 13 分钟前
好的,我想我现在知道可能是什么问题了:
您正在使用 createFactoryConfiguration(java.lang.String factoryPid),这意味着您将创建一个专门绑定到您的包的配置!因此不允许其他包访问配置!
使用 createFactoryConfiguration(java.lang.String factoryPid, java.lang.String location) 而不是位置的空参数!通过这种方式,您可以创建一个匿名配置,该配置将绑定到获取此配置的第一个包。或者,您可以获得目标包的位置并将其作为参数显式传递,但这通常是不需要的。
如果这仍然不起作用,我们必须仔细查看您的配置,连接到 karaf shell(在断点处停止)并获取所有捆绑包的列表 (bundle:list) 和所有捆绑包的列表组件(scr:list)。
您还应该收集有关探测包和应该提供服务的包的详细信息 (packages:imports)。"
我在 DS 中写了一个@component,它应该在多个实例中被实例化和激活。为了测试我写了一个 pax 考试测试,我在其中启动 karaf 并添加了 scr。一切正常,但是......在测试方法具有 运行 之前它不会实例化服务,因此我没有 space 进行断言等
@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 中?),因为一段时间后(当容器正在关闭时)我的接口 impl bundle 可以访问配置,但它真的应该绑定到 pax 测试bundle(当然还有 CM 本身)并且在容器关闭时从来没有 "free:d"。我不知道那个错误在哪里 - 我将结束一个简约的 mvn 项目并尝试 felix cm 家伙,我将 post 更新在这里。
更新 2 我已经提交了一个错误 (https://ops4j1.jira.com/browse/PAXEXAM-725) 如果有人有兴趣关注进展(如果有错误 ;))
更新 1 这是我在测试中的配置class
package se.crossbreed.foundation.persistence.provider.couchbase;
@RunWith(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class CouchbaseConnectionProviderTests extends CbTestBase {
...
}
这是测试class中的配置,它将使用基础class 基本选项。
@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[] {});
}
基础配置取自基础class
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 的项目结构和我无法开始工作的测试(直到测试有 运行 ;)。
我怀疑测试会自行部署 CouchbaseConnectionProvider 接口。因此,您尝试使用与实际服务提供的接口不同的接口来检索服务。
您应该尝试将导入和导出添加到 CouchbaseConnectionProvider 所在包的测试包中。
为此使用 ProbeBuilder
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
probe.setHeader(Constants.IMPORT_PACKAGE, "..");
probe.setHeader(Constants.EXPORT_PACKAGE, "..");
return probe;
}
(我实际上没有发现您的代码有任何问题,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;
感谢你们的意见 - 我选择自己回答这个问题,因为我的代码中有一个错误并得到了 Christoph 的帮助。
如果有人做了我做的,我在这里引用他的回答。
问题是我没有在 createFactoryConfiguration 中通过 (pid, null) 将配置所有权设置为匿名。相反,我使用了 createFactoryConfiguration(pid) 然后它绑定到当前正在执行的包而不是我正在测试的包。正如 Christoph 解释的那样,我可以获取服务包的包位置并明确设置它。
干杯, 马里奥
这是 Christoph Läubrich 的回答
“Christoph Läubrich 添加了评论 - 13 分钟前
好的,我想我现在知道可能是什么问题了: 您正在使用 createFactoryConfiguration(java.lang.String factoryPid),这意味着您将创建一个专门绑定到您的包的配置!因此不允许其他包访问配置! 使用 createFactoryConfiguration(java.lang.String factoryPid, java.lang.String location) 而不是位置的空参数!通过这种方式,您可以创建一个匿名配置,该配置将绑定到获取此配置的第一个包。或者,您可以获得目标包的位置并将其作为参数显式传递,但这通常是不需要的。 如果这仍然不起作用,我们必须仔细查看您的配置,连接到 karaf shell(在断点处停止)并获取所有捆绑包的列表 (bundle:list) 和所有捆绑包的列表组件(scr:list)。 您还应该收集有关探测包和应该提供服务的包的详细信息 (packages:imports)。"