/**
 * Copyright (c) 2002-2014 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.neo4j.server.enterprise;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;

import org.junit.After;
import org.junit.Test;

import org.neo4j.cluster.ClusterSettings;
import org.neo4j.kernel.impl.util.StringLogger;
import org.neo4j.server.ServerStartupException;
import org.neo4j.server.configuration.Configurator;
import org.neo4j.server.configuration.PropertyFileConfigurator;
import org.neo4j.server.modules.ServerModule;
import org.neo4j.test.TargetDirectory;

import static org.junit.Assert.fail;

import static org.neo4j.test.TargetDirectory.forTest;

public class StartupTimeoutFunctionalTest
{
    public EnterpriseNeoServer server;

    @After
    public void stopServer()
    {
        if ( server != null )
        {
            server.stop();
            server = null;
        }
    }

    @Test
    public void shouldTimeoutIfStartupTakesLongerThanTimeout() throws IOException
    {
        Configurator configurator = buildProperties();
        configurator.configuration().setProperty( Configurator.STARTUP_TIMEOUT, 1 );
        server = createSlowServer( configurator );

        try
        {
            server.start();
            fail( "Should have been interrupted." );
        }
        catch ( ServerStartupException e )
        {
            // ok!
        }
    }

    @Test
    public void shouldNotFailIfStartupTakesLessTimeThanTimeout() throws IOException
    {
        Configurator configurator = buildProperties();
        configurator.configuration().setProperty( Configurator.STARTUP_TIMEOUT, 20 );
        server = new EnterpriseNeoServer( configurator )
        {
            @Override
            protected Iterable<ServerModule> createServerModules()
            {
                return Arrays.asList();
            }
        };

        server.start();
    }

    @Test
    public void shouldNotTimeOutIfTimeoutDisabled() throws IOException
    {
        Configurator configurator = buildProperties();
        configurator.configuration().setProperty( Configurator.STARTUP_TIMEOUT, 0 );
        server = createSlowServer( configurator );

        server.start();
    }

    private EnterpriseNeoServer createSlowServer( Configurator configurator )
    {
        return new EnterpriseNeoServer( configurator )
        {
            @Override
            protected Iterable<ServerModule> createServerModules()
            {
                ServerModule slowModule = new ServerModule()
                {
                    @Override
                    public void start( StringLogger logger )
                    {
                        try
                        {
                            Thread.sleep( 1000 * 5 );
                        }
                        catch ( InterruptedException e )
                        {
                            throw new RuntimeException( e );
                        }
                    }

                    @Override
                    public void stop()
                    {
                    }
                };
                return Arrays.asList( slowModule );
            }
        };
    }

    private Configurator buildProperties() throws IOException
    {
        TargetDirectory target = forTest( StartupTimeoutFunctionalTest.class );
        target.cleanup();

        target.directory( "conf" );

        Properties databaseProperties = new Properties();
        String databasePropertiesFileName = target.file( "conf/neo4j.properties" ).getAbsolutePath();
        databaseProperties.setProperty( ClusterSettings.server_id.name(), "1" );
        databaseProperties.setProperty( ClusterSettings.initial_hosts.name(), ":5001,:5002,:5003" );
        databaseProperties.store( new FileWriter( databasePropertiesFileName ), null );

        Properties serverProperties = new Properties();
        String serverPropertiesFilename = target.file( "conf/neo4j-server.properties" ).getAbsolutePath();
        serverProperties.setProperty( Configurator.DATABASE_LOCATION_PROPERTY_KEY,
                target.directory( "data/graph.db", true ).getAbsolutePath() );
        serverProperties.setProperty( Configurator.DB_TUNING_PROPERTY_FILE_KEY, databasePropertiesFileName );
        serverProperties.setProperty( Configurator.NEO_SERVER_CONFIG_FILE_KEY, serverPropertiesFilename );
        serverProperties.store( new FileWriter( serverPropertiesFilename ), null );

        return new PropertyFileConfigurator( new File( serverPropertiesFilename ) );
    }
}

@@ -999,24 +999,47 @@
 unit.After;%0A
+import org.junit.Rule;%0A
 import org.j
@@ -1432,37 +1432,73 @@
 l;%0A%0A
-import static org.neo4j.test.
+public class StartupTimeoutFunctionalTest%0A%7B%0A    @Rule%0A    public 
 Targ
@@ -1513,61 +1513,82 @@
 ory.
-for
 Test
-;%0A%0Apublic class StartupTimeoutFunctionalTest%0A%7B
+Directory target = TargetDirectory.cleanTestDirForTest( getClass() );%0A
 %0A   
@@ -4158,114 +4158,66 @@
     
-TargetDirectory target = forTest( StartupTimeoutFunctionalTest.class );%0A        target.cleanup();%0A%0A       
+//noinspection ResultOfMethodCallIgnored%0A        new File(
  tar
@@ -4234,16 +4234,18 @@
 ory(
+),
  %22conf%22 
 );%0A%0A
@@ -4240,16 +4240,24 @@
  %22conf%22 
+).mkdir(
 );%0A%0A    
@@ -4350,36 +4350,53 @@
 sFileName = 
-target.file(
+new File( target.directory(),
  %22conf/neo4j
@@ -4802,20 +4802,37 @@
 e = 
-target.file(
+new File( target.directory(),
  %22co
@@ -4978,16 +4978,26 @@
         
+ new File(
  target.
@@ -5006,16 +5006,18 @@
 rectory(
+),
  %22data/g
@@ -5028,14 +5028,8 @@
 .db%22
-, true
  ).g

Use TargetDirectory to run each test case in its own directory.