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