Package org.archive.state

Source Code of org.archive.state.ModuleTestBase

/*
*  This file is part of the Heritrix web crawler (crawler.archive.org).
*
*  Licensed to the Internet Archive (IA) by one or more individual
*  contributors.
*
*  The IA licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  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.archive.state;


import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;

import junit.framework.TestCase;

import org.apache.commons.httpclient.URIException;
import org.apache.commons.lang.SerializationUtils;
import org.archive.modules.CrawlURI;
import org.archive.net.UURI;
import org.archive.net.UURIFactory;
import org.archive.util.Recorder;
import org.archive.util.TmpDirTestCase;


/**
* Base class for unit testing Module implementations.
*
* @author pjack
*/
public abstract class ModuleTestBase extends TestCase {


    /**
     * Magical constructor that attempts to auto-create static key field
     * descriptions for your module class.
     *
     * <p>If {@link #getSourceCodeDir} and {@link #getResourceDir} both return
     * non-null values, then the constructor will look in the resources
     * directory for an English resource file for the class.  If it finds
     * one, nothing magical happens.
     *
     * <p>Otherwise, the source code for the module being tested is loaded,
     * and parsed to extract the JavaDoc descriptions for the static key
     * fields.  The results are stored in the appropriate English locale file
     * in the resource directory. 
     *
     * <p>Note the parsing is naive; at minimum, you should load the resulting
     * locale file and remove any HTML markup.
     */   
    public ModuleTestBase() {
        getSourceCodeDir();
        getResourceDir();
    }

   
    /**
     * Returns the location of the source code directory for your project.
     * This defaults to "src/main/java", which is the standard for projects
     * built with maven2.  If you use a different source code directory,
     * you should override this method.
     *
     * <p>If you want to disable automatic key description generation,
     * return null from this method.
     *
     * @return   the source code directory for the project
     */
    protected File getSourceCodeDir() {
        return getProjectDir("src/main/java");
    }
   

    /**
     * Returns the location of the Java resources directory for your project.
     * This defaults to "src/resources/java", which is the standard for projects
     * built with maven2.  If you use a different source code directory --
     * for instance, if your resources directory is the same as your source
     * code directory -- you should override this method.
     *
     * <p>If you want to disable automatic key description generation,
     * return null from this method.
     *
     * @return   the source code directory for the project
     */
    protected File getResourceDir() {
        return getProjectDir("src/main/resources");
    }
   
   
    /**
     * Returns a project directory for a Heritrix subproject.  This is here
     * so that the src and resources directories can be found whether the
     * unit test is run using maven2 or using Eclipse.  The two build systems
     * use different working directories.
     *
     * @param path  the path   the path to find
     * @return   the found path
     */
    private File getProjectDir(String path) {
        File r = new File(path);
        if (r.exists()) {
            return r;
        }
        String cname = getClass().getName();
        if (cname.startsWith("org.archive.processors")) {
            return new File("modules/" + path);
        }
        if (cname.startsWith("org.archive.deciderules")) {
            return new File("modules/" + path);
        }
        if (cname.startsWith("org.archive.crawler")) {
            return new File("engine/" + path);
        }
        return null;
    }
   
    /**
     * Returns the class of the module to test. Deduces from
     * test class name if possible.
     *
     * @return   the class of the module to test
     */
    protected Class<?> getModuleClass() {
        String myClassName = this.getClass().getCanonicalName();
        if(!myClassName.endsWith("Test")) {
            throw new UnsupportedOperationException(
                    "Cannot get module class of "+myClassName);
        }
        String moduleClassName = myClassName.substring(0,myClassName.length()-4);
        try {
            return Class.forName(moduleClassName);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Return an example instance of the module.  This is used by
     * testSerialization to ensure the module can be serialized.
     *
     * @return   an example instance of the module
     * @throws Exception   if the module cannot be constructed for any reason
     */
    protected Object makeModule() throws Exception {
        return getModuleClass().newInstance();
    }

    /**
     * Tests that the module can be serialized.  The value returned by
     * {@link #makeModule} is serialized to a byte array, and then
     * deserialized, and then serialized to a second byte array.  The results
     * are passed to {@link #verifySerialization}, which will simply compare
     * the two byte arrays for equality.  (That won't always work; see
     * that method for details).
     *
     * <p>If nothing else, this test is useful for catching NotSerializable
     * exceptions for your module or classes it depends on.
     *
     * @throws Exception   if the module cannot be serialized
     */
    public void testSerializationIfAppropriate() throws Exception {
        Object first = makeModule();
        if(!(first instanceof Serializable)) {
            return;
        }
        byte[] firstBytes = SerializationUtils.serialize((Serializable)first);
        
        Object second = SerializationUtils.deserialize(firstBytes);
        byte[] secondBytes = SerializationUtils.serialize((Serializable)second);
       
        Object third = SerializationUtils.deserialize(secondBytes);
        byte[] thirdBytes = SerializationUtils.serialize((Serializable)third);
       
        // HashMap serialization reverses order of items in linked buckets
        // each roundtrip -- so don't check one roundtrip, check two
//        verifySerialization(first, firstBytes, second, secondBytes);
        verifySerialization(first, firstBytes, third, thirdBytes);
    }

    /**
     * Verifies that serialization was successful.
     *
     * <p>By default, this method simply compares the first and second byte
     * arrays for equality.  That may not work if you use custom serialization
     * -- for instance, if you're serializing a timestamp.  If that's the case
     * you should override this method to compare the given objects, or to
     * simply do nothing.  (If this method does nothing, then the
     * {@link #testSerialization} test is still useful for catching
     * NotSerializable problems).
     *
     * @param first   the first object that was serialized
     * @param firstBytes   the byte array the first object was serialized to
     * @param second  the second object that was serialized
     * @param secondBytes  the byte array the second object was serialized to
     * @throws Exception   if anyt problem occurs
     */
    protected void verifySerialization(Object first, byte[] firstBytes,
            Object second, byte[] secondBytes) throws Exception {
        assertTrue(Arrays.equals(firstBytes, secondBytes));
    }
   
    @Override
    protected void runTest() throws Throwable {
        try {
            super.runTest();
        } catch (Throwable t) {
            t.printStackTrace();
            throw t;
        }
    }


    protected Recorder getRecorder() throws IOException {
        if (Recorder.getHttpRecorder() == null) {
            Recorder httpRecorder = new Recorder(TmpDirTestCase.tmpDir(),
                    getClass().getName(), 16 * 1024, 512 * 1024);
            Recorder.setHttpRecorder(httpRecorder);
        }
   
        return Recorder.getHttpRecorder();
    }


    protected CrawlURI makeCrawlURI(String uri) throws URIException,
            IOException {
        UURI uuri = UURIFactory.getInstance(uri);
        CrawlURI curi = new CrawlURI(uuri);
        curi.setSeed(true);
        curi.setRecorder(getRecorder());
        return curi;
    }
}
TOP

Related Classes of org.archive.state.ModuleTestBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.