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    package org.apache.directory.server.integ.state;
020    
021    
022    import static org.apache.directory.server.core.integ.IntegrationUtils.doDelete;
023    
024    import java.io.IOException;
025    
026    import org.apache.directory.server.integ.InheritableServerSettings;
027    import org.junit.runner.notification.RunNotifier;
028    import org.junit.runners.model.Statement;
029    import org.junit.runners.model.TestClass;
030    import org.slf4j.Logger;
031    import org.slf4j.LoggerFactory;
032    
033    
034    
035    /**
036     * The state of a running test service which has been used for running
037     * integration tests and has been reverted to contain the same content as it
038     * did when created and started.  It is not really pristine however for all
039     * practical purposes of integration testing it appears to be the same as
040     * when first started.
041     *
042     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
043     * @version $Rev$, $Date$
044     */
045    public class StartedNormalState extends AbstractState
046    {
047        private static final Logger LOG = LoggerFactory.getLogger( StartedNormalState.class );
048    
049    
050        /**
051         * 
052         * Creates a new instance of StartedNormalState.
053         *
054         * @param context the test's context
055         */
056        public StartedNormalState( TestServerContext context )
057        {
058            super( context );
059        }
060    
061    
062        /**
063         * Action where an attempt is made to destroy the service. This
064         * entails nulling out reference to it and triggering garbage
065         * collection.
066         */
067        public void destroy()
068        {
069            LOG.debug( "calling destroy()" );
070            context.getLdapServer().setDirectoryService( null );
071            context.setLdapServer( null );
072            context.setState( context.getNonExistentState() );
073            System.gc();
074        }
075    
076    
077        /**
078         * Action where an attempt is made to erase the contents of the
079         * working directory used by the service for various files including
080         * partition database files.
081         *
082         * @throws IOException on errors while deleting the working directory
083         */
084        public void cleanup() throws IOException
085        {
086            LOG.debug( "calling cleanup()" );
087            doDelete( context.getLdapServer().getDirectoryService().getWorkingDirectory() );
088        }
089    
090    
091        /**
092         * Action where an attempt is made to start up the service.
093         *
094         * @throws Exception on failures to start the core directory service
095         */
096        public void startup() throws Exception
097        {
098            LOG.debug( "calling start()" );
099            context.getLdapServer().getDirectoryService().startup();
100            context.getLdapServer().start();
101        }
102    
103    
104        /**
105         * Action where an attempt is made to shutdown the service.
106         *
107         * @throws Exception on failures to stop the core directory service
108         */
109        public void shutdown() throws Exception
110        {
111            LOG.debug( "calling shutdown()" );
112            context.getLdapServer().stop();
113            context.getLdapServer().getDirectoryService().shutdown();
114        }
115    
116    
117        /**
118         * Action where an attempt is made to revert the service to it's
119         * initial start up state by using a previous snapshot.
120         *
121         * @throws Exception on failures to revert the state of the core
122         * directory service
123         */
124        public void revert() throws Exception
125        {
126            LOG.debug( "calling revert()" );
127            context.getLdapServer().getDirectoryService().revert();
128        }
129    
130    
131        /**
132         * Action where an attempt is made to run a test against the service.
133         *
134         * All annotations should have already been processed for
135         * InheritableServerSettings yet they and others can be processed since we have
136         * access to the method annotations below
137         *
138         * @param testClass the class whose test method is to be run
139         * @param statement the test method which is to be run
140         * @param notifier a notifier to report failures to
141         * @param settings the inherited settings and annotations associated with
142         * the test method
143         */
144        public void test( TestClass testClass, Statement statement, RunNotifier notifier, InheritableServerSettings settings )
145        {
146            LOG.debug( "calling test(): {}, mode {}", settings.getDescription().getDisplayName(), settings.getMode() );
147    
148            switch ( settings.getMode() )
149            {
150                case ROLLBACK:
151                    try
152                    {
153                        context.getLdapServer().getDirectoryService().getChangeLog().tag();
154    
155                        // Inject the LDIFs, if any 
156                        injectLdifs( context.getLdapServer().getDirectoryService(), settings );
157                    }
158                    catch ( Exception e )
159                    {
160                        // @TODO - we might want to check the revision of the service before
161                        // we presume that it has been soiled.  Some tests may simply perform
162                        // some read operations or checks on the service and may not alter it
163                        testAborted( notifier, settings.getDescription(), e );
164                        return;
165                    }
166    
167                    TestServerContext.invokeTest( testClass, statement, notifier, settings.getDescription() );
168                    
169                    try
170                    {
171                        revert();
172                    }
173                    catch ( Exception e )
174                    {
175                        // @TODO - we might want to check the revision of the service before
176                        // we presume that it has been soiled.  Some tests may simply perform
177                        // some read operations or checks on the service and may not alter it
178                        testAborted( notifier, settings.getDescription(), e );
179                        return;
180                    }
181                    
182                    return;
183                    
184                case RESTART :
185                    // Inject the LDIFs, if any 
186                    try
187                    {
188                        injectLdifs( context.getLdapServer().getDirectoryService(), settings );
189                    }
190                    catch ( Exception e )
191                    {
192                        // @TODO - we might want to check the revision of the service before
193                        // we presume that it has been soiled.  Some tests may simply perform
194                        // some read operations or checks on the service and may not alter it
195                        testAborted( notifier, settings.getDescription(), e );
196                        return;
197                    }
198    
199                    TestServerContext.invokeTest( testClass, statement, notifier, settings.getDescription() );
200    
201                    try
202                    {
203                        shutdown();
204                    }
205                    catch ( Exception e )
206                    {
207                        // @TODO - we might want to check the revision of the service before
208                        // we presume that it has been soiled.  Some tests may simply perform
209                        // some read operations or checks on the service and may not alter it
210                        testAborted( notifier, settings.getDescription(), e );
211                        return;
212                    }
213                    
214                    try
215                    {
216                        startup();
217                    }
218                    catch ( Exception e )
219                    {
220                        LOG.error( "Failed to create and start new server instance: " + e );
221                        testAborted( notifier, settings.getDescription(), e );
222                        return;
223                    }
224                    
225                    return;
226                    
227                default:
228                    return;
229            }
230        }
231    }