1 package com.atlassian.plugin.osgi.factory;
2
3 import java.util.Dictionary;
4 import java.util.Hashtable;
5 import java.util.List;
6 import java.util.Set;
7
8 import com.atlassian.plugin.module.ContainerAccessor;
9
10 import com.google.common.collect.ImmutableList;
11
12 import org.apache.felix.framework.resolver.Module;
13 import org.junit.After;
14 import org.junit.Before;
15 import org.junit.Rule;
16 import org.junit.Test;
17 import org.junit.rules.ExpectedException;
18 import org.osgi.framework.Bundle;
19 import org.osgi.framework.BundleContext;
20 import org.osgi.framework.Constants;
21 import org.osgi.service.packageadmin.PackageAdmin;
22 import org.springframework.beans.factory.config.BeanDefinition;
23 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
24 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
25 import org.springframework.context.support.GenericApplicationContext;
26
27 import static org.hamcrest.MatcherAssert.assertThat;
28 import static org.hamcrest.Matchers.arrayContaining;
29 import static org.hamcrest.Matchers.empty;
30 import static org.hamcrest.Matchers.is;
31 import static org.hamcrest.Matchers.notNullValue;
32 import static org.hamcrest.Matchers.nullValue;
33 import static org.mockito.Matchers.argThat;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37
38 public class TestOsgiPluginInstalledHelper
39 {
40 @Rule
41 public ExpectedException expectedException = ExpectedException.none();
42
43
44
45
46 interface ReflectableBundle extends Bundle
47 {
48 List<Module> getModules();
49 }
50
51 private ReflectableBundle bundle;
52 private BundleContext bundleContext;
53 private Dictionary<String, String> dict;
54 private OsgiPluginHelper helper;
55 private PackageAdmin packageAdmin;
56
57 @Before
58 public void setUp()
59 {
60 bundle = mock(ReflectableBundle.class);
61 dict = new Hashtable<String, String>();
62 dict.put(Constants.BUNDLE_DESCRIPTION, "desc");
63 dict.put(Constants.BUNDLE_VERSION, "1.0");
64 when(bundle.getHeaders()).thenReturn(dict);
65 bundleContext = mock(BundleContext.class);
66 when(bundle.getBundleContext()).thenReturn(bundleContext);
67
68 helper = mock(OsgiPluginHelper.class);
69 when(helper.getBundle()).thenReturn(bundle);
70
71 packageAdmin = mock(PackageAdmin.class);
72
73 helper = new OsgiPluginInstalledHelper(bundle, packageAdmin);
74 }
75
76 @After
77 public void tearDown()
78 {
79 bundle = null;
80 packageAdmin = null;
81 helper = null;
82 dict = null;
83 bundleContext = null;
84 }
85
86 @Test
87 public void canSetContainerAccessorToSpringGenericApplicationContext()
88 {
89 final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
90 final BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(ChildBean.class).getBeanDefinition();
91 beanFactory.registerBeanDefinition("child", beanDefinition);
92
93 when(bundle.getSymbolicName()).thenReturn("foo");
94 helper.setPluginContainer(new GenericApplicationContext(beanFactory));
95 final SetterInjectedBean bean = new SetterInjectedBean();
96 helper.getContainerAccessor().injectBean(bean);
97 assertThat(bean.getChild(), notNullValue());
98 }
99
100 @Test
101 public void canSetContainerAccessorToCustomContainerAccessor()
102 {
103 final ContainerAccessor containerAccessor = mock(ContainerAccessor.class);
104 final String expectedBean = "foo";
105 when(containerAccessor.createBean(String.class)).thenReturn(expectedBean);
106
107 helper.setPluginContainer(containerAccessor);
108
109 final String actualBean = helper.getContainerAccessor().createBean(String.class);
110 assertThat(actualBean, is(expectedBean));
111 }
112
113 @Test
114 public void getRequiredContainerAccessorReturnsContainerAccessor()
115 {
116 final ContainerAccessor containerAccessor = mock(ContainerAccessor.class);
117 helper.setPluginContainer(containerAccessor);
118
119 assertThat(helper.getRequiredContainerAccessor(), is(helper.getContainerAccessor()));
120 }
121
122 @Test
123 public void beforeSetGetContainerAccessorIsNull()
124 {
125 assertThat(helper.getContainerAccessor(), nullValue());
126 }
127
128 @Test
129 public void beforeSetGetRequiredContainerAccessorThrows()
130 {
131 final String bundleSymbolicName = "test-bundle-symbolicName";
132 when(bundle.getSymbolicName()).thenReturn(bundleSymbolicName);
133 expectedException.expect(IllegalStateException.class);
134 expectedException.expectMessage(bundleSymbolicName);
135 helper.getRequiredContainerAccessor();
136 }
137
138 @Test
139 public void disableWithoutEnablingDoesNotThrow()
140 {
141 helper.onDisable();
142 }
143
144 @Test
145 public void installedBundlesAreResolvedByGetRequiredPlugins()
146 {
147 when(bundle.getState()).thenReturn(Bundle.INSTALLED);
148 when(bundle.getModules()).thenReturn(ImmutableList.<Module>of());
149 when(packageAdmin.resolveBundles(argThat(arrayContaining(bundle)))).thenReturn(true);
150 helper.getRequiredPlugins();
151 verify(packageAdmin).resolveBundles(new Bundle[] { bundle });
152 }
153
154 @Test
155 public void getRequiredPluginsReturnsEmptySetIfBundleCannotBeResolved()
156 {
157 final String symbolicName = "test-bundle-sybolicName";
158 when(bundle.getSymbolicName()).thenReturn(symbolicName);
159 when(bundle.getState()).thenReturn(Bundle.INSTALLED);
160 when(packageAdmin.resolveBundles(argThat(arrayContaining(bundle)))).thenReturn(false);
161 final Set<String> requiredPlugins = helper.getRequiredPlugins();
162 verify(packageAdmin).resolveBundles(new Bundle[] { bundle });
163 assertThat(requiredPlugins, empty());
164 }
165
166 public static class ChildBean
167 {
168 }
169
170 public static class SetterInjectedBean
171 {
172 private ChildBean child;
173
174 public ChildBean getChild()
175 {
176 return child;
177 }
178
179 @SuppressWarnings ("UnusedDeclaration")
180 public void setChild(final ChildBean child)
181 {
182 this.child = child;
183 }
184 }
185 }