EMBJOPR SVN: r116 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit.
by embjopr-commits@lists.jboss.org
Author: ozizka(a)redhat.com
Date: 2009-01-20 16:55:10 -0500 (Tue, 20 Jan 2009)
New Revision: 116
Added:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/JMXUtils.java
Log:
A tool for JMX operations
Added: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/JMXUtils.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/JMXUtils.java (rev 0)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/JMXUtils.java 2009-01-20 21:55:10 UTC (rev 116)
@@ -0,0 +1,74 @@
+package org.jboss.jopr.jsfunit;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import javax.management.*;
+import javax.naming.*;
+import org.jboss.mx.util.MBeanServerLocator;
+
+/**
+ * JMX utilities.
+ * TODO: Write set, invoke if needed. Possibly also remote JMX support (will we ever need it?).
+ * @author ondra
+ */
+public final class JMXUtils{
+
+ private final MBeanServerConnection jmxServer;
+ private static final String RMI_ADAPTOR_JNDI_NAME = "jmx/invoker/RMIAdaptor";
+
+ private JMXUtils(MBeanServer jmxServer) {
+ this.jmxServer = jmxServer;
+ }
+
+ public static JMXUtils getInstanceForLocalJBoss(){
+ return new JMXUtils( MBeanServerLocator.locateJBoss() );
+ }
+
+ /**
+ * This can come handy later...
+ * @param host JBoss host.
+ * @param port RMI connector port.
+ * @return An instance of callable MBeanServerConnection.
+ * TODO: Needs dependency: jmx-adaptor-plugin - which version?
+ */
+ public static JMXUtils getInstanceForRemoteJBoss( String host, Integer port ) throws NamingException{
+
+ // Setup context environment.
+ Hashtable env = new Hashtable();
+ env.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
+ String providerURL = "jnp://" + host + ":"+ port.toString() +"/";
+ env.put("java.naming.provider.url", providerURL);
+ env.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
+
+ // Do not let another partition member to respond.
+ env.put("jnp.disableDiscovery", "true");
+
+ //log.info("Looking for InitialContext for "+providerURL + " ...");
+
+ InitialContext context = new InitialContext(env);
+
+ //log.info("Found InitialContext: "+ context.toString() );
+
+ // lookup JMX mbean RMI adaptor
+ //RMIAdaptor server = (RMIAdaptor) ic.lookup(RMI_ADAPTOR_JNDI_NAME);
+ //return new JMXUtils( context );
+
+ throw new UnsupportedOperationException(
+ "This uses RMIAdaptor and thus introduces unnecesarry dependency.");
+
+ }// getInstanceForRemoteJBoss()
+
+ public static JMXUtils getInstanceForRemoteJBoss( String host ) throws NamingException {
+ return getInstanceForRemoteJBoss(host, 1099);
+ }
+
+
+ public Object getMBeanAttribute( String mBeanName, String attribute ) throws JMException, IOException {
+ return this.getMBeanAttribute( new ObjectName(mBeanName), attribute );
+ }
+
+ public Object getMBeanAttribute( ObjectName mBeanName, String attribute ) throws JMException, IOException {
+ return jmxServer.getAttribute( mBeanName, attribute );
+ }
+
+}// class JMXUtils
15 years, 11 months
EMBJOPR SVN: r115 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit.
by embjopr-commits@lists.jboss.org
Author: ozizka(a)redhat.com
Date: 2009-01-20 16:54:49 -0500 (Tue, 20 Jan 2009)
New Revision: 115
Modified:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
Log:
EmbjoprTestCase sync - no change
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-01-20 21:47:37 UTC (rev 114)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-01-20 21:54:49 UTC (rev 115)
@@ -295,7 +295,7 @@
assertTrue(message.getDetail().contains(expectedServerMsg));
}
-
+
/**
* Refresh the content under the given nav tree node.
*/
15 years, 11 months
EMBJOPR SVN: r114 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit.
by embjopr-commits@lists.jboss.org
Author: ozizka(a)redhat.com
Date: 2009-01-20 16:47:37 -0500 (Tue, 20 Jan 2009)
New Revision: 114
Modified:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java
Log:
Updated: DatasourceTestBase - added new tests. Currently just copied Farah's version for AS 5; to be overriden as needed.
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java 2009-01-20 20:06:00 UTC (rev 113)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java 2009-01-20 21:47:37 UTC (rev 114)
@@ -22,15 +22,10 @@
package org.jboss.jopr.jsfunit;
-import org.jboss.jopr.jsfunit.*;
import com.gargoylesoftware.htmlunit.html.*;
import java.io.IOException;
import junit.framework.Test;
-import junit.framework.TestSuite;
import org.jboss.mx.util.MBeanServerLocator;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import java.util.Set;
import java.util.Iterator;
import org.jdom.Document;
import org.jdom.Element;
@@ -43,8 +38,8 @@
import javax.sql.DataSource;
import javax.naming.Context;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.logging.Level;
-import java.util.logging.Logger;
import javax.management.*;
@@ -309,8 +304,8 @@
/**
- * Create a new datasource. Leave some property values that aren't
- * required unset.
+ * Create a new datasource. Leave some property values, that aren't
+ * required, unset.
*/
public void testCreateDatasource() throws IOException {
@@ -440,8 +435,227 @@
+ /**
+ * Attempt to create a new datasource but set a property value to a value
+ * that is the correct type but is not an allowed value for that
+ * property. An error should occur.
+ */
+ public void testCreateDatasourcePropertyNotAllowed() throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", "InvalidDS");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:.");
+ // This number is a valid integer but is below the
+ // allowable minimum value
+ propertiesMap.put("max-pool-size", "-25");
+ createDatasource(DatasourceType.NO_TX_DATASOURCE,
+ DatasourceType.NO_TX_DATASOURCE.getTemplateHtmlSelectValue(), //"default__No TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate error messages
+ checkClientAndServerMessages("An invalid value was specified for one "
+ + "or more properties",
+ "Value is less than allowable minimum",
+ true);
+ }
+
+ /**
+ * Attempt to create a new datasource using a JNDI name that already exists.
+ * An error should occur.
+ */
+ public void testCreateDatasourceDuplicateJNDIName() throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", "DefaultDS");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:.");
+
+ createDatasource(DatasourceType.LOCAL_TX_DATASOURCE,
+ DatasourceType.LOCAL_TX_DATASOURCE.getTemplateHtmlSelectValue(), //"default__Local TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate error messages
+ String expectedMessage = "Failed to add Resource (see app server log for "
+ + "additional details): A Local TX Datasource named "
+ + "'DefaultDS' already exists";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, true);
+ }
+
+ /*
+ * DELETION TESTS:
+ */
+
+ /**
+ * Remove a Local TX Datasource.
+ */
+ public void testDeleteLocalTXDatasource() throws Exception {
+ Map<String, String> propertiesMap = createLocalTXDatasource("DeleteLocalTXDS");
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+
+ // Check for the appropriate success messages
+ String expectedMessage = "Successfully deleted Local TX Datasource '"
+ + propertiesMap.get("jndi-name") + "'";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+
+ assertFalse(isDatasourceDeployed(
+ propertiesMap.get("jndi-name"),
+ DatasourceType.LOCAL_TX_DATASOURCE));
+
+ // Make sure the entry was removed from the -ds.xml file
+ assertFalse(containsElement(
+ propertiesMap.get("jndi-name"),
+ DatasourceType.LOCAL_TX_DATASOURCE.getXmlElementName() )); //"local-tx-datasource"
+ }
+
+ /**
+ * Remove a No TX Datasource.
+ */
+ public void testDeleteNoTXDatasource() throws Exception {
+ Map<String, String> propertiesMap = createNoTXDatasource("DeleteNoTXDS");
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+
+ // Check for the appropriate success messages
+ String expectedMessage = "Successfully deleted No TX Datasource '"
+ + propertiesMap.get("jndi-name") + "'";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+
+ assertFalse(isDatasourceDeployed(propertiesMap.get("jndi-name"),
+ DatasourceType.NO_TX_DATASOURCE));
+
+ // Make sure the entry was removed from the -ds.xml file
+ assertFalse(containsElement(propertiesMap.get("jndi-name"),
+ "no-tx-datasource"));
+ }
+
+ /**
+ * Remove an XA Datasource.
+ */
+ public void testDeleteXADatasource() throws Exception {
+ Map<String, String> propertiesMap = createXADatasource("DeleteXADS");
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+
+ // Check for the appropriate success messages
+ String expectedMessage = "Successfully deleted XA Datasource '"
+ + propertiesMap.get("jndi-name") + "'";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+
+ assertFalse(isDatasourceDeployed(propertiesMap.get("jndi-name"),
+ DatasourceType.XA_DATASOURCE));
+
+ // Make sure the entry was removed from the -ds.xml file
+ assertFalse(containsElement(propertiesMap.get("jndi-name"),
+ "xa-datasource"));
+ }
+
+ /*
+ * PRELIMINARY METRICS TESTS
+ */
+
+ /**
+ * Check that the metrics are correct after creating a new datasource.
+ */
+ public void testMetricsAfterDatasourceCreation() throws IOException {
+
+ // Min pool size will be 5, max pool size will be 20
+ Map<String, String> propertiesMap = createLocalTXDatasource("MetricsCreateDS");
+
+ // Set up the expected values
+ Map<String, String> expectedMetrics = new HashMap<String, String>();
+ expectedMetrics.put("Available Connection Count", "20.0");
+ expectedMetrics.put("Connection Count", "0.0");
+ expectedMetrics.put("Connection Created Count", "0.0");
+ expectedMetrics.put("Connection Destroyed Count", "0.0");
+ expectedMetrics.put("In Use Connection Count", "0.0");
+ expectedMetrics.put("Max Connections In Use Count", "0.0");
+ expectedMetrics.put("Max Size", "20.0");
+ expectedMetrics.put("Min Size", "5.0");
+
+ checkMetrics( propertiesMap.get("jndi-name"), DatasourceType.LOCAL_TX_DATASOURCE, expectedMetrics );
+
+ // Clean up
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ }
+
+ /**
+ * Make an initial request for a connection to a database. Make
+ * sure the metrics are updated accordingly.
+ */
+ public void testMetricsAfterInitialDBConnection() throws Exception {
+
+ // Min pool size will be 5, max pool size will be 20
+ Map<String, String> propertiesMap = createLocalTXDatasource("MetricsInitalConnectionDS");
+
+ // Create the first connection
+ Connection con = connectDB(propertiesMap.get("jndi-name"), "sa", "");
+ assertNotNull(con);
+
+ // Set up the expected values
+ Map<String, String> expectedMetrics = new HashMap<String, String>();
+ expectedMetrics.put("Available Connection Count", "19.0");
+ expectedMetrics.put("Connection Count", "5.0");
+ expectedMetrics.put("Connection Created Count", "5.0");
+ expectedMetrics.put("Connection Destroyed Count", "0.0");
+ expectedMetrics.put("In Use Connection Count", "1.0");
+ expectedMetrics.put("Max Connections In Use Count", "1.0");
+ expectedMetrics.put("Max Size", "20.0");
+ expectedMetrics.put("Min Size", "5.0");
+
+ checkMetrics( propertiesMap.get("jndi-name"), DatasourceType.LOCAL_TX_DATASOURCE, expectedMetrics );
+
+ // Clean up
+ disconnectDB(con);
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ }
+
+ /**
+ * Establish multiple connections to a database. Make sure
+ * the metrics are updated accordingly.
+ */
+ public void testMetricsAfterMultipleDBConnections() throws Exception {
+
+ // Min pool size will be 5, max pool size will be 20
+ Map<String, String> propertiesMap = createNoTXDatasource("MetricsMultipleConnectionDS");
+
+ // Establish multiple connections
+ ArrayList<Connection> connections = new ArrayList<Connection>();
+ for(int i = 0; i <= 5; i++) {
+ Connection con = connectDB(propertiesMap.get("jndi-name"), "sa", "");
+ assertNotNull(con);
+ connections.add(con);
+ }
+
+ // Set up the expected values
+ Map<String, String> expectedMetrics = new HashMap<String, String>();
+ expectedMetrics.put("Available Connection Count", "14.0");
+ expectedMetrics.put("Connection Count", "6.0");
+ expectedMetrics.put("Connection Created Count", "6.0");
+ expectedMetrics.put("Connection Destroyed Count", "0.0");
+ expectedMetrics.put("In Use Connection Count", "6.0");
+ expectedMetrics.put("Max Connections In Use Count", "6.0");
+ expectedMetrics.put("Max Size", "20.0");
+ expectedMetrics.put("Min Size", "5.0");
+
+ checkMetrics( propertiesMap.get("jndi-name"), DatasourceType.NO_TX_DATASOURCE, expectedMetrics );
+
+ // Clean up
+ for(int i = 0; i <= 5; i++) {
+ disconnectDB(connections.get(i));
+ }
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ }
+
+
+
+
+
+
/*
* --- Various support methods. ---
*/
@@ -489,7 +703,86 @@
}
+ /**
+ * Create a basic Local TX Datasource. Return the mapping of property
+ * names to property values.
+ */
+ private Map<String, String> createLocalTXDatasource(String datasourceName) throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", datasourceName);
+ propertiesMap.put("max-pool-size", "20");
+ propertiesMap.put("min-pool-size", "5");
+ propertiesMap.put("user-name", "sa");
+ propertiesMap.put("password", "");
+ propertiesMap.put("domain", "HsqlDbRealm");
+ propertiesMap.put("blocking-timeout-millis", "35000");
+ propertiesMap.put("idle-timeout-minutes", "20");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:${jboss.server.data.dir}${/}hypersonic${/}localDB");
+
+ createDatasource(DatasourceType.LOCAL_TX_DATASOURCE,
+ DatasourceType.LOCAL_TX_DATASOURCE.getTemplateHtmlSelectValue(), // "default__Local TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ return propertiesMap;
+ }
+
+
+
+ /**
+ * Create a basic No TX Datasource. Return the mapping of property
+ * names to property values.
+ */
+ private Map<String, String> createNoTXDatasource(String datasourceName) throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", datasourceName);
+ propertiesMap.put("prefill", "true");
+ propertiesMap.put("track-connection-by-tx", "false");
+ propertiesMap.put("max-pool-size", "20");
+ propertiesMap.put("min-pool-size", "5");
+ propertiesMap.put("blocking-timeout-millis", "55000");
+ propertiesMap.put("idle-timeout-minutes", "60");
+ propertiesMap.put("noTxSeparatePools", "true");
+ propertiesMap.put("user-name", "sa");
+ propertiesMap.put("password", "");
+ propertiesMap.put("domain", "HsqlDbRealm");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:${jboss.server.data.dir}${/}hypersonic${/}localDB");
+
+ createDatasource(DatasourceType.NO_TX_DATASOURCE,
+ DatasourceType.NO_TX_DATASOURCE.getTemplateHtmlSelectValue(), //"default__No TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ return propertiesMap;
+ }
+
+
+ /**
+ * Create a basic XA Datasource. Return the mapping of property
+ * name to property values.
+ */
+ private Map<String, String> createXADatasource(String datasourceName) throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", datasourceName);
+ propertiesMap.put("xa-datasource-class", "org.postgresql.xa.PGXADataSource");
+ propertiesMap.put("xa-resource-timeout", "36000");
+ propertiesMap.put("max-pool-size", "15");
+ propertiesMap.put("min-pool-size", "6");
+
+ createDatasource(DatasourceType.XA_DATASOURCE,
+ DatasourceType.XA_DATASOURCE.getTemplateHtmlSelectValue(), //"default__XA Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ return propertiesMap;
+ }
+
+
+
+
/**
*
* @returns a name of the Datasource's config file to check the properties in.
@@ -529,6 +822,102 @@
}// isMBeanStateDeployed()
+
+
+ /**
+ * containsElement returns whether or not the *-ds.xml file corresponding
+ * to the datasource given by jndiName contains the given element.
+ * TODO: Refactor.
+ */
+ private boolean containsElement(String jndiName, String elementName) {
+ try {
+ File file = new File(System.getProperty("jsfunit.deploy.dir")
+ + "/" + jndiName + "-ds.xml");
+
+ SAXBuilder builder = new SAXBuilder();
+ Document doc = builder.build(file);
+
+ Element root = doc.getRootElement();
+ assertTrue(root.getName().equals("datasources"));
+ return root.getChild(elementName) != null;
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+
+ /**
+ * Make sure that the metrics corresponding to the given datasource
+ * are correct.
+ *
+ * @param metricsMap maps metric names to the expected metric values.
+ */
+ private void checkMetrics(String datasourceName,
+ DatasourceType datasourceType,
+ Map<String, String> metricsMap) throws IOException {
+
+ refreshTreeNode("Datasources");
+ ClickableElement datasourceTypeArrow = getNavTreeArrow(datasourceType.getLabel());
+ datasourceTypeArrow.click();
+
+ HtmlAnchor datasource = getNavTreeLink(datasourceName);
+ datasource.click();
+
+ // Check values under the "Metrics" tab
+ HtmlAnchor metricsLink = (HtmlAnchor)client.getElement("metricsTab");
+ metricsLink.click();
+
+ for(Iterator i = metricsMap.keySet().iterator(); i.hasNext();) {
+ String metricName = (String)i.next();
+ assertEquals(metricsMap.get(metricName),
+ getMetricValueFromTable(metricName, "dataTable"));
+ }
+
+ // Check values under the "Summary" tab
+ HtmlAnchor summaryLink = (HtmlAnchor)client.getElement("summaryTab");
+ summaryLink.click();
+
+ assertEquals(metricsMap.get("Available Connection Count"),
+ getMetricValueFromTable("Available Connection Count", "dataTable"));
+ assertEquals(metricsMap.get("Connection Count"),
+ getMetricValueFromTable("Connection Count", "dataTable"));
+ }
+
+
+
+
+ /**
+ * Perform the given operation on the given datasource.
+ */
+ private void performDatasourceOperation(String datasourceName,
+ String datasourceType,
+ String operationName) throws IOException {
+
+ refreshTreeNode("Datasources");
+ ClickableElement datasourceTypeArrow = getNavTreeArrow(datasourceType);
+ datasourceTypeArrow.click();
+
+ HtmlAnchor datasourceLink = getNavTreeLink(datasourceName);
+ datasourceLink.click();
+
+ HtmlAnchor controlLink = (HtmlAnchor)client.getElement("controlTab");
+ controlLink.click();
+
+ HtmlForm form = (HtmlForm)client.getElement("operation_form");
+ String xpath = ".//input[@value=\"" + operationName + "\"]";
+
+ HtmlButtonInput operationButton = (HtmlButtonInput)form.getFirstByXPath(xpath);
+ operationButton.click();
+ }
+
+
+
+
+
+
+
+
/**
* This method should query the JMX server and decide whether the given MBean displays deployed resource.
* @param deploymentMBean Name of the MBean to examine. Differs between AS4 and 5.
15 years, 11 months
EMBJOPR SVN: r113 - trunk/core/src/main/java/org/jboss/on/embedded/bean/history/operation.
by embjopr-commits@lists.jboss.org
Author: ips
Date: 2009-01-20 15:06:00 -0500 (Tue, 20 Jan 2009)
New Revision: 113
Modified:
trunk/core/src/main/java/org/jboss/on/embedded/bean/history/operation/OperationServerServiceImpl.java
Log:
fixed compile errors caused by http://jira.rhq-project.org/browse/RHQ-976 API change to OperationServerService interface
Modified: trunk/core/src/main/java/org/jboss/on/embedded/bean/history/operation/OperationServerServiceImpl.java
===================================================================
--- trunk/core/src/main/java/org/jboss/on/embedded/bean/history/operation/OperationServerServiceImpl.java 2009-01-20 01:02:39 UTC (rev 112)
+++ trunk/core/src/main/java/org/jboss/on/embedded/bean/history/operation/OperationServerServiceImpl.java 2009-01-20 20:06:00 UTC (rev 113)
@@ -49,19 +49,27 @@
public void operationSucceeded(String jobId, Configuration results, long invocationTime, long completionTime)
{
- OperationHistory history = historyBean.getHistory(jobId);
+ OperationHistory history = this.historyBean.getHistory(jobId);
history.setStatus(OperationRequestStatus.SUCCESS);
if (history instanceof ResourceOperationHistory)
{
- results.setId(history.getId());
- ((ResourceOperationHistory)history).setResults(results);
+ if (results != null)
+ results.setId(history.getId());
+ ((ResourceOperationHistory)history).setResults(results);
}
}
- public void operationFailed(String jobId, ExceptionPackage error, long invocationTime, long completionTime)
+ public void operationFailed(String jobId, Configuration results, ExceptionPackage error, long invocationTime,
+ long completionTime)
{
- OperationHistory operationHistory = historyBean.getHistory(jobId);
+ OperationHistory operationHistory = this.historyBean.getHistory(jobId);
operationHistory.setStatus(OperationRequestStatus.FAILURE);
+ if (operationHistory instanceof ResourceOperationHistory)
+ {
+ if (results != null)
+ results.setId(operationHistory.getId());
+ ((ResourceOperationHistory)operationHistory).setResults(results);
+ }
if (error != null)
{
if (error.getExceptionName().equals(UnsupportedOperationException.class.getName()))
@@ -78,7 +86,7 @@
public void operationTimedOut(String jobId, long invocationTime, long timeoutTime)
{
- OperationHistory history = historyBean.getHistory(jobId);
+ OperationHistory history = this.historyBean.getHistory(jobId);
if (history.getStatus() == OperationRequestStatus.INPROGRESS)
{
history.setStatus(OperationRequestStatus.FAILURE);
15 years, 11 months
EMBJOPR SVN: r112 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5.
by embjopr-commits@lists.jboss.org
Author: fjuma
Date: 2009-01-19 20:02:39 -0500 (Mon, 19 Jan 2009)
New Revision: 112
Modified:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java
Log:
Made some modifications to the datasource metrics tests.
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java 2009-01-19 19:19:33 UTC (rev 111)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java 2009-01-20 01:02:39 UTC (rev 112)
@@ -135,7 +135,8 @@
for(Iterator i = metricsMap.keySet().iterator(); i.hasNext();) {
String metricName = (String)i.next();
- assertEquals(metricsMap.get(metricName),
+ assertEquals("Incorrect metric value for: " + metricName,
+ metricsMap.get(metricName),
getMetricValueFromTable(metricName, "dataTable"));
}
@@ -143,10 +144,16 @@
HtmlAnchor summaryLink = (HtmlAnchor)client.getElement("summaryTab");
summaryLink.click();
- assertEquals(metricsMap.get("Available Connection Count"),
- getMetricValueFromTable("Available Connection Count", "dataTable"));
- assertEquals(metricsMap.get("Connection Count"),
- getMetricValueFromTable("Connection Count", "dataTable"));
+ ArrayList<String> summaryMetrics = new ArrayList<String>();
+ summaryMetrics.add("Available Connection Count");
+ summaryMetrics.add("Connection Count");
+
+ for(Iterator i = summaryMetrics.iterator(); i.hasNext();) {
+ String metricName = (String)i.next();
+ assertEquals("Incorrect metric value for: " + metricName,
+ metricsMap.get(metricName),
+ getMetricValueFromTable(metricName, "dataTable"));
+ }
}
/**
@@ -664,7 +671,7 @@
}
/*
- * PRELIMINARY METRICS TESTS
+ * METRICS TESTS
*/
/**
@@ -702,7 +709,9 @@
Map<String, String> propertiesMap = createLocalTXDatasource("MetricsInitalConnectionDS");
// Create the first connection
- Connection con = connectDB(propertiesMap.get("jndi-name"), "sa", "");
+ Connection con = connectDB(propertiesMap.get("jndi-name"),
+ propertiesMap.get("user-name"),
+ propertiesMap.get("password"));
assertNotNull(con);
// Set up the expected values
@@ -735,7 +744,9 @@
// Establish multiple connections
ArrayList<Connection> connections = new ArrayList<Connection>();
for(int i = 0; i <= 5; i++) {
- Connection con = connectDB(propertiesMap.get("jndi-name"), "sa", "");
+ Connection con = connectDB(propertiesMap.get("jndi-name"),
+ propertiesMap.get("user-name"),
+ propertiesMap.get("password"));
assertNotNull(con);
connections.add(con);
}
@@ -760,5 +771,49 @@
deleteDatasource(propertiesMap.get("jndi-name"));
}
+
+ /**
+ * Make sure the metrics are updated appropriately after
+ * closing some connections.
+ */
+ public void testMetricsAfterClosingConnections() throws Exception {
+
+ // Min pool size will be 5, max pool size will be 20
+ Map<String, String> propertiesMap = createNoTXDatasource("MetricsCloseConnectionsDS");
+
+ // Establish some connections
+ ArrayList<Connection> connections = new ArrayList<Connection>();
+ for(int i = 0; i <= 4; i++) {
+ Connection con = connectDB(propertiesMap.get("jndi-name"),
+ propertiesMap.get("user-name"),
+ propertiesMap.get("password"));
+ assertNotNull(con);
+ connections.add(con);
+ }
+
+ // Close some connections
+ disconnectDB(connections.get(0));
+ disconnectDB(connections.get(1));
+
+ // Set up the expected values
+ Map<String, String> expectedMetrics = new HashMap<String, String>();
+ expectedMetrics.put("Available Connection Count", "17.0");
+ expectedMetrics.put("Connection Count", "3.0");
+ expectedMetrics.put("Connection Created Count", "5.0");
+ expectedMetrics.put("Connection Destroyed Count", "0.0");
+ expectedMetrics.put("In Use Connection Count", "3.0");
+ expectedMetrics.put("Max Connections In Use Count", "5.0");
+ expectedMetrics.put("Max Size", "20.0");
+ expectedMetrics.put("Min Size", "5.0");
+
+ checkMetrics(propertiesMap.get("jndi-name"), NO_TX_DATASOURCE, expectedMetrics);
+
+ // Clean up
+ for(int i = 2; i <= 4; i++) {
+ disconnectDB(connections.get(i));
+ }
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ }
}
15 years, 11 months
EMBJOPR SVN: r111 - in trunk: core/src/main/webapp/secure and 2 other directories.
by embjopr-commits@lists.jboss.org
Author: fjuma
Date: 2009-01-19 14:19:33 -0500 (Mon, 19 Jan 2009)
New Revision: 111
Modified:
trunk/core/src/main/webapp/include/tabMenu.xhtml
trunk/core/src/main/webapp/secure/addMap.xhtml
trunk/core/src/main/webapp/secure/resourceInstanceOperation.xhtml
trunk/core/src/main/webapp/secure/resourceInstanceSummary.xhtml
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java
Log:
Added datasource creation tests, deletion tests, and some preliminary metrics tests that are meant to be run specifically against AS5.
Added ID attributes to tags in some xhtml files.
Modified: trunk/core/src/main/webapp/include/tabMenu.xhtml
===================================================================
--- trunk/core/src/main/webapp/include/tabMenu.xhtml 2009-01-19 18:21:11 UTC (rev 110)
+++ trunk/core/src/main/webapp/include/tabMenu.xhtml 2009-01-19 19:19:33 UTC (rev 111)
@@ -53,7 +53,7 @@
<!-- ENABLED panel (can be viewed) -->
<h:panelGroup layout="block" rendered="#{activeTab ne 'summary'}">
<li>
- <s:link styleClass="" view="/secure/summary.xhtml" propagation="end">
+ <s:link id="summaryTab" styleClass="" view="/secure/summary.xhtml" propagation="end">
#{messages['tab.menu.summary']}
</s:link>
</li>
@@ -122,7 +122,7 @@
<h:panelGroup layout="block"
rendered="#{activeTab ne 'operation' and navigationAction.enabledTabs.contains('operation')}">
<li>
- <s:link styleClass="" view="/secure/resourceInstanceOperation.xhtml" propagation="end">
+ <s:link id="controlTab" styleClass="" view="/secure/resourceInstanceOperation.xhtml" propagation="end">
#{messages['tab.menu.control']}
</s:link>
</li>
Modified: trunk/core/src/main/webapp/secure/addMap.xhtml
===================================================================
--- trunk/core/src/main/webapp/secure/addMap.xhtml 2009-01-19 18:21:11 UTC (rev 110)
+++ trunk/core/src/main/webapp/secure/addMap.xhtml 2009-01-19 19:19:33 UTC (rev 111)
@@ -53,7 +53,8 @@
<h:panelGrid columns="2" styleClass="buttons-table" columnClasses="button-cell">
<h:commandButton value="#{messages['resource.configuration.map.button.ok']}"
action="#{resourceConfigurationUIBean.addMap()}"
- styleClass="buttonmed"/>
+ styleClass="buttonmed"
+ id="okButton"/>
</h:panelGrid>
</h:form>
Modified: trunk/core/src/main/webapp/secure/resourceInstanceOperation.xhtml
===================================================================
--- trunk/core/src/main/webapp/secure/resourceInstanceOperation.xhtml 2009-01-19 18:21:11 UTC (rev 110)
+++ trunk/core/src/main/webapp/secure/resourceInstanceOperation.xhtml 2009-01-19 19:19:33 UTC (rev 111)
@@ -95,7 +95,7 @@
<h:outputText value="#{messages['control.resourceInstance.error.noPrevious']}" rendered="#{operationHistory eq null}"/>
-<h:form rendered="#{operationHistory ne null}">
+<h:form id="operationHistoryForm" rendered="#{operationHistory ne null}">
<ui:remove>
<!-- NOTE: The below causes the results/error toggle panels to not display properly. Uncomment when RichFaces
fixes whatever the problem is. (ips, 08/20/08) -->
Modified: trunk/core/src/main/webapp/secure/resourceInstanceSummary.xhtml
===================================================================
--- trunk/core/src/main/webapp/secure/resourceInstanceSummary.xhtml 2009-01-19 18:21:11 UTC (rev 110)
+++ trunk/core/src/main/webapp/secure/resourceInstanceSummary.xhtml 2009-01-19 19:19:33 UTC (rev 111)
@@ -78,7 +78,8 @@
<h:panelGroup rendered="#{navigationAction.enabledTabs.contains('metric')}">
<h2>#{messages['summary.resourceInstance.metrics']}</h2>
- <rich:dataTable value="#{summaryMeasurementDisplayList}"
+ <rich:dataTable id="dataTable"
+ value="#{summaryMeasurementDisplayList}"
var="md"
rowClasses="oddRow,evenRow"
columnClasses="rich-table-cell, rich-table-cell, rich-table-cell-action">
@@ -90,7 +91,7 @@
</rich:columnGroup>
</f:facet>
<rich:column>#{summaryMeasurementDefinitionMap[md.measurementData.name].displayName}</rich:column>
- <rich:column>#{md.measurementValueAndUnits}</rich:column>
+ <rich:column id="measurementValue">#{md.measurementValueAndUnits}</rich:column>
<rich:column>#{summaryMeasurementDefinitionMap[md.measurementData.name].description}</rich:column>
</rich:dataTable>
</h:panelGroup>
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-01-19 18:21:11 UTC (rev 110)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-01-19 19:19:33 UTC (rev 111)
@@ -199,9 +199,11 @@
// Set each property
while(itr.hasNext()) {
String propertyName = (String)itr.next();
+
+ // Make sure the input is enabled
+ HtmlInput input = enableOrDisableFormInput(propertyName,
+ Boolean.TRUE);
- // Enable the input if it is currently disabled
- HtmlInput input = enableFormInput(propertyName);
assertFalse(input.isDisabled());
setFormInput(input, properties.get(propertyName));
@@ -209,44 +211,43 @@
}
/**
- * Enable the given input box or "Yes/No" radio button that corresponds
- * to the given property name on a resource configuration page. If the
- * input box/radio button is already enabled, do nothing.
- *
- * @return the enabled input element
+ * Attempt to enable or disable the given input box or "Yes/No" radio button
+ * that corresponds to the given property name on a resource configuration
+ * page. Return the enabled/disabled input element.
+ * If the input box/radio button does not have an enable/disable checkbox,
+ * return the input element as is.
*/
- public HtmlInput enableFormInput(String propertyName) {
+ public HtmlInput enableOrDisableFormInput(String propertyName,
+ Boolean enableInput) {
HtmlForm form = (HtmlForm)client.getElement("resourceConfigurationForm");
HtmlInput input = (HtmlInput)form.getFirstByXPath(".//input[@ondblclick='//"
- + propertyName + "']");
+ + propertyName + "']");
- assertNotNull("Form input for property "+propertyName+" not found.", input);
+ assertNotNull("Form input for property " + propertyName + " not found.", input);
boolean isRadioButton = input.getTypeAttribute().equals("radio");
String id = input.getId();
String xpath;
- if(input.isDisabled()) {
-
- // Find the enable/disable checkbox corresponding to this
- // input element.
- if(isRadioButton) {
+ // Look for an enable/disable checkbox corresponding to this
+ // input element.
+ if(isRadioButton) {
- xpath = ".//input[@onchange=\"setInputUnset(document.getElementById('"
- + id
- + "'), this.checked);setInputUnset(document.getElementById('"
- + id.substring(0, id.lastIndexOf(":")) + ":1'), this.checked);\"]";
- } else {
- xpath = ".//input[@onchange=\"setInputUnset(document.getElementById('"
- + id + "'), this.checked);\"]";
- }
+ xpath = ".//input[@onchange=\"setInputUnset(document.getElementById('"
+ + id
+ + "'), this.checked);setInputUnset(document.getElementById('"
+ + id.substring(0, id.lastIndexOf(":")) + ":1'), this.checked);\"]";
+ } else {
+ xpath = ".//input[@onchange=\"setInputUnset(document.getElementById('"
+ + id + "'), this.checked);\"]";
+ }
- HtmlInput checkBox = (HtmlInput)form.getFirstByXPath(xpath);
- checkBox.setChecked(Boolean.FALSE);
- input = (HtmlInput)form.getFirstByXPath(".//input[@ondblclick='//"
- + propertyName + "']");
+ HtmlInput checkBox = (HtmlInput)form.getFirstByXPath(xpath);
+
+ if(checkBox != null) {
+ checkBox.setChecked(!enableInput);
}
-
+
return input;
}
@@ -264,8 +265,8 @@
// Get the "No" radio button
input = (HtmlInput)client.getElement(id.substring(0,
- id.lastIndexOf(":"))
- + ":1");
+ id.lastIndexOf(":"))
+ + ":1");
}
input.setChecked(Boolean.TRUE);
@@ -274,7 +275,6 @@
}
}
-
/**
* Check that the given messages occur on the client side
* and server side.
@@ -297,6 +297,19 @@
}
/**
+ * Refresh the content under the given nav tree node.
+ */
+ public void refreshTreeNode(String nodeName) throws IOException {
+
+ // Collapse and then expand the nav tree node
+ ClickableElement nodeArrow = getNavTreeArrow(nodeName);
+ nodeArrow.click();
+
+ nodeArrow = getNavTreeArrow(nodeName);
+ nodeArrow.click();
+ }
+
+ /**
* This just checks that the JSFServerSession object was created.
*/
public void testServerSessionCreated() {
@@ -310,190 +323,168 @@
assertTrue(client != null);
}
+ /**
+ * Finds a row in the "details table" using the text in the Name column
+ * and returns the text from the Value column.
+ * @param name
+ * @return
+ */
+ public String getDetailsRowValue(String name) throws AssertException {
+ HtmlDivision contentDiv = (HtmlDivision) client.getElement("content");
+ List<?> valueTDs = contentDiv.getByXPath(
+ ".//div[@class='tabmenubox']//td[contains(text(),'"+name+"']/following-sibling::td[1]");
+ //assertTrue( name + " row not found.", valueTDs.size() == 1 );
+ if( valueTDs.size() == 1 )
+ throw new AssertException( name + " row not found." );
+ String value = ((HtmlTableCell) valueTDs).getTextContent();
+ return value;
+ }
+ /**
+ * Returns the content element - <div id="content"> - which contains whole page.
+ * Good as a start point for XPath queries - other elements usually have generated IDs.
+ * Assertion fails if the element is not found.
+ * @return
+ */
+ public HtmlElement getContentElement() throws AssertException {
+ HtmlElement contentElement = (HtmlElement)client.getElement("content");
+ //assertNotNull("Content <div> not found.", contentElement);
+ if( null == contentElement )
+ throw new AssertException( "Content <div> not found." );
+ return contentElement;
+ }
+ /**
+ * Convenience method, calls getElementsByXPath() with content element.
+ * @param sXPath
+ * @return
+ */
+ public List<? extends HtmlElement> getElementsByXPath(String sXPath ) throws AssertException {
+ //return (List<? extends HtmlElement>) getContentElement().getByXPath(sXPath);
+ return getElementsByXPath( getContentElement(), sXPath );
+ }
+ /**
+ * Retuns a list of elements chosen by XPath, with the given element as context node.
+ * @param xPathContextElement
+ * @param sXPath
+ * @return
+ */
+ public List<? extends HtmlElement> getElementsByXPath(
+ HtmlElement xPathContextElement, String sXPath )
+ throws AssertException
+ {
+ if( null == xPathContextElement ){
+ throw new AssertException("Given XPath context element is null.");
+ }
+ return (List<? extends HtmlElement>) xPathContextElement.getByXPath(sXPath);
+ }
+ /**
+ * Returns the first element in the list returned by getElementsByXPath(String sXPath ).
+ * @param sXPath
+ * @return
+ */
+ public HtmlElement getFirstElementByXPath( HtmlElement xPathContext, String sXPath ) throws AssertException {
+ List<? extends HtmlElement> elementsByXPath = getElementsByXPath(xPathContext, sXPath);
+ if( elementsByXPath.size() == 0 ){
+ throw new RuntimeException("XPath expression found no elements: "+sXPath);
+ // Exception is better - will get the stack trace.
+ //fail("XPath expression found no elements: "+sXPath);
+ }
+ return elementsByXPath.get(0);
+ }
+ /**
+ * Convenience method - calls getFirstElementByXPath() with content div as context.
+ * @param sXPath
+ * @return
+ */
+ public HtmlElement getFirstElementByXPath( String sXPath ) throws AssertException{
+ return getFirstElementByXPath( getContentElement(), sXPath );
+ }
+ /**
+ * Retrieves an input element from a named row of a table in a form.
+ * Supposes that the form is in the "tabmenubox" or "notabmenubox" div.
+ * @param sRowName
+ * @return
+ * @throws org.jboss.jopr.jsfunit.AssertException
+ */
+ public HtmlInput getFormInputByRowName(String sRowName) throws AssertException {
+ try {
+ HtmlInput input = (HtmlInput) getFirstElementByXPath(
+ getTabMenuBoxElement(),
+ ".//td[contains(text(),'"+sRowName+"')]/following-sibling::td[@class='property-value-cell']//input"
+ );
+ if( null == input ){
+ throw new AssertException("Input for value "+sRowName+" not found.");
+ }
+ return input;
+ }
+ catch(AssertException ex){
+ //throw new AssertException("Row with name \""+sRowName+"\" not found.", ex);
+ throw ex;
+ }
+ }
- /**
- * Finds a row in the "details table" using the text in the Name column
- * and returns the text from the Value column.
- * @param name
- * @return
- */
- public String getDetailsRowValue(String name) throws AssertException {
- HtmlDivision contentDiv = (HtmlDivision) client.getElement("content");
- List<?> valueTDs = contentDiv.getByXPath(
- ".//div[@class='tabmenubox']//td[contains(text(),'"+name+"']/following-sibling::td[1]");
- //assertTrue( name + " row not found.", valueTDs.size() == 1 );
- if( valueTDs.size() == 1 )
- throw new AssertException( name + " row not found." );
- String value = ((HtmlTableCell) valueTDs).getTextContent();
- return value;
- }
+ /**
+ * Retrieves a named row of a table in the "right side of the page".
+ * Supposes that the table is in the "tabmenubox" or "notabmenubox" div.
+ * Uses getTabMenuBoxElement() to get that div.
+ * @param sRowName
+ * @return
+ * @throws org.jboss.jopr.jsfunit.AssertException
+ */
+ public HtmlTableRow getRowByName(String sRowName) throws AssertException {
+ HtmlTableRow row = (HtmlTableRow) getFirstElementByXPath(
+ getTabMenuBoxElement(),
+ ".//td[contains(text(),'"+sRowName+"')]/ancestor::tr"
+ );
+ if( null == row ){
+ throw new AssertException("Row for value "+sRowName+" not found.");
+ }
+ return row;
+ }
+ /**
+ * Returns the element which contains the "right side of the page".
+ * <div class="tabmenubox"> element exists on each page that shows resource's details.
+ * <div class="notabmenubox"> element exists on each page with form for resource's properties editation.
+ * @return
+ * @throws org.jboss.jopr.jsfunit.AssertException
+ */
+ public HtmlElement getTabMenuBoxElement() throws AssertException {
+ return getFirstElementByXPath(".//div[@class='tabmenubox' or @class='notabmenubox']");
+ }
- /**
- * Returns the content element - <div id="content"> - which contains whole page.
- * Good as a start point for XPath queries - other elements usually have generated IDs.
- * Assertion fails if the element is not found.
- * @return
- */
- public HtmlElement getContentElement() throws AssertException {
- HtmlElement contentElement = (HtmlElement)client.getElement("content");
- //assertNotNull("Content <div> not found.", contentElement);
- if( null == contentElement )
- throw new AssertException( "Content <div> not found." );
- return contentElement;
- }
+ /**
+ * Returns an integer part of the beginning of the given string.
+ * @param s
+ * @return Integer with the value of numerical part of the string,
+ * or null if there are no digits at the beginning.
+ */
+ public Integer integerFromString(String s) {
+ int pos;
+ for( pos = 0; pos < s.length(); pos++ ){
+ char ch = s.charAt(0);
+ if( '0' > ch || ch > '9' )
+ break;
+ }
+ if( pos == 0 )
+ return null;
- /**
- * Convenience method, calls getElementsByXPath() with content element.
- * @param sXPath
- * @return
- */
- public List<? extends HtmlElement> getElementsByXPath(String sXPath ) throws AssertException {
- //return (List<? extends HtmlElement>) getContentElement().getByXPath(sXPath);
- return getElementsByXPath( getContentElement(), sXPath );
- }
+ try{
+ int val = Integer.parseInt( s.substring( 0, pos ) );
+ return val;
+ }catch( NumberFormatException ex ){
+ return null;
+ }
-
- /**
- * Retuns a list of elements chosen by XPath, with the given element as context node.
- * @param xPathContextElement
- * @param sXPath
- * @return
- */
- public List<? extends HtmlElement> getElementsByXPath(
- HtmlElement xPathContextElement, String sXPath )
- throws AssertException
- {
- if( null == xPathContextElement ){
- throw new AssertException("Given XPath context element is null.");
- }
-
- return (List<? extends HtmlElement>) xPathContextElement.getByXPath(sXPath);
- }
-
-
- /**
- * Returns the first element in the list returned by getElementsByXPath(String sXPath ).
- * @param sXPath
- * @return
- */
- public HtmlElement getFirstElementByXPath( HtmlElement xPathContext, String sXPath ) throws AssertException {
-
- List<? extends HtmlElement> elementsByXPath = getElementsByXPath(xPathContext, sXPath);
- if( elementsByXPath.size() == 0 ){
- throw new RuntimeException("XPath expression found no elements: "+sXPath);
- // Exception is better - will get the stack trace.
- //fail("XPath expression found no elements: "+sXPath);
- }
- return elementsByXPath.get(0);
- }
-
-
- /**
- * Convenience method - calls getFirstElementByXPath() with content div as context.
- * @param sXPath
- * @return
- */
- public HtmlElement getFirstElementByXPath( String sXPath ) throws AssertException{
- return getFirstElementByXPath( getContentElement(), sXPath );
- }
-
-
- /**
- * Retrieves an input element from a named row of a table in a form.
- * Supposes that the form is in the "tabmenubox" or "notabmenubox" div.
- * @param sRowName
- * @return
- * @throws org.jboss.jopr.jsfunit.AssertException
- */
- public HtmlInput getFormInputByRowName(String sRowName) throws AssertException {
- try {
- HtmlInput input = (HtmlInput) getFirstElementByXPath(
- getTabMenuBoxElement(),
- ".//td[contains(text(),'"+sRowName+"')]/following-sibling::td[@class='property-value-cell']//input"
- );
- if( null == input ){
- throw new AssertException("Input for value "+sRowName+" not found.");
- }
- return input;
- }
- catch(AssertException ex){
- //throw new AssertException("Row with name \""+sRowName+"\" not found.", ex);
- throw ex;
- }
- }
-
-
- /**
- * Retrieves a named row of a table in the "right side of the page".
- * Supposes that the table is in the "tabmenubox" or "notabmenubox" div.
- * Uses getTabMenuBoxElement() to get that div.
- * @param sRowName
- * @return
- * @throws org.jboss.jopr.jsfunit.AssertException
- */
- public HtmlTableRow getRowByName(String sRowName) throws AssertException {
- HtmlTableRow row = (HtmlTableRow) getFirstElementByXPath(
- getTabMenuBoxElement(),
- ".//td[contains(text(),'"+sRowName+"')]/ancestor::tr"
- );
- if( null == row ){
- throw new AssertException("Row for value "+sRowName+" not found.");
- }
- return row;
- }
-
-
- /**
- * Returns the element which contains the "right side of the page".
- * <div class="tabmenubox"> element exists on each page that shows resource's details.
- * <div class="notabmenubox"> element exists on each page with form for resource's properties editation.
- * @return
- * @throws org.jboss.jopr.jsfunit.AssertException
- */
- public HtmlElement getTabMenuBoxElement() throws AssertException {
- return getFirstElementByXPath(".//div[@class='tabmenubox' or @class='notabmenubox']");
- }
-
-
-
-
- /**
- * Returns an integer part of the beginning of the given string.
- * @param s
- * @return Integer with the value of numerical part of the string,
- * or null if there are no digits at the beginning.
- */
- public Integer integerFromString(String s) {
- int pos;
- for( pos = 0; pos < s.length(); pos++ ){
- char ch = s.charAt(0);
- if( '0' > ch || ch > '9' )
- break;
- }
-
- if( pos == 0 )
- return null;
-
- try{
- int val = Integer.parseInt( s.substring( 0, pos ) );
- return val;
- }catch( NumberFormatException ex ){
- return null;
- }
-
- }
-
-
+ }
}
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java 2009-01-19 18:21:11 UTC (rev 110)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/DatasourceTest.java 2009-01-19 19:19:33 UTC (rev 111)
@@ -38,6 +38,7 @@
import javax.management.ObjectName;
import java.util.Set;
import java.util.Iterator;
+import java.util.ArrayList;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
@@ -50,7 +51,6 @@
import javax.sql.DataSource;
import javax.naming.Context;
import java.sql.SQLException;
-import org.jboss.jopr.jsfunit.EmbjoprTestCase;
/**
* When complete, this class will contain tests for creating,
@@ -67,6 +67,8 @@
private final String NO_TX_DATASOURCE="No TX Datasources";
private final String XA_DATASOURCE="XA Datasources";
+ private final String MAX_ITEMS_PER_PAGE="20";
+
/**
* Create a new datasource using the given type, template, and properties.
*
@@ -99,12 +101,55 @@
private void deleteDatasource(String datasourceName) throws IOException {
HtmlAnchor datasourceLink = getNavTreeLink("Datasources");
datasourceLink.click();
+
+ HtmlSelect menu = (HtmlSelect)client.getElement("currentPageSize");
+ if(menu != null) {
+ menu.setSelectedAttribute(MAX_ITEMS_PER_PAGE, Boolean.TRUE);
+ }
+
HtmlButtonInput deleteButton = getDeleteButton("categorySummaryForm",
datasourceName);
deleteButton.click();
}
/**
+ * Make sure that the metrics corresponding to the given datasource
+ * are correct.
+ *
+ * @param metricsMap maps metric names to the expected metric values.
+ */
+ private void checkMetrics(String datasourceName,
+ String datasourceType,
+ Map<String, String> metricsMap) throws IOException {
+
+ refreshTreeNode("Datasources");
+ ClickableElement datasourceTypeArrow = getNavTreeArrow(datasourceType);
+ datasourceTypeArrow.click();
+
+ HtmlAnchor datasource = getNavTreeLink(datasourceName);
+ datasource.click();
+
+ // Check values under the "Metrics" tab
+ HtmlAnchor metricsLink = (HtmlAnchor)client.getElement("metricsTab");
+ metricsLink.click();
+
+ for(Iterator i = metricsMap.keySet().iterator(); i.hasNext();) {
+ String metricName = (String)i.next();
+ assertEquals(metricsMap.get(metricName),
+ getMetricValueFromTable(metricName, "dataTable"));
+ }
+
+ // Check values under the "Summary" tab
+ HtmlAnchor summaryLink = (HtmlAnchor)client.getElement("summaryTab");
+ summaryLink.click();
+
+ assertEquals(metricsMap.get("Available Connection Count"),
+ getMetricValueFromTable("Available Connection Count", "dataTable"));
+ assertEquals(metricsMap.get("Connection Count"),
+ getMetricValueFromTable("Connection Count", "dataTable"));
+ }
+
+ /**
* Use JMX to check if the datasource given by datasourceName is
* deployed.
*/
@@ -227,6 +272,51 @@
}
/**
+ * containsElement returns whether or not the *-ds.xml file corresponding
+ * to the datasource given by jndiName contains the given element.
+ */
+ private boolean containsElement(String jndiName, String elementName) {
+ try {
+ File file = new File(System.getProperty("jsfunit.deploy.dir")
+ + "/" + jndiName + "-ds.xml");
+
+ SAXBuilder builder = new SAXBuilder();
+ Document doc = builder.build(file);
+
+ Element root = doc.getRootElement();
+ assertTrue(root.getName().equals("datasources"));
+ return root.getChild(elementName) != null;
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Perform the given operation on the given datasource.
+ */
+ private void performDatasourceOperation(String datasourceName,
+ String datasourceType,
+ String operationName) throws IOException {
+
+ refreshTreeNode("Datasources");
+ ClickableElement datasourceTypeArrow = getNavTreeArrow(datasourceType);
+ datasourceTypeArrow.click();
+
+ HtmlAnchor datasourceLink = getNavTreeLink(datasourceName);
+ datasourceLink.click();
+
+ HtmlAnchor controlLink = (HtmlAnchor)client.getElement("controlTab");
+ controlLink.click();
+
+ HtmlForm form = (HtmlForm)client.getElement("operation_form");
+ String xpath = ".//input[@value=\"" + operationName + "\"]";
+
+ HtmlButtonInput operationButton = (HtmlButtonInput)form.getFirstByXPath(xpath);
+ operationButton.click();
+ }
+
+
+ /**
* Connect to the database identified by the given JNDI name,
* using the given username and password. Return the Connection
* object.
@@ -248,6 +338,76 @@
}
/**
+ * Create a basic Local TX Datasource. Return the mapping of property
+ * names to property values.
+ */
+ private Map<String, String> createLocalTXDatasource(String datasourceName) throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", datasourceName);
+ propertiesMap.put("max-pool-size", "20");
+ propertiesMap.put("min-pool-size", "5");
+ propertiesMap.put("user-name", "sa");
+ propertiesMap.put("password", "");
+ propertiesMap.put("domain", "HsqlDbRealm");
+ propertiesMap.put("blocking-timeout-millis", "35000");
+ propertiesMap.put("idle-timeout-minutes", "20");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:${jboss.server.data.dir}${/}hypersonic${/}localDB");
+
+ createDatasource(LOCAL_TX_DATASOURCE, "default__Local TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ return propertiesMap;
+ }
+
+ /**
+ * Create a basic No TX Datasource. Return the mapping of property
+ * names to property values.
+ */
+ private Map<String, String> createNoTXDatasource(String datasourceName) throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", datasourceName);
+ propertiesMap.put("prefill", "true");
+ propertiesMap.put("track-connection-by-tx", "false");
+ propertiesMap.put("max-pool-size", "20");
+ propertiesMap.put("min-pool-size", "5");
+ propertiesMap.put("blocking-timeout-millis", "55000");
+ propertiesMap.put("idle-timeout-minutes", "60");
+ propertiesMap.put("noTxSeparatePools", "true");
+ propertiesMap.put("user-name", "sa");
+ propertiesMap.put("password", "");
+ propertiesMap.put("domain", "HsqlDbRealm");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:${jboss.server.data.dir}${/}hypersonic${/}localDB");
+
+ createDatasource(NO_TX_DATASOURCE, "default__No TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ return propertiesMap;
+ }
+
+ /**
+ * Create a basic XA Datasource. Return the mapping of property
+ * name to property values.
+ */
+ private Map<String, String> createXADatasource(String datasourceName) throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", datasourceName);
+ propertiesMap.put("xa-datasource-class", "org.postgresql.xa.PGXADataSource");
+ propertiesMap.put("xa-resource-timeout", "36000");
+ propertiesMap.put("max-pool-size", "15");
+ propertiesMap.put("min-pool-size", "6");
+
+ createDatasource(XA_DATASOURCE, "default__XA Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ return propertiesMap;
+ }
+
+ /**
* @return the suite of tests being tested
*/
public static Test suite()
@@ -256,7 +416,7 @@
}
/*
- * Some preliminary creation tests
+ * CREATION TESTS:
*/
/**
@@ -267,7 +427,7 @@
Map<String, String> propertiesMap = new HashMap<String, String>();
// The properties we want to configure
- propertiesMap.put("jndi-name", "TestDS");
+ propertiesMap.put("jndi-name", "CreationTestDS");
propertiesMap.put("user-name", "testUser");
propertiesMap.put("password", "password");
propertiesMap.put("min-pool-size", "5");
@@ -287,7 +447,7 @@
propertiesMap.put("background-validation-millis", "15000");
propertiesMap.put("use-try-lock", "61000");
propertiesMap.put("prefill", "true");
- propertiesMap.put("share-prepared-statements", "false");
+ propertiesMap.put("share-prepared-statements", "false");
createDatasource(LOCAL_TX_DATASOURCE,
"default__Local TX Datasource",
@@ -306,13 +466,10 @@
// TODO: need to verify that appropriate default values were
// set for properties that were not specified above
-
+
// Clean up
deleteDatasource(propertiesMap.get("jndi-name"));
- expectedMessage = "Successfully deleted Local TX Datasource '"
- + propertiesMap.get("jndi-name") + "'";
- checkClientAndServerMessages(expectedMessage, expectedMessage, false);
- }
+ }
/**
* Attempt to create a new datasource but leave at least one required
@@ -338,7 +495,7 @@
+ "or more properties",
"Value is required",
true);
- }
+ }
/**
* Attempt to create a new datasource but set a property value
@@ -391,5 +548,217 @@
"Value is not a valid integer",
true);
}
+
+ /**
+ * Attempt to create a new datasource but set a property value to a value
+ * that is the correct type but is not an allowed value for that
+ * property. An error should occur.
+ */
+ public void testCreateDatasourcePropertyNotAllowed() throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", "InvalidDS");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:.");
+
+ // This number is a valid integer but is below the
+ // allowable minimum value
+ propertiesMap.put("max-pool-size", "-25");
+
+ createDatasource(NO_TX_DATASOURCE, "default__No TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate error messages
+ checkClientAndServerMessages("An invalid value was specified for one "
+ + "or more properties",
+ "Value is less than allowable minimum",
+ true);
+ }
+
+ /**
+ * Attempt to create a new datasource using a JNDI name that already exists.
+ * An error should occur.
+ */
+ public void testCreateDatasourceDuplicateJNDIName() throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", "DefaultDS");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:.");
+
+ createDatasource(LOCAL_TX_DATASOURCE, "default__Local TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate error messages
+ String expectedMessage = "Failed to add Resource (see app server log for "
+ + "additional details): A Local TX Datasource named "
+ + "'DefaultDS' already exists";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, true);
+ }
+
+ /*
+ * DELETION TESTS:
+ */
+
+ /**
+ * Remove a Local TX Datasource.
+ */
+ public void testDeleteLocalTXDatasource() throws Exception {
+ Map<String, String> propertiesMap = createLocalTXDatasource("DeleteLocalTXDS");
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+
+ // Check for the appropriate success messages
+ String expectedMessage = "Successfully deleted Local TX Datasource '"
+ + propertiesMap.get("jndi-name") + "'";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+
+ assertFalse(isDatasourceDeployed(propertiesMap.get("jndi-name"),
+ LOCAL_TX_DATASOURCE));
+
+ // Make sure the entry was removed from the -ds.xml file
+ assertFalse(containsElement(propertiesMap.get("jndi-name"),
+ "local-tx-datasource"));
+ }
+
+ /**
+ * Remove a No TX Datasource.
+ */
+ public void testDeleteNoTXDatasource() throws Exception {
+ Map<String, String> propertiesMap = createNoTXDatasource("DeleteNoTXDS");
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+
+ // Check for the appropriate success messages
+ String expectedMessage = "Successfully deleted No TX Datasource '"
+ + propertiesMap.get("jndi-name") + "'";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+
+ assertFalse(isDatasourceDeployed(propertiesMap.get("jndi-name"),
+ NO_TX_DATASOURCE));
+
+ // Make sure the entry was removed from the -ds.xml file
+ assertFalse(containsElement(propertiesMap.get("jndi-name"),
+ "no-tx-datasource"));
+ }
+
+ /**
+ * Remove an XA Datasource.
+ */
+ public void testDeleteXADatasource() throws Exception {
+ Map<String, String> propertiesMap = createXADatasource("DeleteXADS");
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+
+ // Check for the appropriate success messages
+ String expectedMessage = "Successfully deleted XA Datasource '"
+ + propertiesMap.get("jndi-name") + "'";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+
+ assertFalse(isDatasourceDeployed(propertiesMap.get("jndi-name"),
+ XA_DATASOURCE));
+
+ // Make sure the entry was removed from the -ds.xml file
+ assertFalse(containsElement(propertiesMap.get("jndi-name"),
+ "xa-datasource"));
+ }
+
+ /*
+ * PRELIMINARY METRICS TESTS
+ */
+
+ /**
+ * Check that the metrics are correct after creating a new datasource.
+ */
+ public void testMetricsAfterDatasourceCreation() throws IOException {
+
+ // Min pool size will be 5, max pool size will be 20
+ Map<String, String> propertiesMap = createLocalTXDatasource("MetricsCreateDS");
+
+ // Set up the expected values
+ Map<String, String> expectedMetrics = new HashMap<String, String>();
+ expectedMetrics.put("Available Connection Count", "20.0");
+ expectedMetrics.put("Connection Count", "0.0");
+ expectedMetrics.put("Connection Created Count", "0.0");
+ expectedMetrics.put("Connection Destroyed Count", "0.0");
+ expectedMetrics.put("In Use Connection Count", "0.0");
+ expectedMetrics.put("Max Connections In Use Count", "0.0");
+ expectedMetrics.put("Max Size", "20.0");
+ expectedMetrics.put("Min Size", "5.0");
+
+ checkMetrics(propertiesMap.get("jndi-name"), LOCAL_TX_DATASOURCE, expectedMetrics);
+
+ // Clean up
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ }
+
+ /**
+ * Make an initial request for a connection to a database. Make
+ * sure the metrics are updated accordingly.
+ */
+ public void testMetricsAfterInitialDBConnection() throws Exception {
+
+ // Min pool size will be 5, max pool size will be 20
+ Map<String, String> propertiesMap = createLocalTXDatasource("MetricsInitalConnectionDS");
+
+ // Create the first connection
+ Connection con = connectDB(propertiesMap.get("jndi-name"), "sa", "");
+ assertNotNull(con);
+
+ // Set up the expected values
+ Map<String, String> expectedMetrics = new HashMap<String, String>();
+ expectedMetrics.put("Available Connection Count", "19.0");
+ expectedMetrics.put("Connection Count", "5.0");
+ expectedMetrics.put("Connection Created Count", "5.0");
+ expectedMetrics.put("Connection Destroyed Count", "0.0");
+ expectedMetrics.put("In Use Connection Count", "1.0");
+ expectedMetrics.put("Max Connections In Use Count", "1.0");
+ expectedMetrics.put("Max Size", "20.0");
+ expectedMetrics.put("Min Size", "5.0");
+
+ checkMetrics(propertiesMap.get("jndi-name"), LOCAL_TX_DATASOURCE, expectedMetrics);
+
+ // Clean up
+ disconnectDB(con);
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ }
+
+ /**
+ * Establish multiple connections to a database. Make sure
+ * the metrics are updated accordingly.
+ */
+ public void testMetricsAfterMultipleDBConnections() throws Exception {
+
+ // Min pool size will be 5, max pool size will be 20
+ Map<String, String> propertiesMap = createNoTXDatasource("MetricsMultipleConnectionDS");
+
+ // Establish multiple connections
+ ArrayList<Connection> connections = new ArrayList<Connection>();
+ for(int i = 0; i <= 5; i++) {
+ Connection con = connectDB(propertiesMap.get("jndi-name"), "sa", "");
+ assertNotNull(con);
+ connections.add(con);
+ }
+
+ // Set up the expected values
+ Map<String, String> expectedMetrics = new HashMap<String, String>();
+ expectedMetrics.put("Available Connection Count", "14.0");
+ expectedMetrics.put("Connection Count", "6.0");
+ expectedMetrics.put("Connection Created Count", "6.0");
+ expectedMetrics.put("Connection Destroyed Count", "0.0");
+ expectedMetrics.put("In Use Connection Count", "6.0");
+ expectedMetrics.put("Max Connections In Use Count", "6.0");
+ expectedMetrics.put("Max Size", "20.0");
+ expectedMetrics.put("Min Size", "5.0");
+
+ checkMetrics(propertiesMap.get("jndi-name"), NO_TX_DATASOURCE, expectedMetrics);
+
+ // Clean up
+ for(int i = 0; i <= 5; i++) {
+ disconnectDB(connections.get(i));
+ }
+
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ }
}
15 years, 11 months
EMBJOPR SVN: r110 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit.
by embjopr-commits@lists.jboss.org
Author: ozizka(a)redhat.com
Date: 2009-01-19 13:21:11 -0500 (Mon, 19 Jan 2009)
New Revision: 110
Added:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java
Log:
Added: Datasource test base class - common denominator for AS 4 and AS 5 test subclasses.
Added: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java (rev 0)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/DatasourceTestBase.java 2009-01-19 18:21:11 UTC (rev 110)
@@ -0,0 +1,544 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.jopr.jsfunit;
+
+import org.jboss.jopr.jsfunit.*;
+import com.gargoylesoftware.htmlunit.html.*;
+import java.io.IOException;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.jboss.mx.util.MBeanServerLocator;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.util.Set;
+import java.util.Iterator;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+import java.io.File;
+import java.util.Map;
+import java.util.HashMap;
+import javax.naming.InitialContext;
+import java.sql.Connection;
+import javax.sql.DataSource;
+import javax.naming.Context;
+import java.sql.SQLException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.management.*;
+
+
+
+
+/**
+ * When complete, this class will contain tests for creating,
+ * configuring, and deleting various types of datasources. This
+ * test class should be run against JBAS 5.x.
+ *
+ * @author Farah Juma
+ * @author Ondrej Zizka
+ *
+ */
+public abstract class DatasourceTestBase extends EmbjoprTestCase {
+
+
+ // Datasource types, as they appear in the left nav
+ protected enum DatasourceType {
+
+ // Some of these values are specific for AS 5. TODO: Think up some way to split nicely.
+ LOCAL_TX_DATASOURCE("Local TX Datasources", "LocalTxCM", "local-tx-datasource", "default__Local TX Datasource"),
+ NO_TX_DATASOURCE( "No TX Datasources", "NoTxCM", "no-tx-datasource", null), // TODO: Fill the value.
+ XA_DATASOURCE( "XA Datasources", "XATxCM", "xa-datasource", "default__XA Datasource");
+
+ protected String label;
+ public String getLabel() { return label; }
+ //public void setLabel(String label) { this.label = label; }
+
+ protected final String serviceName;
+ public String getServiceName() { return serviceName; }
+
+
+ protected final String xmlElementName;
+ public String getXmlElementName() { return xmlElementName; }
+
+ protected final String templateHtmlSelectValue;
+ public String getTemplateHtmlSelectValue() { return templateHtmlSelectValue; }
+
+
+
+ private DatasourceType(String label, String serviceName,
+ String xmlElementName, String htmlSelectValue)
+ {
+ this.label = label;
+ this.serviceName = serviceName;
+ this.xmlElementName = xmlElementName;
+ this.templateHtmlSelectValue = htmlSelectValue;
+ }
+
+ }// DatasourceTypes
+
+
+
+ // --- Datasource Templates --- //
+ /*
+ <select id="resourceCreateForm:selectedTemplate" size="1" name="resourceCreateForm:selectedTemplate">
+ <option value="">Select Template</option>
+ <option value="Oracle Local TX__Datasource">Oracle Local TX (Datasource)</option>
+ <option value="Oracle XA__Datasource">Oracle XA (Datasource)</option>
+ <option value="default__Datasource">default (Datasource)</option>
+ </select>
+ */
+ protected enum DatasourceTemplate {
+
+ ORACLE_LOCAL_TX("Oracle Local TX__Datasource"),
+ ORACLE_XA("Oracle XA__Datasource"),
+ DEFAULT("default__Datasource");
+
+ protected final String templateHtmlSelectValue;
+
+
+ private DatasourceTemplate(String templateHtmlSelectValue) {
+ this.templateHtmlSelectValue = templateHtmlSelectValue;
+ }
+
+
+
+ /**
+ * Value of HTML select option for this template.
+ */
+ public String getTemplateHtmlSelectValue() {
+ return templateHtmlSelectValue;
+ }
+
+ }
+
+
+
+
+
+ // Datasource properties
+
+ private Map<String, String> datasourceProperties = createDatasourceProperties();
+
+ /**
+ * @returns a set of properties created upon initialization by overriden createDatasourceProperties().
+ */
+ public Map<String, String> getDatasourceProperties() { return datasourceProperties; }
+
+
+
+
+
+ /**
+ * Create a new datasource using the given type, template, and properties.
+ *
+ * @param datasourceType must be the name of a datasource type, as it
+ * appears in the left nav (eg. "Local TX Datasources")
+ */
+ protected abstract void createDatasource(DatasourceType datasourceType,
+ String datasourceTemplate,
+ Map<String, String> propertiesMap) throws IOException;
+
+ /**
+ * Delete the datasource given by datasourceName.
+ */
+ protected abstract void deleteDatasource(String datasourceName) throws IOException;
+
+ /**
+ * Use JMX to check if the datasource given by datasourceName is deployed.
+ */
+ protected boolean isDatasourceDeployed(String jndiName, DatasourceType datasourceType) {
+ try {
+
+ String[] dsMBeanServices = {"DataSourceBinding",
+ "ManagedConnectionPool",
+ "ManagedConnectionFactory",
+ datasourceType.getServiceName() };
+
+ // Query the MBean server to check if the datasource is deployed
+ MBeanServer jmxServer = MBeanServerLocator.locateJBoss();
+
+ // Inspect these MBeans and make sure that the their state indicates successful deployment
+ // (e.g. for AS 5, "State" attribute is "DEPLOYED"):
+ // 1) "jboss.jca:name=TestDS,service=DataSourceBinding",type=Component
+ // 2) "jboss.jca:name=TestDS,service=ManagedConnectionPool",type=Component
+ // 3) "jboss.jca:name=TestDS,service=ManagedConnectionFactory",type=Component
+ // 4) The fourth MBean inspected depends on the type of datasource.
+ for(int i = 0; i < dsMBeanServices.length; i++) {
+
+ // Is this necessary? Can't we just query? See InstanceNotFoundException;
+ // And AFAIK, full MBean name is unique. I vote for minimalistic code.
+ /*ObjectName objName = new ObjectName( this.getMBeanName(jndiName, dsMBeanServices[i]));
+
+ Set dsMBeans = jmxServer.queryNames(objName, null);
+ if (dsMBeans.size() != 1) return false;
+
+ // Get the first and only one MBean returned.
+ ObjectName deploymentMBean = (ObjectName)dsMBeans.iterator().next(); /**/
+
+ ObjectName deploymentMBean = new ObjectName( this.getMBeanName(jndiName, dsMBeanServices[i]) );
+
+ ///Object state = jmxServer.getAttribute(deploymentMBean, "State");
+ ///if(!("DEPLOYED".equals(state.toString()))) return false;
+ if( !this.isMBeanStateDeployed( deploymentMBean ) )
+ return false;
+
+ }
+
+ return true;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+
+ /**
+ * checkProperties reads the *-ds.xml file corresponding to the datasource
+ * given by jndiName and compares the property values in this file to the
+ * given expected values. checkProperties returns true if all the given
+ * properties are correctly set in the *-ds.xml file and false otherwise.
+ */
+ protected boolean checkProperties(String jndiName,
+ DatasourceType datasourceType,
+ Map<String, String> expectedValuesMap) {
+
+ Map<String, String> actualValuesMap = new HashMap<String, String>();
+
+
+ try {
+
+ // Parse the *-ds.xml file; create appropriate file name for AS 4 or 5.
+ File file = new File( this.getDatasourceConfigFile());
+
+ SAXBuilder builder = new SAXBuilder();
+ Document doc = builder.build(file);
+
+ Element root = doc.getRootElement();
+ assertTrue(root.getName().equals("datasources"));
+
+ // Get the datasource element
+ Element datasource = root.getChild( datasourceType.getXmlElementName() );
+
+ // Create actualValuesMap by mapping property names to
+ // property values
+ Iterator itr = (datasource.getChildren()).iterator();
+ while(itr.hasNext()) {
+ Element property = (Element)itr.next();
+ actualValuesMap.put(property.getName(), property.getValue());
+ }
+
+ // Compare the actual values to the expected ones
+ itr = expectedValuesMap.keySet().iterator();
+ while(itr.hasNext()) {
+ String key = (String)itr.next();
+ if(actualValuesMap.containsKey(key)) {
+ if(!expectedValuesMap.get(key).equals(actualValuesMap.get(key))) {
+ return false; // incorrect value
+ }
+ } else {
+ return false; // value was not set
+ }
+ }
+
+ return true;
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Connect to the database identified by the given JNDI name,
+ * using the given username and password. Return the Connection
+ * object.
+ */
+ public Connection connectDB(String jndiName, String username,
+ String password) throws Exception{
+ Context ctx = new InitialContext();
+ DataSource ds = (DataSource)ctx.lookup(jndiName);
+ return ds.getConnection(username, password);
+ }
+
+ /**
+ * Disconnect from the database.
+ */
+ public void disconnectDB(Connection con) throws SQLException {
+ if(con != null) {
+ con.close();
+ }
+ }
+
+ /**
+ * @return the suite of tests being tested
+ * @throws UnsupportedOperationException - you have to override this.
+ * Can't be abstract, must be static.
+ */
+ public static Test suite()
+ {
+ throw new UnsupportedOperationException("This has to be overriden.");
+ }
+
+
+
+
+ /*
+ * --- Some preliminary creation tests ---
+ */
+
+
+
+ /**
+ * Create a new datasource. Leave some property values that aren't
+ * required unset.
+ */
+ public void testCreateDatasource() throws IOException {
+
+
+ // The properties we want to configure
+ Map<String, String> propertiesMap = this.getDatasourceProperties();
+
+ createDatasource(DatasourceType.LOCAL_TX_DATASOURCE,
+ //was: "default__Local TX Datasource",
+ DatasourceType.LOCAL_TX_DATASOURCE.getTemplateHtmlSelectValue(), // TODO: Redundant - remove.
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate success messages
+ String expectedMessage = "Successfully added new Local TX Datasource";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+
+ assertTrue(isDatasourceDeployed(propertiesMap.get("jndi-name"),
+ DatasourceType.LOCAL_TX_DATASOURCE));
+ assertTrue(checkProperties(propertiesMap.get("jndi-name"),
+ DatasourceType.LOCAL_TX_DATASOURCE,
+ propertiesMap));
+
+ // TODO: need to verify that appropriate default values were
+ // set for properties that were not specified above
+
+ // Clean up
+ deleteDatasource(propertiesMap.get("jndi-name"));
+ expectedMessage = "Successfully deleted Local TX Datasource '"
+ + propertiesMap.get("jndi-name") + "'";
+ checkClientAndServerMessages(expectedMessage, expectedMessage, false);
+ }
+
+
+
+
+
+
+
+ /**
+ * Attempt to create a new datasource but leave at least one required
+ * value unset. An error should occur.
+ *
+ * TODO: Check if works for AS 4 .
+ */
+ public void testCreateDatasourceMissingRequiredValues() throws IOException {
+
+ // Leave jndi-name and connection-url unset
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("user-name", "testUser");
+ propertiesMap.put("max-pool-size", "10");
+ propertiesMap.put("prefill", "true");
+ propertiesMap.put("idle-timeout-minutes", "20");
+ propertiesMap.put("set-tx-query-timeout", "true");
+ propertiesMap.put("query-timeout", "1800");
+
+ createDatasource(DatasourceType.NO_TX_DATASOURCE,
+ DatasourceType.NO_TX_DATASOURCE.getTemplateHtmlSelectValue(), //"default__No TX Datasource",
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate error messages
+ checkClientAndServerMessages("An invalid value was specified for one "
+ + "or more properties",
+ "Value is required",
+ true);
+ }
+
+ /**
+ * Attempt to create a new datasource but set a property value
+ * beyond its expected range of values. An error should occur.
+ *
+ * TODO: Check if works for AS 4 .
+ */
+ public void testCreateDatasourcePropertyOutOfRange() throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", "InvalidDS");
+ propertiesMap.put("user-name", "testUser");
+ propertiesMap.put("password", "password");
+ propertiesMap.put("xa-datasource-class", "org.postgresql.xa.PGXADataSource");
+ propertiesMap.put("xa-resource-timeout", "36000");
+
+ // This number is too big
+ propertiesMap.put("max-pool-size", "100000000000000");
+
+ createDatasource(DatasourceType.XA_DATASOURCE,
+ DatasourceType.XA_DATASOURCE.getTemplateHtmlSelectValue(),
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate error messages
+ checkClientAndServerMessages("An invalid value was specified for one or more properties",
+ "Specified attribute is not between the expected values",
+ true);
+ }
+
+
+ /**
+ * Attempt to create a new datasource but set a property value
+ * to an invalid type. An error should occur.
+ *
+ * TODO: Check if works for AS 4 .
+ */
+ public void testCreateDatasourceInvalidPropertyType() throws IOException {
+ Map<String, String> propertiesMap = new HashMap<String, String>();
+ propertiesMap.put("jndi-name", "InvalidDS");
+ propertiesMap.put("min-pool-size", "10");
+ propertiesMap.put("max-pool-size", "20");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:.");
+ propertiesMap.put("share-prepared-statements", "false");
+
+ // This property value is supposed to be an integer
+ propertiesMap.put("background-validation-millis", "abcde");
+
+ createDatasource(DatasourceType.LOCAL_TX_DATASOURCE,
+ DatasourceType.LOCAL_TX_DATASOURCE.getTemplateHtmlSelectValue(), // TODO: Redundant, remove.
+ propertiesMap);
+ client.click("resourceConfigurationForm:saveButton");
+
+ // Check for the appropriate error messages
+ checkClientAndServerMessages("An invalid value was specified for one or more properties",
+ "Value is not a valid integer",
+ true);
+ }
+
+
+
+
+
+
+ /*
+ * --- Various support methods. ---
+ */
+
+
+
+
+ /**
+ * Creates the default properties for the datasource - shared by AS4 and AS5.
+ * Overriding method should get result of this method and overwrite it with it's custom properties.
+ * @returns a set of default properties.
+ */
+ protected Map<String, String> createDatasourceProperties()
+ {
+ Map<String, String> propertiesMap = new HashMap();
+
+ // The properties we want to configure
+ propertiesMap.put("jndi-name", "TestDS");
+ propertiesMap.put("user-name", "testUser");
+ propertiesMap.put("password", "password");
+ propertiesMap.put("min-pool-size", "5");
+ propertiesMap.put("driver-class", "org.hsqldb.jdbcDriver");
+ propertiesMap.put("connection-url", "jdbc:hsqldb:."); // Store data current working dir.
+ propertiesMap.put("idle-timeout-minutes", "20");
+ //propertiesMap.put("query-timeout", "180"); // AS 5 only - moved there
+ propertiesMap.put("prepared-statement-cache-size", "2");
+ // Share Prepared Statements - AS 5
+ //propertiesMap.put("share-prepared-statements", "false"); // AS 5
+
+ propertiesMap.put("valid-connection-checker-class-name",
+ "org.jboss.resource.adapter.jdbc.CheckValidConnectionSQL");
+ //propertiesMap.put("stale-connection-checker-class-name",
+ // "org.jboss.resource.adapter.jdbc.StaleConnectionChecker"); // AS 5
+ propertiesMap.put("exception-sorter-class-name",
+ "org.jboss.resource.adapter.jdbc.ExceptionSorter");
+ //propertiesMap.put("allocation-retry", "10000"); // AS 5
+ //propertiesMap.put("allocation-retry-wait-millis", "10000"); // AS 5
+
+ //propertiesMap.put("background-validation-millis", "15000"); // AS 5
+ //propertiesMap.put("prefill", "true"); // AS 5
+ //propertiesMap.put("use-try-lock", "61000"); // AS 5
+
+ return propertiesMap;
+
+ }
+
+
+
+ /**
+ *
+ * @returns a name of the Datasource's config file to check the properties in.
+ */
+ protected abstract String getDatasourceConfigFile();
+
+ protected abstract String getMBeanName( String jndiName, String serviceName );
+
+ /**
+ * This method is wrapper that handles JMX exceptions at Base level.
+ * Intended to keep AS-version-specific method, isMBeanStateDeployedImpl(), as small as possible.
+ * @param deploymentMBean
+ * @return
+ * @throws javax.management.JMException
+ * @throws java.io.IOException
+ */
+ protected boolean isMBeanStateDeployed( ObjectName deploymentMBean ) {
+
+ try {
+ return this.isMBeanStateDeployedImpl(deploymentMBean);
+ }
+ // This super-exception includes JMX operation failures, including:
+ // AttributeNotFoundException, InstanceNotFoundException, MalformedObjectNameException, ServiceNotFoundException
+ catch (OperationsException ex) {
+ log.log(Level.WARNING, "JMX operation error when retrieving MBean attribute.", ex);
+ return false;
+ }
+ // All other JMX failures...
+ catch (JMException ex) {
+ log.log(Level.WARNING, "JMX error when retrieving MBean attribute.", ex);
+ return false;
+ }
+ catch (IOException ex) {
+ log.log(Level.SEVERE, "I/O error when retrieving MBean attribute.", ex);
+ return false;
+ }
+
+ }// isMBeanStateDeployed()
+
+ /**
+ * This method should query the JMX server and decide whether the given MBean displays deployed resource.
+ * @param deploymentMBean Name of the MBean to examine. Differs between AS4 and 5.
+ * @return true if the MBean indicates that the resource is deployed, false otherwise.
+ * @throws javax.management.JMException upon JMX related error, including invalid
+ * or non-existent MBean / attribute name.
+ * @throws java.io.IOException upon I/O error.
+ */
+ protected abstract boolean isMBeanStateDeployedImpl( ObjectName deploymentMBean ) throws JMException, IOException;
+
+
+}
+
15 years, 11 months
EMBJOPR SVN: r109 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit.
by embjopr-commits@lists.jboss.org
Author: ozizka(a)redhat.com
Date: 2009-01-19 10:16:20 -0500 (Mon, 19 Jan 2009)
New Revision: 109
Added:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AssertException.java
Log:
Added: AssertException - to be used as a base class for assertion exceptions.
Added: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AssertException.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AssertException.java (rev 0)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AssertException.java 2009-01-19 15:16:20 UTC (rev 109)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file 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.jopr.jsfunit;
+
+
+/**
+ *
+ * @author ondra
+ */
+public class AssertException extends Exception {
+
+ public AssertException(Throwable cause) {
+ super(cause);
+ }
+
+ public AssertException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public AssertException(String message) {
+ super(message);
+ }
+
+ public AssertException() {
+ }
+
+}
15 years, 11 months
EMBJOPR SVN: r108 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit.
by embjopr-commits@lists.jboss.org
Author: ozizka(a)redhat.com
Date: 2009-01-19 10:13:51 -0500 (Mon, 19 Jan 2009)
New Revision: 108
Modified:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
Log:
Added: Various helper methods; some of them duplicate the functionality in Farah's code - to be reduced later.
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-01-14 12:33:04 UTC (rev 107)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-01-19 15:13:51 UTC (rev 108)
@@ -24,19 +24,12 @@
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
-import com.gargoylesoftware.htmlunit.html.ClickableElement;
-import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
-import com.gargoylesoftware.htmlunit.html.HtmlButtonInput;
-import com.gargoylesoftware.htmlunit.html.HtmlForm;
-import com.gargoylesoftware.htmlunit.html.HtmlImage;
-import com.gargoylesoftware.htmlunit.html.HtmlTable;
-import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
-import com.gargoylesoftware.htmlunit.html.HtmlTableCell;
-import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.*;
import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.logging.Logger;
+import javax.naming.NamingException;
+import javax.naming.InitialContext;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.ServletTestCase;
@@ -45,7 +38,13 @@
import org.jboss.jsfunit.jsfsession.JSFServerSession;
import org.jboss.jsfunit.jsfsession.JSFSession;
import javax.faces.application.FacesMessage;
+import javax.management.*;
+import org.jboss.mx.util.MBeanServerLocator;
+//import org.jboss.jmx.adaptor.rmi.RMIAdaptor; // Needs dependency: jmx-adaptor-plugin
+
+
+
/**
* This is the base test class for Embedded Jopr test cases.
* It supplies access to a JSFClientSession object and a JSFServerSession
@@ -53,15 +52,19 @@
* commonly used UI components.
*
* @author Farah Juma
+ * @author Ondrej Zizka
* @author Stan Silvert
*/
public class EmbjoprTestCase extends ServletTestCase {
+ protected final Logger log = Logger.getLogger(this.getClass().getName());
+
protected boolean isJBoss4;
protected JSFClientSession client;
protected JSFServerSession server;
+
/**
* Start a JSFUnit session by logging in to the main page. Note that
* because setUp() is called before each test, a new HttpSession will be
@@ -216,6 +219,8 @@
HtmlForm form = (HtmlForm)client.getElement("resourceConfigurationForm");
HtmlInput input = (HtmlInput)form.getFirstByXPath(".//input[@ondblclick='//"
+ propertyName + "']");
+
+ assertNotNull("Form input for property "+propertyName+" not found.", input);
boolean isRadioButton = input.getTypeAttribute().equals("radio");
String id = input.getId();
@@ -304,5 +309,192 @@
public void testClientSessionCreated() {
assertTrue(client != null);
}
+
+
+
+
+
+
+
+
+
+
+ /**
+ * Finds a row in the "details table" using the text in the Name column
+ * and returns the text from the Value column.
+ * @param name
+ * @return
+ */
+ public String getDetailsRowValue(String name) throws AssertException {
+ HtmlDivision contentDiv = (HtmlDivision) client.getElement("content");
+ List<?> valueTDs = contentDiv.getByXPath(
+ ".//div[@class='tabmenubox']//td[contains(text(),'"+name+"']/following-sibling::td[1]");
+ //assertTrue( name + " row not found.", valueTDs.size() == 1 );
+ if( valueTDs.size() == 1 )
+ throw new AssertException( name + " row not found." );
+ String value = ((HtmlTableCell) valueTDs).getTextContent();
+ return value;
+ }
+
+
+ /**
+ * Returns the content element - <div id="content"> - which contains whole page.
+ * Good as a start point for XPath queries - other elements usually have generated IDs.
+ * Assertion fails if the element is not found.
+ * @return
+ */
+ public HtmlElement getContentElement() throws AssertException {
+ HtmlElement contentElement = (HtmlElement)client.getElement("content");
+ //assertNotNull("Content <div> not found.", contentElement);
+ if( null == contentElement )
+ throw new AssertException( "Content <div> not found." );
+ return contentElement;
+ }
+
+
+ /**
+ * Convenience method, calls getElementsByXPath() with content element.
+ * @param sXPath
+ * @return
+ */
+ public List<? extends HtmlElement> getElementsByXPath(String sXPath ) throws AssertException {
+ //return (List<? extends HtmlElement>) getContentElement().getByXPath(sXPath);
+ return getElementsByXPath( getContentElement(), sXPath );
+ }
+
+
+ /**
+ * Retuns a list of elements chosen by XPath, with the given element as context node.
+ * @param xPathContextElement
+ * @param sXPath
+ * @return
+ */
+ public List<? extends HtmlElement> getElementsByXPath(
+ HtmlElement xPathContextElement, String sXPath )
+ throws AssertException
+ {
+ if( null == xPathContextElement ){
+ throw new AssertException("Given XPath context element is null.");
+ }
+
+ return (List<? extends HtmlElement>) xPathContextElement.getByXPath(sXPath);
+ }
+
+
+ /**
+ * Returns the first element in the list returned by getElementsByXPath(String sXPath ).
+ * @param sXPath
+ * @return
+ */
+ public HtmlElement getFirstElementByXPath( HtmlElement xPathContext, String sXPath ) throws AssertException {
+
+ List<? extends HtmlElement> elementsByXPath = getElementsByXPath(xPathContext, sXPath);
+ if( elementsByXPath.size() == 0 ){
+ throw new RuntimeException("XPath expression found no elements: "+sXPath);
+ // Exception is better - will get the stack trace.
+ //fail("XPath expression found no elements: "+sXPath);
+ }
+ return elementsByXPath.get(0);
+ }
+
+
+ /**
+ * Convenience method - calls getFirstElementByXPath() with content div as context.
+ * @param sXPath
+ * @return
+ */
+ public HtmlElement getFirstElementByXPath( String sXPath ) throws AssertException{
+ return getFirstElementByXPath( getContentElement(), sXPath );
+ }
+
+
+ /**
+ * Retrieves an input element from a named row of a table in a form.
+ * Supposes that the form is in the "tabmenubox" or "notabmenubox" div.
+ * @param sRowName
+ * @return
+ * @throws org.jboss.jopr.jsfunit.AssertException
+ */
+ public HtmlInput getFormInputByRowName(String sRowName) throws AssertException {
+ try {
+ HtmlInput input = (HtmlInput) getFirstElementByXPath(
+ getTabMenuBoxElement(),
+ ".//td[contains(text(),'"+sRowName+"')]/following-sibling::td[@class='property-value-cell']//input"
+ );
+ if( null == input ){
+ throw new AssertException("Input for value "+sRowName+" not found.");
+ }
+ return input;
+ }
+ catch(AssertException ex){
+ //throw new AssertException("Row with name \""+sRowName+"\" not found.", ex);
+ throw ex;
+ }
+ }
+
+
+ /**
+ * Retrieves a named row of a table in the "right side of the page".
+ * Supposes that the table is in the "tabmenubox" or "notabmenubox" div.
+ * Uses getTabMenuBoxElement() to get that div.
+ * @param sRowName
+ * @return
+ * @throws org.jboss.jopr.jsfunit.AssertException
+ */
+ public HtmlTableRow getRowByName(String sRowName) throws AssertException {
+ HtmlTableRow row = (HtmlTableRow) getFirstElementByXPath(
+ getTabMenuBoxElement(),
+ ".//td[contains(text(),'"+sRowName+"')]/ancestor::tr"
+ );
+ if( null == row ){
+ throw new AssertException("Row for value "+sRowName+" not found.");
+ }
+ return row;
+ }
+
+
+ /**
+ * Returns the element which contains the "right side of the page".
+ * <div class="tabmenubox"> element exists on each page that shows resource's details.
+ * <div class="notabmenubox"> element exists on each page with form for resource's properties editation.
+ * @return
+ * @throws org.jboss.jopr.jsfunit.AssertException
+ */
+ public HtmlElement getTabMenuBoxElement() throws AssertException {
+ return getFirstElementByXPath(".//div[@class='tabmenubox' or @class='notabmenubox']");
+ }
+
+
+
+
+ /**
+ * Returns an integer part of the beginning of the given string.
+ * @param s
+ * @return Integer with the value of numerical part of the string,
+ * or null if there are no digits at the beginning.
+ */
+ public Integer integerFromString(String s) {
+ int pos;
+ for( pos = 0; pos < s.length(); pos++ ){
+ char ch = s.charAt(0);
+ if( '0' > ch || ch > '9' )
+ break;
+ }
+
+ if( pos == 0 )
+ return null;
+
+ try{
+ int val = Integer.parseInt( s.substring( 0, pos ) );
+ return val;
+ }catch( NumberFormatException ex ){
+ return null;
+ }
+
+ }
+
+
}
+
+
15 years, 11 months
EMBJOPR SVN: r107 - trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as4.
by embjopr-commits@lists.jboss.org
Author: ozizka(a)redhat.com
Date: 2009-01-14 07:33:04 -0500 (Wed, 14 Jan 2009)
New Revision: 107
Removed:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as4/HelloJoprTest.java
Log:
Removed: org.jboss.jopr.jsfunit.as4.HelloJoprTest.java - it's in root package
Deleted: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as4/HelloJoprTest.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as4/HelloJoprTest.java 2009-01-13 21:39:30 UTC (rev 106)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as4/HelloJoprTest.java 2009-01-14 12:33:04 UTC (rev 107)
@@ -1,236 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file 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.jopr.jsfunit.as4;
-
-import com.gargoylesoftware.htmlunit.BrowserVersion;
-import com.gargoylesoftware.htmlunit.WebClient;
-import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
-import com.gargoylesoftware.htmlunit.html.HtmlButtonInput;
-import com.gargoylesoftware.htmlunit.html.HtmlFileInput;
-import com.gargoylesoftware.htmlunit.html.HtmlForm;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import javax.faces.application.FacesMessage;
-import javax.faces.context.FacesContext;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.servlet.http.HttpServletRequest;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import org.apache.cactus.ServletTestCase;
-import org.jboss.jopr.jsfunit.JoprLoginStrategy;
-import org.jboss.jopr.jsfunit.SimpleConfirmHandler;
-import org.jboss.jsfunit.framework.WebClientSpec;
-import org.jboss.jsfunit.jsfsession.JSFClientSession;
-import org.jboss.jsfunit.jsfsession.JSFServerSession;
-import org.jboss.jsfunit.jsfsession.JSFSession;
-import org.jboss.mx.util.MBeanServerLocator;
-
-/**
- * Sample for testing Embedded Jopr. Here I present a fairly complex test
- * case to show some of the things that JSFUnit can do.
- *
- * @author Stan Silvert
- */
-public class HelloJoprTest extends ServletTestCase
-{
- private boolean isJBoss4;
-
- private JSFClientSession client;
- private JSFServerSession server;
-
- /**
- * Start a JSFUnit session by logging in to the main page. Note that
- * because setUp() is called before each test, a new HttpSession will be
- * created each time a test is run.
- */
- public void setUp() throws IOException
- {
- isJBoss4 = Package.getPackage("org.jboss.system.server")
- .getImplementationVersion()
- .startsWith("4");
-
- // Initial JSF request
- WebClientSpec wcSpec = new WebClientSpec("/", BrowserVersion.FIREFOX_3);
-
- // This is temporary because embedded Jopr can't find /js/rhq.js
- wcSpec.getWebClient().setThrowExceptionOnFailingStatusCode(false);
-
- // Always press OK for confirm dialogs
- wcSpec.getWebClient().setConfirmHandler(new SimpleConfirmHandler(true));
-
- wcSpec.setInitialRequestStrategy(new JoprLoginStrategy()); // logs in
-
- JSFSession jsfSession = new JSFSession(wcSpec);
- this.client = jsfSession.getJSFClientSession();
- this.server = jsfSession.getJSFServerSession();
- }
-
- /**
- * @return the suite of tests being tested
- */
- public static Test suite()
- {
- return new TestSuite( HelloJoprTest.class );
- }
-
- public void testDeployWAR() throws IOException
- {
- // click the nave tree
- HtmlAnchor warLink = getNavTreeLink("Web Application (WAR)");
- warLink.click();
-
- // click on the "Add new resource" button
- client.click("actionHeaderForm:addNewContent"); // 404 if setThrowExceptionOnFailingStatusCode(true) above
-
- // upload hellothere.war
- HtmlFileInput fileInput = (HtmlFileInput)client.getElement("createContentForm:file");
- fileInput.setContentType("application/war");
- fileInput.setValueAttribute(System.getProperty("jsfunit.testdata") + "/war/hellothere.war");
- client.click("createContentForm:addButton");
-
- // assert that the success message appeared on the client side
- assertTrue(client.getPageAsText().contains("hellothere.war created successfully"));
-
- // assert text and sevrity level for FacesMessage on server side
- assertTrue(server.getFacesMessages().hasNext());
- FacesMessage successMessage = server.getFacesMessages().next();
- assertTrue(FacesMessage.SEVERITY_INFO.equals(successMessage.getSeverity()));
- assertTrue(successMessage.getDetail().contains("hellothere.war created successfully"));
-
- // Use JMX to assert that the WAR really did deploy successfully
- assertTrue(isWarDeployed("hellothere.war"));
-
- // use HtmlUnit to test the newly deployed war in a new WebClient session
- // note that I have full access to the FacesContext and the previous request
- HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
- int port = request.getLocalPort();
- WebClient webClient = new WebClient();
- HtmlPage page = (HtmlPage)webClient.getPage("http://localhost:" + port + "/hellothere/hello.jsp");
- assertTrue(page.asText().contains("HELLO WORLD"));
-
- // Undeploy the WAR
- HtmlButtonInput deleteButton = getDeleteButton("hellothere.war");
- deleteButton.click();
-
- // This assert doesn't work. jopr does remove the WAR, but for some
- // reason, JBoss doesn't undeploy the MBeans
- //assertFalse(isWarDeployed("hellothere.war"));
- }
-
- private boolean isWarDeployed(String warName)
- {
- if (isJBoss4)
- {
- return checkWarDeployment_4_2(warName);
- }
- else
- {
- return checkWarDeployment_5_0(warName);
- }
- }
-
- // Query the MBean server to find if WAR is deployed
- private boolean checkWarDeployment_4_2(String warName)
- {
- try {
- MBeanServer jmxServer = MBeanServerLocator.locateJBoss();
- ObjectName objName = new ObjectName("jboss.web.deployment:war=" + warName + ",*");
- Set mBeans = jmxServer.queryNames(objName, null);
- if (mBeans.size() != 1) return false;
- ObjectName deploymentMBean = (ObjectName)mBeans.iterator().next();
- String state = (String)jmxServer.getAttribute(deploymentMBean, "StateString");
- return "Started".equals(state);
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
-
- // Query the MBean server to find if WAR is deployed
- private boolean checkWarDeployment_5_0(String warName)
- {
- if (warName.endsWith(".war"))
- {
- warName = warName.substring(0, warName.lastIndexOf(".war"));
- }
- else
- {
- warName = warName.substring(0, warName.lastIndexOf(".WAR"));
- }
-
- try {
- MBeanServer jmxServer = MBeanServerLocator.locateJBoss();
- ObjectName objName = new ObjectName("jboss.deployment:id=\"jboss.web.deployment:war=/" + warName + "\",*");
- Set mBeans = jmxServer.queryNames(objName, null);
- if (mBeans.size() != 1) return false;
- ObjectName deploymentMBean = (ObjectName)mBeans.iterator().next();
-
- // returns org.jboss.deployers.spi.DeploymentState
- Object state = jmxServer.getAttribute(deploymentMBean, "State");
- return "DEPLOYED".equals(state.toString());
- }
- catch (Exception e)
- {
- throw new RuntimeException(e);
- }
- }
-
- // need a standard JSFUnit API to replace this code
- private HtmlAnchor getNavTreeLink(String linkLabel)
- {
- return getLinkInsideForm("navTreeForm", linkLabel);
- }
-
- private HtmlButtonInput getDeleteButton(String resourceName)
- {
- HtmlAnchor link = getLinkInsideForm("resourceSummaryForm", resourceName);
- // The id will look like "resourceSummaryForm:dataTable:2:resourceName"
- // I need the row number. (2 in the above example)
- String id = link.getIdAttribute();
- String[] idElements = id.split(":");
- String row = idElements[idElements.length - 2];
- return (HtmlButtonInput)client.getElement(row + ":removeButton");
- }
-
- // finds a <a> tag inside a form that has a particular label
- private HtmlAnchor getLinkInsideForm(String formId, String linkLabel)
- {
- HtmlForm form = (HtmlForm)client.getElement(formId);
- List links = form.getByXPath(".//a"); // get all <a> tags inside form
-
- for (Iterator i = links.iterator(); i.hasNext();)
- {
- HtmlAnchor link = (HtmlAnchor)i.next();
- String linkText = link.getTextContent();
- if (linkText.contains(linkLabel)) return link;
- }
-
- throw new IllegalStateException("Nav Tree link for '" + linkLabel + "' not found.");
- }
-
-}
\ No newline at end of file
15 years, 11 months