View Javadoc
1   package com.atlassian.plugin.refimpl;
2   
3   import com.atlassian.event.api.EventPublisher;
4   import com.atlassian.plugin.Plugin;
5   import com.atlassian.plugin.event.PluginEventListener;
6   import com.atlassian.plugin.event.events.PluginFrameworkDelayedEvent;
7   import com.atlassian.plugin.module.ContainerManagedPlugin;
8   import com.atlassian.plugin.test.PluginJarBuilder;
9   import com.atlassian.tenancy.api.TenantContext;
10  import org.hamcrest.Matchers;
11  import org.junit.After;
12  import org.junit.Before;
13  import org.junit.Rule;
14  import org.junit.Test;
15  import org.junit.contrib.java.lang.system.RestoreSystemProperties;
16  import org.junit.runner.RunWith;
17  import org.mockito.Mock;
18  import org.mockito.invocation.InvocationOnMock;
19  import org.mockito.stubbing.Answer;
20  
21  import javax.servlet.ServletContext;
22  import java.io.File;
23  
24  import static com.atlassian.plugin.refimpl.tenant.RefappTenancyCondition.getAtlassianTenancyEnabledProperty;
25  import static org.apache.commons.io.FileUtils.deleteQuietly;
26  import static org.apache.commons.io.FileUtils.forceMkdir;
27  import static org.hamcrest.CoreMatchers.instanceOf;
28  import static org.hamcrest.CoreMatchers.startsWith;
29  import static org.hamcrest.MatcherAssert.assertThat;
30  import static org.hamcrest.Matchers.is;
31  import static org.mockito.Matchers.any;
32  import static org.mockito.Mockito.when;
33  
34  /**
35   * Tests for the {@link ContainerManager}.
36   *
37   * When running this test you will see ERROR logs about org.springframework.web not starting because it can't resolve the servlet
38   * package. This is because this component is provided at runtime by the servlet container, that is,
39   * Tomcat. I think the right fix here is to allow the framework bundles to be configured for this test, since we don't need the
40   * full set of framework bundles in this case. Even better, we could break up ContainerManager into more testable pieces, as it
41   * is quite a monolith.
42   */
43  @RunWith(org.mockito.runners.MockitoJUnitRunner.class)
44  public class ContainerManagerTest {
45      @Rule
46      public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(getAtlassianTenancyEnabledProperty());
47  
48      @Mock
49      private ServletContext servletContext;
50  
51      private File webappDirectory;
52      private File frameworkBundles;
53  
54      public static class Helper {
55          static final String PLUGIN_KEY = "test.helper";
56  
57          private final TenantContext tenantContext;
58  
59          private Boolean tenantAvailableAfterEarlyStartup;
60  
61          public Helper(final EventPublisher eventPublisher, final TenantContext tenantContext) {
62              this.tenantContext = tenantContext;
63              eventPublisher.register(this);
64          }
65  
66          public Boolean getTenantAvailableAfterEarlyStartup() {
67              return tenantAvailableAfterEarlyStartup;
68          }
69  
70          @PluginEventListener
71          public void onEarlyStartupComplete(PluginFrameworkDelayedEvent pluginFrameworkDelayedEvent) {
72              tenantAvailableAfterEarlyStartup = (null != tenantContext.getCurrentTenant());
73          }
74      }
75  
76      @Before
77      public void setUp() throws Exception {
78          webappDirectory = new File("target/" + ContainerManagerTest.class.getName());
79          frameworkBundles = new File("target/framework-bundles");
80          System.setProperty("framework.bundles", "target/framework-bundles");
81          forceMkdir(webappDirectory);
82          when(servletContext.getRealPath(any(String.class))).thenAnswer(new Answer<Object>() {
83              @Override
84              public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
85                  String path = (String) invocationOnMock.getArguments()[0];
86                  // Paths that aren't absolute won't work with Tomcat 8, so let's stop them now
87                  assertThat(path, startsWith("/"));
88                  return new File(webappDirectory, path).getPath();
89              }
90          });
91          when(servletContext.getMajorVersion()).thenReturn(3);
92          when(servletContext.getMinorVersion()).thenReturn(1);
93          final File pluginsDirectory = new File(webappDirectory, "/WEB-INF/plugins");
94          forceMkdir(pluginsDirectory);
95          new PluginJarBuilder("testHelper")
96                  .addFormattedResource("atlassian-plugin.xml",
97                          "<atlassian-plugin name='TestHelper' key='" + Helper.PLUGIN_KEY + "' pluginsVersion='2'>",
98                          "    <plugin-info>",
99                          "        <version>1.0</version>",
100                         "    </plugin-info>",
101                         "    <component key='helper' class='" + Helper.class.getName() + "'/>",
102                         "</atlassian-plugin>")
103                 .build(pluginsDirectory);
104     }
105 
106     @After
107     public void tearDown() throws Exception {
108         deleteQuietly(webappDirectory);
109     }
110 
111     @Test
112     public void tenantAvailableAfterEarlyStartupWhenTenancyNotEnabled() {
113         final ContainerManager containerManager = new ContainerManager(servletContext);
114         try {
115             final Helper helper = getHelper(containerManager);
116             assertThat(helper.getTenantAvailableAfterEarlyStartup(), is(Boolean.TRUE));
117         } finally {
118             containerManager.shutdown();
119         }
120     }
121 
122     @Test
123     public void tenantNotAvailableAfterEarlyStatupWhenTenancyEnabled() {
124         System.setProperty(getAtlassianTenancyEnabledProperty(), "true");
125         final ContainerManager containerManager = new ContainerManager(servletContext);
126         try {
127             final Helper helper = getHelper(containerManager);
128             assertThat(helper.getTenantAvailableAfterEarlyStartup(), is(Boolean.FALSE));
129         } finally {
130             containerManager.shutdown();
131         }
132     }
133 
134     private Helper getHelper(final ContainerManager containerManager) {
135         final Plugin plugin = containerManager.getPluginAccessor().getPlugin(Helper.PLUGIN_KEY);
136         assertThat(plugin, instanceOf(ContainerManagedPlugin.class));
137         final Object helperBean = ((ContainerManagedPlugin) plugin).getContainerAccessor().getBean("helper");
138         assertThat(helperBean, Matchers.instanceOf(Helper.class));
139         return (Helper) helperBean;
140     }
141 }