Использование декларативных служб OSGi в контексте теста JUnit

Я пытаюсь понять, как реализовать тест интеграции с несколькими пакетами в OSGi с помощью JUnit.

Под интеграционным тестом я имею в виду создание экземпляра подмножества пакетов для автоматической проверки функциональности в этой подсистеме.

Мы запускаем Equinox и используем Eclipse в качестве инструментария. Eclipse предлагает опцию «Запуск от имени подключаемого модуля JUnit», которая запускает инфраструктуру OSGi и создает экземпляры пакетов конфигураций, поэтому я думаю, что это путь, по которому следует идти, но я не нахожу способа внедрить ссылки DS в мои тесты. Я видел использование ServiceTracker в качестве программного средства для доступа к различным пакетам услуг, но это превосходит цель наличия DS, не так ли?

Я только начинаю работать с OSGI, поэтому полагаю, что « Мне просто не хватает части головоломки, которая позволила бы мне собрать мои тесты с несколькими пакетами.

Есть идеи?

Спасибо, Джерард.

* РЕДАКТИРОВАТЬ: РЕШЕНИЕ *

После дальнейшего изучения этого вопроса , Я, наконец, понял, как применить эти тесты интеграции с несколькими пакетами, используя функцию подключаемого модуля JUnit:

Для работы динамического внедрения сервисов необходимо создать файл определения сервиса, в котором должны быть объявлены внедренные зависимости, как это обычно делается при работе с DS. Этот файл (обычно) находится в каталоге OSGI-INF / . например OSGI-INF / service.xml

service.xml должен объявлять необходимые зависимости для этого теста, но не предлагает собственных услуг:

service.xml
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="MyTest" activate="startup" deactivate="shutdown">

   <implementation class="com.test.functionaltest.MyTester"/>
   <reference name="OtherService" interface="com.product.service.FooService" policy="static" cardinality="1..1" bind="onServiceUp" unbind="onServiceDown"/>

</scr:component>

Это даст указание DS внедрить зависимость от FooService с помощью объявлен метод onServiceUp. onServiceDown должен быть реализован так, как он вызывается во время фазы выключения OSGi после запуска тестов.

com.test.functionaltest.MyTester содержит методы тестирования, которые должны быть выполнены, в соответствии с типичными практиками JUnit.

До сих пор это все «по книге». Тем не менее, если Junit запущен, он выдаст исключение NullPointerException при доступе к ссылке на FooService. Причина в том, что инфраструктура OSGi находится в состоянии гонки с контекстом средства запуска тестов JUnit, и обычно средство запуска тестов Junit выигрывает в этой гонке, выполняя тесты до того, как будет введена ссылка на требуемую службу.

В этой ситуации необходимо, чтобы тест Junit ждал, пока среда выполнения OSGi выполнит свою работу. Я решил эту проблему, используя CountDownLatch,который инициализируется количеством зависимых сервисов, требуемых в тесте. Затем выполняется обратный отсчет каждого метода внедрения зависимостей, и когда все они будут выполнены, начнется тест. Код выглядит следующим образом:

private static CountDownLatch dependencyLatch = new CountDownLatch(1);// 1 = number of dependencies required    
static FooService  fooService = null;   
public void onFooServiceUp(FooService service) {
  fooService = service;
  dependencyLatch.countDown();
}

Обратите внимание, что ссылка fooService должна быть статической, чтобы разрешить совместное использование ссылки на службу между OSGi и контекстами выполнения JUnit. CountDownLatch обеспечивает высокоуровневый механизм синхронизации для безопасной публикации этой общей ссылки.

Затем перед выполнением теста следует добавить проверку зависимости:

@Before
public void dependencyCheck() {
  // Wait for OSGi dependencies
    try {
      dependencyLatch.await(10, TimeUnit.SECONDS); 
      // Dependencies fulfilled
    } catch (InterruptedException ex)  {
      fail("OSGi dependencies unfulfilled");
    }
}

Таким образом, инфраструктура Junit ожидает, пока служба OSGi DS внедрит зависимости или сбой после тайм-аута.

Мне потребовалось некоторое время, чтобы полностью разобраться в этом. Я надеюсь, что в будущем это избавит от головной боли коллег-программистов.

12
задан maasg 8 November 2011 в 11:06
поделиться