1 package com.atlassian.plugin.osgi.factory;
2
3 import com.atlassian.plugin.PluginState;
4 import com.atlassian.plugin.descriptors.AbstractModuleDescriptor;
5 import com.atlassian.plugin.descriptors.RequiresRestart;
6 import com.atlassian.plugin.event.PluginEventManager;
7 import com.atlassian.plugin.event.events.PluginContainerRefreshedEvent;
8 import junit.framework.TestCase;
9 import org.mockito.invocation.InvocationOnMock;
10 import org.mockito.stubbing.Answer;
11 import org.osgi.framework.Bundle;
12 import org.osgi.framework.BundleContext;
13 import org.osgi.framework.BundleException;
14 import org.osgi.framework.Constants;
15
16 import java.util.Dictionary;
17 import java.util.Hashtable;
18
19 import static org.mockito.Mockito.*;
20
21 public class TestOsgiPlugin extends TestCase
22 {
23 private Bundle bundle;
24 private OsgiPlugin plugin;
25 private BundleContext bundleContext;
26 private Dictionary<String, String> dict;
27 private OsgiPluginHelper helper;
28
29 @Override
30 public void setUp()
31 {
32 bundle = mock(Bundle.class);
33 dict = new Hashtable<String, String>();
34 dict.put(Constants.BUNDLE_DESCRIPTION, "desc");
35 dict.put(Constants.BUNDLE_VERSION, "1.0");
36 when(bundle.getHeaders()).thenReturn(dict);
37 bundleContext = mock(BundleContext.class);
38 when(bundle.getBundleContext()).thenReturn(bundleContext);
39
40 helper = mock(OsgiPluginHelper.class);
41 when(helper.getBundle()).thenReturn(bundle);
42
43 plugin = new OsgiPlugin(mock(PluginEventManager.class), helper);
44 }
45
46 @Override
47 public void tearDown()
48 {
49 bundle = null;
50 plugin = null;
51 bundleContext = null;
52 }
53
54 public void testEnabled() throws BundleException
55 {
56 when(bundle.getState()).thenReturn(Bundle.RESOLVED);
57 plugin.enable();
58 verify(bundle).start();
59 }
60
61 public void testDisabled() throws BundleException
62 {
63 when(bundle.getState()).thenReturn(Bundle.ACTIVE);
64 plugin.disable();
65 verify(bundle).stop();
66 }
67
68 public void testDisabledOnNonDynamicPlugin() throws BundleException
69 {
70 plugin.addModuleDescriptor(new StaticModuleDescriptor());
71 plugin.onPluginFrameworkStartedEvent(null);
72 when(bundle.getState()).thenReturn(Bundle.ACTIVE);
73 plugin.disable();
74 verify(bundle, never()).stop();
75 }
76
77 public void testUninstall() throws BundleException
78 {
79 when(bundle.getState()).thenReturn(Bundle.ACTIVE);
80 plugin.uninstall();
81 assertEquals(plugin.getPluginState(), PluginState.UNINSTALLED);
82 }
83
84 public void testOnSpringRefresh()
85 {
86 plugin.setKey("plugin-key");
87 when(bundle.getState()).thenReturn(Bundle.RESOLVED);
88 plugin.enable();
89 PluginContainerRefreshedEvent event = new PluginContainerRefreshedEvent(new Object(), "plugin-key");
90 plugin.onSpringContextRefresh(event);
91 assertEquals(PluginState.ENABLED, plugin.getPluginState());
92 }
93
94 public void testQuickOnSpringRefresh() throws BundleException, InterruptedException
95 {
96 plugin.setKey("plugin-key");
97 when(bundle.getState()).thenReturn(Bundle.RESOLVED);
98
99 final ConcurrentStateEngine states = new ConcurrentStateEngine("bundle-starting", "spring-created", "bundle-started", "mid-start", "end");
100 when(bundle.getBundleContext()).thenAnswer(new Answer<Object>()
101 {
102 public Object answer(InvocationOnMock invocation) throws Throwable
103 {
104 states.tryNextState("bundle-started", "mid-start");
105 return mock(BundleContext.class);
106 }
107 });
108
109 doAnswer(new Answer<Object>()
110 {
111 public Object answer(InvocationOnMock invocation) throws Throwable
112 {
113 states.state("bundle-starting");
114 Thread t = new Thread()
115 {
116 public void run()
117 {
118 PluginContainerRefreshedEvent event = new PluginContainerRefreshedEvent(new Object(), "plugin-key");
119 states.tryNextState("bundle-starting", "spring-created");
120 plugin.onSpringContextRefresh(event);
121 }
122 };
123 t.start();
124 states.tryNextState("spring-created", "bundle-started");
125 return null;
126 }
127 }).when(bundle).start();
128
129 plugin.enable();
130
131
132 states.tryNextState("mid-start", "end");
133
134 assertEquals(PluginState.ENABLED, plugin.getPluginState());
135 }
136
137 public void testOnSpringRefreshNotEnabling()
138 {
139 plugin.setKey("plugin-key");
140 PluginContainerRefreshedEvent event = new PluginContainerRefreshedEvent(new Object(), "plugin-key");
141 when(bundle.getState()).thenReturn(Bundle.ACTIVE);
142 plugin.disable();
143 plugin.onSpringContextRefresh(event);
144 assertEquals(PluginState.DISABLED, plugin.getPluginState());
145 }
146
147 @RequiresRestart
148 public static class StaticModuleDescriptor extends AbstractModuleDescriptor<Object>
149 {
150 public Object getModule()
151 {
152 return null;
153 }
154 }
155 }