//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//


package org.eclipse.jetty.server.session;

import java.io.File;

import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.util.IO;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * ForwardedSessionTest
 *
 *
 */
public class ForwardedSessionTest extends AbstractForwardedSessionTest
{ 
   File tmpDir;
    
    @Before
    public void before() throws Exception
    {
        tmpDir = File.createTempFile("hash-session-forward-test", null);
        tmpDir.delete();
        tmpDir.mkdirs();
        tmpDir.deleteOnExit();
    }
    
    @After 
    public void after()
    {
        IO.delete(tmpDir);
    }
    
    @Override
    public AbstractTestServer createServer(int port)
    {
        return new HashTestServer(port)
        {

            @Override
            public SessionManager newSessionManager()
            {
                HashSessionManager sessionManager = (HashSessionManager)super.newSessionManager();
                sessionManager.setSavePeriod(2);
                
                try
                {
                    sessionManager.setStoreDirectory(tmpDir);
                }
                catch (Exception e)
                {
                    throw new IllegalStateException(e);
                }
                return sessionManager;
            }

        };
    }

    
    
    @Test
    public void testSessionCreateInForward() throws Exception
    {
        super.testSessionCreateInForward();
    }

  


}
