/* * JBoss, Home of Professional Open Source * Copyright 2008, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.seam.example.common.test.booking.cluster.selenium; import java.io.IOException; import java.text.MessageFormat; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static org.testng.AssertJUnit.*; import org.jboss.seam.example.common.test.selenium.SeamSelenium; import org.jboss.seam.example.common.test.selenium.SeamSeleniumTest; import com.thoughtworks.selenium.Wait; /** * This class tests booking functionality of the example. Two instances of JBoss AS are * being used. First part of test is executed at first (master) instance. Then the first * instance is killed and a second (slave) instance takes over executing of the application. * This behaviour simulates recovery from breakdown. * * Prior to executing this test it is needed to start both JBoss AS instances manually. * For example (assuming you have created second "all" configuration ("all2")): * ./run.sh -c all -g DocsPartition -u 239.255.101.101 -b localhost -Djboss.messaging.ServerPeerID=1 * -Djboss.service.binding.set=ports-default * ./run.sh -c all2 -g DocsPartition -u 239.255.101.101 -b localhost -Djboss.messaging.ServerPeerID=2 * -Djboss.service.binding.set=ports-01 * The configuration all is considered to be master jboss instance (related to * jboss.service.binding.set=ports-default) and the application is deployed to server/all/farm directory * at "jboss5.home" location specified in ftest.properties * * * @author mgencur * @author jharting * */ public class FailoverTest extends SeamSeleniumTest { private final String HOTEL_NAME = "W Hotel"; private final String DEFAULT_USERNAME = "demo"; private final String DEFAULT_PASSWORD = "demo"; private final String EXPECTED_NAME = "Demo User"; private final String CREDIT_CARD = "0123456789012345"; private final String CREDIT_CARD_NAME = "visa"; private final long JBOSS_SHUTDOWN_TIMEOUT = 20000; private final int SECOND_BROWSER_PORT = 8180; private final String SECOND_INSTANCE_BROWSER_URL = "http://localhost:" + SECOND_BROWSER_PORT; private SeamSelenium browser2; @Override @BeforeMethod public void setUp() { super.setUp(); deleteCookies(browser); browser2 = startSecondBrowser(); deleteCookies(browser2); assertTrue("Login failed.", login(browser)); } @Override @AfterMethod public void tearDown() { logout(browser2); super.tearDown(); stopSecondBrowser(); } /** * Simply books hotel with failover during booking. */ @Test public void simpleBookingWithFailoverTest() { preFailurePart(browser); String newAddress = getAddressForSecondInstance(browser); shutdownMasterJBossInstance(); postFailurePart(browser2, newAddress); // main page String message = browser2.getText(getProperty("HOTEL_MESSAGE")); assertTrue("Booking failed. Confirmation message does not match.", message.matches( MessageFormat.format(getProperty("BOOKING_CONFIRMATION_MESSAGE"), EXPECTED_NAME, HOTEL_NAME))); } public void shutdownMasterJBossInstance() { String command = ""; if (CONTAINER.contains("jboss6")) { command = JBOSS_HOME + "/bin/shutdown.sh -s service:jmx:rmi:///jndi/rmi://localhost:1090/jmxrmi -S"; } else { command = JBOSS_HOME + "/bin/shutdown.sh -s localhost:1099 -S"; } try { Process process = Runtime.getRuntime().exec(command); process.waitFor(); Thread.sleep(JBOSS_SHUTDOWN_TIMEOUT); } catch (IOException e) { throw new RuntimeException(e.getCause()); } catch (InterruptedException e) { } } public void preFailurePart(SeamSelenium browser) { if (!isLoggedIn(browser)) fail(); if (!browser.isElementPresent(getProperty("SEARCH_SUBMIT"))) { browser.open(CONTEXT_PATH + getProperty("MAIN_PAGE")); browser.waitForPageToLoad(TIMEOUT); } enterSearchQueryUsingAJAX(browser, HOTEL_NAME); browser.click(getProperty("SEARCH_RESULT_TABLE_FIRST_ROW_LINK")); browser.waitForPageToLoad(TIMEOUT); // go to booking page browser.click(getProperty("BOOKING_BOOK")); browser.waitForPageToLoad(TIMEOUT); } public void postFailurePart(SeamSelenium browser, String newAddress) { browser2.open(newAddress); //booking page populateBookingFields(browser); //a jsessionid cookie has to be deleted because at this moment there already exists one deleteCookies(browser); browser.click(getProperty("HOTEL_PROCEED")); browser.waitForPageToLoad(TIMEOUT); deleteCookies(browser); // confirm page browser.click(getProperty("HOTEL_CONFIRM")); browser.waitForPageToLoad(TIMEOUT); } public SeamSelenium startSecondBrowser() { BROWSER_URL = SECOND_INSTANCE_BROWSER_URL; //System.out.println("host: " + HOST + ", port: " + PORT + ", browser_url: " + BROWSER_URL); return super.startBrowser(); } public void stopSecondBrowser() { browser2.stop(); } public String getAddressForSecondInstance(SeamSelenium browser) { String[] parsedStrings = browser.getLocation().split("/"); StringBuilder sb = new StringBuilder(); for (int i = 3; i != parsedStrings.length; i++){ sb.append("/").append(parsedStrings[i]); } String sid = browser.getCookieByName("JSESSIONID"); String newAddress = sb.toString(); String firstPart = newAddress.substring(0, newAddress.indexOf("?")); String secondPart = newAddress.substring(newAddress.indexOf("?") , newAddress.length()); newAddress = firstPart + ";jsessionid=" + sid + secondPart; return newAddress; } protected void populateBookingFields(SeamSelenium browser) { populateBookingFields(browser, 2, 0, CREDIT_CARD, CREDIT_CARD_NAME); } protected void populateBookingFields(SeamSelenium browser, int bed, int smoking, String creditCard, String creditCardName) { browser.select(getProperty("HOTEL_BED_FIELD"), getProperty("HOTEL_BED_FIELD_SELECT_CRITERIA") + bed); if (smoking == 1) { browser.check(getProperty("HOTEL_SMOKING_1")); } else { browser.check(getProperty("HOTEL_SMOKING_2")); } browser.type(getProperty("HOTEL_CREDIT_CARD"), creditCard); browser.type(getProperty("HOTEL_CREDIT_CARD_NAME"), creditCardName); } private void deleteCookies(SeamSelenium browser) { browser.deleteCookie("JSESSIONID", "path=" + CONTEXT_PATH + ", domain=localhost, recurse=true"); } public boolean login(SeamSelenium browser) { return login(browser, DEFAULT_USERNAME, DEFAULT_PASSWORD); } public boolean login(SeamSelenium browser, String username, String password) { if (isLoggedIn(browser)) { fail("User already logged in."); } browser.open(CONTEXT_PATH + getProperty("HOME_PAGE")); browser.waitForPageToLoad(TIMEOUT); if (!browser.getTitle().equals(getProperty("PAGE_TITLE"))) { return false; } browser.type(getProperty("LOGIN_USERNAME_FIELD"), username); browser.type(getProperty("LOGIN_PASSWORD_FIELD"), password); browser.click(getProperty("LOGIN_SUBMIT")); browser.waitForPageToLoad(TIMEOUT); return isLoggedIn(browser); } public void logout(SeamSelenium browser) { if (isLoggedIn(browser)) { browser.click(getProperty("LOGOUT")); browser.waitForPageToLoad(TIMEOUT); } } public boolean isLoggedIn(SeamSelenium browser) { return browser.isElementPresent(getProperty("LOGOUT")); } public void enterSearchQueryUsingAJAX(final SeamSelenium browser, String query) { browser.type(getProperty("SEARCH_STRING_FIELD"), ""); browser.type(getProperty("SEARCH_STRING_FIELD"), query.substring(0, query.length() - 1)); browser.typeKeys(getProperty("SEARCH_STRING_FIELD"), query.substring(query.length() - 1)); browser.click(getProperty("SEARCH_SUBMIT")); // wait for javascript to show spinner try { Thread.sleep(1000); } catch (InterruptedException e) { } // wait for page to get updated new Wait() { @Override public boolean until() { return !browser.isVisible(getProperty("SPINNER")); } }.wait("Spinner hasn't come out."); new Wait() { @Override public boolean until() { return (browser.isElementPresent(getProperty("SEARCH_RESULT_TABLE")) || browser.isElementPresent(getProperty("NO_HOTELS_FOUND"))); } }.wait("Search results not found."); } }