001/****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one   *
003 * or more contributor license agreements.  See the NOTICE file *
004 * distributed with this work for additional information        *
005 * regarding copyright ownership.  The ASF licenses this file   *
006 * to you under the Apache License, Version 2.0 (the            *
007 * "License"); you may not use this file except in compliance   *
008 * with the License.  You may obtain a copy of the License at   *
009 *                                                              *
010 *   http://www.apache.org/licenses/LICENSE-2.0                 *
011 *                                                              *
012 * Unless required by applicable law or agreed to in writing,   *
013 * software distributed under the License is distributed on an  *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015 * KIND, either express or implied.  See the License for the    *
016 * specific language governing permissions and limitations      *
017 * under the License.                                           *
018 ****************************************************************/
019
020package org.apache.james.mpt.script;
021
022import java.io.InputStream;
023import java.util.Locale;
024
025import org.apache.commons.io.IOUtils;
026import org.apache.james.mpt.api.HostSystem;
027import org.apache.james.mpt.protocol.FileProtocolSessionBuilder;
028import org.apache.james.mpt.protocol.ProtocolSession;
029import org.junit.After;
030
031/**
032 * A Protocol test which reads the test protocol session from a file. The file
033 * read is taken as "<test-name>.test", where <test-name> is the value passed
034 * into the constructor. Subclasses of this test can set up {@link #preElements}
035 * and {@link #postElements} for extra elements not defined in the protocol
036 * session file.
037 */
038public abstract class AbstractSimpleScriptedTestProtocol extends AbstractProtocolTestFramework {
039    
040    private static final Locale BASE_DEFAULT_LOCALE = Locale.getDefault();
041
042    private final FileProtocolSessionBuilder builder = new FileProtocolSessionBuilder();
043    private final String scriptDirectory;
044
045    /**
046     * Sets up a SimpleFileProtocolTest which reads the protocol session from a
047     * file of name "<fileName>.test". This file should be available in the
048     * classloader in the same location as this test class.
049     * 
050     * @param scriptDirectory
051     *            name of the directory containing the scripts to be run
052     * @param fileName
053     *            The name of the file to read protocol elements from.
054     * @throws Exception
055     */
056    public AbstractSimpleScriptedTestProtocol(HostSystem hostSystem, String userName, String password,
057            String scriptDirectory) throws Exception {
058        super(hostSystem, userName, password);
059        this.scriptDirectory = scriptDirectory;
060    }
061
062    @After
063    public void tearDown() throws Exception {
064        super.tearDown();
065        Locale.setDefault(BASE_DEFAULT_LOCALE);
066    }
067
068    /**
069     * Reads test elements from the protocol session file and adds them to the
070     * {@link #testElements} ProtocolSession. Then calls {@link #runSessions}.
071     * 
072     * @param locale
073     *            execute the test using this locale
074     */
075    protected void scriptTest(String fileName, Locale locale) throws Exception {
076        Locale.setDefault(locale);
077        addTestFile(fileName + ".test", testElements);
078        runSessions();
079    }
080
081    /**
082     * Finds the protocol session file identified by the test name, and builds
083     * protocol elements from it. All elements from the definition file are
084     * added to the supplied ProtocolSession.
085     * 
086     * @param fileName
087     *            The name of the file to read
088     * @param session
089     *            The ProtocolSession to add elements to.
090     */
091    protected void addTestFile(String fileName, ProtocolSession session) throws Exception {
092
093        fileName = scriptDirectory + fileName;
094        
095        // Need to find local resource.
096        InputStream is = this.getClass().getResourceAsStream(fileName);
097
098        if (is == null) {
099            throw new Exception("Test Resource '" + fileName + "' not found.");
100        }
101
102        try {
103            builder.addProtocolLinesFromStream(is, session, fileName);
104        }
105        finally {
106            IOUtils.closeQuietly(is);
107        }
108        
109    }
110
111}