From: <ble...@us...> - 2010-09-10 19:44:46
|
Revision: 3530 http://bigdata.svn.sourceforge.net/bigdata/?rev=3530&view=rev Author: blevine218 Date: 2010-09-10 19:44:37 +0000 (Fri, 10 Sep 2010) Log Message: ----------- Get initial test to pass. Re-work setting of system properties. Modified Paths: -------------- branches/maven_scaleout/bigdata-integ/pom.xml Added Paths: ----------- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/AbstractServerTestCase.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClient.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClientRemote.java branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/test/util/ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/test/util/Util.java Modified: branches/maven_scaleout/bigdata-integ/pom.xml =================================================================== --- branches/maven_scaleout/bigdata-integ/pom.xml 2010-09-10 17:12:33 UTC (rev 3529) +++ branches/maven_scaleout/bigdata-integ/pom.xml 2010-09-10 19:44:37 UTC (rev 3530) @@ -1,5 +1,4 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <parent> @@ -15,7 +14,40 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <project.build.deployDirectory>${project.build.directory}/deploy</project.build.deployDirectory> + <deploy.root.dir>${project.build.directory}/deploy</deploy.root.dir> + <bigdata.dependency>bigdata-core</bigdata.dependency> + + + <!-- + This is kinda hokey, but not sure there's a better way to + construct the path to the root of the exploded tarball --> + + <deploy.dir>${deploy.root.dir}/${bigdata.dependency}-${project.version}</deploy.dir> + <test.dir>${deploy.dir}/testing</test.dir> + <testScript>${test.dir}/test.xml</testScript> + + <basedir>${test.dir}</basedir> + <app.home>${deploy.dir}</app.home> + <deploy.conf.dir>${test.dir}/conf</deploy.conf.dir> + <deploy.lib>${deploy.dir}/lib</deploy.lib> + <deploy.lib.test>${test.dir}/lib-test</deploy.lib.test> + <deploy.lib.dl>${deploy.dir}/lib-dl</deploy.lib.dl> + <test.codebase.dir>${deploy.lib.dl}</test.codebase.dir> + <test.codebase.port>23333</test.codebase.port> + <java.security.policy>${deploy.conf.dir}/policy.all</java.security.policy> + <log4j.configuration>${deploy.dir}/var/config/logging/log4j.properties</log4j.configuration> + <java.net.preferIPv4Stack>true</java.net.preferIPv4Stack> + <default.nic>eth0</default.nic> + <parent.artifactName>bigdata-core</parent.artifactName> + + + <!-- + In the ANT script, hostname is obtained by an exec of the + 'hostname' command. Hard-coding to localhost for now. + --> + <hostname>blevine-desktop</hostname> + <test.codebase>http://${hostname}:${test.codebase.port}/jsk-dl.jar</test.codebase> + <federation.name>bigdata.test.group-${hostname}</federation.name> </properties> @@ -33,15 +65,17 @@ <configuration> <artifactItems> <artifactItem> - <groupId>com.nokia.dataos.rds.bigdata</groupId> - <artifactId>bigdata-dist</artifactId> - <version>0.83.2-SNAPSHOT</version> - <type>tgz</type> - <outputDirectory>${project.build.deployDirectory}</outputDirectory> + <groupId>com.bigdata</groupId> + <artifactId>bigdata-core</artifactId> + <classifier>deploy</classifier> + <type>tar.gz</type> + <outputDirectory>${deploy.directory}</outputDirectory> </artifactItem> </artifactItems> + <useSubdirPerArtifact>true</useSubdirPerArtifact> + <!-- <overWriteSnapshots>true</overWriteSnapshots> - <overWriteReleases>true</overWriteReleases> + <overWriteReleases>true</overWriteReleases> --> </configuration> </execution> </executions> @@ -64,13 +98,55 @@ </plugin> <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>failsafe-maven-plugin</artifactId> - <version>2.4.3-alpha-1</version> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> <configuration> <includes> - <include>**/*.java</include> + <include>**/Test*.java</include> + <include>**/*Test.java</include> </includes> + <excludes> + <exclude>**/TestBigdataClientRemote.java</exclude> + </excludes> + <systemPropertyVariables> + <foo.bar.prop>hello</foo.bar.prop> + <java.security.policy>${java.security.policy}</java.security.policy> + <java.net.preferIPv4Stack>{java.net.preferIPv4Stack}"</java.net.preferIPv4Stack> + <log4j.configuration>${log4j.configuration}</log4j.configuration> + <!-- ><log4j.debug>true"</log4j.debug> --> + + <basedir>${basedir}</basedir> <!-- Tells the unit tests where the ant script is, so they can find resources. --> + <app.home>${app.home}</app.home> <!-- This is the deployment directory, easily accessed by the DataFinder class. --> + <log4j.path>${log4j.configuration}</log4j.path> + <default.nic>${default.nic}</default.nic> + + <!-- Jini group name --> + <federation.name>${federation.name}</federation.name> + + <!-- TODO !!!!!! + <property key="java.class.path" value="${junit.classpath.text}" /> + --> + + <classserver.jar>${deploy.lib}/classserver.jar</classserver.jar> + <colt.jar>${deploy.lib}/colt.jar</colt.jar> + <ctc_utils.jar>${deploy.lib}/ctc_utils.jar</ctc_utils.jar> + <cweb-commons.jar>${deploy.lib}/cweb-commons.jar</cweb-commons.jar> + <cweb-extser.jar>${deploy.lib}/cweb-extser.jar</cweb-extser.jar> + <highscalelib.jar>${deploy.lib}/highscalelib.jar</highscalelib.jar> + <dsiutils.jar>${deploy.lib}/dsiutils.jar</dsiutils.jar> + <lgplutils.jar>${deploy.lib}/lgplutils.jar</lgplutils.jar> + <fastutil.jar>${deploy.lib}/fastutil.jar</fastutil.jar> + <icu4j.jar>${deploy.lib}/icu4j.jar</icu4j.jar> + <jsk-lib.jar>${deploy.lib}/jsk-lib.jar</jsk-lib.jar> + <jsk-platform.jar>${deploy.lib}jsk-platform.jar</jsk-platform.jar> + <log4j.jar>${deploy.lib}/log4j.jar</log4j.jar> + <iris.jar>${deploy.lib}/iris.jar</iris.jar> + <jgrapht.jar>${deploy.lib}/jgrapht.jar</jgrapht.jar> + <openrdf-sesame.jar>${deploy.lib}/openrdf-sesame.jar</openrdf-sesame.jar> + <slf4j.jar>${deploy.lib}/slf4j.jar</slf4j.jar> + <nxparser.jar>${deploy.lib}/nxparser.jar</nxparser.jar> + <zookeeper.jar>${deploy.lib}/zookeeper.jar</zookeeper.jar> + </systemPropertyVariables> </configuration> <executions> <execution> @@ -91,9 +167,8 @@ <phase>pre-integration-test</phase> <configuration> <tasks> - <ant - antfile="${project.build.testOutputDirectory}/test.xml" - target="hello" /> + <echo message="testscript = ${testScript}" /> + <ant antfile="${testScript}" target="startTestServices" useNativeBasedir="true" inheritAll="false"/> </tasks> </configuration> <goals> @@ -106,9 +181,8 @@ <phase>post-integration-test</phase> <configuration> <tasks> - <ant - antfile="${project.build.testOutputDirectory}/test.xml" - target="hello" /> + <echo message="testscript = ${testScript}" /> + <ant antfile="${testScript}" target="stopTestServices" useNativeBasedir="true" inheritAll="false"/> </tasks> </configuration> <goals> @@ -127,9 +201,16 @@ <groupId>com.bigdata</groupId> <artifactId>bigdata-core</artifactId> <version>${project.version}</version> + <classifier>deploy</classifier> + <type>tar.gz</type> <scope>test</scope> </dependency> + <dependency> + <groupId>com.bigdata</groupId> + <artifactId>bigdata-core</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> @@ -137,6 +218,13 @@ <scope>test</scope> </dependency> + <dependency> + <groupId>com.bigdata.thirdparty</groupId> + <artifactId>cweb-junit-ext</artifactId> + <version>1.1.0-b3-dev</version> + <scope>test</scope> + </dependency> + </dependencies> </project> Added: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/AbstractServerTestCase.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/AbstractServerTestCase.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/AbstractServerTestCase.java 2010-09-10 19:44:37 UTC (rev 3530) @@ -0,0 +1,503 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Apr 22, 2007 + */ + +package com.bigdata.service.jini; + +import java.io.IOException; +import java.net.InetAddress; + +import junit.framework.AssertionFailedError; +import junit.framework.TestCase2; +import net.jini.core.discovery.LookupLocator; +import net.jini.core.lookup.ServiceID; +import net.jini.core.lookup.ServiceRegistrar; +import net.jini.core.lookup.ServiceTemplate; + +import com.bigdata.journal.ITx; +import com.bigdata.mdi.IResourceMetadata; +import com.bigdata.mdi.LocalPartitionMetadata; +import com.bigdata.mdi.PartitionLocator; +import com.bigdata.service.DataService; +import com.bigdata.service.IDataService; +import com.bigdata.service.MetadataService; +import com.sun.jini.tool.ClassServer; +import com.bigdata.util.config.ConfigDeployUtil; +import com.bigdata.util.config.NicUtil; + +/** + * Abstract base class for tests of remote services. + * <p> + * Note: jini MUST be running. You can get the jini starter kit and install it + * to get jini running. + * </p> + * <p> + * Note: You MUST specify a security policy that is sufficiently lax. + * </p> + * <p> + * Note: You MUST specify the codebase for downloadable code. + * </p> + * <p> + * Note: The <code>bigdata</code> JAR must be current in order for the client + * and the service to agree on interface definitions, etc. You can use + * <code>build.xml</code> in the root of this module to update that JAR. + * </p> + * <p> + * Note: A {@link ClassServer} will be started on port 8081 by default. If that + * port is in use then you MUST specify another port. + * </p> + * + * The following system properties will do the trick unless you have something + * running on port 8081. + * + * <pre> + * -Djava.security.policy=policy.all -Djava.rmi.server.codebase=http://localhost:8081 + * </pre> + * + * To use another port, try: + * + * <pre> + * -Djava.security.policy=policy.all -Dbigdata.test.port=8082 -Djava.rmi.server.codebase=http://localhost:8082 + * </pre> + * + * You can enable NIO using: + * <pre> + * -Dcom.sun.jini.jeri.tcp.useNIO=true + * </pre> + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public abstract class AbstractServerTestCase extends TestCase2 { + + /** + * Equal to {@link ITx#UNISOLATED}. + */ + protected final long UNISOLATED = ITx.UNISOLATED; + + /** + * + */ + public AbstractServerTestCase() { + } + + /** + * @param arg0 + */ + public AbstractServerTestCase(String arg0) { + super(arg0); + } + +// /** +// * Return an open port on current machine. Try the suggested port first. If +// * suggestedPort is zero, just select a random port +// */ +// private static int getPort(int suggestedPort) throws IOException { +// ServerSocket openSocket; +// try { +// openSocket = new ServerSocket(suggestedPort); +// } catch (BindException ex) { +// // the port is busy, so look for a random open port +// openSocket = new ServerSocket(0); +// } +// +// int port = openSocket.getLocalPort(); +// openSocket.close(); +// +// return port; +// } + +// /** +// * This may be used to verify that a specific port is available. The method +// * will return iff the port is available at the time that this method was +// * called. The method will retry a few times since sometimes it takes a bit +// * for a socket to get released and we are reusing the same socket for the +// * {@link ClassServer} for each test. +// * +// * @param port +// * The port to try. +// * +// * @exception AssertionFailedError +// * if the port is not available. +// */ +// protected static void assertOpenPort(final int port) throws IOException { +// +// ServerSocket openSocket; +// +// int i = 0; +// +// final int maxTries = 3; +// +// while (i < maxTries) { +// +// try { +// +// // try to open a server socket on that port. +// openSocket = new ServerSocket(port); +// +// // close the socket - it is available for the moment. +// openSocket.close(); +// +// return; +// +// } catch (BindException ex) { +// +// if (i++ < maxTries) { +// +// log.warn("Port " + port + " is busy - retrying: " + ex); +// +// try { +// Thread.sleep(100/* ms */); +// } catch (InterruptedException t) { +// /* ignore */ +// } +// +// } else { +// +// fail("Port is busy: " + ex + " - use " + PORT_OPTION +// + " to specify another port?"); +// +// } +// +// } +// +// } +// +// } + +// private ClassServer classServer; +// +// /** +// * The name of the System property that may be used to change the port on which +// * the {@link ClassServer} will be started. +// */ +// public static final String PORT_OPTION = "bigdata.test.port"; +// +// /** +// * The default port on which the {@link ClassServer} will be started. +// * <p> +// * Note: Outlook appears to conflict with 8081. +// */ +// public static final String DEFAULT_PORT = "8082"; +// +// /** +// * Starts a {@link ClassServer} that supports downloadable code for the unit +// * test. The {@link ClassServer} will start on the port named by the System +// * property {@link #PORT_OPTION} and on port {@link #DEFAULT_PORT} if that +// * system property is not set. +// * +// * @throws IOException +// */ +// protected void startClassServer() throws IOException { +// +// // Note: See below. +//// if(true) return; +// +// Logger.getLogger("com.sun.jini.tool.ClassServer").setLevel(Level.ALL); +// +// /* +// * Obtain port from System.getProperties() so that other ports may be +// * used. +// */ +// final int port = Integer.parseInt(System.getProperty(PORT_OPTION,DEFAULT_PORT)); +// +// /* +// * The directories containing the JARs and the compiled classes for the +// * bigdata project. +// */ +// String dirlist = +// "lib"+File.pathSeparatorChar+ +// "lib"+File.separatorChar+"icu"+File.pathSeparatorChar+ +// "lib"+File.separatorChar+"jini"+File.pathSeparatorChar +// /* +// * FIXME This does not seem to be resolving the bigdata classes +// * necessitating that we list that jar explicitly below (and that it +// * be up to date). The problem can be seen in the Jini Service +// * Browser and the console for the Service Browser. In fact, the +// * test suite executes just fine if you do NOT use the ClassServer! +// * +// * I can only get this working right now by placing bigdata-core.jar into +// * the lib directory (or some other directory below the current +// * working directory, but not ant-build since that gives the ant +// * script fits). +// * +// * I still see a ClassNotFound problem in the Jini console complaining +// * that it can not find IDataService, but only when I select the +// * registrar on which the services are running! +// */ +//// + +//// "bin" +// //+File.pathSeparatorChar+ +//// "ant-build" +// ; +// +// assertOpenPort(port); +// +// classServer = new ClassServer( +// port, +// dirlist, +// true, // trees - serve up files inside of JARs, +// true // verbose +// ); +// +// classServer.start(); +// +// } + + public void setUp() throws Exception { + + if (log.isInfoEnabled()) + log.info(getName()); + +// startClassServer(); + + } + + /** + * Stops the {@link ClassServer}. + */ + public void tearDown() throws Exception { + +// if (classServer != null) { +// +// classServer.terminate(); +// +// } + + super.tearDown(); + + if (log.isInfoEnabled()) + log.info(getName()); + + } + + /** + * Return the {@link ServiceID} of a server that we started ourselves. The + * method waits until the {@link ServiceID} becomes available on + * {@link AbstractServer#getServiceID()}. + * + * @exception AssertionFailedError + * If the {@link ServiceID} can not be found after a timeout. + * + * @exception InterruptedException + * if the thread is interrupted while it is waiting to retry. + */ + static public ServiceID getServiceID(final AbstractServer server) + throws AssertionFailedError, InterruptedException { + + ServiceID serviceID = null; + + for(int i=0; i<10 && serviceID == null; i++) { + + /* + * Note: This can be null since the serviceID is not assigned + * synchronously by the registrar. + */ + + serviceID = server.getServiceID(); + + if(serviceID == null) { + + /* + * We wait a bit and retry until we have it or timeout. + */ + + Thread.sleep(200); + + } + + } + + assertNotNull("serviceID",serviceID); + + /* + * Verify that we have discovered the _correct_ service. This is a + * potential problem when starting a stopping services for the test + * suite. + */ + assertEquals("serviceID", server.getServiceID(), serviceID); + + return serviceID; + + } + + /** + * Lookup a {@link DataService} by its {@link ServiceID} using unicast + * discovery on localhost. + * + * @param serviceID + * The {@link ServiceID}. + * + * @return The service. + * + * @todo Modify to return the service item? + * + * @todo Modify to not be specific to {@link DataService} vs + * {@link MetadataService} (we need a common base interface for both + * that carries most of the functionality but allows us to make + * distinctions easily during discovery). + */ + public IDataService lookupDataService(ServiceID serviceID) + throws IOException, ClassNotFoundException, InterruptedException { + + /* + * Lookup the discover service (unicast on localhost). + */ + + // get the hostname. + String hostname = NicUtil.getIpAddress("default.nic", "default", true); + + // Find the service registrar (unicast protocol). + final int timeout = 4*1000; // seconds. + System.err.println("hostname: "+hostname); + LookupLocator lookupLocator = new LookupLocator("jini://"+hostname); + ServiceRegistrar serviceRegistrar = lookupLocator.getRegistrar( timeout ); + + /* + * Prepare a template for lookup search. + * + * Note: The client needs a local copy of the interface in order to be + * able to invoke methods on the service without using reflection. The + * implementation class will be downloaded from the codebase identified + * by the server. + */ + ServiceTemplate template = new ServiceTemplate(// + /* + * use this to request the service by its serviceID. + */ + serviceID, + /* + * Use this to filter services by an interface that they expose. + */ +// new Class[] { IDataService.class }, + null, + /* + * use this to filter for services by Entry attributes. + */ + null); + + /* + * Lookup a service. This can fail if the service registrar has not + * finished processing the service registration. If it does, you can + * generally just retry the test and it will succeed. However this + * points out that the client may need to wait and retry a few times if + * you are starting everything up at once (or just register for + * notification events for the service if it is not found and enter a + * wait state). + */ + + IDataService service = null; + + for (int i = 0; i < 10 && service == null; i++) { + + service = (IDataService) serviceRegistrar + .lookup(template /* , maxMatches */); + + if (service == null) { + + System.err.println("Service not found: sleeping..."); + + Thread.sleep(200); + + } + + } + + if (service != null) { + + System.err.println("Service found."); + + } + + return service; + + } + + /** + * Compares two representations of the {@link PartitionLocator} + * without the left- and right-separator keys that bound the index + * partition. + * + * @param expected + * @param actual + */ + protected void assertEquals(PartitionLocator expected, PartitionLocator actual) { + + assertEquals("partitionId", expected.getPartitionId(), actual + .getPartitionId()); + + assertEquals("dataServiceUUID", expected.getDataServiceUUID(), actual + .getDataServiceUUID()); + + } + + /** + * Compares two representations of the {@link LocalPartitionMetadata} for an + * index partition including the optional resource descriptions. + * + * @param expected + * @param actual + */ + protected void assertEquals(LocalPartitionMetadata expected, + LocalPartitionMetadata actual) { + + assertEquals("partitionId",expected.getPartitionId(), actual.getPartitionId()); + + assertEquals("leftSeparatorKey", expected.getLeftSeparatorKey(), + ((LocalPartitionMetadata) actual) + .getLeftSeparatorKey()); + + assertEquals("rightSeparatorKey", expected.getRightSeparatorKey(), + ((LocalPartitionMetadata) actual) + .getRightSeparatorKey()); + + final IResourceMetadata[] expectedResources = expected.getResources(); + + final IResourceMetadata[] actualResources = actual.getResources(); + + assertEquals("#resources",expectedResources.length,actualResources.length); + + for(int i=0;i<expected.getResources().length; i++) { + + // verify by components so that it is obvious what is wrong. + + assertEquals("filename[" + i + "]", expectedResources[i].getFile(), + actualResources[i].getFile()); + +// assertEquals("size[" + i + "]", expectedResources[i].size(), +// actualResources[i].size()); + + assertEquals("UUID[" + i + "]", expectedResources[i].getUUID(), + actualResources[i].getUUID()); + + // verify by equals. + assertTrue("resourceMetadata",expectedResources[i].equals(actualResources[i])); + + } + + } + +} Added: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClient.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClient.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClient.java 2010-09-10 19:44:37 UTC (rev 3530) @@ -0,0 +1,214 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * Created on Apr 23, 2007 + */ + +package com.bigdata.service.jini; + +import java.io.Serializable; +import java.util.Random; +import java.util.UUID; + +import com.bigdata.btree.IIndex; +import com.bigdata.btree.ITuple; +import com.bigdata.btree.ITupleIterator; +import com.bigdata.btree.IndexMetadata; + +import com.bigdata.btree.proc.BatchInsert.BatchInsertConstructor; +import com.bigdata.journal.ITx; +import com.bigdata.service.DataService; +import com.bigdata.service.IBigdataFederation; +import com.bigdata.service.IDataService; +import com.bigdata.service.jini.util.JiniServicesHelper; +import com.bigdata.test.util.Util; + +/** + * Test suite for the {@link JiniClient}. + * <p> + * Note: The core test suite has already verified the basic semantics of the + * {@link IDataService} interface and partitioned indices so all we have to + * focus on here is the jini integration and verifying that the serialization + * imposed by RMI goes off without a hitch (e.g., that everything implements + * {@link Serializable} and that those {@link Serializable} implementations can + * correctly round trip the data). + * + * @author <a href="mailto:tho...@us...">Bryan Thompson</a> + * @version $Id$ + */ +public class TestBigdataClient extends AbstractServerTestCase { + + protected boolean serviceImplRemote; + + public TestBigdataClient() { + this.serviceImplRemote = false; + } + + public TestBigdataClient(String name) { + super(name); + this.serviceImplRemote = false; + } + + public TestBigdataClient(boolean serviceImplRemote) { + this.serviceImplRemote = serviceImplRemote; + } + + public TestBigdataClient(String name, boolean serviceImplRemote) { + super(name); + this.serviceImplRemote = serviceImplRemote; + } + + /** + * Starts a {@link DataServer} ({@link #dataServer1}) and then a + * {@link MetadataServer} ({@link #metadataServer0}). Each runs in its own + * thread. + */ + public void setUp() throws Exception { + super.setUp(); + helper = new JiniServicesHelper(serviceImplRemote); + helper.start(); + } + + protected JiniServicesHelper helper = null; + + /** + * Destroy the test services. + */ + public void tearDown() throws Exception { + if (helper != null) { + helper.destroy(); + } + + super.tearDown(); + } + + /** + * Test ability to registers a scale-out index on one of the + * {@link DataService}s. + * + * @throws Exception + */ + public void test_registerIndex1() throws Exception { + final IBigdataFederation<?> fed = helper.client.connect(); + final String name = "testIndex"; + final IndexMetadata metadata = new IndexMetadata(name, UUID.randomUUID()); + + metadata.setDeleteMarkers(true); + fed.registerIndex(metadata); + final IIndex ndx = fed.getIndex(name, ITx.UNISOLATED); + + assertEquals("indexUUID", metadata.getIndexUUID(), ndx + .getIndexMetadata().getIndexUUID()); + + doBasicIndexTests(ndx); + } + + /** + * Test ability to registers a scale-out index on both of the + * {@link DataService}s. + * + * @throws Exception + */ + public void test_registerIndex2() throws Exception { + final IBigdataFederation<?> fed = helper.client.connect(); + final String name = "testIndex"; + final IndexMetadata metadata = new IndexMetadata(name,UUID.randomUUID()); + + metadata.setDeleteMarkers(true); + + final UUID indexUUID = fed.registerIndex( metadata, // + // separator keys. + new byte[][] { + new byte[]{}, + Util.asSortKey(500) + },// + // data service assignments. + new UUID[] { // + helper.getDataService0().getServiceUUID(),// + helper.getDataService1().getServiceUUID() // + }); + + final IIndex ndx = fed.getIndex(name, ITx.UNISOLATED); + + assertEquals("indexUUID", indexUUID, ndx.getIndexMetadata() + .getIndexUUID()); + + // verify partition 0 on dataService0 + assertNotNull(helper.getDataService0().getIndexMetadata( + DataService.getIndexPartitionName(name, 0), ITx.UNISOLATED)); + + // verify partition 1 on dataService1 + assertNotNull(helper.getDataService1().getIndexMetadata( + DataService.getIndexPartitionName(name, 1), ITx.UNISOLATED)); + + doBasicIndexTests(ndx); + } + + /** + * Test helper reads and writes some data on the index in order to verify + * that these operations can be performed without serialization errors + * arising from the RPC calls. + * + * @param ndx + */ + protected void doBasicIndexTests(final IIndex ndx) { + + final int limit = 1000; + + final byte[][] keys = new byte[limit][]; + final byte[][] vals = new byte[limit][]; + + final Random r = new Random(); + + for (int i = 0; i < limit; i++) { + keys[i] = Util.asSortKey(i); + final byte[] val = new byte[10]; + r.nextBytes(val); + vals[i] = val; + } + + // batch insert. + ndx.submit(0/* fromIndex */, limit/* toIndex */, keys, vals, BatchInsertConstructor.RETURN_NO_VALUES, null); + + // verify #of index entries. + assertEquals(limit, ndx.rangeCount(null, null)); + + // verify data. + { + final ITupleIterator<?> itr = ndx.rangeIterator(null, null); + + int i = 0; + + while (itr.hasNext()) { + final ITuple<?> tuple = itr.next(); + + assertEquals(keys[i], tuple.getKey()); + assertEquals(vals[i], tuple.getValue()); + i++; + } + + assertEquals(limit, i); + } + } +} Added: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClientRemote.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClientRemote.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/service/jini/TestBigdataClientRemote.java 2010-09-10 19:44:37 UTC (rev 3530) @@ -0,0 +1,40 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package com.bigdata.service.jini; + +/** + * Test suite for the {@link JiniClient} using the purely remote + * service implementations. + */ +public class TestBigdataClientRemote extends TestBigdataClient { + + public TestBigdataClientRemote() { + super(true); + } + + public TestBigdataClientRemote(String name) { + super(name, true); + } +} Added: branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/test/util/Util.java =================================================================== --- branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/test/util/Util.java (rev 0) +++ branches/maven_scaleout/bigdata-integ/src/test/java/com/bigdata/test/util/Util.java 2010-09-10 19:44:37 UTC (rev 3530) @@ -0,0 +1,100 @@ +/** + +Copyright (C) SYSTAP, LLC 2006-2007. All rights reserved. + +Contact: + SYSTAP, LLC + 4501 Tower Road + Greensboro, NC 27410 + lic...@bi... + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package com.bigdata.test.util; + +import java.util.Locale; + +import com.bigdata.btree.keys.IKeyBuilder; +import com.bigdata.btree.keys.KeyBuilder; + +/** + * A utility class for utility methods useful to unit and integration tests. + * + * @todo This may need to be moved into the unit test component and a dependency + * on that component added to the integration tests. + * + * @author blevine + * + */ +public class Util +{ + /** + * Used to unbox an application key (convert it to an unsigned byte[]). + */ + static private final IKeyBuilder _keyBuilder = KeyBuilder.newUnicodeInstance(); + + /** + * Utility method converts an application key to a sort key (an unsigned + * byte[] that imposes the same sort order). + * <p> + * Note: This method is thread-safe. + * <p> + * Note: Strings are Unicode safe for the default locale. See + * {@link Locale#getDefault()}. If you require a specific local or different + * locals at different times or for different indices then you MUST + * provision and apply your own {@link KeyBuilder}. + * <p> + * Note: This method circumvents explicit configuration of the + * {@link KeyBuilder} and is used nearly exclusively by unit tests. While + * explicit configuration is not required for keys which do not include + * Unicode sort key components, this method also relies on a single global + * {@link KeyBuilder} instance protected by a lock. That lock is therefore a + * bottleneck. The correct practice is to use thread-local or per task + * {@link IKeyBuilder}s to avoid lock contention. + * + * This method is cloned from a method of the same name in <code>TestKeyBuilder</code>. + * Moving it into a utility class to remove a direct dependency from one test on + * another. + * + * @param val + * An application key. + * + * @return The unsigned byte[] equivalent of that key. This will be + * <code>null</code> iff the <i>key</i> is <code>null</code>. If the + * <i>key</i> is a byte[], then the byte[] itself will be returned. + */ + public static final byte[] asSortKey(final Object val) + { + + if (val == null) + { + return null; + } + + if (val instanceof byte[]) + { + return (byte[]) val; + } + + /* + * Synchronize on the keyBuilder to avoid concurrent modification of its + * state. + */ + + synchronized (_keyBuilder) + { + return _keyBuilder.getSortKey(val); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |