From f5cee7572171f6b7f08a4e02712b1409d9f6eb8f Mon Sep 17 00:00:00 2001 From: Richard Millet Date: Fri, 5 Feb 2010 22:57:05 +0000 Subject: [PATCH] CSPACE-413: Adding module for performance tests. Contains an initial simple test that creates 1000 records and then deletes them. --- services/PerformanceTests/.classpath | 10 + services/PerformanceTests/.project | 30 +++ .../.settings/org.eclipse.jdt.core.prefs | 5 + .../.settings/org.maven.ide.eclipse.prefs | 9 + services/PerformanceTests/pom.xml | 121 ++++++++++ .../test/CollectionSpacePerformanceTest.java | 225 ++++++++++++++++++ .../test/PerformanceTest.java | 198 +++++++++++++++ .../src/test/resources/log4j.properties | 23 ++ 8 files changed, 621 insertions(+) create mode 100644 services/PerformanceTests/.classpath create mode 100644 services/PerformanceTests/.project create mode 100644 services/PerformanceTests/.settings/org.eclipse.jdt.core.prefs create mode 100644 services/PerformanceTests/.settings/org.maven.ide.eclipse.prefs create mode 100644 services/PerformanceTests/pom.xml create mode 100644 services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/CollectionSpacePerformanceTest.java create mode 100644 services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/PerformanceTest.java create mode 100644 services/PerformanceTests/src/test/resources/log4j.properties diff --git a/services/PerformanceTests/.classpath b/services/PerformanceTests/.classpath new file mode 100644 index 000000000..425cd1620 --- /dev/null +++ b/services/PerformanceTests/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/services/PerformanceTests/.project b/services/PerformanceTests/.project new file mode 100644 index 000000000..460e47e2e --- /dev/null +++ b/services/PerformanceTests/.project @@ -0,0 +1,30 @@ + + + org.collectionspace.services.PerformanceTests + + + org.collectionspace.services.client + org.collectionspace.services.collectionobject.client + org.collectionspace.services.collectionobject.jaxb + org.collectionspace.services.common + org.collectionspace.services.intake.client + org.collectionspace.services.intake.jaxb + org.collectionspace.services.relation.client + + + + org.eclipse.jdt.core.javabuilder + + + + + org.maven.ide.eclipse.maven2Builder + + + + + + org.maven.ide.eclipse.maven2Nature + org.eclipse.jdt.core.javanature + + diff --git a/services/PerformanceTests/.settings/org.eclipse.jdt.core.prefs b/services/PerformanceTests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..49a5e1698 --- /dev/null +++ b/services/PerformanceTests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Wed Jan 20 14:09:34 PST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/services/PerformanceTests/.settings/org.maven.ide.eclipse.prefs b/services/PerformanceTests/.settings/org.maven.ide.eclipse.prefs new file mode 100644 index 000000000..c279a2256 --- /dev/null +++ b/services/PerformanceTests/.settings/org.maven.ide.eclipse.prefs @@ -0,0 +1,9 @@ +#Fri Sep 11 17:00:31 PDT 2009 +activeProfiles= +eclipse.preferences.version=1 +fullBuildGoals=process-test-resources +includeModules=false +resolveWorkspaceProjects=true +resourceFilterGoals=process-resources resources\:testResources +skipCompilerPlugin=true +version=1 diff --git a/services/PerformanceTests/pom.xml b/services/PerformanceTests/pom.xml new file mode 100644 index 000000000..27670a196 --- /dev/null +++ b/services/PerformanceTests/pom.xml @@ -0,0 +1,121 @@ + + + + org.collectionspace.services.main + org.collectionspace.services + 1.0 + + 4.0.0 + org.collectionspace.services + org.collectionspace.services.PerformanceTests + jar + 1.0 + services.PerformanceTests + + + + org.slf4j + slf4j-api + test + + + org.slf4j + slf4j-log4j12 + test + + + org.collectionspace.services + org.collectionspace.services.client + 1.0 + + + org.testng + testng + 5.6 + + + org.jboss.resteasy + resteasy-jaxrs + 1.0.2.GA + + + + tjws + webserver + + + + + org.jboss.resteasy + resteasy-jaxb-provider + 1.0.2.GA + + + org.jboss.resteasy + resteasy-multipart-provider + 1.0.2.GA + + + commons-httpclient + commons-httpclient + 3.1 + + + org.collectionspace.services + org.collectionspace.services.common + 1.0 + + + org.collectionspace.services + org.collectionspace.services.collectionobject.jaxb + 1.0 + + + org.collectionspace.services + org.collectionspace.services.collectionobject.client + 1.0 + + + org.collectionspace.services + org.collectionspace.services.intake.jaxb + 1.0 + + + org.collectionspace.services + org.collectionspace.services.intake.client + 1.0 + + + org.collectionspace.services + org.collectionspace.services.relation.client + 1.0 + + + + + collectionspace-services-PerformanceTests + + + org.apache.maven.plugins + maven-surefire-plugin + + + + log4j.configuration + file:target/test-classes/log4j.properties + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + diff --git a/services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/CollectionSpacePerformanceTest.java b/services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/CollectionSpacePerformanceTest.java new file mode 100644 index 000000000..5577e4ec9 --- /dev/null +++ b/services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/CollectionSpacePerformanceTest.java @@ -0,0 +1,225 @@ +/** + * CollectionSpacePerformanceTest.java + * + * {Purpose of This Class} + * + * {Other Notes Relating to This Class (Optional)} + * + * $LastChangedBy: $ + * $LastChangedRevision: $ + * $LastChangedDate: $ + * + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright © 2009 {Contributing Institution} + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ +package org.collectionspace.services.PerformanceTests.test; + +import java.util.ArrayList; + +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; + +import org.collectionspace.services.collectionobject.CollectionobjectsCommon; +import org.collectionspace.services.intake.IntakesCommon; +import org.collectionspace.services.relation.RelationsCommon; +import org.collectionspace.services.relation.RelationshipType; +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.plugins.providers.multipart.InputPart; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; + +/** + * The Class CollectionSpacePerformanceTests. + */ +public abstract class CollectionSpacePerformanceTest { + + /* + * Package scoped methods. + */ + + /** + * Fill collection object. + * + * @param co the co + * @param identifier the identifier + */ + void fillCollectionObject(CollectionobjectsCommon co, String identifier) { + fillCollectionObject(co, "objectNumber-" + identifier, "objectName-" + + identifier); + } + + /** + * Fill collection object. + * + * @param co the co + * @param objectNumber the object number + * @param objectName the object name + */ + void fillCollectionObject(CollectionobjectsCommon co, String objectNumber, + String objectName) { + co.setObjectNumber(objectNumber); + co.setObjectName(objectName); + } + + /** + * Fill intake. + * + * @param theIntake the the intake + * @param identifier the identifier + */ + void fillIntake(IntakesCommon theIntake, String identifier) { + fillIntake(theIntake, "entryNumber-" + identifier, "entryDate-" + + identifier); + } + + /** + * Fill intake. + * + * @param theIntake the the intake + * @param entryNumber the entry number + * @param entryDate the entry date + */ + void fillIntake(IntakesCommon theIntake, String entryNumber, String entryDate) { + theIntake.setEntryNumber(entryNumber); + theIntake.setEntryDate(entryDate); + } + + /** + * Fill relation. + * + * @param relation the relation + * @param documentId1 the document id1 + * @param documentType1 the document type1 + * @param documentId2 the document id2 + * @param documentType2 the document type2 + * @param rt the rt + */ + void fillRelation(RelationsCommon relation, String documentId1, String documentType1, + String documentId2, String documentType2, RelationshipType rt) + { + relation.setDocumentId1(documentId1); + relation.setDocumentType1(documentType1); + relation.setDocumentId2(documentId2); + relation.setDocumentType2(documentType2); + + relation.setRelationshipType(rt); + } + + /** + * Creates the identifier. + * + * @return the string + */ + String createIdentifier() { + long identifier = System.currentTimeMillis(); + return Long.toString(identifier); + } + + /** + * Extract id. + * + * @param res the res + * + * @return the string + */ + String extractId(ClientResponse res) { + String result = null; + + MultivaluedMap mvm = res.getMetadata(); + String uri = (String) ((ArrayList) mvm.get("Location")).get(0); + verbose("extractId:uri=" + uri); + String[] segments = uri.split("/"); + result = segments[segments.length - 1]; + verbose("id=" + result); + + return result; + } + + /** + * Extract part. + * + * @param input + * the input + * @param label + * the label + * @param clazz + * the clazz + * + * @return the object + * + * @throws Exception + * the exception + */ + static Object extractPart(MultipartInput input, String label, Class clazz) { + Object obj = null; + + try { + for (InputPart part : input.getParts()) { + String partLabel = part.getHeaders().getFirst("label"); + if (label.equalsIgnoreCase(partLabel)) { + String partStr = part.getBodyAsString(); + obj = part.getBody(clazz, null); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return obj; + } + + /** + * Verbose. + * + * @param msg the msg + */ + void verbose(String msg) { +// System.out.println(msg); + } + + /** + * Verbose. + * + * @param msg the msg + * @param o the o + * @param clazz the clazz + */ + void verbose(String msg, Object o, Class clazz) { + try { + verbose(msg); + JAXBContext jc = JAXBContext.newInstance(clazz); + Marshaller m = jc.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + m.marshal(o, System.out); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Verbose map. + * + * @param map the map + */ + void verboseMap(MultivaluedMap map) { + for (Object entry : map.entrySet()) { + MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry; + verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue()); + } + } + +} diff --git a/services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/PerformanceTest.java b/services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/PerformanceTest.java new file mode 100644 index 000000000..a70b2c101 --- /dev/null +++ b/services/PerformanceTests/src/test/java/org/collectionspace/services/PerformanceTests/test/PerformanceTest.java @@ -0,0 +1,198 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright (c) 2009 Regents of the University of California + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.collectionspace.services.PerformanceTests.test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Date; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.testng.Assert; +import org.testng.annotations.Test; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.HeadMethod; +import org.apache.commons.httpclient.methods.OptionsMethod; +import org.apache.commons.httpclient.methods.TraceMethod; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.jboss.resteasy.client.ClientResponse; +import org.jboss.resteasy.plugins.providers.multipart.MultipartInput; +import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput; +import org.jboss.resteasy.plugins.providers.multipart.OutputPart; + +import org.collectionspace.services.client.TestServiceClient; + +import org.collectionspace.services.CollectionObjectJAXBSchema; +import org.collectionspace.services.client.CollectionObjectClient; +import org.collectionspace.services.collectionobject.CollectionobjectsCommon; +import org.collectionspace.services.collectionobject.CollectionobjectsCommonList; + +import org.collectionspace.services.IntakeJAXBSchema; +import org.collectionspace.services.client.IntakeClient; +import org.collectionspace.services.intake.IntakesCommon; +import org.collectionspace.services.intake.IntakesCommonList; + +import org.collectionspace.services.common.relation.RelationJAXBSchema; +import org.collectionspace.services.client.RelationClient; +import org.collectionspace.services.relation.RelationsCommon; +import org.collectionspace.services.relation.RelationsCommonList; +import org.collectionspace.services.relation.RelationshipType; + +/** + * A ServiceTest. + * + * @version $Revision:$ + */ +public class PerformanceTest extends CollectionSpacePerformanceTest { + + final Logger logger = LoggerFactory + .getLogger(PerformanceTest.class); + // + // Get clients for the CollectionSpace services + // + private RelationClient relationClient = new RelationClient(); + private IntakeClient intakeClient = new IntakeClient(); + private static int MAX_RECORDS = 100; + + private String createCollectionObject(CollectionObjectClient collectionObjectClient) { + String result = null; + // + // First create a CollectionObject + // + CollectionobjectsCommon co = new CollectionobjectsCommon(); + fillCollectionObject(co, createIdentifier()); + + // Next, create a part object + MultipartOutput multipart = new MultipartOutput(); + OutputPart commonPart = multipart.addPart(co, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", collectionObjectClient.getCommonPartName()); + // Make the create call and check the response + ClientResponse response = collectionObjectClient.create(multipart); + Assert.assertEquals(response.getStatus(), Response.Status.CREATED + .getStatusCode()); + result = extractId(response); + + return result; + } + + @Test + public void createCollectionObjects() { + CollectionObjectClient collectionObjectClient = new CollectionObjectClient(); + String[] coList = new String[MAX_RECORDS]; + + Date startTime = new Date(); + for (int i = 0; i < MAX_RECORDS; i++) { + coList[i] = createCollectionObject(collectionObjectClient); + } + Date stopTime = new Date(); + if (logger.isDebugEnabled()) { + logger.debug("Created " + MAX_RECORDS + " CollectionObjects" + + " in " + (stopTime.getTime() - startTime.getTime())/1000.0 + " seconds."); + } + + startTime = new Date(); + for (int i = 0; i < MAX_RECORDS; i++) { + deleteCollectionObject(collectionObjectClient, coList[i]); + } + stopTime = new Date(); + if (logger.isDebugEnabled()) { + logger.debug("Deleted " + MAX_RECORDS + " CollectionObjects" + + " in " + (stopTime.getTime() - startTime.getTime())/1000.0 + " seconds."); + } + } + + private void deleteCollectionObject(CollectionObjectClient collectionObjectClient, + String resourceId) { + ClientResponse res = collectionObjectClient.delete(resourceId); + } + + @Test + public void relateCollectionObjectToIntake() { + + // + // First create a CollectionObject + // + CollectionObjectClient collectionObjectClient = new CollectionObjectClient(); + CollectionobjectsCommon co = new CollectionobjectsCommon(); + fillCollectionObject(co, createIdentifier()); + + // Next, create a part object + MultipartOutput multipart = new MultipartOutput(); + OutputPart commonPart = multipart.addPart(co, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", collectionObjectClient.getCommonPartName()); + // Make the create call and check the response + ClientResponse response = collectionObjectClient.create(multipart); + Assert.assertEquals(response.getStatus(), Response.Status.CREATED + .getStatusCode()); + String collectionObjectCsid = extractId(response); + + + // Next, create an Intake object + IntakesCommon intake = new IntakesCommon(); + fillIntake(intake, createIdentifier()); + // Create the a part object + multipart = new MultipartOutput(); + commonPart = multipart.addPart(intake, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", intakeClient.getCommonPartName()); + // Make the call to create and check the response + response = intakeClient.create(multipart); + Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode()); + String intakeCsid = extractId(response); + + // Lastly, relate the two entities, by creating a new relation object + RelationsCommon relation = new RelationsCommon(); + fillRelation(relation, collectionObjectCsid, CollectionobjectsCommon.class.getSimpleName(), + intakeCsid, IntakesCommon.class.getSimpleName(), + RelationshipType.COLLECTIONOBJECT_INTAKE); + // Create the part and fill it with the relation object + multipart = new MultipartOutput(); + commonPart = multipart.addPart(relation, MediaType.APPLICATION_XML_TYPE); + commonPart.getHeaders().add("label", relationClient.getCommonPartName()); + // Make the call to crate + response = relationClient.create(multipart); + Assert.assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode()); + String relationCsid = extractId(response); + } + + /* + * Private Methods + */ + +} diff --git a/services/PerformanceTests/src/test/resources/log4j.properties b/services/PerformanceTests/src/test/resources/log4j.properties new file mode 100644 index 000000000..18c510350 --- /dev/null +++ b/services/PerformanceTests/src/test/resources/log4j.properties @@ -0,0 +1,23 @@ +log4j.rootLogger=debug, stdout, R + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Pattern to output the caller's file name and line number. +log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=target/test-client.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n + +#packages +log4j.logger.org.collectionspace=DEBUG +log4j.logger.org.apache=INFO +log4j.logger.httpclient=INFO +log4j.logger.org.jboss.resteasy=INFO -- 2.47.3