/jira-project/jira-components/jira-plugins/jira-ha-plugin/ha-test-api/src/main/java/com/atlassian/jira/plugins/ha/testapi/test/JiraCluster.java
Java | 271 lines | 190 code | 47 blank | 34 comment | 3 complexity | 9523ffdce60268fdd31fc490b805d58f MD5 | raw file
Possible License(s): Apache-2.0
- package com.atlassian.jira.plugins.ha.testapi.test;
- import com.atlassian.jira.functest.framework.Administration;
- import com.atlassian.jira.functest.framework.AdministrationImpl;
- import com.atlassian.jira.functest.framework.DefaultFuncTestHttpUnitOptions;
- import com.atlassian.jira.functest.framework.FuncTestWebClientListener;
- import com.atlassian.jira.functest.framework.LocatorFactoryImpl;
- import com.atlassian.jira.functest.framework.Navigation;
- import com.atlassian.jira.functest.framework.NavigationImpl;
- import com.atlassian.jira.functest.framework.assertions.Assertions;
- import com.atlassian.jira.functest.framework.assertions.AssertionsImpl;
- import com.atlassian.jira.functest.framework.backdoor.Backdoor;
- import com.atlassian.jira.functest.framework.setup.JiraSetupInstanceHelper;
- import com.atlassian.jira.pageobjects.JiraTestedProduct;
- import com.atlassian.jira.pageobjects.pages.DashboardPage;
- import com.atlassian.jira.plugins.ha.testapi.client.ClusterCleaner;
- import com.atlassian.jira.plugins.ha.testapi.client.ReplicationControl;
- import com.atlassian.jira.webtests.WebTesterFactory;
- import com.atlassian.jira.webtests.util.JIRAEnvironmentData;
- import com.atlassian.pageobjects.elements.timeout.DefaultTimeouts;
- import com.google.common.base.Throwables;
- import com.google.common.collect.ImmutableList;
- import net.sourceforge.jwebunit.WebTester;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.net.URL;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- import java.util.Random;
- import java.util.concurrent.TimeUnit;
- import static com.atlassian.pageobjects.elements.query.Conditions.forSupplier;
- import static com.atlassian.pageobjects.elements.query.Poller.waitUntilTrue;
- /**
- * A set of nodes that run as part of a JIRA cluster for testing.
- */
- public class JiraCluster {
- private static final String ADMIN_USERNAME = "admin";
- private static final String ADMIN_PASSWORD = "admin";
- private static final String USER_USERNAME = "fred";
- private static final String USER_PASSWORD = "fred";
- private final List<? extends Node> nodes;
- private final Random randomGenerator;
- private final ReplicationControl replication;
- private final ClusterCleaner cleaner;
- public JiraCluster(Collection<? extends Node> nodes) {
- this.nodes = ImmutableList.copyOf(nodes);
- this.randomGenerator = new Random();
- //Replication can be used from any node with same effect since actions typically wait for all nodes to sync
- this.replication = new ReplicationControl(this.nodes.get(0).environment());
- this.cleaner = new ClusterCleaner(this);
- }
- /**
- * @return a random node in the cluster.
- */
- public Node anyNode() {
- return nodes.get(randomGenerator.nextInt(nodes.size()));
- }
- /**
- * @return returns a node guaranteed to be different than the specified node.
- */
- public Node differentNode(Node than) {
- List<Node> remainingNodes = new ArrayList<>(this.nodes);
- remainingNodes.remove(than);
- return remainingNodes.get(randomGenerator.nextInt(remainingNodes.size()));
- }
- protected ReplicationControl replication() {
- return replication;
- }
- public Collection<? extends Node> nodes() {
- return nodes;
- }
- public ClusterCleaner cleaner() {
- return cleaner;
- }
- public String adminUsername() {
- return ADMIN_USERNAME;
- }
- public String adminPassword() {
- return ADMIN_PASSWORD;
- }
- /**
- * Waits until all nodes in the cluster have synchronized their indexes and there are no pending inter-node operations.
- * Fails with an exception if nodes haven't synchronized after the specified time.
- */
- public void waitForSync(long time, TimeUnit timeUnit) {
- replication().waitForAllReplicationOperations(time, timeUnit);
- }
- /**
- * Waits until all nodes in the cluster have synchronized their indexes and there are no pending inter-node operations.
- * Fails with an exception if nodes haven't synchronized up after 30 seconds.
- */
- public void waitForSync() {
- waitForSync(30, TimeUnit.SECONDS);
- }
- /**
- * Waits for all cluster nodes to be fully started up, throwing an error if it takes longer than the specified time.
- */
- public void waitForStartup(long time, TimeUnit timeUnit) {
- int nodeCount = nodes.size();
- replication().waitForClusterNodes(nodeCount, time, timeUnit);
- }
- /**
- * Waits for all cluster nodes ot be fully started up, throwing an error if it takes longer than 5 minutes.
- */
- public void waitForStartup() {
- //It really can take a while for all the nodes to come up
- waitForStartup(5, TimeUnit.MINUTES);
- }
- @Override
- public String toString() {
- return JiraCluster.class.getSimpleName() + nodes();
- }
- /**
- * A node running in a JIRA cluster.
- */
- public static class Node {
- private final JiraTestedProduct product;
- private final WebTester tester;
- private final Administration administration;
- public Node(JiraTestedProduct product) {
- this(product, false);
- }
- public Node(JiraTestedProduct product, boolean skipSetup) {
- this.product = product;
- JIRAEnvironmentData environmentData =
- new HaProductEnvironmentData(product.getProductInstance(), "./src/test/resources");
- this.tester = WebTesterFactory.createNewWebTester(environmentData);
- DefaultFuncTestHttpUnitOptions.setDefaultOptions();
- final JiraSetupInstanceHelper helper = new JiraSetupInstanceHelper(tester, environmentData);
- if (skipSetup) {
- // An easy way to navigate past startup.jsp
- helper.isJiraSetup();
- } else {
- ensureJIRAIsReadyToGo(helper);
- }
- Navigation navigation = new NavigationImpl(tester, environmentData);
- Assertions assertions = new AssertionsImpl(tester, environmentData, navigation,
- new LocatorFactoryImpl(tester));
- administration = new AdministrationImpl(tester, environmentData, navigation, assertions);
- }
- private void ensureJIRAIsReadyToGo(JiraSetupInstanceHelper helper) {
- //Sigh, due to binary incompatible changes between versions we have to use reflection to invoke this
- //7.1+: helper.ensureJIRAIsReadyToGo()
- //7.0-: helper.ensureJIRAIsReadyToGo(WebClientListener)
- try {
- Method em = JiraSetupInstanceHelper.class.getMethod("ensureJIRAIsReadyToGo");
- em.invoke(helper);
- } catch (NoSuchMethodException e) {
- try {
- Method em = JiraSetupInstanceHelper.class.getMethod("ensureJIRAIsReadyToGo", FuncTestWebClientListener.class);
- em.invoke(helper, new FuncTestWebClientListener());
- } catch (NoSuchMethodException ex) {
- throw new RuntimeException("Failed to find a compatible ensureJIRAIsReadyToGo method in JiraSetupInstanceHelper.", e);
- } catch (IllegalAccessException ex) {
- //Should not happen
- throw new RuntimeException(e);
- } catch (InvocationTargetException ex) {
- Throwables.propagateIfPossible(e.getCause());
- throw new RuntimeException(e);
- }
- } catch (IllegalAccessException e) {
- //Should not happen
- throw new RuntimeException(e);
- } catch (InvocationTargetException e) {
- Throwables.propagateIfPossible(e.getCause());
- throw new RuntimeException(e);
- }
- }
- public Backdoor backdoor() {
- return product.backdoor();
- }
- public JIRAEnvironmentData environment() {
- return product.environmentData();
- }
- public JiraTestedProduct product() {
- return product;
- }
- public WebTester tester() {
- return tester;
- }
- public Administration admin() {
- return administration;
- }
- public String baseUrlString() {
- return environment().getBaseUrl().toExternalForm();
- }
- public URL baseUrl() {
- return environment().getBaseUrl();
- }
- public URI baseUri() {
- try {
- return environment().getBaseUrl().toURI();
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- }
- public void login() {
- login(ADMIN_USERNAME, ADMIN_PASSWORD);
- }
- public void loginAsUser() {
- login(USER_USERNAME, USER_PASSWORD);
- }
- public void login(String username, String password) {
- login(username, password, product());
- }
- public void logout() {
- product().logout();
- }
- private static void login(String username, String password, JiraTestedProduct... products) {
- for (JiraTestedProduct product : products) {
- product.quickLogin(username, password);
- DashboardPage homePage = product.gotoHomePage();
- waitUntilTrue("Couldn't authenticate node", forSupplier(
- DefaultTimeouts.DEFAULT_PAGE_LOAD, () -> homePage.getHeader().isLoggedIn()));
- }
- }
- @Override
- public String toString() {
- return "[" + baseUrlString() + "]";
- }
- }
- }