PageRenderTime 44ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jira-project/jira-components/jira-plugins/jira-ha-plugin/ha-test-api/src/main/java/com/atlassian/jira/plugins/ha/testapi/test/JiraCluster.java

https://bitbucket.org/ahmed_bilal_360factors/jira7-core
Java | 271 lines | 190 code | 47 blank | 34 comment | 3 complexity | 9523ffdce60268fdd31fc490b805d58f MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.atlassian.jira.plugins.ha.testapi.test;
  2. import com.atlassian.jira.functest.framework.Administration;
  3. import com.atlassian.jira.functest.framework.AdministrationImpl;
  4. import com.atlassian.jira.functest.framework.DefaultFuncTestHttpUnitOptions;
  5. import com.atlassian.jira.functest.framework.FuncTestWebClientListener;
  6. import com.atlassian.jira.functest.framework.LocatorFactoryImpl;
  7. import com.atlassian.jira.functest.framework.Navigation;
  8. import com.atlassian.jira.functest.framework.NavigationImpl;
  9. import com.atlassian.jira.functest.framework.assertions.Assertions;
  10. import com.atlassian.jira.functest.framework.assertions.AssertionsImpl;
  11. import com.atlassian.jira.functest.framework.backdoor.Backdoor;
  12. import com.atlassian.jira.functest.framework.setup.JiraSetupInstanceHelper;
  13. import com.atlassian.jira.pageobjects.JiraTestedProduct;
  14. import com.atlassian.jira.pageobjects.pages.DashboardPage;
  15. import com.atlassian.jira.plugins.ha.testapi.client.ClusterCleaner;
  16. import com.atlassian.jira.plugins.ha.testapi.client.ReplicationControl;
  17. import com.atlassian.jira.webtests.WebTesterFactory;
  18. import com.atlassian.jira.webtests.util.JIRAEnvironmentData;
  19. import com.atlassian.pageobjects.elements.timeout.DefaultTimeouts;
  20. import com.google.common.base.Throwables;
  21. import com.google.common.collect.ImmutableList;
  22. import net.sourceforge.jwebunit.WebTester;
  23. import java.lang.reflect.InvocationTargetException;
  24. import java.lang.reflect.Method;
  25. import java.net.URI;
  26. import java.net.URISyntaxException;
  27. import java.net.URL;
  28. import java.util.ArrayList;
  29. import java.util.Collection;
  30. import java.util.List;
  31. import java.util.Random;
  32. import java.util.concurrent.TimeUnit;
  33. import static com.atlassian.pageobjects.elements.query.Conditions.forSupplier;
  34. import static com.atlassian.pageobjects.elements.query.Poller.waitUntilTrue;
  35. /**
  36. * A set of nodes that run as part of a JIRA cluster for testing.
  37. */
  38. public class JiraCluster {
  39. private static final String ADMIN_USERNAME = "admin";
  40. private static final String ADMIN_PASSWORD = "admin";
  41. private static final String USER_USERNAME = "fred";
  42. private static final String USER_PASSWORD = "fred";
  43. private final List<? extends Node> nodes;
  44. private final Random randomGenerator;
  45. private final ReplicationControl replication;
  46. private final ClusterCleaner cleaner;
  47. public JiraCluster(Collection<? extends Node> nodes) {
  48. this.nodes = ImmutableList.copyOf(nodes);
  49. this.randomGenerator = new Random();
  50. //Replication can be used from any node with same effect since actions typically wait for all nodes to sync
  51. this.replication = new ReplicationControl(this.nodes.get(0).environment());
  52. this.cleaner = new ClusterCleaner(this);
  53. }
  54. /**
  55. * @return a random node in the cluster.
  56. */
  57. public Node anyNode() {
  58. return nodes.get(randomGenerator.nextInt(nodes.size()));
  59. }
  60. /**
  61. * @return returns a node guaranteed to be different than the specified node.
  62. */
  63. public Node differentNode(Node than) {
  64. List<Node> remainingNodes = new ArrayList<>(this.nodes);
  65. remainingNodes.remove(than);
  66. return remainingNodes.get(randomGenerator.nextInt(remainingNodes.size()));
  67. }
  68. protected ReplicationControl replication() {
  69. return replication;
  70. }
  71. public Collection<? extends Node> nodes() {
  72. return nodes;
  73. }
  74. public ClusterCleaner cleaner() {
  75. return cleaner;
  76. }
  77. public String adminUsername() {
  78. return ADMIN_USERNAME;
  79. }
  80. public String adminPassword() {
  81. return ADMIN_PASSWORD;
  82. }
  83. /**
  84. * Waits until all nodes in the cluster have synchronized their indexes and there are no pending inter-node operations.
  85. * Fails with an exception if nodes haven't synchronized after the specified time.
  86. */
  87. public void waitForSync(long time, TimeUnit timeUnit) {
  88. replication().waitForAllReplicationOperations(time, timeUnit);
  89. }
  90. /**
  91. * Waits until all nodes in the cluster have synchronized their indexes and there are no pending inter-node operations.
  92. * Fails with an exception if nodes haven't synchronized up after 30 seconds.
  93. */
  94. public void waitForSync() {
  95. waitForSync(30, TimeUnit.SECONDS);
  96. }
  97. /**
  98. * Waits for all cluster nodes to be fully started up, throwing an error if it takes longer than the specified time.
  99. */
  100. public void waitForStartup(long time, TimeUnit timeUnit) {
  101. int nodeCount = nodes.size();
  102. replication().waitForClusterNodes(nodeCount, time, timeUnit);
  103. }
  104. /**
  105. * Waits for all cluster nodes ot be fully started up, throwing an error if it takes longer than 5 minutes.
  106. */
  107. public void waitForStartup() {
  108. //It really can take a while for all the nodes to come up
  109. waitForStartup(5, TimeUnit.MINUTES);
  110. }
  111. @Override
  112. public String toString() {
  113. return JiraCluster.class.getSimpleName() + nodes();
  114. }
  115. /**
  116. * A node running in a JIRA cluster.
  117. */
  118. public static class Node {
  119. private final JiraTestedProduct product;
  120. private final WebTester tester;
  121. private final Administration administration;
  122. public Node(JiraTestedProduct product) {
  123. this(product, false);
  124. }
  125. public Node(JiraTestedProduct product, boolean skipSetup) {
  126. this.product = product;
  127. JIRAEnvironmentData environmentData =
  128. new HaProductEnvironmentData(product.getProductInstance(), "./src/test/resources");
  129. this.tester = WebTesterFactory.createNewWebTester(environmentData);
  130. DefaultFuncTestHttpUnitOptions.setDefaultOptions();
  131. final JiraSetupInstanceHelper helper = new JiraSetupInstanceHelper(tester, environmentData);
  132. if (skipSetup) {
  133. // An easy way to navigate past startup.jsp
  134. helper.isJiraSetup();
  135. } else {
  136. ensureJIRAIsReadyToGo(helper);
  137. }
  138. Navigation navigation = new NavigationImpl(tester, environmentData);
  139. Assertions assertions = new AssertionsImpl(tester, environmentData, navigation,
  140. new LocatorFactoryImpl(tester));
  141. administration = new AdministrationImpl(tester, environmentData, navigation, assertions);
  142. }
  143. private void ensureJIRAIsReadyToGo(JiraSetupInstanceHelper helper) {
  144. //Sigh, due to binary incompatible changes between versions we have to use reflection to invoke this
  145. //7.1+: helper.ensureJIRAIsReadyToGo()
  146. //7.0-: helper.ensureJIRAIsReadyToGo(WebClientListener)
  147. try {
  148. Method em = JiraSetupInstanceHelper.class.getMethod("ensureJIRAIsReadyToGo");
  149. em.invoke(helper);
  150. } catch (NoSuchMethodException e) {
  151. try {
  152. Method em = JiraSetupInstanceHelper.class.getMethod("ensureJIRAIsReadyToGo", FuncTestWebClientListener.class);
  153. em.invoke(helper, new FuncTestWebClientListener());
  154. } catch (NoSuchMethodException ex) {
  155. throw new RuntimeException("Failed to find a compatible ensureJIRAIsReadyToGo method in JiraSetupInstanceHelper.", e);
  156. } catch (IllegalAccessException ex) {
  157. //Should not happen
  158. throw new RuntimeException(e);
  159. } catch (InvocationTargetException ex) {
  160. Throwables.propagateIfPossible(e.getCause());
  161. throw new RuntimeException(e);
  162. }
  163. } catch (IllegalAccessException e) {
  164. //Should not happen
  165. throw new RuntimeException(e);
  166. } catch (InvocationTargetException e) {
  167. Throwables.propagateIfPossible(e.getCause());
  168. throw new RuntimeException(e);
  169. }
  170. }
  171. public Backdoor backdoor() {
  172. return product.backdoor();
  173. }
  174. public JIRAEnvironmentData environment() {
  175. return product.environmentData();
  176. }
  177. public JiraTestedProduct product() {
  178. return product;
  179. }
  180. public WebTester tester() {
  181. return tester;
  182. }
  183. public Administration admin() {
  184. return administration;
  185. }
  186. public String baseUrlString() {
  187. return environment().getBaseUrl().toExternalForm();
  188. }
  189. public URL baseUrl() {
  190. return environment().getBaseUrl();
  191. }
  192. public URI baseUri() {
  193. try {
  194. return environment().getBaseUrl().toURI();
  195. } catch (URISyntaxException e) {
  196. throw new RuntimeException(e);
  197. }
  198. }
  199. public void login() {
  200. login(ADMIN_USERNAME, ADMIN_PASSWORD);
  201. }
  202. public void loginAsUser() {
  203. login(USER_USERNAME, USER_PASSWORD);
  204. }
  205. public void login(String username, String password) {
  206. login(username, password, product());
  207. }
  208. public void logout() {
  209. product().logout();
  210. }
  211. private static void login(String username, String password, JiraTestedProduct... products) {
  212. for (JiraTestedProduct product : products) {
  213. product.quickLogin(username, password);
  214. DashboardPage homePage = product.gotoHomePage();
  215. waitUntilTrue("Couldn't authenticate node", forSupplier(
  216. DefaultTimeouts.DEFAULT_PAGE_LOAD, () -> homePage.getHeader().isLoggedIn()));
  217. }
  218. }
  219. @Override
  220. public String toString() {
  221. return "[" + baseUrlString() + "]";
  222. }
  223. }
  224. }