Конфигурационные административные и декларативные сервисы не созданы на этапе экзамена Pax.
Я написал @component в DS, который должен создаваться и активироваться в нескольких экземплярах. Чтобы проверить, что я написал экзамен 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?), Поскольку в конфигурации, к которой у моего интерфейса был доступ, через некоторое время появился пакет (пока контейнер закрывался), но он действительно должен был быть связан с pax test bundle (и, конечно, сам CM) и никогда не был "свободен: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 и тест, который мне не удается запустить (до тех пор, пока тест не будет запущен;).
3 ответа
Спасибо вам обоим за ваш вклад - я решил ответить на этот вопрос сам, так как у меня была ошибка в моем коде и я получил помощь от Кристофа.
Я цитирую ответ от него здесь, если там кто-то еще сделал то, что я сделал.
Проблема заключалась в том, что я не установил владение конфигурацией как анонимное через (pid, null) в createFactoryConfiguration. Вместо этого я использовал createFactoryConfiguration (pid), после чего он привязался к текущему исполняемому пакету, а не к тестируемому. Как объяснил Кристоф, я смог получить местоположение пакета услуг и установить его явно.
Ура, Марио
Вот ответ Кристофа Любрича
"Christoph Läubrich добавил комментарий - 13 минут назад
Хорошо, я думаю, я знаю, в чем может быть проблема сейчас: вы используете createFactoryConfiguration(java.lang.String factoryPid), это означает, что вы создадите конфигурацию, которая исключительно привязана к вашему пакету! Таким образом, никакой другой пакет не может получить доступ к конфигурации! Вместо этого используйте createFactoryConfiguration(java.lang.String factoryPid, java.lang.String location) с нулевым аргументом для местоположения! Таким образом, вы создаете анонимную конфигурацию, которая будет связана с первым пакетом, который извлекает эту конфигурацию. В качестве альтернативы вы можете получить местоположение целевого комплекта и явно передать его в качестве параметра, но это часто не требуется. Если это по-прежнему не работает, мы должны более внимательно изучить вашу конфигурацию, подключиться к оболочке karaf (пока она остановлена на точке останова) и получить список всех пакетов (bundle:list) и список всех компонентов (scr: список). Также вам следует собрать подробную информацию о пакете проб и пакете, который должен предоставлять услугу (пакеты: импорт)."
(На самом деле я не вижу ничего плохого в вашем коде, 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;
Я подозреваю, что тест развертывает интерфейс CouchbaseConnectionProvider с собой. Таким образом, вы пытаетесь получить сервис, используя интерфейс, отличный от того, который предоставляет реальный сервис.
Вы должны попытаться добавить импорт и экспорт в свой тестовый пакет для пакета, в котором находится CouchbaseConnectionProvider.
Для этого используйте ProbeBuilder
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
probe.setHeader(Constants.IMPORT_PACKAGE, "..");
probe.setHeader(Constants.EXPORT_PACKAGE, "..");
return probe;
}