diff --git a/eap-datagrid-subsystem/README.md b/eap-datagrid-subsystem/README.md index 5b0964fd7..f81537cc4 100644 --- a/eap-datagrid-subsystem/README.md +++ b/eap-datagrid-subsystem/README.md @@ -27,7 +27,7 @@ Simple start $EAP_HOME/bin/standalone.sh -4. use the CLI scipts to configure the datagrid subsystem and necessary dependencies +4. use the CLI scripts to configure the datagrid subsystem and necessary dependencies $EAP_HOME/bin/jboss-cli.sh -c --file=$SRC_HOME/install1-standalone-local.cli > restart the server ! @@ -66,7 +66,7 @@ To see the behaviour for JDG caches $EAP_HOME/bin/standalone.sh [-c standalone-ha.xml] -4. use the CLI scipts to configure the datagrid subsystem and necessary dependencies +4. use the CLI scripts to configure the datagrid subsystem and necessary dependencies $EAP_HOME/bin/jboss-cli.sh -c --file=$SRC_HOME/install1-standalone-clustered.cli > restart the server ! @@ -91,7 +91,7 @@ To see the behaviour for JDG caches Notes ======= - You can simple rename the jboss-eap-datagrid-subsystem-AppWeb.war to any other name.war to simulate different applications. - If there are multiple applicatations they share the same cache! + If there are multiple applications they share the same cache! - Caches are independent from application lifecycles. Undeploying any, or all, applications instances has no affect on a cache's lifecycle or data. Even if the cache has no persistence the data will be kept as long as the server is not stopped. - In this example the EAP server is not clustered, but if the cache is configured as clustered with the datagrid-jgroups subsystem and replicated or @@ -99,3 +99,24 @@ Notes - The respective JGroups subsystem needs to be defined for both EAP and JDG as the respective subsystems depend on different JGroups versions and provide different functionality. - Also it is indespensable that the communication addresses and port for the JGroups subsystems need to be different. This prevent from cross-talking which cause performance drawback, WARN message or error messages. + + +Run tests +======================== +1. Prepare the server instances and keep EAP server running + +2. Run `mvn test -Ptests-eap -DeapHome=$EAP_HOME` + + + +Run tests in clustered cache mode +======================== +1. Set variables + $EAP_SERVER_ZIP_PATH - path to jboss-eap.zip + $JDG_MODULES_ZIP_PATH - path to jboss-datagrid-eap-modules-library.zip + +2. Prepare two EAP server instances or run prepareTwoEAP.sh from working directory (this will prepare two EAPs) + +3. Save path to EAPs directories as $EAP_HOME1 and $EAP_HOME2 + +4. Run `mvn test -Ptests-eap-clustered -DeapHome1=$EAP_HOME1 -DeapHome2=$EAP_HOME2` \ No newline at end of file diff --git a/eap-datagrid-subsystem/pom.xml b/eap-datagrid-subsystem/pom.xml index 8074f3f89..062982fa5 100644 --- a/eap-datagrid-subsystem/pom.xml +++ b/eap-datagrid-subsystem/pom.xml @@ -66,6 +66,14 @@ 2.10.1 2.10.1 3.0.0 + + + 1.7 + 9.0.1.Final + 1.7 + + UTF-8 + phantomjs @@ -93,17 +101,33 @@ pom import + + - org.wildfly - wildfly-ejb-client-bom - ${version.wildfly} - import + org.wildfly.bom + jboss-javaee-7.0-wildfly-with-tools + ${version.jboss.spec.javaee.7.0} pom + import + + + + src/test/resources + true + + + org.codehaus.mojo @@ -116,5 +140,153 @@ + + + skip.tests.by.default + + true + + + true + + + + + + tests-eap + + false + + + + + + + org.wildfly.arquillian + wildfly-arquillian-container-managed + + + org.jboss.arquillian.protocol + arquillian-protocol-servlet + test + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + ${version.buildhelper.maven.plugin} + + + add-source + generate-sources + + add-source + + + + src/local/java + + + + + + + maven-surefire-plugin + + + + **/SubsystemTest* + + tests-eap + + ${basedir}/target + ${project.artifactId}.war + + + jbossas-managed + + + -Djava.util.logging.config.file=${basedir}/web/src/test/resources/logging.properties + + + + + + + + + + tests-eap-clustered + + false + + + + org.wildfly.arquillian + wildfly-arquillian-container-managed + + + org.jboss.arquillian.protocol + arquillian-protocol-servlet + test + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + ${version.buildhelper.maven.plugin} + + + add-source + generate-sources + + add-source + + + + src/local/java + + + + + + + maven-surefire-plugin + + + + **/SubsystemClusteredTest* + + tests-eap-clustered + + ${basedir}/target + ${project.artifactId}.war + + + jbossas-cluster + + + + + -Djava.util.logging.config.file=${basedir}/web/src/test/resources/logging.properties + + + + + + + diff --git a/eap-datagrid-subsystem/prepareTwoEAP.sh b/eap-datagrid-subsystem/prepareTwoEAP.sh new file mode 100755 index 000000000..f3e68f01d --- /dev/null +++ b/eap-datagrid-subsystem/prepareTwoEAP.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +export SRC_HOME=`pwd` + +echo "Removing directories from previous run ..." +rm -rf eap-server +rm -rf jdg-modules +rm -rf eap1 +rm -rf eap2 + +echo "Unzipping EAP server ..." +unzip -q ${EAP_SERVER_ZIP_PATH} -d eap-server +export EAP_HOME=`cd eap-server/*;pwd` +echo $EAP_HOME + +echo "Unzipping JDG eap modules library ..." +unzip -q ${JDG_MODULES_ZIP_PATH} -d jdg-modules +export JDG_MODULES=`cd jdg-modules/*;pwd` +echo $JDG_MODULES + +echo "Copying the JDG modules to EAP home directory" +cp -a "${JDG_MODULES}/modules" "${EAP_HOME}" + +echo "Starting EAP server" +sh "${EAP_HOME}"/bin/standalone.sh > "${EAP_HOME}/server.log" & +sleep 10 + +echo "Executing install1-standalone-clustered.cli console scripts" +"${EAP_HOME}"/bin/jboss-cli.sh -c --file="${SRC_HOME}"/install1-standalone-clustered.cli +sleep 2 + +echo "Restarting EAP server" +(ps -ef | grep 'Standalone' | grep -v grep | awk '{print $2}' | xargs kill) > /dev/null 2>&1 +sleep 2 +sh "${EAP_HOME}"/bin/standalone.sh > "${EAP_HOME}/server.log" & +sleep 10 + +echo "Executing install2-standalone-clustered.cli console scripts" +"${EAP_HOME}"/bin/jboss-cli.sh -c --file="${SRC_HOME}"/install2-standalone-clustered.cli +sleep 5 + +echo "Stopping EAP server" +(ps -ef | grep 'Standalone' | grep -v grep | awk '{print $2}' | xargs kill) > /dev/null 2>&1 + +echo "Making the first copy of EAP server ..." +cp -R "${EAP_HOME}" eap1 +export EAP_HOME1=`cd eap1;pwd` + +echo "Making the second copy of EAP server ..." +cp -R "${EAP_HOME}" eap2 +export EAP_HOME1=`cd eap2;pwd` diff --git a/eap-datagrid-subsystem/web/pom.xml b/eap-datagrid-subsystem/web/pom.xml index 28ba6d789..d7070d0ba 100644 --- a/eap-datagrid-subsystem/web/pom.xml +++ b/eap-datagrid-subsystem/web/pom.xml @@ -36,6 +36,9 @@ http://maven.apache.org war + + phantomjs + + + org.jboss.arquillian.junit + arquillian-junit-container + test + + + org.jboss.arquillian.graphene + graphene-webdriver + pom + test + + + junit + junit + test + diff --git a/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/Deployments.java b/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/Deployments.java new file mode 100644 index 000000000..c7b932f4e --- /dev/null +++ b/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/Deployments.java @@ -0,0 +1,19 @@ +package org.jboss.as.quickstarts.datagrid.subsystem; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.importer.ZipImporter; +import org.jboss.shrinkwrap.api.spec.WebArchive; + +import java.io.File; + +public class Deployments { + private static final String ARCHIVE_NAME = System.getProperty("subsystem.war.file"); + private static final String BUILD_DIRECTORY = System.getProperty("subsystem.war.directory"); + + public static WebArchive createDeployment() { + System.out.println(BUILD_DIRECTORY + '/' + ARCHIVE_NAME); + return ShrinkWrap.create(ZipImporter.class, ARCHIVE_NAME).importFrom(new File(BUILD_DIRECTORY + '/' + ARCHIVE_NAME)) + .as(WebArchive.class); + } + +} diff --git a/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/SubsystemClusteredTest.java b/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/SubsystemClusteredTest.java new file mode 100644 index 000000000..3645b2c3a --- /dev/null +++ b/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/SubsystemClusteredTest.java @@ -0,0 +1,145 @@ +package org.jboss.as.quickstarts.datagrid.subsystem; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.OperateOnDeployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.container.test.api.TargetsContainer; +import org.jboss.arquillian.drone.api.annotation.Drone; +import org.jboss.arquillian.graphene.findby.FindByJQuery; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +import java.net.URL; + +import static org.jboss.arquillian.graphene.Graphene.waitModel; +import static org.junit.Assert.assertTrue; + +/** + * Test for eap-datagrid-subsystem in clustered cache mode with use of Drone Arquillian extension for deployment and Graphenebrowser framework to test UI + * Test to put key:value from one server and check if is present at the second server + * + * @author Gabriel Babcan + */ +@RunWith(Arquillian.class) +@RunAsClient +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class SubsystemClusteredTest { + @FindBy(id = "invokeForm") + private WebElement form_ID; + @FindBy(id = "response") + private WebElement responseForm_ID; + @FindBy(id = "invokeForm:add") + private WebElement addValueButton; + + @FindBy(id = "invokeForm:clear") + private WebElement clearFormButton; + + @FindBy(id = "invokeForm:list") + private WebElement listValuesButton; + + @FindBy(id = "invokeForm:get") + private WebElement getValueButton; + + @FindBy(id = "invokeForm:del") + private WebElement deleteValueButton; + + @FindByJQuery("#invokeForm:contains('Key:')") + private WebElement keyLabel; + @FindByJQuery(":input[type=text]:eq(0)") + private WebElement keyInput; + @FindByJQuery(":input[type=text]:eq(1)") + private WebElement valueInput; + @FindByJQuery("#response table:eq(0) tr:eq(0) td:eq(0)") + private WebElement cacheEntries; + @FindByJQuery("#response table:eq(0) tr:eq(1) td:eq(0)") + private WebElement cacheSize; + + @Drone + WebDriver browser; + + @ArquillianResource + private URL contextPath; + + @Deployment(name = "eap1", testable = false) + @TargetsContainer("clustered-jbossas-managed-1") + public static WebArchive createTestDeployment1() { + return Deployments.createDeployment(); + } + + @Deployment(name = "eap2", testable = false) + @TargetsContainer("clustered-jbossas-managed-2") + public static WebArchive createTestDeployment2() { + return Deployments.createDeployment(); + } + + @Test + @OperateOnDeployment("eap1") + public void AinsertIntoCacheContainerOneTest() { + browser.get(contextPath.toExternalForm()); + System.out.println("Inside basicOperationsTest, contextPath: " + contextPath); + + waitModel().until().element(form_ID).is().present(); + assertTrue("form_ID element is not present", form_ID.isDisplayed()); + + waitModel().until().element(addValueButton).is().present(); + assertTrue("addValueButton is not present", addValueButton.isDisplayed()); + waitModel().until().element(listValuesButton).is().present(); + assertTrue("listValuesButton is not present", listValuesButton.isDisplayed()); + waitModel().until().element(getValueButton).is().present(); + assertTrue("getValueButton is not present", getValueButton.isDisplayed()); + + waitModel().until().element(keyInput).is().present(); + assertTrue("keyInput is not present", keyInput.isDisplayed()); + waitModel().until().element(valueInput).is().present(); + assertTrue("valueInput is not present", valueInput.isDisplayed()); + waitModel().until().element(cacheSize).is().present(); + assertTrue("cacheSize is not present", cacheSize.isDisplayed()); + + keyInput.sendKeys("key1"); + valueInput.sendKeys("value1"); + addValueButton.click(); + + String cacheSizeAfterFirstEntry = cacheSize.getText(); + System.out.println(cacheSizeAfterFirstEntry); + assertTrue("cacheSize after first entry into first container is not 1 but " + cacheSizeAfterFirstEntry, cacheSizeAfterFirstEntry.equals("1")); + + clearFormButton.click(); + keyInput.sendKeys("key2"); + valueInput.sendKeys("value2"); + addValueButton.click(); + + String cacheSizeAfterSecondEntry = cacheSize.getText(); + System.out.println(cacheSizeAfterSecondEntry); + assertTrue("cacheSize after second entry is not 2 but " + cacheSizeAfterSecondEntry, cacheSizeAfterSecondEntry.equals("2")); + } + + @Test + @OperateOnDeployment("eap2") + public void BlistCacheValuesContainerTwoTest() { + browser.get(contextPath.toExternalForm()); + System.out.println("Inside basicOperationsTest, contextPath: " + contextPath); + + waitModel().until().element(form_ID).is().present(); + assertTrue("form_ID element is not present", form_ID.isDisplayed()); + + waitModel().until().element(listValuesButton).is().present(); + assertTrue("listValuesButton is not present", listValuesButton.isDisplayed()); + waitModel().until().element(cacheSize).is().present(); + assertTrue("cacheSize is not present", cacheSize.isDisplayed()); + + listValuesButton.click(); + waitModel().until().element(cacheEntries).is().present(); + assertTrue("cacheEntries is not present", cacheEntries.isDisplayed()); + String listOfEntries = cacheEntries.getText().trim(); + System.out.println(listOfEntries); + assertTrue("cacheEntries number loaded from second application is wrong: " + listOfEntries, listOfEntries.equals("key1 : value1 || key2 : value2 ||")); + } +} diff --git a/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/SubsystemTest.java b/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/SubsystemTest.java new file mode 100644 index 000000000..56bd492c9 --- /dev/null +++ b/eap-datagrid-subsystem/web/src/test/java/org/jboss/as/quickstarts/datagrid/subsystem/SubsystemTest.java @@ -0,0 +1,159 @@ +package org.jboss.as.quickstarts.datagrid.subsystem; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.drone.api.annotation.Drone; +import org.jboss.arquillian.graphene.findby.FindByJQuery; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.FindBy; + +import java.net.URL; + +import static org.jboss.arquillian.graphene.Graphene.waitModel; +import static org.junit.Assert.assertTrue; + +/** + * Test for eap-datagrid-subsystem with use of Drone Arquillian extension for deployment and Graphenebrowser framework to test UI + * Test basic operations like put key:value, check if added, load list and delete values by key + * + * @author gbabcan@redhat.com + */ +@RunWith(Arquillian.class) +@RunAsClient +public class SubsystemTest { + + @FindBy(id = "invokeForm") + private WebElement form_ID; + @FindBy(id = "response") + private WebElement responseForm_ID; + @FindBy(id = "invokeForm:add") + private WebElement addValueButton; + + @FindBy(id = "invokeForm:clear") + private WebElement clearFormButton; + + @FindBy(id = "invokeForm:list") + private WebElement listValuesButton; + + @FindBy(id = "invokeForm:get") + private WebElement getValueButton; + + @FindBy(id = "invokeForm:del") + private WebElement deleteValueButton; + + @FindByJQuery("#invokeForm:contains('Key:')") + private WebElement keyLabel; + @FindByJQuery(":input[type=text]:eq(0)") + private WebElement keyInput; + @FindByJQuery(":input[type=text]:eq(1)") + private WebElement valueInput; + @FindByJQuery("#response table:eq(0) tr:eq(0) td:eq(0)") + private WebElement cacheEntries; + @FindByJQuery("#response table:eq(0) tr:eq(1) td:eq(0)") + private WebElement cacheSize; + + @Drone + WebDriver browser; + + @ArquillianResource + private URL contextPath; + + @Deployment(testable = false) + public static WebArchive createTestDeployment() { + return Deployments.createDeployment(); + } + + @Test + public void basicOperationsTest() { + browser.get(contextPath.toExternalForm()); + System.out.println("Inside basicOperationsTest, contextPath: " + contextPath); + + waitModel().until().element(form_ID).is().present(); + assertTrue("form_ID element is not present", form_ID.isDisplayed()); + + waitModel().until().element(addValueButton).is().present(); + assertTrue("addValueButton is not present", addValueButton.isDisplayed()); + waitModel().until().element(clearFormButton).is().present(); + assertTrue("clearFormButton is not present", clearFormButton.isDisplayed()); + waitModel().until().element(listValuesButton).is().present(); + assertTrue("listValuesButton is not present", listValuesButton.isDisplayed()); + waitModel().until().element(getValueButton).is().present(); + assertTrue("getValueButton is not present", getValueButton.isDisplayed()); + waitModel().until().element(deleteValueButton).is().present(); + assertTrue("deleteValueButton is not present", deleteValueButton.isDisplayed()); + + waitModel().until().element(keyLabel).is().present(); + assertTrue("keyLabel is not present", keyLabel.isDisplayed()); + waitModel().until().element(keyInput).is().present(); + assertTrue("keyInput is not present", keyInput.isDisplayed()); + waitModel().until().element(valueInput).is().present(); + assertTrue("valueInput is not present", valueInput.isDisplayed()); + waitModel().until().element(cacheSize).is().present(); + assertTrue("cacheSize is not present", cacheSize.isDisplayed()); + + keyInput.sendKeys("key1"); + valueInput.sendKeys("value1"); + addValueButton.click(); + + String cacheSizeAfterFirstEntry = cacheSize.getText(); + System.out.println(cacheSizeAfterFirstEntry); + assertTrue("cacheSize after first entry is not 1 but " + cacheSizeAfterFirstEntry, cacheSizeAfterFirstEntry.equals("1")); + + clearFormButton.click(); + keyInput.sendKeys("key2"); + valueInput.sendKeys("value2"); + addValueButton.click(); + + String cacheSizeAfterSecondEntry = cacheSize.getText(); + System.out.println(cacheSizeAfterSecondEntry); + assertTrue("cacheSize after second entry is not 2 but " + cacheSizeAfterSecondEntry, cacheSizeAfterSecondEntry.equals("2")); + + listValuesButton.click(); + waitModel().until().element(cacheEntries).is().present(); + assertTrue("cacheEntries is not present", cacheEntries.isDisplayed()); + String listOfEntries = cacheEntries.getText().trim(); + System.out.println(listOfEntries); + assertTrue("cacheEntries after two inserts is wrong: " + listOfEntries, listOfEntries.equals("key1 : value1 || key2 : value2 ||")); + + clearFormButton.click(); + keyInput.sendKeys("key1"); + getValueButton.click(); + String valueOfKeyOne = valueInput.getAttribute("value"); + System.out.println(valueOfKeyOne); + assertTrue("retrieved value of key1 is wrong:" + valueOfKeyOne, valueOfKeyOne.equals("value1")); + + + clearFormButton.click(); + keyInput.sendKeys("key2"); + deleteValueButton.click(); + + clearFormButton.click(); + keyInput.sendKeys("key2"); + getValueButton.click(); + String valueOfNonExistingKey = valueInput.getAttribute("value"); + System.out.println(valueOfNonExistingKey); + assertTrue("retrieved value of non existing key is wrong:" + valueOfNonExistingKey, valueOfNonExistingKey.equals("NOT AVAILABLE")); + + listValuesButton.click(); + assertTrue("cacheEntries is not present", cacheEntries.isDisplayed()); + listOfEntries = cacheEntries.getText().trim(); + System.out.println(listOfEntries); + assertTrue("cacheEntries after one delete is wrong: " + listOfEntries, listOfEntries.equals("key1 : value1 ||")); + + clearFormButton.click(); + keyInput.sendKeys("key1"); + deleteValueButton.click(); + + listValuesButton.click(); + assertTrue("cacheEntries is not present", cacheEntries.isDisplayed()); + listOfEntries = cacheEntries.getText().trim(); + System.out.println(listOfEntries); + assertTrue("cacheEntries should be empty, but contains: " + listOfEntries, listOfEntries.isEmpty()); + } +} diff --git a/eap-datagrid-subsystem/web/src/test/resources/arquillian.xml b/eap-datagrid-subsystem/web/src/test/resources/arquillian.xml new file mode 100644 index 000000000..1be63bb55 --- /dev/null +++ b/eap-datagrid-subsystem/web/src/test/resources/arquillian.xml @@ -0,0 +1,35 @@ + + + ${browser} + + + + + ${eapHome} + true + + + + + + + ${eapHome1} + + + + + + + ${eapHome2} + -Djboss.socket.binding.port-offset=100 -Djboss.management.native.port=9990 + 10090 + + + + + + \ No newline at end of file diff --git a/eap-datagrid-subsystem/web/src/test/resources/logging.properties b/eap-datagrid-subsystem/web/src/test/resources/logging.properties new file mode 100644 index 000000000..787744a08 --- /dev/null +++ b/eap-datagrid-subsystem/web/src/test/resources/logging.properties @@ -0,0 +1,14 @@ +# Specify the handlers to create in the root logger +# (all loggers are children of the root logger) +# The following creates two handlers +handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler + +# Set the default logging level for new ConsoleHandler instances +java.util.logging.ConsoleHandler.level= WARNING +java.util.logging.ConsoleHandler.formatter= java.util.logging.SimpleFormatter + +# Set the default logging level for new FileHandler instances +java.util.logging.FileHandler.level= INFO +java.util.logging.FileHandler.pattern = target/jul-info.log +java.util.logging.FileHandler.append=true +java.util.logging.FileHandler.formatter= java.util.logging.SimpleFormatter diff --git a/pom.xml b/pom.xml index b3c180831..087275a41 100644 --- a/pom.xml +++ b/pom.xml @@ -95,5 +95,7 @@ + +