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