Статьи

Пакеты фрагментов OSGi не имеют активаторов. Или они?

Используя «псевдо» -активаторы, фрагменты могут быть более активными, чем вы думаете! Написание тестового кода в OSGi-настройке требует больше работы и решений, чем в простой Java-main () — application-setting.

Например, мы, как правило, не хотим помещать тестовый код в сами «функциональные» пакеты, так как это делает процесс сборки более сложным, так как мы должны иметь возможность извлечь тестовый код из «производственного» релиз-пакета. С другой стороны, мы не хотим экспортировать все пакеты. Поэтому, если мы поместим наш тестовый код в отдельные пакеты, мы не сможем получить доступ ко всем классам / пакетам, которые мы хотели бы протестировать …

Тогда часто цитируемым подходом может быть включение тестового кода в связки фрагментов. Их можно легко включить / исключить в тестовых запусках или выпуске пакетов, и они используют тот же загрузчик классов, что и пакет хоста, поэтому они имеют доступ ко всем классам хоста.

Для получения дополнительной информации / обсуждения по этому вопросу, проверьте:

Хорошо, а теперь что?

В самом деле. После того, как принято решение поместить тестовый код во фрагменты, следующий шаг: как мы можем выполнить эти тесты ???

Проблемы:

  • фрагменты не активируются, поэтому они не могут регистрировать сервисы, запускать трекеры сервисов и т. д. AFAIK не позволяет фрагменту инициировать какие-либо действия при «запуске».
  • Фрагментные классы / ресурсы видны только в пакете хоста, если только пакет хоста не экспортирует их. Но если фрагмент не является обязательным, мы не можем экспортировать его пакеты с хоста.
  • хост-пакеты не могут легко обнаружить их зарегистрированные фрагменты. Единственный подход, который я нашел, состоял в том, чтобы проверить МАНИФЕСТ всех работающих пакетов и выяснить, есть ли некоторые с записью Fragment-Host, которая ссылается на пакет хоста. И даже там нам могут понадобиться функции, которые практически доступны только в новой OSGi 4.2. Смотрите  http://java.dzone.com/articles/osgi-junit-test-extender-using

Итак, как мы можем «обнаружить» наличие тестовых случаев? В приведенных выше ссылках описаны все виды трюков с отражением, или с использованием специфических для затмения вещей. Другие гарантируют, что их тестовые фрагменты предоставляют «магический файл» в корне и т. Д., Который может найти хост. Все эти подходы основаны на том, что хост-пакет знает о необязательном присутствии тестового фрагмента и проверяет наличие класса или файла по некоторому предопределенному пути. Таким образом, тестовые наборы могут быть найдены и добавлены в наборы тестов и т. Д. Но это подразумевает, что пакет хоста знает о назначении фрагмента (ов).

Теперь, чтобы еще больше усложнить задачу, нам часто нравится запускать тесты с помощью команд консоли Equinox. Это подразумевает, что мы должны иметь возможность регистрировать реализации CommandProvider как сервисы OSGi. Но у фрагментов нет активаторов, так как они могут зарегистрировать реализации сервисов !?

Введите TestFragmentActivator

Чтобы повысить гибкость тестирования, мы не хотим, чтобы узел хоста знал, предоставляет ли фрагмент тестовые случаи JUnit, CommandProviders или другие тестовые подходы.

В то же время мы хотим, чтобы фрагмент мог регистрировать службы OSGi или выполнять другую магию OSGi, обычно выполняемую в активаторах.

Поэтому мы предлагаем следующий подход:

  • каждый фрагмент теста должен предоставлять реализацию BundleActivator с предопределенным квалифицированным именем. Например, для FOO проекта, для тестирования внутренних служб, имя может быть com.foo.backend.service.test.TestFragmentActivator.
  • в Activator пакета узла мы добавляем такой код:
public class Activator  implements BundleActivator {private static Activator defaultInstance;// a reference to the fragment's pseudo-activatorprivate BundleActivator testFragmentActivator;public void start(BundleContext context) throws Exception {defaultInstance = this;try {Class<? extends BundleActivator> frgActClass =                               (Class<? extends BundleActivator>) Class.forName("com.foo.backend.service.test.TestFragmentActivator");testFragmentActivator = frgActClass.newInstance();testFragmentActivator.start(context);} catch (ClassNotFoundException e) {// ignore, means the test fragment is not present...// it's a dirty way to find out, but don't know how to                         // discover fragment contribution in a better way...}}public void stop(BundleContext context) throws Exception {defaultInstance = null;if(testFragmentActivator!=null) testFragmentActivator.stop(context);}public static Activator getDefault() {return defaultInstance;}}
  • и во фрагмент добавляем реализацию, которая может, например, зарегистрировать новый CommandProvider:
package com.foo.backend.service.test;import org.eclipse.osgi.framework.console.CommandProvider;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceRegistration;import com.foo.backend.service.test.impl.ServiceTestCommandProvider;/** * This is a fake activator, i.e. the OSGI platform will never see or invoke it, * as we're inside a fragment. The goal is that the host bundle tries to  * figure out if this kind of activator is present and if so, invoke its start()  * & stop() methods from inside its own ones. *  * Remark that this activator will not really start the fragment, it will remain  * in the RESOLVED state as far as the OSGi platform is concerned! */public class TestFragmentActivator implements BundleActivator {private ServiceRegistration svcReg;public void start(BundleContext context) throws Exception {ServiceTestCommandProvider svcTester = new ServiceTestCommandProvider();svcReg = context.registerService(CommandProvider.class.getName(),                                                      svcTester, null);}public void stop(BundleContext context) throws Exception {svcReg.unregister();}}

Аналогичным образом, мы могли бы использовать псевдоактиватор фрагмента для регистрации тестовых случаев JUnit для какого-либо исполнителя централизованного набора тестов и т. Д.

Может ли вообще быть полезным шаблон для фрагментов, то есть не только для фрагментов, ориентированных на тестирование?

Что вы думаете?

Эрвин Де Лей
iSencia Бельгия
Voorhavenlaan 31 — 011
B-9000 Gent
Бельгия

http://www.isencia.be/