+++ /dev/null
-/**
- * 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 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.client.test;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.Marshaller;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpException;
-import org.apache.commons.httpclient.HttpMethod;
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.PutMethod;
-import org.apache.commons.httpclient.methods.RequestEntity;
-import org.apache.commons.httpclient.methods.StringRequestEntity;
-
-import org.collectionspace.services.client.TestServiceClient;
-import org.collectionspace.services.client.test.ServiceRequestType;
-
-import org.jboss.resteasy.client.ClientResponse;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * AbstractServiceTest, abstract base class for the client tests to be performed
- * to test an entity or relation service.
- *
- * For Javadoc descriptions of this class's methods, see the ServiceTest interface.
- */
-public abstract class AbstractServiceTest implements ServiceTest {
-
- final Logger logger = LoggerFactory.getLogger(AbstractServiceTest.class);
-
- // An HTTP client, used for performing several negative (failure) tests.
- //
- // @TODO To be replaced with RESTeasy's ClientRequest (a higher-level API
- // that is based on HttpClient), per Issue CSPACE-386.
- protected HttpClient httpClient = new HttpClient();
-
- // A base-level client, used (only) to obtain the base service URL.
- private static final TestServiceClient serviceClient = new TestServiceClient();
-
- // A resource identifier believed to be non-existent in actual use,
- // used when testing service calls that reference non-existent resources.
- protected final String NON_EXISTENT_ID = createNonExistentIdentifier();
-
- // The HTTP status code expected to be returned in the response,
- // from a request made to a service (where relevant).
- int EXPECTED_STATUS_CODE = 0;
-
- // The generic type of service request being tested (e.g. CREATE, UPDATE, DELETE).
- //
- // This makes it possible to check behavior specific to that type of request,
- // such as the set of valid status codes that may be returned.
- ServiceRequestType REQUEST_TYPE = ServiceRequestType.NON_EXISTENT;
-
- // ---------------------------------------------------------------
- // CRUD tests : CREATE tests
- // ---------------------------------------------------------------
-
- // Success outcomes
-
- @Override
- public abstract void create();
-
- protected void setupCreate() {
- clearSetup();
- // Expected status code: 201 Created
- EXPECTED_STATUS_CODE = Response.Status.CREATED.getStatusCode();
- // Type of service request being tested
- REQUEST_TYPE = ServiceRequestType.CREATE;
- }
-
- @Override
- public abstract void createMultiple();
-
- // No setup required for createMultiple()
-
- // Failure outcomes
-
- @Override
- public void createNull() {
- }
-
- // No setup required for createNull()
-
- @Override
- public abstract void createWithMalformedXml();
-
- protected void setupCreateWithMalformedXml() {
- clearSetup();
- // Expected status code: 400 Bad Request
- EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.CREATE;
- }
-
- @Override
- public abstract void createWithWrongXmlSchema();
-
- protected void setupCreateWithWrongXmlSchema() {
- clearSetup();
- // Expected status code: 400 Bad Request
- EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.CREATE;
- }
-
-
- // ---------------------------------------------------------------
- // CRUD tests : READ tests
- // ---------------------------------------------------------------
-
- // Success outcomes
-
- @Override
- public abstract void read();
-
- protected void setupRead() {
- clearSetup();
- // Expected status code: 200 OK
- EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.READ;
- }
-
- // Failure outcomes
-
- @Override
- public abstract void readNonExistent();
-
- protected void setupReadNonExistent() {
- clearSetup();
- // Expected status code: 404 Not Found
- EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.READ;
- }
-
-
- // ---------------------------------------------------------------
- // CRUD tests : READ (list, or multiple) tests
- // ---------------------------------------------------------------
-
- // Success outcomes
-
- @Override
- public abstract void readList();
-
- protected void setupReadList() {
- clearSetup();
- // Expected status code: 200 OK
- EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.READ_MULTIPLE;
- }
-
- // Failure outcomes
-
- // None tested at present.
-
-
- // ---------------------------------------------------------------
- // CRUD tests : UPDATE tests
- // ---------------------------------------------------------------
-
- // Success outcomes
- // ----------------
-
- @Override
- public abstract void update();
-
- protected void setupUpdate() {
- clearSetup();
- // Expected status code: 200 OK
- EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.UPDATE;
- }
-
- // Failure outcomes
-
- @Override
- public abstract void updateWithMalformedXml();
-
- protected void setupUpdateWithMalformedXml() {
- clearSetup();
- // Expected status code: 400 Bad Request
- EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.UPDATE;
- }
-
- @Override
- public abstract void updateWithWrongXmlSchema();
-
- protected void setupUpdateWithWrongXmlSchema() {
- clearSetup();
- // Expected status code: 400 Bad Request
- EXPECTED_STATUS_CODE = Response.Status.BAD_REQUEST.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.UPDATE;
- }
-
- @Override
- public abstract void updateNonExistent();
-
- protected void setupUpdateNonExistent() {
- clearSetup();
- // Expected status code: 404 Not Found
- EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.UPDATE;
- }
-
-
- // ---------------------------------------------------------------
- // CRUD tests : DELETE tests
- // ---------------------------------------------------------------
-
- // Success outcomes
-
- @Override
- public abstract void delete();
-
- protected void setupDelete() {
- clearSetup();
- // Expected status code: 200 OK
- EXPECTED_STATUS_CODE = Response.Status.OK.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.DELETE;
- }
-
- // Failure outcomes
-
- @Override
- public abstract void deleteNonExistent();
-
- protected void setupDeleteNonExistent() {
- clearSetup();
- // Expected status code: 404 Not Found
- EXPECTED_STATUS_CODE = Response.Status.NOT_FOUND.getStatusCode();
- REQUEST_TYPE = ServiceRequestType.DELETE;
- }
-
-
- // ---------------------------------------------------------------
- // Abstract utility methods
- //
- // Must be implemented by classes that extend
- // this abstract base class.
- // ---------------------------------------------------------------
-
- /**
- * Returns the URL path component of the service.
- *
- * This component will follow directly after the
- * base path, if any.
- */
- protected abstract String getServicePathComponent();
-
-
- // ---------------------------------------------------------------
- // Utility methods
- // ---------------------------------------------------------------
-
- /**
- * Reinitializes setup values, to help expose any unintended reuse
- * of those values between tests.
- */
- protected void clearSetup() {
- EXPECTED_STATUS_CODE = 0;
- REQUEST_TYPE = ServiceRequestType.NON_EXISTENT;
- }
-
- // @TODO Add Javadoc comments to all methods requiring them, below.
-
- protected String invalidStatusCodeMessage(ServiceRequestType requestType, int statusCode) {
- return
- "Status code '" + statusCode + "' in response is NOT within the expected set: " +
- requestType.validStatusCodesAsString();
- }
-
- protected String getServiceRootURL() {
- return serviceClient.getBaseURL() + getServicePathComponent();
- }
-
- protected String getResourceURL(String resourceIdentifier) {
- return getServiceRootURL() + "/" + resourceIdentifier;
- }
-
- protected int submitRequest(HttpMethod method) {
- int statusCode = 0;
- try {
- statusCode = httpClient.executeMethod(method);
- } catch(HttpException e) {
- logger.error("Fatal protocol violation: ", e);
- } catch(IOException e) {
- logger.error("Fatal transport error: ", e);
- } catch(Exception e) {
- logger.error("Unknown exception: ", e);
- } finally {
- // Release the connection.
- method.releaseConnection();
- }
- return statusCode;
- }
-
- protected int submitRequest(EntityEnclosingMethod method, RequestEntity entity) {
- int statusCode = 0;
- try {
- method.setRequestEntity(entity);
- statusCode = httpClient.executeMethod(method);
- } catch(HttpException e) {
- logger.error("Fatal protocol violation: ", e);
- } catch(IOException e) {
- logger.error("Fatal transport error: ", e);
- } catch(Exception e) {
- logger.error("Unknown exception: ", e);
- } finally {
- // Release the connection.
- method.releaseConnection();
- }
- return statusCode;
- }
-
- protected StringRequestEntity getXmlEntity(String contents) {
- if (contents == null) {
- contents = "";
- }
- StringRequestEntity entity = null;
- final String XML_DECLARATION =
- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
- final String XML_CONTENT_TYPE=MediaType.APPLICATION_XML;
- final String UTF8_CHARSET_NAME = "UTF-8";
- try {
- entity =
- new StringRequestEntity(
- XML_DECLARATION + contents, XML_CONTENT_TYPE, UTF8_CHARSET_NAME);
- } catch (UnsupportedEncodingException e) {
- logger.error("Unsupported character encoding error: ", e);
- }
- return entity;
- }
-
- protected String extractId(ClientResponse<Response> res) {
- MultivaluedMap mvm = res.getMetadata();
- String uri = (String) ((ArrayList) mvm.get("Location")).get(0);
- verbose("extractId:uri=" + uri);
- String[] segments = uri.split("/");
- String id = segments[segments.length - 1];
- verbose("id=" + id);
- return id;
- }
-
- protected void verbose(String msg) {
- if (logger.isDebugEnabled()) {
- logger.debug(msg);
- }
- }
-
- protected 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();
- }
- }
-
- protected void verboseMap(MultivaluedMap map) {
- for(Object entry : map.entrySet()){
- MultivaluedMap.Entry mentry = (MultivaluedMap.Entry) entry;
- verbose(" name=" + mentry.getKey() + " value=" + mentry.getValue());
- }
- }
-
- protected String createIdentifier() {
- long identifier = System.currentTimeMillis();
- return Long.toString(identifier);
- }
-
- protected String createNonExistentIdentifier() {
- return Long.toString(Long.MAX_VALUE);
- }
-
-}
-
-
+++ /dev/null
-/**
- * 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 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.client.test;
-
-import java.util.Arrays;
-import javax.ws.rs.core.Response;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * ServiceRequestType, identifies types of service requests
- * and the valid HTTP status codes that can be returned from
- * each type of request.
- *
- * Used by client tests of services.
- *
- * $LastChangedRevision: 566 $
- * $LastChangedDate$
- */
-public enum ServiceRequestType {
-
- // Define each of the service request types and their valid HTTP status codes.
-
- CREATE {
- @Override
- public int[] validStatusCodes() {
- final int[] STATUS_CODES = {
- Response.Status.CREATED.getStatusCode(),
- Response.Status.BAD_REQUEST.getStatusCode(),
- Response.Status.FORBIDDEN.getStatusCode(),
- Response.Status.CONFLICT.getStatusCode(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()
- };
- Arrays.sort(STATUS_CODES);
- return STATUS_CODES;
- }
- @Override
- public boolean isValidStatusCode(int statusCode) {
- if (Arrays.binarySearch(CREATE.validStatusCodes(), statusCode) >= 0) {
- return true;
- } else {
- return false;
- }
- }
- @Override
- public String validStatusCodesAsString() {
- return Arrays.toString(CREATE.validStatusCodes());
- }
- }, // Note that commas are required at the end of each enum block, except the last.
-
-
- READ {
- @Override
- public int[] validStatusCodes() {
- final int[] STATUS_CODES = {
- Response.Status.OK.getStatusCode(),
- Response.Status.FORBIDDEN.getStatusCode(),
- Response.Status.NOT_FOUND.getStatusCode(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()
- };
- Arrays.sort(STATUS_CODES);
- return STATUS_CODES;
- }
- @Override
- public boolean isValidStatusCode(int statusCode) {
- if (Arrays.binarySearch(READ.validStatusCodes(), statusCode) >= 0) {
- return true;
- } else {
- return false;
- }
- }
- @Override
- public String validStatusCodesAsString() {
- return Arrays.toString(READ.validStatusCodes());
- }
- },
-
-
- READ_MULTIPLE {
- @Override
- public int[] validStatusCodes() {
- final int[] STATUS_CODES = {
- Response.Status.OK.getStatusCode(),
- Response.Status.BAD_REQUEST.getStatusCode(),
- Response.Status.FORBIDDEN.getStatusCode(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()
- };
- Arrays.sort(STATUS_CODES);
- return STATUS_CODES;
- }
- @Override
- public boolean isValidStatusCode(int statusCode) {
- if (Arrays.binarySearch(READ_MULTIPLE.validStatusCodes(), statusCode) >= 0) {
- return true;
- } else {
- return false;
- }
- }
- @Override
- public String validStatusCodesAsString() {
- return Arrays.toString(READ_MULTIPLE.validStatusCodes());
- }
- },
-
-
- UPDATE {
- @Override
- public int[] validStatusCodes() {
- final int[] STATUS_CODES = {
- Response.Status.OK.getStatusCode(),
- Response.Status.BAD_REQUEST.getStatusCode(),
- Response.Status.FORBIDDEN.getStatusCode(),
- Response.Status.NOT_FOUND.getStatusCode(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()
- };
- Arrays.sort(STATUS_CODES);
- return STATUS_CODES;
- }
- @Override
- public boolean isValidStatusCode(int statusCode) {
- if (Arrays.binarySearch(UPDATE.validStatusCodes(), statusCode) >= 0) {
- return true;
- } else {
- return false;
- }
- }
- @Override
- public String validStatusCodesAsString() {
- return Arrays.toString(UPDATE.validStatusCodes());
- }
- },
-
-
- DELETE {
- @Override
- public int[] validStatusCodes() {
- final int[] STATUS_CODES = {
- Response.Status.OK.getStatusCode(),
- Response.Status.FORBIDDEN.getStatusCode(),
- Response.Status.NOT_FOUND.getStatusCode(),
- Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()
- };
- Arrays.sort(STATUS_CODES);
- return STATUS_CODES;
- }
- @Override
- public boolean isValidStatusCode(int statusCode) {
- if (Arrays.binarySearch(DELETE.validStatusCodes(), statusCode) >= 0) {
- return true;
- } else {
- return false;
- }
- }
- @Override
- public String validStatusCodesAsString() {
- return Arrays.toString(DELETE.validStatusCodes());
- }
- },
-
-
- // Used by guard code.
- NON_EXISTENT {
- @Override
- public int[] validStatusCodes() {
- final int[] STATUS_CODES = { 0 };
- Arrays.sort(STATUS_CODES);
- return STATUS_CODES;
- }
- @Override
- public boolean isValidStatusCode(int statusCode) {
- return false;
- }
- @Override
- public String validStatusCodesAsString() {
- return Arrays.toString(NON_EXISTENT.validStatusCodes());
- }
- };
-
- // Template methods to be implemented by each ServiceRequestType.
-
- public abstract int[] validStatusCodes();
-
- public abstract boolean isValidStatusCode(int statusCode);
-
- public abstract String validStatusCodesAsString();
-
-}