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.