1 package com.atlassian.sal.core.lifecycle;
2
3 import com.atlassian.plugin.event.events.PluginFrameworkStartedEvent;
4 import com.atlassian.sal.api.lifecycle.LifecycleAware;
5 import com.google.common.collect.ImmutableList;
6 import org.junit.Test;
7 import org.junit.runner.RunWith;
8 import org.mockito.invocation.InvocationOnMock;
9 import org.mockito.runners.MockitoJUnitRunner;
10 import org.mockito.stubbing.Answer;
11 import org.osgi.framework.Bundle;
12 import org.osgi.framework.ServiceReference;
13
14 import java.util.Collection;
15
16 import static org.hamcrest.MatcherAssert.assertThat;
17 import static org.hamcrest.Matchers.is;
18 import static org.hamcrest.Matchers.notNullValue;
19 import static org.mockito.Matchers.anyString;
20 import static org.mockito.Matchers.same;
21 import static org.mockito.Mockito.doThrow;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.never;
24 import static org.mockito.Mockito.verify;
25 import static org.mockito.Mockito.when;
26
27 @RunWith(MockitoJUnitRunner.class)
28 public class TestDefaultLifecycleManager extends TestDefaultLifecycleManagerBase {
29 @Test
30 public void onStartCalledForServicesRegisteredBeforeDefaultLifecycleManagerIsInitialized() throws Exception {
31 final LifecycleAware lifecycleAware = mock(LifecycleAware.class);
32 final ServiceReference<LifecycleAware> service = registerService(pluginBundle, lifecycleAware);
33 when(bundleContext.getServiceReferences(LifecycleAware.class, null)).thenReturn(ImmutableList.of(service));
34
35 defaultLifecycleManager.afterPropertiesSet();
36
37 isApplicationSetup = true;
38 enablePlugin(pluginKey);
39
40
41 verify(lifecycleAware, never()).onStart();
42
43 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
44
45
46 verify(lifecycleAware).onStart();
47
48
49
50 verify(bundleContext).ungetService(service);
51 }
52
53 @Test
54 public void onStartCalledWhenPluginFrameworkStartedIfApplicationIsSetup() throws Exception {
55 defaultLifecycleManager.afterPropertiesSet();
56
57 final LifecycleAware lifecycleAware = mockLifecycleAwareAndRegisterService(pluginBundle);
58 enablePlugin(pluginKey);
59
60
61 verify(lifecycleAware, never()).onStart();
62
63 isApplicationSetup = true;
64 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
65
66
67 verify(lifecycleAware).onStart();
68 }
69
70 @Test
71 public void onStartCalledWhenStartCalledIfApplicationIsSetupAfterPluginFrameworkStarted() throws Exception {
72 defaultLifecycleManager.afterPropertiesSet();
73
74 final LifecycleAware lifecycleAware = mockLifecycleAwareAndRegisterService(pluginBundle);
75 enablePlugin(pluginKey);
76
77 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
78
79
80 verify(lifecycleAware, never()).onStart();
81
82 isApplicationSetup = true;
83 defaultLifecycleManager.start();
84
85
86 verify(lifecycleAware).onStart();
87 }
88
89 @Test
90 public void onStartCalledWhenPluginEnabledAfterStarted() throws Exception {
91 defaultLifecycleManager.afterPropertiesSet();
92
93 final LifecycleAware lifecycleAware = mockLifecycleAwareAndRegisterService(pluginBundle);
94 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
95 isApplicationSetup = true;
96 defaultLifecycleManager.start();
97
98
99 verify(lifecycleAware, never()).onStart();
100
101 enablePlugin(pluginKey);
102
103
104 verify(lifecycleAware).onStart();
105 }
106
107 @Test
108 public void onStartCalledWhenLifecycleAwareRegisteredAfterPluginEnabled() throws Exception {
109 defaultLifecycleManager.afterPropertiesSet();
110
111 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
112 isApplicationSetup = true;
113 defaultLifecycleManager.start();
114
115 enablePlugin(pluginKey);
116
117 final LifecycleAware lifecycleAware = mockLifecycleAwareAndRegisterService(pluginBundle);
118
119 verify(lifecycleAware).onStart();
120 }
121
122 @Test
123 public void notifyOnStartCalledWhenPluginFrameworkStartedWhenSetup() throws Exception {
124 defaultLifecycleManager.afterPropertiesSet();
125
126 isApplicationSetup = true;
127 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
128
129 assertThat(notifyOnStartCalled, is(1));
130 }
131
132 @Test
133 public void notifyOnStartCalledWhenStartCalledIfApplicationIsSetupAfterPluginFrameworkStarted() throws Exception {
134 defaultLifecycleManager.afterPropertiesSet();
135
136 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
137
138
139 assertThat(notifyOnStartCalled, is(0));
140
141 isApplicationSetup = true;
142 defaultLifecycleManager.start();
143
144 assertThat(notifyOnStartCalled, is(1));
145 }
146
147 @Test
148 public void notifyOnStartOnlyCalledOnceEvenWhenBothPluginFrameworkStartedAndStartCalledWhenSetup() throws Exception {
149 defaultLifecycleManager.afterPropertiesSet();
150
151 isApplicationSetup = true;
152 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
153 defaultLifecycleManager.start();
154
155 assertThat(notifyOnStartCalled, is(1));
156 }
157
158 @Test
159 public void onStartNotCalledWhenLifecycleAwareUnregisteredBeforeStart() throws Exception {
160 defaultLifecycleManager.afterPropertiesSet();
161
162 final LifecycleAware lifecycleAware = mock(LifecycleAware.class);
163 final ServiceReference serviceReference = registerService(pluginBundle, lifecycleAware);
164 unregisterService(serviceReference);
165
166 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
167 isApplicationSetup = true;
168 defaultLifecycleManager.start();
169 }
170
171 @Test
172 public void verifyListenerRegistrationManagement() throws Exception {
173 defaultLifecycleManager.afterPropertiesSet();
174
175 assertThat(serviceListener, notNullValue());
176
177 verify(pluginEventManager).register(defaultLifecycleManager);
178
179
180 verify(bundleContext).addServiceListener(same(serviceListener), anyString());
181
182
183 verify(pluginEventManager, never()).unregister(defaultLifecycleManager);
184 verify(bundleContext, never()).removeServiceListener(serviceListener);
185
186 defaultLifecycleManager.destroy();
187
188 verify(pluginEventManager).unregister(defaultLifecycleManager);
189 verify(bundleContext).removeServiceListener(serviceListener);
190 }
191
192 @Test
193 public void serviceDeregisteredJustAfterPostConstructSnapshotIsNotLeaked() throws Exception {
194
195 final LifecycleAware lifecycleAware = mock(LifecycleAware.class);
196 final ServiceReference<LifecycleAware> serviceReference = registerService(pluginBundle, lifecycleAware);
197
198 when(bundleContext.getServiceReferences(LifecycleAware.class, null)).thenAnswer(
199 new Answer<Collection<ServiceReference<LifecycleAware>>>() {
200 @Override
201 public Collection<ServiceReference<LifecycleAware>> answer(final InvocationOnMock invocation)
202 throws Throwable {
203
204 final ImmutableList<ServiceReference<LifecycleAware>> services = ImmutableList.of(serviceReference);
205 unregisterService(serviceReference);
206 return services;
207 }
208 });
209
210 defaultLifecycleManager.afterPropertiesSet();
211
212
213
214 enablePlugin(pluginKey);
215 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
216 isApplicationSetup = true;
217 defaultLifecycleManager.start();
218
219
220 verify(lifecycleAware, never()).onStart();
221 }
222
223 @Test
224 public void onStartExceptionsAreCaught() throws Exception {
225
226
227 defaultLifecycleManager.afterPropertiesSet();
228
229 final LifecycleAware lifecycleAware = mock(LifecycleAware.class);
230 final ServiceReference<LifecycleAware> service = registerService(pluginBundle, lifecycleAware);
231 doThrow(new RuntimeException("Test onStart failure")).when(lifecycleAware).onStart();
232 enablePlugin(pluginKey);
233
234
235 verify(lifecycleAware, never()).onStart();
236
237 isApplicationSetup = true;
238 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
239
240
241 verify(lifecycleAware).onStart();
242
243 verify(bundleContext).ungetService(service);
244 }
245
246 @Test
247 public void staleServiceReferencesReturningNullBundleAndLifecycleAreHandled() throws Exception {
248 verifyStaleServiceReferencesAreHandled(true);
249 }
250
251 @Test
252 public void staleServiceReferencesReturningNullLifecycleAreHandled() throws Exception {
253 verifyStaleServiceReferencesAreHandled(false);
254 }
255
256 private void verifyStaleServiceReferencesAreHandled(final boolean makeBundleNull) throws Exception {
257
258
259 defaultLifecycleManager.afterPropertiesSet();
260
261 final LifecycleAware lifecycleAware = mock(LifecycleAware.class);
262 final ServiceReference<LifecycleAware> service = registerService(pluginBundle, lifecycleAware);
263 enablePlugin(pluginKey);
264
265 if (makeBundleNull) {
266 when(service.getBundle()).thenReturn(null);
267 }
268 when(bundleContext.getService(service)).thenReturn(null);
269
270 isApplicationSetup = true;
271 defaultLifecycleManager.onPluginFrameworkStarted(new PluginFrameworkStartedEvent(pluginController, pluginAccessor));
272
273
274
275
276 verify(lifecycleAware, never()).onStart();
277
278 verify(bundleContext, never()).ungetService(service);
279 }
280
281 private LifecycleAware mockLifecycleAwareAndRegisterService(final Bundle bundle) {
282 return mockLifecycleAwareAndRegisterService(bundle, LifecycleAware.class).left();
283 }
284 }