/*
* Copyright © 2010 Martin Riedel
*
* This file is part of TransFile.
*
* TransFile is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TransFile 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with TransFile. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.transfile.operations;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.transfile.operations.messages.DisconnectMessage;
import net.sourceforge.transfile.operations.messages.FileOfferMessage;
import net.sourceforge.jenerics.Tools;
import org.junit.Test;
/**
* TODO doc
*
* @author codistmonk (creation 2010-06-15)
*
*/
public abstract class AbstractSessionTestBase extends AbstractTestWithConnections {
@Test(timeout = TEST_TIMEOUT)
public final void testOfferFile() throws IOException {
this.createAndConnectMatchingConnectionPair();
final File sourceFile = AbstractOperationTestBase.SOURCE_FILE;
final Session session = new Session(this.getConnection1(), new ReceiveOperationTest.TemporaryDestinationFileProvider(sourceFile));
final SessionRecorder sessionRecorder = new SessionRecorder(session);
session.offerFile(sourceFile);
this.waitUntilMatchingConnectionPairAreReady();
this.getConnection1().disconnect();
waitAndAssertState(Connection.State.DISCONNECTED, this.getConnections());
assertEquals(Arrays.asList(
Connection.State.CONNECTING,
Connection.State.CONNECTED,
Connection.State.DISCONNECTED
), this.getConnectionRecorder1().getEvents());
assertEquals(Arrays.asList(
Connection.State.CONNECTING,
Connection.State.CONNECTED,
new FileOfferMessage(sourceFile),
Connection.State.DISCONNECTED,
new DisconnectMessage()
), this.getConnectionRecorder2().getEvents());
assertTrue(sessionRecorder.getEvents().size() == 1);
final SendOperation sendOperation = Tools.cast(SendOperation.class, sessionRecorder.getEvents().get(0));
assertNotNull(sendOperation);
assertEquals(sourceFile, sendOperation.getLocalFile());
}
@Test(timeout = TEST_TIMEOUT)
public final void testOfferAndTransfer() throws IOException, InterruptedException {
this.createAndConnectMatchingConnectionPair();
final File sourceFile = AbstractOperationTestBase.SOURCE_FILE;
final Session localSession = new Session(this.getConnection1(), new ReceiveOperationTest.TemporaryDestinationFileProvider(sourceFile));
final SessionRecorder localSessionRecorder = new SessionRecorder(localSession);
final ReceiveOperationTest.TemporaryDestinationFileProvider destinationFileProvider = new ReceiveOperationTest.TemporaryDestinationFileProvider(sourceFile);
final Session remoteSession = new Session(this.getConnection2(), destinationFileProvider);
final SessionRecorder remoteSessionRecorder = new SessionRecorder(remoteSession);
localSession.offerFile(sourceFile);
this.waitUntilMatchingConnectionPairAreReady();
Tools.debugPrint(localSessionRecorder.getEvents());
Tools.debugPrint(remoteSessionRecorder.getEvents());
final Thread localUser = new LocalUser((SendOperation) localSessionRecorder.getEvents().get(0));
final Thread remoteUser = new RemoteUser((ReceiveOperation) remoteSessionRecorder.getEvents().get(0));
localUser.start();
remoteUser.start();
localUser.join();
remoteUser.join();
this.waitUntilMatchingConnectionPairAreReady();
localSession.getConnection().disconnect();
this.waitUntilMatchingConnectionPairAreReady();
assertEquals(sourceFile.length(), destinationFileProvider.getDestinationFile("").length());
}
/**
*
* TODO doc
*
* @author codistmonk (creation 2010-06-18)
*
*/
private static abstract class AbstractUser extends Thread {
private final Operation operation;
/**
*
* @param operation
* <br>Not null
* <br>Shared
*/
public AbstractUser(final Operation operation) {
this.operation = operation;
}
/**
*
* @return
* <br>Not null
* <br>Shared
*/
public final Operation getOperation() {
return this.operation;
}
}
/**
*
* TODO doc
*
* @author codistmonk (creation 2010-06-18)
*
*/
private static final class LocalUser extends AbstractUser {
/**
*
* @param operation
* <br>Not null
* <br>Shared
*/
public LocalUser(final Operation operation) {
super(operation);
}
@Override
public final void run() {
this.getOperation().getController().start();
}
}
/**
*
* TODO doc
*
* @author codistmonk (creation 2010-06-18)
*
*/
private static final class RemoteUser extends AbstractUser {
/**
*
* @param operation
* <br>Not null
* <br>Shared
*/
public RemoteUser(final Operation operation) {
super(operation);
}
@Override
public final void run() {
this.getOperation().getController().start();
}
}
/**
* TODO doc
*
* @author codistmonk (creation 2010-06-08)
*
*/
public static class SessionRecorder implements Session.Listener {
private final Session session;
private final List<Object> events;
/**
*
* @param session
* <br>Should not be null
* <br>Shared parameter
*/
public SessionRecorder(final Session session) {
this.session = session;
this.events = new ArrayList<Object>();
this.getSession().addSessionListener(this);
}
/**
*
* @return
* <br>A non-null value
* <br>A shared value
*/
public final Session getSession() {
return this.session;
}
/**
*
* @return
* <br>A non-null value
* <br>A shared value
*/
public final List<Object> getEvents() {
return this.events;
}
@Override
public final void receiveOperationAdded(final ReceiveOperation receiveOperation) {
this.getEvents().add(receiveOperation);
}
@Override
public final void sendOperationAdded(final SendOperation sendOperation) {
this.getEvents().add(sendOperation);
}
}
}