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 org.apache.james.mpt.Runner;
023import org.apache.james.mpt.api.Continuation;
024import org.apache.james.mpt.api.HostSystem;
025import org.apache.james.mpt.api.Session;
026import org.apache.james.mpt.protocol.ProtocolSession;
027
028/**
029 * Abstract Protocol Test is the root of all of the scripted test cases. It
030 * provides basic functionality for running a protocol session as a JUnit test,
031 * and failing if exceptions are thrown. To create a test which reads the entire
032 * protocol session from a single protocol definition file, use the
033 * {@link AbstractSimpleScriptedTestProtocol}.
034 * 
035 * @author Darrell DeBoer
036 * @author Andrew C. Oliver
037 */
038public abstract class AbstractProtocolTestFramework {
039
040    /** The Protocol session which is run before the testElements */
041    protected ProtocolSession preElements = new ProtocolSession();
042
043    /** The Protocol session which contains the tests elements */
044    protected ProtocolSession testElements = new ProtocolSession();
045
046    /** The Protocol session which is run after the testElements. */
047    protected ProtocolSession postElements = new ProtocolSession();
048
049    protected final Runner runner;
050    private final HostSystem hostSystem;
051
052    private final String userName;
053    private final String password;
054
055    public AbstractProtocolTestFramework(HostSystem hostSystem, String userName, String password) {
056        this.hostSystem = hostSystem;
057        this.userName = userName;
058        this.password = password;
059        runner = new Runner();
060    }
061
062    protected void setUp() throws Exception {
063        hostSystem.beforeTest();
064        hostSystem.addUser(userName, password);
065    }
066
067    protected void tearDown() throws Exception {
068        hostSystem.afterTest();
069    }
070
071    /**
072     * <p>
073     * Runs the pre,test and post protocol sessions against a local copy of the
074     * Server. This is useful for rapid development and debugging.
075     * </p>
076     * Instead of sending requests to a socket connected to a running instance
077     * of James, this method uses the {@link HostSystem} to simplify testing.
078     * One mock instance is required per protocol session/connection.
079     */
080    protected void runSessions() throws Exception {
081        class SessionContinuation implements Continuation {
082
083            public ProtocolSession session;
084
085            public void doContinue() {
086                if (session != null) {
087                    session.doContinue();
088                }
089            }
090
091        }
092        SessionContinuation continuation = new SessionContinuation();
093
094        Session[] sessions = new Session[testElements.getSessionCount()];
095
096        for (int i = 0; i < sessions.length; i++) {
097            sessions[i] = hostSystem.newSession(continuation);
098            sessions[i].start();
099        }
100        try {
101            continuation.session = preElements;
102            preElements.runSessions(sessions);
103            continuation.session = testElements;
104            testElements.runSessions(sessions);
105            continuation.session = postElements;
106            postElements.runSessions(sessions);
107        }
108        finally {
109            for (Session session : sessions) {
110                session.stop();
111            }
112        }
113    }
114
115}