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;
021
022import org.apache.james.mpt.api.Continuation;
023import org.apache.james.mpt.api.HostSystem;
024import org.apache.james.mpt.api.ProtocolInteractor;
025import org.apache.james.mpt.api.Session;
026import org.apache.james.mpt.api.SessionFactory;
027import org.apache.james.mpt.protocol.ProtocolSession;
028
029/**
030 * Runs protocol scripts.
031 */
032public class Runner {
033    
034    /** The Protocol session which is run before the testElements */
035    private final ProtocolSession preElements = new ProtocolSession();
036
037    /** The Protocol session which contains the tests elements */
038    private final ProtocolSession testElements = new ProtocolSession();
039
040    /** The Protocol session which is run after the testElements. */
041    private final ProtocolSession postElements = new ProtocolSession();
042    
043    public void continueAfterFailure() {
044        preElements.setContinueAfterFailure(true);
045        testElements.setContinueAfterFailure(true);
046        postElements.setContinueAfterFailure(true);
047    }
048    
049    /**
050     * Gets protocol session run after test.
051     * @return not null
052     */
053    public ProtocolInteractor getPostElements() {
054        return postElements;
055    }
056
057    /**
058     * Gets protocol session run before test.
059     * @return not null
060     */
061    public ProtocolInteractor getPreElements() {
062        return preElements;
063    }
064    /**
065     * Gets protocol session run on test.
066     * @return not null
067     */
068    public ProtocolInteractor getTestElements() {
069        return testElements;
070    }
071
072
073
074    /**
075     * <p>Runs the pre,test and post protocol sessions against a local copy of the
076     * server. This does not require that James be running, and is useful
077     * for rapid development and debugging.
078     * </p><p>
079     * Instead of sending requests to a socket connected to a running instance
080     * of James, this method uses the {@link HostSystem} to simplify
081     * testing. One mock instance is required per protocol session/connection.
082     */
083    public void runSessions(SessionFactory factory) throws Exception {
084        class SessionContinuation implements Continuation {
085
086            public ProtocolSession session;
087
088            public void doContinue() {
089                if (session != null) {
090                    session.doContinue();
091                }
092            }
093
094        }
095        SessionContinuation continuation = new SessionContinuation();
096
097        Session[] sessions = new Session[testElements
098                .getSessionCount()];
099
100        for (int i = 0; i < sessions.length; i++) {
101            sessions[i] = factory.newSession(continuation);
102            sessions[i].start();
103        }
104        try {
105            continuation.session = preElements;
106            preElements.runSessions(sessions);
107            continuation.session = testElements;
108            testElements.runSessions(sessions);
109            continuation.session = postElements;
110            postElements.runSessions(sessions);
111        } finally {
112            for (Session session : sessions) {
113                session.stop();
114            }
115        }
116    }
117
118    /**
119     * Constructs a <code>String</code> with all attributes
120     * in name = value format.
121     *
122     * @return a <code>String</code> representation 
123     * of this object.
124     */
125    public String toString()
126    {
127        final String TAB = " ";
128
129        return "Runner ( "
130            + "preElements = " + this.preElements + TAB
131            + "testElements = " + this.testElements + TAB
132            + "postElements = " + this.postElements + TAB
133            + " )";
134    }
135
136    
137}