[or-cvs] r16587: {puppetor} Finally I could fix those weird bugs that appeared only rare (in puppetor/branches/gsoc2008: doc src/de/uniba/wiai/lspi/puppetor src/de/uniba/wiai/lspi/puppetor/impl src/de/uniba/wiai/lspi/puppetor/rmi src/de/uniba/wiai/lspi/puppetor/rmi/execute src/de/uniba/wiai/lspi/puppetor/rmi/impl src/de/uniba/wiai/lspi/puppetor/rmi/tasks src/de/uniba/wiai/lspi/puppetor/rmi/tests tools)

sebastian at seul.org sebastian at seul.org
Mon Aug 18 17:24:21 UTC 2008


Author: sebastian
Date: 2008-08-18 13:24:21 -0400 (Mon, 18 Aug 2008)
New Revision: 16587

Added:
   puppetor/branches/gsoc2008/doc/DistributedPuppeTorReadme
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskExecutionNotSuccessfulException.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTestImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AccessGoogleTask.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AddHiddenServiceTask.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/ConfigureAsPrivateTask.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/AccessGoogleOverPublicTorNetwork.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/StartingAndAccessingHiddenServiceOverPrivateTorNetworkTest.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/TestRegistration.java
Removed:
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestImpl.java
Modified:
   puppetor/branches/gsoc2008/doc/howtosecurermi.txt
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/Network.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ClientApplicationImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/HiddenServiceImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ServerApplicationImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/AbstractMasterFactory.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Network.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Task.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskResult.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Test.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TestExecutor.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TorInstance.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorMasterProgram.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorSlaveProgram.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTaskImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImplFactory.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/NetworkImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/SlaveImplFactory.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TaskResultImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestExecutorImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TorInstanceImpl.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateDirectoryAuthorityTask.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateProxyTask.java
   puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateRouterTask.java
   puppetor/branches/gsoc2008/tools/create_keystores.sh
Log:
Finally I could fix those weird bugs that appeared only rarely... So there are two working example testcases etc now :)

Added: puppetor/branches/gsoc2008/doc/DistributedPuppeTorReadme
===================================================================
--- puppetor/branches/gsoc2008/doc/DistributedPuppeTorReadme	                        (rev 0)
+++ puppetor/branches/gsoc2008/doc/DistributedPuppeTorReadme	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,96 @@
+This document intents to show you how to set up a distributed PuppeTor network
+to do Tor testing with entirely private networks or the public Tor network.
+PuppeTor allows you to build a network of PuppeTor Tor controllers that are
+linked together through a secure network. In this network, a Master controls
+all aspects of test execution, and slaves that connect to the master control
+the Tor instances that are used to form the Tor network that is used for the
+test.
+
+Prerequisites:
+	- All participating computers should allow ports above 7000 to be opened. 
+		This requirement will be relaxed with newer versions
+	- At least Java version 1.5 or higher on each computer
+	- An installation of Tor, with the tor executable in the PATH, on each
+		computer, and the tor-gencert executable in the PATH for every
+		authority
+
+The first step will be to set up the public key infrastructure that is used for
+the secure connection between the computers. In the puppetor/tools directory
+you can find the create_keystores.sh shellscript. Edit the top section of the
+file to fit your needs, make sure that you at least change the password! After
+saving, execute the script. It will create two files for each slave that you
+intent to set up, plus two files for the master.
+
+Now it is time to create the PuppeTor programs. Make one new directory for each
+slave that you want to set up, and one for the master. Copy the contents of the
+puppetor/ directory into the new directories, and place a keystore/truststore
+pair into each /res/-directory. For the directory that will contain the master,
+edit the file /src/de/uniba/wiai/lspi/puppetor/rmi/execute/
+PuppeTorMasterProgram.java. Change serverport and serveraddress to match your
+needs, then skip down to the part after 
+        private PuppeTorMasterProgram() ...
+and change the settings in the System.setProperty calls according to what you
+want. You will definitely need to change the keystore and truststore locations,
+as well as the password.
+After you are done, compile the program and transfer it to the computer that
+will act as the master.
+
+For each of the slaves, change the file /src/de/uniba/wiai/lspi/puppetor/rmi/
+execute/PuppeTorSlaveProgram.java just as you change the file for the master.
+Choose the same serverport and serveraddress as for the master, set the
+slaveaddress to the IP address the slave will run on (or set it to 127.0.0.1
+if the slave will act as Tor client only) and set a unique name for each slave.
+After
+	private PuppeTorSlaveProgram() ...
+set the locations for keystore and truststore, as well as the password. Compile
+and transfer the resulting programs to the appropriate computers (Note that the
+computer that runs the master can also run a slave without a problem).
+
+To start testing, go ahead and start all the Slaves. Go to the puppetor
+directory, and simply execute
+	java -cp bin/ de.uniba.wiai.lspi.puppetor.rmi.execute.PuppeTorSlaveProgram
+This will run the PuppeTorSlaveProgram in a loop that tries connecting to the
+specified master once a minute. After it has made a connection, it will go back
+to this mode of continuously trying to reach the master, so you don't have to
+touch the slave when you want to rerun tests. Please note that depending on the
+the tests you're intending to run, the test-env directory can become quite
+large. Make sure you clean it occasionally.
+
+After all the slaves are started, fire up the Master by going into the puppetor
+directory, and executing
+	java -cp bin/ de.uniba.wiai.lspi.puppetor.rmi.execute.PuppeTorMasterProgram
+
+You will see some output at the master to indicate connected slaves and the
+success of the execution of tests. Note that there are no good logging
+mechanisms built into the master currently, unfortunately. 
+
+About Tests:
+All the tests live in the puppetor/src/de/uniba/wiai/lspi/puppetor/rmi/tests/
+directory. At the moment, to example tests are provided which are automatically
+executed: One very simple testcase that connects to Google over the public Tor
+network, and one testcase that creates a private Tor network, adds a hidden
+service to it, and tries to reach that hidden service. To add your own test,
+simply create a new subclass of AbstractTestImpl, choose some tasks that you
+want to execute from the tasks directory, and then add register your new test
+by adding a new 
+	testExecutor.registerTest(new YourNewTest());
+line to TestRegistration in the tests directory. In your constructor, you will
+want to call super with two arguments: A String to explain what your testcase
+is useful for, and a NetworkDescription to explain what kind of network you
+need. Currently, you can specify the number of authorities, routers, and
+proxies. Note that at the moment, the specified number of authorities, routers,
+and proxies is opened at every connected slave. This will be changed.
+
+It may be necessary that you write a new task, because the already provided
+tasks are not sufficient for your needs. If that is the case, add a new task
+by extending AbstractTaskImpl. If your task operates on a node, your
+constructor will need three arguments, the task id (int), the networkname
+(String), and the nodeName (String). Pass the first two arguments to the
+superconstructor, and store the third. If your task operates on the entire
+slave, you will have only the first two parameters. The execute method will be
+executed at the slave. You can get the currently running network by executing
+	final Network network = NetworkFactory.getNetworkByName(name);
+If you work with a single node directly, access it by calling
+	network.getNode(nodeName);
+After that is done, you will have access to all the testing options that
+PuppeTor offers for standalone tests.

Modified: puppetor/branches/gsoc2008/doc/howtosecurermi.txt
===================================================================
--- puppetor/branches/gsoc2008/doc/howtosecurermi.txt	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/doc/howtosecurermi.txt	2008-08-18 17:24:21 UTC (rev 16587)
@@ -1,3 +1,5 @@
+Please see DistributedPuppeTorReadme for basic instructions instead!
+
 To securely use PuppeTor to connect a testing network over untrusted networks
 such as the Internet, a public/private key environment is set up. The one 
 instance of PuppeTor that controls the flow of the test and checks milestones
@@ -6,8 +8,6 @@
 (ssl-secured) connection to the master. The master will then validate that it 
 knows about the client and only allow connections from clients that provide a
 valid certificate. 
-TODO: Write a script that allows easy creation of certificates for a given
-network
 
 Setting up the application:
 
@@ -104,4 +104,4 @@
     
   You have now set up everything that is necessary for the encryption.
   XXX We need a description here that it is better to use different keys for
-    different slaves.
\ No newline at end of file
+    different slaves.

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/Network.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/Network.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/Network.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -93,6 +93,13 @@
 	public abstract void configureAsPrivateNetwork() throws PuppeTorException;
 
 	/**
+	 * XXX document properly -SH
+	 */
+	public void configureAsPartOfPrivateNetwork(
+			List<String> authorizedDirectoriesFingerprints);
+
+	
+	/**
 	 * Creates a new client application, but does not yet perform a request.
 	 *
 	 * @param clientApplicationName

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ClientApplicationImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ClientApplicationImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ClientApplicationImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -51,7 +51,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class ClientApplicationImpl implements ClientApplication {
 
 	/**
@@ -255,24 +254,17 @@
 								s.close();
 								logger.log(Level.FINE, "Socket closed.");
 
-							} catch (final Exception e1) {
+							} catch (final IOException e) {
 
 								// log warning
-								logger
-										.log(
-												Level.WARNING,
-												"Exception when trying to close socket!",
-												e1);
+								logger.log(Level.WARNING,
+									"Exception when trying to close socket!",
+									e);
 							}
 						}
 					}
 				}
 
-			} catch (final Exception e) {
-
-				// log that we have been interrupted
-				logger.log(Level.WARNING, "Client has been interrupted!", e);
-
 			} finally {
 
 				// we are done here

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/DirectoryNodeImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -55,7 +55,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class DirectoryNodeImpl extends RouterNodeImpl implements DirectoryNode {
 
 	/**

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -61,7 +61,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class EventManagerImpl implements EventManager {
 
 	/**

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/HiddenServiceImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/HiddenServiceImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/HiddenServiceImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -15,7 +15,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class HiddenServiceImpl implements HiddenService {
 
 	/**

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -60,7 +60,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class NetworkImpl implements Network {
 
 	/**
@@ -284,13 +283,6 @@
 		// log entering
 		logger.entering(this.getClass().getName(), "configureAsPrivateNetwork");
 
-		for (final ProxyNode node : nodes.values()) {
-			if (node.getNodeState() == NodeState.CONFIGURING) {
-				// add to configuration
-				node.addConfiguration("TestingTorNetwork 1");
-			}
-		}
-
 		// read DirServer strings for all directories
 		final List<String> authorizedDirectoriesFingerprints =
 				new ArrayList<String>();
@@ -302,16 +294,56 @@
 			}
 		}
 
-		// configure nodes
+		this.configureAsPartOfPrivateNetwork(authorizedDirectoriesFingerprints);
+
+		// read fingerprints for all directories and routers
+		final HashSet<String> approvedRoutersFingerprints =
+				new HashSet<String>();
 		for (final ProxyNode node : nodes.values()) {
-			if (node.getNodeState() == NodeState.CONFIGURING) {
+			if (node instanceof RouterNode) {
+				final RouterNode routerOrDirNode = (RouterNode) node;
+				approvedRoutersFingerprints.add(routerOrDirNode
+						.getFingerprint());
+			}
+		}
 
+		// write fingerprints for all directories and routers to the
+		// approved-routers file
+		for (final ProxyNode node : nodes.values()) {
+			if (node instanceof DirectoryNode) {
+				final DirectoryNode dirNode = (DirectoryNode) node;
+				dirNode.addApprovedRouters(approvedRoutersFingerprints);
+			}
+		}
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "configureAsPrivateNetwork");
+	}
+
+	public void configureAsPartOfPrivateNetwork(
+			List<String> authorizedDirectoriesFingerprints) {
+			//throws PuppeTorException {
+		// log entering
+		logger.entering(this.getClass().getName(), "configureAsPartOfPrivateNetwork");
+
+		for (final ProxyNode node : nodes.values()) {
+			if (node.getNodeState() == NodeState.CONFIGURING ||
+					node.getNodeState() == NodeState.CONFIGURATION_WRITTEN) {
 				// add to configuration
+				node.addConfiguration("TestingTorNetwork 1");
+			}
+		}
+
+		// configure nodes
+		for (final ProxyNode node : nodes.values()) {
+			if (node.getNodeState() == NodeState.CONFIGURING ||
+					node.getNodeState() == NodeState.CONFIGURATION_WRITTEN) {
+				// add to configuration
 				node.addConfigurations(authorizedDirectoriesFingerprints);
 			}
 		}
 
-		// read fingerprints for all directories and routers
+/*		// read fingerprints for all directories and routers
 		final HashSet<String> approvedRoutersFingerprints =
 				new HashSet<String>();
 		for (final ProxyNode node : nodes.values()) {
@@ -330,9 +362,9 @@
 				dirNode.addApprovedRouters(approvedRoutersFingerprints);
 			}
 		}
-
+*/
 		// log exiting
-		logger.exiting(this.getClass().getName(), "configureAsPrivateNetwork");
+		logger.exiting(this.getClass().getName(), "configureAsPartOfPrivateNetwork");
 	}
 
 	public ClientApplication createClient(final String clientApplicationName,
@@ -665,14 +697,16 @@
 			return true;
 		}
 
+		final Object hupLock = new Object();
 		// create and register a new event handler for each node
-		final Thread sleepingThread = Thread.currentThread();
 		for (final ProxyNode node : nodes.values()) {
 			eventManager.addEventListener(node.getNodeName(),
 					new EventListener() {
 						public void handleEvent(final Event event) {
 							if (event.getType() == NodeEventType.NODE_CIRCUIT_OPENED) {
-								sleepingThread.interrupt();
+								synchronized(hupLock) {
+									hupLock.notify();	
+								}
 								eventManager.removeEventListener(this);
 							}
 						}
@@ -682,28 +716,28 @@
 		// walk through wait-check-hup loop until there are no tries left
 		for (int i = 0; i < tries; i++) {
 
-			// determine how long to sleep
+			// determine how long to try waiting for the hangup
 			final long endOfSleeping = System.currentTimeMillis() + hupInterval;
-			long now;
 
 			// unless all nodes have reported to be up, wait for the given
 			// maximum time
-			while ((now = System.currentTimeMillis()) < endOfSleeping) {
+			while (System.currentTimeMillis() < endOfSleeping) {
 
-				// sleep
-				try {
-					Thread.sleep(endOfSleeping - now);
-				} catch (final InterruptedException e) {
-					// do nothing about it
-				}
+				synchronized(hupLock) {
+					// check if nodes are up now
+					if (allNodesUp()) {
 
-				// check if nodes are up now
-				if (allNodesUp()) {
-
-					// log exiting and return true
-					logger.exiting(this.getClass().getName(), "hupUntilUp",
-							true);
-					return true;
+						// log exiting and return true
+						logger.exiting(this.getClass().getName(), "hupUntilUp",
+								true);
+						return true;
+					}
+					// sleep
+					try {
+						hupLock.wait(hupInterval);
+					} catch (final InterruptedException e) {
+						// do nothing about it
+					}
 				}
 			}
 

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -57,7 +57,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class ProxyNodeImpl implements ProxyNode {
 
 	/**
@@ -434,15 +433,7 @@
 							e);
 			logger.throwing(this.getClass().getName(), "hup", ex);
 			throw ex;
-		} catch (final NullPointerException e) {
-			// TODO sometimes, this throws a NullPointerException...
-			logger.log(Level.SEVERE, "is conn null? " + (conn == null));
-			logger.log(Level.SEVERE,
-					"NullPointerException while sending HUP signal to node "
-							+ toString());
-			throw e;
 		}
-
 		// log exiting
 		logger.exiting(this.getClass().getName(), "hup");
 	}

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -50,7 +50,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class RouterNodeImpl extends ProxyNodeImpl implements RouterNode {
 
 	/**

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ServerApplicationImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ServerApplicationImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/impl/ServerApplicationImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -48,7 +48,6 @@
  *
  * @author kloesing
  */
- at SuppressWarnings("serial")
 public class ServerApplicationImpl implements ServerApplication {
 
 	/**

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/AbstractMasterFactory.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/AbstractMasterFactory.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/AbstractMasterFactory.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -33,6 +33,8 @@
 
 import java.rmi.RemoteException;
 
+import de.uniba.wiai.lspi.puppetor.rmi.tests.TestRegistration;
+
 /**
  * Factory to create all objects needed by the master side of a PuppeTor
  * network.
@@ -43,8 +45,7 @@
 
 	/**
 	 * Hold the concrete RemotePuppeTorFactory that will be used to create the
-	 * implementation classes. Use <code>AbstractMasterFactory.class</code>
-	 * for locking.
+	 * implementation classes.
 	 */
 	private static AbstractMasterFactory factory;
 
@@ -63,9 +64,10 @@
 	 */
 	final public synchronized static void initialize(
 			final AbstractMasterFactory factory) {
-		if (AbstractMasterFactory.factory == null) {
-			AbstractMasterFactory.factory = factory;
+		if (AbstractMasterFactory.factory != null) {
+			throw new RuntimeException("Don't call initialize twice!");
 		}
+		AbstractMasterFactory.factory = factory;
 	}
 
 	/**
@@ -85,18 +87,18 @@
 	public abstract TestExecutor getTestExecutorInstance();
 
 	/**
-	 * Create a new test that uses the public Tor network without additional
-	 * relays. XXX Maybe this should have its own Factory together with a way to
-	 * make network descriptions. This is all the test-writer will use as an
-	 * interface.
+	 * Override this to create a subclass of <code>TestRegistration</code>.
+	 *
+	 * @return The <code>TestRegistration</code> instance.
 	 */
-	public abstract Test createPublicNetworkTestForClientsOnly(
-			String description);
-
+	public abstract TestRegistration getTestRegistrationInstance();
+	
 	/**
 	 * XXX just for now so I don't forget.-SH
 	 */
 	public abstract NetworkDescription createNetworkDescription();
 
-	public abstract Network createNetwork(String name);
+	
+
+//	public abstract Network createNetwork(String name);
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Network.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Network.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Network.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -32,13 +32,24 @@
 package de.uniba.wiai.lspi.puppetor.rmi;
 
 import java.io.Serializable;
+import java.util.List;
 import java.util.Set;
 
+/**
+ * This class describes all Tor instances on the slaves that are used to form a
+ * private Tor network, or the Tor instances that are added to the public
+ * network and are used in a set of tests.
+ * 
+ * @author Sebastian Hahn
+ */
 public interface Network extends Serializable {
 
-	// XXX Maybe we want to do this in the constructor-SH
+	/**
+	 * @param torInstance
+	 *  	add this <code>TorInstance</code> to the network.
+	 */
 	public void addTorInstance(TorInstance torInstance);
-
+	
 	/**
 	 * @return this network's name, mainly to identify it in logs.
 	 */
@@ -81,4 +92,14 @@
 	 *         routers)
 	 */
 	public Set<TorInstance> getProxies();
+	
+	/**
+	 * @return all Tests that can run on this network -SH
+	 */
+	public List<Test> getTests();
+
+	/**
+	 * Is this a private network or part of the public one?
+	 */
+	public boolean isPrivateNetwork();
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Task.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Task.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Task.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -31,9 +31,11 @@
  */
 package de.uniba.wiai.lspi.puppetor.rmi;
 
+import java.io.Serializable;
 import java.rmi.RemoteException;
+import java.util.Collection;
 
-public interface Task {
+public interface Task extends Serializable {
 
 	/**
 	 * Execute the task. Must be called by the slave.
@@ -50,4 +52,13 @@
 	 * or 0 to indicate a task that was sent out by the slave, not the master.
 	 */
 	public int getId();
+
+	/**
+	 * This method will be called by the <code>TestExecutor</code> to allow
+	 * tasks to collect additional information if they need it.
+	 * @param additionalInformation
+	 * 		offer this information.
+	 */
+	public void addAdditionalInformation(
+			Collection<String> additionalInformation);
 }

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskExecutionNotSuccessfulException.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskExecutionNotSuccessfulException.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskExecutionNotSuccessfulException.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,18 @@
+package de.uniba.wiai.lspi.puppetor.rmi;
+
+import java.util.Set;
+
+public class TaskExecutionNotSuccessfulException extends Exception {
+	private static final long serialVersionUID = 1L;
+	final private Set<TaskResult> taskResults;
+
+	public TaskExecutionNotSuccessfulException(final Set<TaskResult> taskResults) {
+		this.taskResults = taskResults;
+	}
+
+	public Set<TaskResult> getTaskResults() {
+		return taskResults;
+	}
+
+	// XXX Add some logging capabilities -SH
+}

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskResult.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskResult.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TaskResult.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -33,9 +33,33 @@
 
 import java.io.Serializable;
 
+/**
+ * After the completion of a <code>Task</code>, a <code>TaskResult</code> is
+ * created to report the result of the task as well as logging information to
+ * the Master.  
+ * 
+ * @author Sebastian Hahn
+ */
 public interface TaskResult extends Serializable {
 
+	/**
+	 * @return
+	 * 		the task that we have a result for
+	 */
 	public Task getTask();
-
+	
+	/**
+	 * @return
+	 * 		<code>true</code> if the task execution was successful,
+	 * 		false otherwise.
+	 */
 	public boolean wasSuccessful();
-}
+	
+	/**
+	 * A <code>Task</code> may optionally pass back a result that can be used
+	 * by the Master to manage further Task execution. 
+	 * @return
+	 * 		the result of this task or null if no result is set.
+	 */
+	public String getTaskResult();
+}
\ No newline at end of file

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Test.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Test.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/Test.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -42,7 +42,22 @@
  * @author Sebastian Hahn
  */
 public interface Test extends Serializable {
+	/**
+	 * @return
+	 * 		a description of what this test is useful for.
+	 */
 	public String getDescription();
 
+	/**
+	 * @return
+	 * 		a description of the network that this test requires to run, so the
+	 * 		</code>TestExecutor</code> can pick or set up one. 
+	 */
 	public NetworkDescription getNetworkDescription();
+	
+	/**
+	 * Call this when the network has been set up and you want to run the test
+	 * with the current network.
+	 */
+	public void doTest();
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TestExecutor.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TestExecutor.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TestExecutor.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -31,6 +31,7 @@
  */
 package de.uniba.wiai.lspi.puppetor.rmi;
 
+import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
@@ -75,7 +76,7 @@
 	 * Return all tests that could not be executed because the PuppeTorNetwork
 	 * could not match a test's preconditions.
 	 */
-	public Set<Test> cannotRunTests();
+	public Set<Test> getCannotRunTests();
 
 	/**
 	 * Register a newly connected PuppeTor slave via its
@@ -87,4 +88,53 @@
 	 * Unregister a PuppeTor slave. Called when a slave disconnects.
 	 */
 	public void unregisterLocalMaster(LocalMaster master);
+
+	/**
+	 * @return
+	 * 		the currently running network.
+	 */
+	public Network getCurrentNetwork();
+
+	/**
+	 * Execute the passed <code>Task</code> once per passed
+	 * <code>LocalMaster</code>. If a <code>LocalMaster</code> is passed
+	 * more than once, the task will be executed multiple times.
+	 *
+	 * @param masters
+	 *            execute the task for those masters.
+	 * @param taskClass
+	 *            create a task of this class and execute it.
+	 * @param taskResults
+	 * 			place the results of the task in this <code>Set</code> unless
+	 * 			<code>null</code> is passed.
+	 * @param additionalInformation TODO
+	 * @throws TaskExecutionNotSuccessfulException
+	 *             Indicates a failure during task execution
+	 */
+	public void executeTaskForMasters(final Collection<LocalMaster> masters,
+			final Class<? extends Task> taskClass, final Set<TaskResult> taskResults,
+			Collection<String> additionalInformation)
+			throws TaskExecutionNotSuccessfulException;
+
+	/**
+	 * Execute the passed <code>Task</code> once per passed
+	 * <code>TorInstance</code>. If a <code>TorInstance</code> is passed
+	 * more than once, the task will be executed multiple times.
+	 * @param taskClass
+	 *          create a task of this class and execute it.
+	 * @param taskResults
+	 * 			place the results of the task in this <code>Set</code> unless
+	 * 			<code>null</code> is passed.
+	 * @param additionalInformation
+	 * 			call the task's addAdditionalInformation method with this
+	 * 			parameter.
+	 * @param torInstances
+	 *          execute the task for those masters.
+	 * @throws TaskExecutionNotSuccessfulException
+	 *          Indicates a failure during task execution
+	 */
+	public void executeTaskForTorInstances(Collection<TorInstance> instances,
+			Class<? extends Task> taskClass, Set<TaskResult> taskResults,
+			Collection<String> additionalInformation)
+			throws TaskExecutionNotSuccessfulException;
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TorInstance.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TorInstance.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/TorInstance.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -72,7 +72,7 @@
 	public boolean isRouter();
 
 	public boolean isExit();
-
+	
 	public boolean isOnPrivateNetwork();
 
 	public int getRevision();

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorMasterProgram.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorMasterProgram.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorMasterProgram.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -50,6 +50,7 @@
 import de.uniba.wiai.lspi.puppetor.rmi.RemoteMaster;
 import de.uniba.wiai.lspi.puppetor.rmi.TestExecutor;
 import de.uniba.wiai.lspi.puppetor.rmi.impl.MasterImplFactory;
+import de.uniba.wiai.lspi.puppetor.rmi.tests.TestRegistration;
 
 /**
  * The <code>PuppeTorMasterProgram</code> contains the main method for the
@@ -77,7 +78,7 @@
 	 * The address this server should bind on. Use 127.0.0.1 for local testing.
 	 * XXX Someone should check if this works with IPv6 -SH
 	 */
-	final private static String serveraddress = "78.47.18.109";
+	final private static String serveraddress = "127.0.0.1";
 
 	/**
 	 * Master application entry point
@@ -113,17 +114,18 @@
 		// Set the location of the keystore where your private certificate is.
 		System.setProperty("javax.net.ssl.keyStore", "res/keystore");
 		// Set the password for your keystore.
-		System.setProperty("javax.net.ssl.keyStorePassword", "asdasd");
+		System.setProperty("javax.net.ssl.keyStorePassword", "pleasechange");
 
 		/*
 		 * Set the location of the truststore which contains the exported
 		 * certificates of your slaves.
 		 */
 		System.setProperty("javax.net.ssl.trustStore", "res/truststore");
+		// Use a timeout of 45 seconds to detect disconnected clients.
+		System.setProperty("java.rmi.dgc.leaseValue", "45000");
+
 		// Tell the RMI system the location of the master
 		System.setProperty("java.rmi.server.hostname", serveraddress);
-		// Use a timeout of 15 seconds to detect disconnected clients.
-		System.setProperty("java.rmi.dgc.leaseValue", "15000");
 
 		// Set up the factories we want to use
 		AbstractMasterFactory.initialize(new MasterImplFactory());
@@ -147,7 +149,7 @@
 
 		System.out.println("waiting for slaves.");
 		try {
-			Thread.sleep(1000 * 10);// XXX this should be two minutes-SH
+			Thread.sleep(1000 * 60 * 2);
 		} catch (final InterruptedException e) {
 			e.printStackTrace();
 			throw new RuntimeException("This is the main thread. We don't "
@@ -164,9 +166,8 @@
 	private void registerTests() {
 		final AbstractMasterFactory fact = AbstractMasterFactory.getInstance();
 		final TestExecutor exec = fact.getTestExecutorInstance();
-		exec
-				.registerTest(fact
-						.createPublicNetworkTestForClientsOnly("Access google over public Tor network."));
+		final TestRegistration registration = fact.getTestRegistrationInstance();
+		registration.registerTests(exec);
 	}
 
 	private void unregisterRMIRegistry() throws NoSuchObjectException {

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorSlaveProgram.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorSlaveProgram.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/execute/PuppeTorSlaveProgram.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -75,9 +75,16 @@
 	 * the master's configuration. XXX Someone should check if this works with
 	 * IPv6 -SH
 	 */
-	final private static String serveraddress = "78.47.18.109";
+	final private static String serveraddress = "127.0.0.1";//78.47.18.109";
 
 	/**
+	 * The address this slave listens on. Use 127.0.0.1 for slaves that do not
+	 * open any ports for the outside world and thus can act as Tor clients
+	 * only.
+	 */
+	final private static String myaddress = "127.0.0.1";
+	
+	/**
 	 * Each slave is identified by its unique <code>slaveName</code>. Be
 	 * careful to prevent naming collisions between slaves.
 	 */
@@ -100,71 +107,72 @@
 	 */
 	public static void main(final String[] args) {
 		final PuppeTorSlaveProgram slave = new PuppeTorSlaveProgram();
-		// XXX put this in a while(true) -SH
-		// while(true) {
-		while (slave.connectToMaster() == false) {
-			try {
-				Thread.sleep(5000); // wait one minute
-			} catch (final InterruptedException e) {
-				// and immediatly retry if we're interrupted.
+		while(true) {
+			while (slave.connectToMaster() == false) {
+				try {
+					Thread.sleep(60000);
+				} catch (final InterruptedException e) {
+					throw new RuntimeException("Bug: Nothing should " +
+							"interrupt us here!");
+				}
 			}
-		}
-
-		final Thread taskGetter = new Thread(new Runnable() {
-			public void run() {
-				while (true) {
-					try {
+	
+			final Thread taskGetter = new Thread(new Runnable() {
+				public void run() {
+					while (true) {
 						try {
-							// XXX I dislike the following three lines, but
-							// interruption doesn't work while we wait for the
-							// master. Maybe there is a better solution that
-							// doesn't eat the poison pill twice. -SH
-							Task task =
-									AbstractSlaveFactory.getMaster()
-											.getNewTask();
-							tasks.put(task);
-							if (task instanceof TerminateTask) {
-								break;
+							try {
+								// XXX I dislike the following lines, but
+								// interruption doesn't work while we wait for the
+								// master. Maybe there is a better solution that
+								// doesn't eat the poison pill twice. -SH
+								Task task = AbstractSlaveFactory.getMaster()
+												.getNewTask();
+								tasks.put(task);
+								if (task instanceof TerminateTask) {
+									break;
+								}
+							} catch (final RemoteException e) {
+								// Empty the task queue - we cannot send any results
+								// back, anyways.
+								tasks.clear();
+								// A taskid of 0 indicates a local Task
+								tasks.put(new TerminateTask(0,
+										"local termination"));
+								Thread.currentThread().interrupt();
 							}
-						} catch (final RemoteException e) {
-							// Empty the task queue - we cannot send any results
-							// back, anyways.
-							// tasks.clear();
-							// A taskid of 0 indicates a local Task
-							tasks
-									.put(new TerminateTask(0,
-											"local termination"));
+						} catch (final InterruptedException e) {
 							Thread.currentThread().interrupt();
 						}
-					} catch (final InterruptedException e) {
-						Thread.currentThread().interrupt();
+						if (Thread.interrupted()) {
+							break;
+						}
+	
 					}
+				}
+			});
+	
+			taskGetter.start();
+			// XXX We use just a single Thread here. That isn't the smartest move.
+			// -SH
+			try {
+				while (true) {
+					final Task newTask = tasks.take();
+					newTask.execute();
 					if (Thread.interrupted()) {
 						break;
 					}
-
 				}
-			}
-		});
+			} catch (final InterruptedException ignored) {} catch (final RemoteException ignored) {}
+			taskGetter.interrupt();
+			AbstractSlaveFactory.setMaster(null);
+			// We don't shut down, but want the Master to see we disconnected,
+			// so hopefully a gc will happen soon.
+			System.gc();
+		}
 
-		taskGetter.start();
-		// XXX We use just a single Thread here. That isn't the smartest move.
-		// -SH
-		try {
-			while (true) {
-				final Task newTask = tasks.take();
-				newTask.execute();
-				if (Thread.interrupted()) {
-					break;
-				}
-			}
-		} catch (final InterruptedException ignored) {} catch (final RemoteException ignored) {}
-		taskGetter.interrupt();
-		AbstractSlaveFactory.setMaster(null);
 	}
 
-	// }
-
 	/**
 	 * Private constructor to set up RMI-related Java-internal variables.
 	 */
@@ -176,7 +184,7 @@
 		/*
 		 * Set the password for your keystore.
 		 */
-		System.setProperty("javax.net.ssl.keyStorePassword", "asdasd");
+		System.setProperty("javax.net.ssl.keyStorePassword", "pleasechange");
 		/*
 		 * Set the location of the truststore which contains the exported
 		 * certificates of your slaves
@@ -189,15 +197,15 @@
 		/*
 		 * Create a new slave with the properties that are relevant for the
 		 * computer and networking environment it runs on.
+		 * XXX unused for now -SH
 		 */
 		final Set<Integer> ports = new HashSet<Integer>();
-		for (int i = 10025; i < 20000; i++) {
+		/*for (int i = 10025; i < 20000; i++) {
 			ports.add(i);
-		}
+		}*/
 		final Set<Integer> availableRevisions =
 				new CopyOnWriteArraySet<Integer>();
-		slave =
-				fac.createSlave(slaveName, Slave.OS.UNDEFINED, "127.0.0.1",
+		slave = fac.createSlave(slaveName, Slave.OS.UNDEFINED, myaddress,
 						ports, availableRevisions);
 
 	}
@@ -230,5 +238,4 @@
 		}
 		return true;
 	}
-
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTaskImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTaskImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTaskImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -31,16 +31,20 @@
  */
 package de.uniba.wiai.lspi.puppetor.rmi.impl;
 
-import java.io.Serializable;
 import java.rmi.RemoteException;
+import java.util.Collection;
 
 import de.uniba.wiai.lspi.puppetor.rmi.AbstractSlaveFactory;
 import de.uniba.wiai.lspi.puppetor.rmi.Task;
 import de.uniba.wiai.lspi.puppetor.rmi.TaskResult;
 
-public abstract class AbstractTaskImpl implements Serializable, Task {
-
+public abstract class AbstractTaskImpl implements Task {
 	/**
+	 * Required for serialization. Needs to change for new released versions.
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	/**
 	 * A human-readable name for the task (to be included in log-messages, etc).
 	 */
 	final protected String name;
@@ -63,12 +67,21 @@
 
 	protected void reportResult(final boolean success)
 			throws InterruptedException, RemoteException {
-		reportResult(success, new TaskResultImpl(success, this));
+		reportResult(new TaskResultImpl(success, this, null));
 	}
+	
+	protected void reportResult(final boolean success, final String result)
+			throws InterruptedException, RemoteException {
+		reportResult(new TaskResultImpl(success, this, result));
+	}
 
-	protected void reportResult(final boolean success,
-			final TaskResult taskResult) throws InterruptedException,
-			RemoteException {
+	// XXX protect against double-reporting of results -SH
+	protected void reportResult( final TaskResult taskResult)
+			throws InterruptedException, RemoteException {
 		AbstractSlaveFactory.getMaster().reportTaskResult(taskResult);
 	}
+	
+	public void addAdditionalInformation(
+			Collection<String> additionalInformation) {}
+
 }

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTestImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTestImpl.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/AbstractTestImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2008, Sebastian Hahn
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.uniba.wiai.lspi.puppetor.rmi.impl;
+
+import de.uniba.wiai.lspi.puppetor.rmi.AbstractMasterFactory;
+import de.uniba.wiai.lspi.puppetor.rmi.NetworkDescription;
+import de.uniba.wiai.lspi.puppetor.rmi.Test;
+import de.uniba.wiai.lspi.puppetor.rmi.TestExecutor;
+
+/**
+ * Extend <code>AbstractTestImpl</code> for your own tests. Make sure you also add them
+ * to the TestRegistration.registerTest method.
+ * 
+ * @author Sebastian Hahn
+ */
+abstract public class AbstractTestImpl implements Test {
+
+	/**
+	 * Required for serialization. Needs to change for new released versions.
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	/**
+	 * A test description for log messages.
+	 */
+	final private String description;
+
+	/**
+	 * The network that must exist for the test to be executed.
+	 */
+	final private NetworkDescription networkDescription;
+
+	final protected TestExecutor exec;
+	
+	public AbstractTestImpl(final String description, final NetworkDescription network) {
+		this.description = description;
+		networkDescription = network;
+		exec = AbstractMasterFactory.getInstance().
+				getTestExecutorInstance();
+	}
+
+	public final NetworkDescription getNetworkDescription() {
+		return networkDescription;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+}

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -116,12 +116,10 @@
 
 	/**
 	 * Remove the slave from the Map of slaves and destroy its workqueues.
-	 * Inform the TestRunner that all still-running tests failed because the
-	 * slave went away. XXX Don't just promise to do that - we actually have to
-	 * do that when there are the queues that I mentioned.-SH
+	 * Inform the TestExecutor that all still-running tests failed because the
+	 * slave went away.
 	 */
 	public void unreferenced() {
-		System.out.println("unreferenced called");
 		AbstractMasterFactory.getInstance().getTestExecutorInstance()
 				.unregisterLocalMaster(this);
 	}

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImplFactory.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImplFactory.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/MasterImplFactory.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -34,11 +34,10 @@
 import java.rmi.RemoteException;
 import de.uniba.wiai.lspi.puppetor.rmi.AbstractMasterFactory;
 import de.uniba.wiai.lspi.puppetor.rmi.Master;
-import de.uniba.wiai.lspi.puppetor.rmi.Network;
 import de.uniba.wiai.lspi.puppetor.rmi.NetworkDescription;
 import de.uniba.wiai.lspi.puppetor.rmi.Slave;
-import de.uniba.wiai.lspi.puppetor.rmi.Test;
 import de.uniba.wiai.lspi.puppetor.rmi.TestExecutor;
+import de.uniba.wiai.lspi.puppetor.rmi.tests.TestRegistration;
 
 /**
  * Create <code>RemotePuppeTorImpl</code> instances
@@ -58,18 +57,25 @@
 	}
 
 	@Override
-	public Test createPublicNetworkTestForClientsOnly(final String description) {
-		return new TestImpl(description, new NetworkDescriptionImpl(1, 0, 0));
+	public TestRegistration getTestRegistrationInstance() {
+		return TestRegistration.getInstance();
 	}
 
-	@Override
+/*	@Override
+	public Test createPublicNetworkTestForClientsOnly(final String description) {
+		return null;
+		return new AbstractTestImpl(description, new NetworkDescriptionImpl(1, 0, 0));
+	}*/
+
+	/*@Override
 	public Network createNetwork(final String name) {
 		return new NetworkImpl(name);
-	}
+	}*/
 
 	@Override
 	public NetworkDescription createNetworkDescription() {
-		// TODO Auto-generated method stub
+		// XXX implement -SH
 		return null;
 	}
+
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/NetworkImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/NetworkImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/NetworkImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -61,12 +61,19 @@
 	 */
 	private final List<Test> tests;
 
+	/**
+	 * All the Tor instances running at the slaves that are linked to this
+	 * network.
+	 */
 	private final Set<TorInstance> torInstances;
 
-	public NetworkImpl(final String name) {
+	private final boolean privateNetwork;
+	
+	public NetworkImpl(final String name, boolean privateNetwork) {
 		this.name = name;
 		tests = new CopyOnWriteArrayList<Test>();
 		torInstances = new CopyOnWriteArraySet<TorInstance>();
+		this.privateNetwork = privateNetwork;
 	}
 
 	public void addTorInstance(final TorInstance torInstance) {
@@ -132,5 +139,13 @@
 		}
 		return Collections.unmodifiableSet(routers);
 	}
+	
+	public List<Test> getTests() {
+		return Collections.unmodifiableList(tests);
+	}
 
+	public boolean isPrivateNetwork() {
+		return privateNetwork;
+	}
+
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/SlaveImplFactory.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/SlaveImplFactory.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/SlaveImplFactory.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -51,7 +51,6 @@
 	public Slave createSlave(final String slaveName, final OS os,
 			final String ip, final Set<Integer> ports,
 			final Set<Integer> availableRevisions) throws NullPointerException {
-		System.out.println(slaveName);
 		return new SlaveImpl(slaveName, os, ip, ports, availableRevisions);
 	}
 

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TaskResultImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TaskResultImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TaskResultImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -41,13 +41,26 @@
 	 */
 	private static final long serialVersionUID = 1L;
 
+	/**
+	 * The task this result is used for.
+	 */
 	final private Task task;
 
+	/**
+	 * Store the result of the <code>task</code>, or <code>null</code> if no
+	 * result is necessary.
+	 */
+	final private String result;
+	
+	/**
+	 * Whether the task execution was successful.
+	 */
 	final private boolean wasSuccessful;
 
-	public TaskResultImpl(final boolean success, final Task task) {
+	public TaskResultImpl(final boolean success, final Task task, final String result) {
 		wasSuccessful = success;
 		this.task = task;
+		this.result = result;
 	}
 
 	public Task getTask() {
@@ -58,4 +71,7 @@
 		return wasSuccessful;
 	}
 
+	public String getTaskResult() {
+		return result;
+	}
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestExecutorImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestExecutorImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestExecutorImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -41,7 +41,6 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Queue;
 import java.util.Set;
 import java.util.Vector;
 import java.util.concurrent.Callable;
@@ -58,12 +57,14 @@
 import de.uniba.wiai.lspi.puppetor.rmi.NetworkDescription;
 import de.uniba.wiai.lspi.puppetor.rmi.RemoteMaster;
 import de.uniba.wiai.lspi.puppetor.rmi.Task;
+import de.uniba.wiai.lspi.puppetor.rmi.TaskExecutionNotSuccessfulException;
 import de.uniba.wiai.lspi.puppetor.rmi.TaskResult;
 import de.uniba.wiai.lspi.puppetor.rmi.Test;
 import de.uniba.wiai.lspi.puppetor.rmi.TestResult;
 import de.uniba.wiai.lspi.puppetor.rmi.TestExecutor;
 import de.uniba.wiai.lspi.puppetor.rmi.TorInstance;
 import de.uniba.wiai.lspi.puppetor.rmi.tasks.BuildCircuitsTask;
+import de.uniba.wiai.lspi.puppetor.rmi.tasks.ConfigureAsPrivateTask;
 import de.uniba.wiai.lspi.puppetor.rmi.tasks.CreateDirectoryAuthorityTask;
 import de.uniba.wiai.lspi.puppetor.rmi.tasks.CreateNetworkTask;
 import de.uniba.wiai.lspi.puppetor.rmi.tasks.CreateProxyTask;
@@ -83,8 +84,8 @@
 	private static final TestExecutor instance = new TestExecutorImpl();
 
 	/**
-	 * Store all local representations of connections to slaves. Use the slave's
-	 * name as key.
+	 * Store all local representations of connections to slaves. Use the
+	 * slave's name as key.
 	 */
 	private static final ConcurrentMap<String, LocalMaster> masters =
 			new ConcurrentHashMap<String, LocalMaster>();
@@ -110,6 +111,12 @@
 	 */
 	private static final Set<Network> networks =
 			new CopyOnWriteArraySet<Network>();
+	
+	/**
+	 * Store the currently active network when executing a test. Null indicates
+	 * that either testing hasn't started yet, or is already finished.
+	 */
+	private static Network currentNetwork = null;
 
 	/**
 	 * Store all failed tests.
@@ -148,7 +155,7 @@
 		if (startedTesting.get() == true) {
 			throw new RuntimeException("Bug: Testing has started already.");
 		}
-		System.out.println("register slave " + master.getSlave().getName());
+		System.out.println(master.getSlave().getName() + " registered");
 		if (null != masters.putIfAbsent(master.getSlave().getName(), master)) {
 			throw new IllegalArgumentException(master.getSlave().getName()
 					+ " has already registered with this Server");
@@ -158,7 +165,6 @@
 	public void unregisterLocalMaster(final LocalMaster master) {
 		// XXX Don't forget to mark all tests as failed that depended on this
 		// slave if we have already started with testing-SH
-		System.out.println("unregister slave " + master.getSlave().getName());
 		try {
 			UnicastRemoteObject.unexportObject((RemoteMaster) master, true);
 		} catch (final NoSuchObjectException e) {
@@ -167,7 +173,8 @@
 		}
 		if (masters.remove(master.getSlave().getName()) == null) {
 			throw new RuntimeException(
-					"This is a bug. unregisterLocalMaster must never be called twice for the same master.");
+					"This is a bug. unregisterLocalMaster must never be " +
+					"called twice for the same master.");
 		}
 	}
 
@@ -192,120 +199,187 @@
 		startedTesting.set(true);
 		// check which tests we can actually execute
 		evaluateNetwork();
-		System.out.println("start making networks");
-		// XXX We can probably be much smarter here and reuse networks that
-		// have been built already. Later.-SH
 		for (final Test test : newTests) {
 			makeNetworks(test);
 		}
-		// final int networkCount = 0;
 		// XXX cancelled networks will still appear here...=SH
 		for (final Network nw : networks) {
-
+			synchronized(TestExecutorImpl.class) {
+				currentNetwork = nw;
+			}
 			try {
-				executeTaskForMaster(nw.getMasters(), CreateNetworkTask.class,
-						nw.getName(), nw.getName());
+				executeTaskForMasters(nw.getMasters(),
+						CreateNetworkTask.class, null, null);
 				// The network has been created at the slaves. Set up
 				// authorities, routers and proxies.
 
-				final Queue<LocalMaster> masters =
-						new LinkedList<LocalMaster>();
-
-				for (final TorInstance authority : nw.getDirectoryAuthorities()) {
-					masters.add(authority.getMaster());
+				Set<TaskResult> authorityResults =
+						new CopyOnWriteArraySet<TaskResult>();
+				executeTaskForTorInstances(nw.getDirectoryAuthorities(),
+						CreateDirectoryAuthorityTask.class, authorityResults,
+						null);
+				executeTaskForTorInstances(nw.getRoutersOnly(),
+						CreateRouterTask.class, null, null);
+				executeTaskForTorInstances(nw.getProxiesOnly(),
+						CreateProxyTask.class, null, null);
+				if(nw.isPrivateNetwork()) {
+					List<String> authorities = new LinkedList<String>();
+					for(TaskResult result : authorityResults) {
+						authorities.add(result.getTaskResult());
+					}
+					executeTaskForMasters(nw.getMasters(),
+							ConfigureAsPrivateTask.class, null, authorities);
 				}
-				executeTaskForMaster(masters,
-						CreateDirectoryAuthorityTask.class, nw.getName(),
-						"authority");
-				masters.clear();
-				System.out.println("after authoritycreation");
-				for (final TorInstance router : nw.getRoutersOnly()) {
-					masters.add(router.getMaster());
-				}
-				executeTaskForMaster(masters, CreateRouterTask.class, nw
-						.getName(), "router");
-				masters.clear();
-				for (final TorInstance proxy : nw.getProxiesOnly()) {
-					masters.add(proxy.getMaster());
-				}
-				executeTaskForMaster(masters, CreateProxyTask.class, nw
-						.getName(), "proxy");
-
 				// Start the nodes ...
-				executeTaskForMaster(nw.getMasters(), StartNodesTask.class, nw
-						.getName(), "");
+				executeTaskForMasters(nw.getMasters(), StartNodesTask.class,
+						null, null);
 				// ... and build circuits. This may take some time.
-				System.out.println("Build circuits");
-				executeTaskForMaster(nw.getMasters(), BuildCircuitsTask.class,
-						nw.getName(), "");
+				executeTaskForMasters(nw.getMasters(), BuildCircuitsTask.class,
+						null, null);
 
-				// Put the tests here.
+				// Start using the individual tests that were set up for this
+				// network.
+				for (final Test test : nw.getTests()) {
+					test.doTest();
+				}
 
-				System.out.println("Shutdown the nodes");
 				// We don't need the network anymore, make sure it's shut down
 				// properly.
-				executeTaskForMaster(nw.getMasters(), ShutdownNodesTask.class,
-						nw.getName(), "");
-				System.out.println("Sending the terminate task");
-				executeTaskForMaster(nw.getMasters(), TerminateTask.class, nw
-						.getName(), "");
+				executeTaskForMasters(nw.getMasters(), ShutdownNodesTask.class,
+						null, null);
 
 			} catch (final TaskExecutionNotSuccessfulException e) {
 				e.printStackTrace();
-				// XXX Log this properly -SH
+				// XXX Log this properly. -SH
 			}
 
 		}
-		System.out.println("done testing");
-		networks.clear();
+		// The terminate Task interrupts the slave's main process to
+		// indicate that it should disconnect.
+		synchronized(TestExecutorImpl.class) {
+			currentNetwork = null;
+		}
+		try {
+			executeTaskForMasters(masters.values(), TerminateTask.class, null,
+					null);
+		} catch (TaskExecutionNotSuccessfulException e) {
+			e.printStackTrace();
+			// XXX Log this properly. -SH
+		}
 	}
 
-	// protected void executeTaskForTorInstance(final List<TorInstance>
-	// instances,
-	// final Task task) {}
+	//XXX This method and the next look very similar. See what we can do. -SH
+	public void executeTaskForMasters(final Collection<LocalMaster> masters,
+			final Class<? extends Task> taskClass,
+			final Set<TaskResult> taskResults,
+			Collection<String> additionalInformation)
+			throws TaskExecutionNotSuccessfulException {
 
-	/**
-	 * Execute the passed <code>Task</code> once per passed
-	 * <code>LocalMaster</code>. If a <code>LocalMaster</code> is passed
-	 * more than once, the task will be executed multiple times.
-	 *
-	 * @param masters
-	 *            execute the task for those masters.
-	 * @param task
-	 *            execute this task.
-	 * @throws TaskExecutionNotSuccessfulException
-	 *             Indicates a failure during task execution
-	 */
-	protected void executeTaskForMaster(final Collection<LocalMaster> masters,
-			final Class<? extends Task> taskClass, final String networkName,
-			final String taskName) throws TaskExecutionNotSuccessfulException {
-
 		if (masters.isEmpty()) {
 			return;
 		}
-		int i = 1;
 		final Set<MasterTask> mTasks = new HashSet<MasterTask>();
 		Constructor<? extends Task> ctor = null;
 		try {
+			ctor = taskClass.getConstructor(int.class, String.class);
+			String networkName = "";
+			synchronized(TestExecutorImpl.class) {
+				if(currentNetwork == null) {
+					networkName = "";
+				} else {
+					networkName = currentNetwork.getName();
+				}
+			}
+			for (final LocalMaster master : masters) {
+				Task task = ctor.newInstance(
+						nextTaskId.getAndIncrement(), networkName);
+				task.addAdditionalInformation(additionalInformation);
+				mTasks.add(new MasterTask(master, task));				
+			}
+
+			final TaskManager man = new TaskManager(mTasks);
+			final FutureTask<Boolean> futureTask =
+				new FutureTask<Boolean>(man);
+			new Thread(futureTask).start();
 			try {
-				ctor =
-						taskClass.getConstructor(int.class, String.class,
-								String.class);
-				for (final LocalMaster master : masters) {
-					mTasks.add(new MasterTask(master, ctor.newInstance(
-							nextTaskId.getAndIncrement(), networkName, taskName
-									+ i++)));
+				if (futureTask.get() == false) {
+					throw new TaskExecutionNotSuccessfulException(man
+							.getTaskResults());
 				}
-			} catch (final NoSuchMethodException e) {
-				ctor = taskClass.getConstructor(int.class, String.class);
-				for (final LocalMaster master : masters) {
-					mTasks.add(new MasterTask(master, ctor.newInstance(
-							nextTaskId.getAndIncrement(), networkName)));
+			} catch (final InterruptedException e) {
+				throw new TaskExecutionNotSuccessfulException(null);
+			} catch (final ExecutionException e) {
+				// XXX Log this with the cause. Should not happen. -SH
+				e.printStackTrace();
+				throw new TaskExecutionNotSuccessfulException(null);
+			}
+			if(taskResults != null) {
+				taskResults.addAll(man.getTaskResults());
+			}
+		} catch (final SecurityException e) {
+			throw new RuntimeException(
+					"BUG: We're not using a security manager, so where " +
+					"does this exception come from?");
+		} catch (final NoSuchMethodException e) {
+			e.printStackTrace();
+			throw new RuntimeException("BUG: Expected constructor undefined!");
+		} catch (final IllegalArgumentException e) {
+			e.printStackTrace();
+			throw new RuntimeException("BUG: Expected constructor undefined!");
+		} catch (final InstantiationException e) {
+			e.printStackTrace();
+			throw new RuntimeException("BUG: InstantiationException.");
+		} catch (final IllegalAccessException e) {
+			e.printStackTrace();
+			throw new RuntimeException("BUG: Expected constructor undefined!");
+		} catch (final InvocationTargetException e) {
+			e.printStackTrace();
+			throw new RuntimeException("BUG: Constructor threw an exception.");
+		}
+	}
+	
+	public Network getCurrentNetwork() {
+		synchronized(TestExecutorImpl.class) {
+			if(currentNetwork == null) {
+				throw new RuntimeException("There is no network currently!");
+			}
+			return currentNetwork;
+		}
+	}
+
+	public void executeTaskForTorInstances(
+			final Collection<TorInstance> torInstances,
+			final Class<? extends Task> taskClass,
+			final Set<TaskResult> taskResults,
+			Collection<String> additionalInformation)
+			throws TaskExecutionNotSuccessfulException {
+
+		if (torInstances.isEmpty()) {
+			return;
+		}
+		final Set<MasterTask> mTasks = new HashSet<MasterTask>();
+		Constructor<? extends Task> ctor = null;
+		try {
+			ctor = taskClass.getConstructor(int.class, String.class,
+							String.class);
+			String networkName = "";
+			synchronized(TestExecutorImpl.class) {
+				if(currentNetwork == null) {
+					networkName = "";
+				} else {
+					networkName = currentNetwork.getName();
 				}
 			}
+			for (final TorInstance torInstance : torInstances) {
+				Task task = ctor.newInstance(nextTaskId.getAndIncrement(),
+						networkName, torInstance.getName());
+				task.addAdditionalInformation(additionalInformation);
+				mTasks.add(new MasterTask(torInstance.getMaster(), task));
+			}
 
 			final TaskManager man = new TaskManager(mTasks);
-			final FutureTask<Boolean> futureTask = new FutureTask<Boolean>(man);
+			final FutureTask<Boolean> futureTask =
+				new FutureTask<Boolean>(man);
 			new Thread(futureTask).start();
 			try {
 				if (futureTask.get() == false) {
@@ -319,21 +393,25 @@
 				e.printStackTrace();
 				throw new TaskExecutionNotSuccessfulException(null);
 			}
+			if(taskResults != null) {
+				taskResults.addAll(man.getTaskResults());
+			}
 		} catch (final SecurityException e) {
 			throw new RuntimeException(
-					"BUG: We're not using a security manager, so where does this exception come from?");
+					"BUG: We're not using a security manager, " +
+					"so where does this exception come from?");
 		} catch (final NoSuchMethodException e) {
 			e.printStackTrace();
-			throw new RuntimeException("BUG: Expected constructor undefined1!");
+			throw new RuntimeException("BUG: Expected constructor undefined!");
 		} catch (final IllegalArgumentException e) {
 			e.printStackTrace();
-			throw new RuntimeException("BUG: Expected constructor undefined2!");
+			throw new RuntimeException("BUG: Expected constructor undefined!");
 		} catch (final InstantiationException e) {
 			e.printStackTrace();
 			throw new RuntimeException("BUG: InstantiationException.");
 		} catch (final IllegalAccessException e) {
 			e.printStackTrace();
-			throw new RuntimeException("BUG: Expected constructor undefined3!");
+			throw new RuntimeException("BUG: Expected constructor undefined!");
 		} catch (final InvocationTargetException e) {
 			e.printStackTrace();
 			throw new RuntimeException("BUG: Constructor threw an exception.");
@@ -344,31 +422,40 @@
 		final NetworkDescription nd = test.getNetworkDescription();
 		// XXX we want to do something much smarter here.-SH
 
+		// XXX obviously, the following code adds the specified amount of
+		// authorities, routers, and proxies for each slave, regardless of
+		// capabilities. That isn't good. -SH
 		for (final LocalMaster master : masters.values()) {
+			int necessaryDirectoryAuthorities =
+				nd.necessaryDirectoryAuthorities();
+			boolean onPrivateNetwork = (necessaryDirectoryAuthorities > 0);
 			// XXX the name choosing doesn't make sense. -SH
 			final Network nw =
 					new NetworkImpl(test.getDescription() + " slavename:"
-							+ master.getSlave().getName());
-			int necessaryDirectoryAuthorities =
-					nd.necessaryDirectoryAuthorities();
+							+ master.getSlave().getName(), onPrivateNetwork);
 			while (necessaryDirectoryAuthorities >= 1) {
-				System.out.println("adding authority");
-				// XXX add an actual authority, not a regular instance -SH
-				nw.addTorInstance(new TorInstanceImpl(master));
+				TorInstanceImpl authority = new TorInstanceImpl(master, 
+						"Authority" + necessaryDirectoryAuthorities);
+				authority.setDirectoryAuthority(true);
+				authority.setOnPrivateNetwork(onPrivateNetwork);
+				nw.addTorInstance(authority);
 				necessaryDirectoryAuthorities--;
 			}
 			int necessaryRouters = nd.necessaryRouters();
 			while (necessaryRouters >= 1) {
-				System.out.println("adding router");
-				// XXX add an actual router, not a regular instance -SH
-				nw.addTorInstance(new TorInstanceImpl(master));
+				TorInstanceImpl router = new TorInstanceImpl(master, "Router" + 
+						necessaryRouters);
+				router.setRouter(true);
+				router.setOnPrivateNetwork(onPrivateNetwork);
+				nw.addTorInstance(router);
 				necessaryRouters--;
 			}
 			int necessaryProxies = nd.necessaryProxies();
 			while (necessaryProxies >= 1) {
-				System.out.println("adding proxy");
-				// XXX add an actual proxy, not a regular instance -SH
-				nw.addTorInstance(new TorInstanceImpl(master));
+				TorInstanceImpl proxy = new TorInstanceImpl(master, "Proxy" +
+						necessaryProxies); 
+				proxy.setOnPrivateNetwork(onPrivateNetwork);
+				nw.addTorInstance(proxy);
 				necessaryProxies--;
 			}
 			nw.addTest(test);
@@ -380,7 +467,7 @@
 		return failedTests;
 	}
 
-	public Set<Test> cannotRunTests() {
+	public Set<Test> getCannotRunTests() {
 		return cannotRunTests;
 	}
 
@@ -398,22 +485,6 @@
 		newTests.add(test);
 	}
 
-	private static class TaskExecutionNotSuccessfulException extends Exception {
-
-		private static final long serialVersionUID = 1L;
-		final private Set<TaskResult> taskResults;
-
-		TaskExecutionNotSuccessfulException(final Set<TaskResult> taskResults) {
-			this.taskResults = taskResults;
-		}
-
-		public Set<TaskResult> getTaskResults() {
-			return taskResults;
-		}
-
-		// XXX Add some logging capabilities -SH
-	}
-
 	private static class TaskManager implements Callable<Boolean> {
 
 		final private Set<TaskResult> taskResults =
@@ -428,7 +499,8 @@
 				throw new IllegalArgumentException("No tasks passed!");
 			}
 			this.tasks =
-					Collections.synchronizedSet(new HashSet<MasterTask>(tasks));
+					Collections.synchronizedSet(
+							new HashSet<MasterTask>(tasks));
 		}
 
 		public Boolean call() {
@@ -453,7 +525,7 @@
 					return true;
 				}
 			} catch (final InterruptedException e) {
-				// figure out a better solution here -SH
+				// XXX figure out a better solution here -SH
 				e.printStackTrace();
 			}
 			return false;

Deleted: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TestImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2008, Sebastian Hahn
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- *     * Neither the names of the copyright owners nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-package de.uniba.wiai.lspi.puppetor.rmi.impl;
-
-import de.uniba.wiai.lspi.puppetor.rmi.NetworkDescription;
-import de.uniba.wiai.lspi.puppetor.rmi.Test;
-
-public class TestImpl implements Test {
-
-	/**
-	 * Required for serialization. Needs to change for new released versions.
-	 */
-	private static final long serialVersionUID = 1L;
-
-	final private String description;
-
-	/**
-	 * The network that must exist for the test to be executed.
-	 */
-	final private NetworkDescription networkDescription;
-
-	public TestImpl(final String description, final NetworkDescription network) {
-		this.description = description;
-		networkDescription = network;
-	}
-
-	public final NetworkDescription getNetworkDescription() {
-		return networkDescription;
-	}
-
-	public String getDescription() {
-		return description;
-	}
-
-}

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TorInstanceImpl.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TorInstanceImpl.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/impl/TorInstanceImpl.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -32,6 +32,7 @@
 package de.uniba.wiai.lspi.puppetor.rmi.impl;
 
 import java.util.Collections;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -49,12 +50,12 @@
 	/**
 	 * Saves configuration options in an "option value" format.
 	 */
-	private List<String> configuration;
+	private final List<String> configuration = new LinkedList<String>();
 
 	/**
 	 * The name of this node.
 	 */
-	private String name;
+	private final String name;
 
 	/**
 	 * The svn revision of the Tor build. 0 means no specified revision.
@@ -79,7 +80,7 @@
 	/**
 	 * Whether we are a relay.
 	 */
-	private final AtomicBoolean relay = new AtomicBoolean(false);
+	private final AtomicBoolean router = new AtomicBoolean(false);
 
 	/**
 	 * Whether we are a bridge.
@@ -89,55 +90,101 @@
 	/**
 	 * Whether we are on a private network.
 	 */
-	private AtomicBoolean privateNetwork;
+	private AtomicBoolean privateNetwork = new AtomicBoolean(false);
 
 	/**
 	 * Whether the configuration of the tor instance should be replaced by the
 	 * config returned from <code>this.getConfiguration()</code>.
 	 */
-	private AtomicBoolean replaceConfiguration;
+	private AtomicBoolean replaceConfiguration = new AtomicBoolean(false);
 
 	/**
 	 * Provide a link to the slave where this torInstance will run.
 	 */
 	private final LocalMaster master;
 
-	TorInstanceImpl(final LocalMaster master) {
+	/**
+	 * @param master
+	 * 		the <code>LocalMaster</code> that represents the slave on which
+	 * 		this Tor instance is running.
+	 * @param name
+	 * 		A name to identify the node.
+	 * 		XXX think about duplicates, we need a unique name to identify the
+	 * 		node, but is it smart to use that name as the Tor proxy's name as
+	 * 		well? -SH
+	 */
+	TorInstanceImpl(final LocalMaster master, final String name) {
 		this.master = master;
+		this.name = name;
 	}
 
 	public synchronized List<String> getConfiguration() {
 		return Collections.unmodifiableList(configuration);
 	}
+	
+	public synchronized void addConfiguration(List<String> newConfig) {
+		configuration.addAll(newConfig);
+	}
 
 	public int getRevision() {
 		return revision.get();
 	}
+	
+	public void setRevision(final int revision) {
+		this.revision.set(revision);
+	}
 
 	public boolean isBridgeAuthority() {
 		return bridgeAuthority.get();
 	}
+	
+	public void setBridgeAuthority(boolean isBridgeAuthority) {
+		bridgeAuthority.set(isBridgeAuthority);
+	}
 
 	public boolean isDirectoryAuthority() {
 		return directoryAuthority.get();
 	}
+	
+	public void setDirectoryAuthority(boolean isDirectoryAuthority) {
+		if(isDirectoryAuthority) {
+			setRouter(true);
+		}
+		directoryAuthority.set(isDirectoryAuthority);
+	}
 
 	public boolean isExit() {
 		return exit.get();
 	}
 
 	public boolean isRouter() {
-		return relay.get();
+		return router.get();
 	}
+	
+	public void setRouter(boolean isRouter) {
+		if(!isRouter) {
+			setDirectoryAuthority(false);
+		}
+		router.set(isRouter);
+	}
 
 	public boolean isOnPrivateNetwork() {
 		return privateNetwork.get();
 	}
+	
+	public void setOnPrivateNetwork(boolean onPrivateNetwork) {
+		privateNetwork.set(onPrivateNetwork);
+	}
 
 	public boolean shouldReplaceConfiguration() {
 		return replaceConfiguration.get();
 	}
 
+	public void setShouldReplaceConfiguration(
+			boolean shouldReplaceConfiguration) {
+		replaceConfiguration.set(shouldReplaceConfiguration);
+	}
+
 	public boolean isBridge() {
 		return bridge.get();
 	}

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AccessGoogleTask.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AccessGoogleTask.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AccessGoogleTask.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2008, Sebastian Hahn
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.uniba.wiai.lspi.puppetor.rmi.tasks;
+
+import java.rmi.RemoteException;
+
+import de.uniba.wiai.lspi.puppetor.ClientApplication;
+import de.uniba.wiai.lspi.puppetor.ClientEventType;
+import de.uniba.wiai.lspi.puppetor.Event;
+import de.uniba.wiai.lspi.puppetor.EventListener;
+import de.uniba.wiai.lspi.puppetor.EventManager;
+import de.uniba.wiai.lspi.puppetor.Network;
+import de.uniba.wiai.lspi.puppetor.NetworkFactory;
+import de.uniba.wiai.lspi.puppetor.rmi.impl.AbstractTaskImpl;
+
+public class AccessGoogleTask extends AbstractTaskImpl {
+	/**
+	 * Required for serialization. Needs to change for new released versions.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The name of this tor node.
+	 */
+	private final String nodeName;
+	
+	public AccessGoogleTask(final int id, final String networkName,
+			final String nodeName) {
+		super(id, networkName);
+		this.nodeName = nodeName;
+	}
+
+	@Override
+	public void execute() throws InterruptedException, RemoteException {
+		final Network network = NetworkFactory.getNetworkByName(name);
+		
+		final ClientApplication client =
+			network.createClient("client", "www.google.com", 80, network.getNode(nodeName)
+					.getSocksPort());
+
+		// create event listener to listen for client application events
+		final EventListener clientEventListener = new EventListener() {
+	
+			// remember time when request was sent
+			//private long before;
+	
+			public void handleEvent(Event event) {
+				if (event.getType() == ClientEventType.CLIENT_SENDING_REQUEST) {
+					//before = System.currentTimeMillis();
+				} else if (event.getType() == ClientEventType.CLIENT_REPLY_RECEIVED) {
+					// XXX Log how long requests took, see whether we need this all -SH
+					;
+				}
+			}
+		};
+	
+		// obtain reference to event manager to be able to respond to events
+		final EventManager manager = network.getEventManager();
+	
+		manager.addEventListener(client.getClientApplicationName(),
+				clientEventListener);
+
+		// perform at most three request with a timeout of 20 seconds each
+		client.startRequests(3, 20000, true);
+	
+		// block this thread as long as client requests are running, but don't wait forever.
+		reportResult(manager.waitForAnyOccurence(client.getClientApplicationName(),
+				ClientEventType.CLIENT_REQUESTS_PERFORMED, 75000));
+	}
+}

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AddHiddenServiceTask.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AddHiddenServiceTask.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/AddHiddenServiceTask.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2008, Sebastian Hahn
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.uniba.wiai.lspi.puppetor.rmi.tasks;
+
+import java.rmi.RemoteException;
+import java.util.Set;
+
+import de.uniba.wiai.lspi.puppetor.ClientApplication;
+import de.uniba.wiai.lspi.puppetor.ClientEventType;
+import de.uniba.wiai.lspi.puppetor.Event;
+import de.uniba.wiai.lspi.puppetor.EventListener;
+import de.uniba.wiai.lspi.puppetor.EventManager;
+import de.uniba.wiai.lspi.puppetor.HiddenService;
+import de.uniba.wiai.lspi.puppetor.HiddenServiceEventType;
+import de.uniba.wiai.lspi.puppetor.Network;
+import de.uniba.wiai.lspi.puppetor.NetworkFactory;
+import de.uniba.wiai.lspi.puppetor.ProxyNode;
+import de.uniba.wiai.lspi.puppetor.PuppeTorException;
+import de.uniba.wiai.lspi.puppetor.ServerApplication;
+import de.uniba.wiai.lspi.puppetor.rmi.impl.AbstractTaskImpl;
+
+public class AddHiddenServiceTask extends AbstractTaskImpl {
+	/**
+	 * Required for serialization. Needs to change for new released versions.
+	 */
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * The name of this tor node.
+	 */
+	private final String nodeName;
+	
+	public AddHiddenServiceTask(final int id, final String networkName,
+			final String nodeName) {
+		super(id, networkName);
+		this.nodeName = nodeName;
+	}
+
+	@Override
+	public void execute() throws InterruptedException, RemoteException {
+		final Network network = NetworkFactory.getNetworkByName(name);
+		ProxyNode node = network.getNode(nodeName);
+		try {
+			// add hidden service
+			final HiddenService hidServ = node.addHiddenService("hidServ");
+			node.writeConfiguration();
+			node.hup();
+			final EventManager manager = network.getEventManager();
+	
+			// wait for 6 minutes that the proxy has published its first RSD
+			if (!manager.waitForAnyOccurence(node.getNodeName(),
+					HiddenServiceEventType.BOB_DESC_PUBLISHED_RECEIVED,
+					6L * 60L * 1000L)) {
+				// failed to publish an RSD
+				reportResult(false);
+				return;
+			}
+	
+			// create server application
+			final ServerApplication server =
+					network.createServer("server", hidServ.getServicePort());
+	
+			// create client application, pick one of the nodes.
+			// XXX fix this so we can choose which node we want. -SH
+			Set<String> nodes = network.getAllNodes().keySet();
+			String[] localNodeNames = new String[10];
+			localNodeNames = nodes.toArray(localNodeNames);
+			final ClientApplication client =
+					network.createClient("client",
+							hidServ.determineOnionAddress(), hidServ
+									.getVirtualPort(), network.getNode(localNodeNames[0]).getSocksPort());
+	
+			// register event listener
+			final EventListener clientAndServerEventListener = new EventListener() {
+				public void handleEvent(Event event) {
+					// XXX log -SH
+				}
+			};
+			manager.addEventListener(client.getClientApplicationName(),
+					clientAndServerEventListener);
+			manager.addEventListener(server.getServerApplicationName(),
+					clientAndServerEventListener);
+	
+			// start server
+			server.startListening();
+	
+			// perform at most five request with a timeout of 45 seconds each
+			client.startRequests(5, 45000, true);
+	
+			// wait for request to be performed
+			manager.waitForAnyOccurence(client.getClientApplicationName(),
+					ClientEventType.CLIENT_REQUESTS_PERFORMED);
+			reportResult(true);
+			} catch (final PuppeTorException e) {
+			e.printStackTrace();
+			reportResult(false);
+		}
+
+
+	}
+
+}

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/ConfigureAsPrivateTask.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/ConfigureAsPrivateTask.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/ConfigureAsPrivateTask.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2008, Sebastian Hahn
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.uniba.wiai.lspi.puppetor.rmi.tasks;
+
+import java.rmi.RemoteException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import de.uniba.wiai.lspi.puppetor.Network;
+import de.uniba.wiai.lspi.puppetor.NetworkFactory;
+import de.uniba.wiai.lspi.puppetor.PuppeTorException;
+import de.uniba.wiai.lspi.puppetor.rmi.impl.AbstractTaskImpl;
+
+public class ConfigureAsPrivateTask extends AbstractTaskImpl {
+
+	/**
+	 * Required for serialization. Needs to change for new released versions.
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	final List<String> authorityInformation = new LinkedList<String>();
+
+	public ConfigureAsPrivateTask(final int id, final String networkName) {
+		super(id, networkName);
+	}
+
+	@Override
+	public void execute() throws InterruptedException, RemoteException {
+		final Network network = NetworkFactory.getNetworkByName(name);
+		network.configureAsPartOfPrivateNetwork(authorityInformation);
+		try {
+			network.writeConfigurations();
+			reportResult(true);
+		} catch (final PuppeTorException e) {
+			e.printStackTrace();
+			reportResult(false);
+		}
+	}
+	
+	@Override
+	public void addAdditionalInformation(
+			Collection<String> additionalInformation) {
+		authorityInformation.addAll(additionalInformation);
+	}
+}
\ No newline at end of file

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateDirectoryAuthorityTask.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateDirectoryAuthorityTask.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateDirectoryAuthorityTask.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -33,6 +33,7 @@
 
 import java.rmi.RemoteException;
 
+import de.uniba.wiai.lspi.puppetor.DirectoryNode;
 import de.uniba.wiai.lspi.puppetor.Network;
 import de.uniba.wiai.lspi.puppetor.NetworkFactory;
 import de.uniba.wiai.lspi.puppetor.PuppeTorException;
@@ -46,7 +47,7 @@
 	private static final long serialVersionUID = 1L;
 
 	/**
-	 * The name of this tor authority.
+	 * The name of this Tor authority.
 	 */
 	private final String authorityName;
 
@@ -59,16 +60,14 @@
 	@Override
 	public void execute() throws InterruptedException, RemoteException {
 		final Network network = NetworkFactory.getNetworkByName(name);
-		network.createDirectory(authorityName);
-
+		DirectoryNode node = network.createDirectory(authorityName);
 		// write configuration of proxy node
 		try {
 			network.writeConfigurations();
-			System.out.println("wrote authority configuration");
+			reportResult(true, node.getDirServerString());
 		} catch (final PuppeTorException e) {
 			e.printStackTrace();
 			reportResult(false);
 		}
-		reportResult(true);
 	}
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateProxyTask.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateProxyTask.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateProxyTask.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -64,12 +64,10 @@
 		// write configuration of proxy node
 		try {
 			network.writeConfigurations();
-			System.out.println("wrote proxy configuration");
+			reportResult(true);
 		} catch (final PuppeTorException e) {
 			e.printStackTrace();
 			reportResult(false);
 		}
-		reportResult(true);
 	}
-
 }

Modified: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateRouterTask.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateRouterTask.java	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tasks/CreateRouterTask.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -63,11 +63,11 @@
 		// write configuration of router node
 		try {
 			network.writeConfigurations();
-			System.out.println("wrote authority configuration");
+			reportResult(true);
 		} catch (final PuppeTorException e) {
 			e.printStackTrace();
 			reportResult(false);
 		}
-		reportResult(true);
+
 	}
 }

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/AccessGoogleOverPublicTorNetwork.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/AccessGoogleOverPublicTorNetwork.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/AccessGoogleOverPublicTorNetwork.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008, Sebastian Hahn
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.uniba.wiai.lspi.puppetor.rmi.tests;
+
+import java.util.Set;
+
+import de.uniba.wiai.lspi.puppetor.rmi.Network;
+import de.uniba.wiai.lspi.puppetor.rmi.TaskExecutionNotSuccessfulException;
+import de.uniba.wiai.lspi.puppetor.rmi.TorInstance;
+import de.uniba.wiai.lspi.puppetor.rmi.impl.AbstractTestImpl;
+import de.uniba.wiai.lspi.puppetor.rmi.impl.NetworkDescriptionImpl;
+import de.uniba.wiai.lspi.puppetor.rmi.tasks.AccessGoogleTask;
+
+public class AccessGoogleOverPublicTorNetwork extends AbstractTestImpl {
+	/**
+	 * Required for serialization. Needs to change for new released versions.
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	public AccessGoogleOverPublicTorNetwork() {
+		super("Use the public Tor network to connect to google.com and wait" +
+				" for a response", new NetworkDescriptionImpl(1, 0, 0));
+	}
+
+	public void doTest() {
+		Network nw = exec.getCurrentNetwork();
+		Set<TorInstance> proxies = nw.getProxies();
+		try {
+			exec.executeTaskForTorInstances(proxies, AccessGoogleTask.class, null, null);
+			System.out.println("Accessing google succeeded");
+		} catch (TaskExecutionNotSuccessfulException e) {
+			System.out.println("Accessing google failed");
+			// Log this properly, especially where we failed
+		}
+	}
+}
\ No newline at end of file

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/StartingAndAccessingHiddenServiceOverPrivateTorNetworkTest.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/StartingAndAccessingHiddenServiceOverPrivateTorNetworkTest.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/StartingAndAccessingHiddenServiceOverPrivateTorNetworkTest.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008, Sebastian Hahn
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.uniba.wiai.lspi.puppetor.rmi.tests;
+
+import java.util.Set;
+
+import de.uniba.wiai.lspi.puppetor.rmi.Network;
+import de.uniba.wiai.lspi.puppetor.rmi.TaskExecutionNotSuccessfulException;
+import de.uniba.wiai.lspi.puppetor.rmi.TorInstance;
+import de.uniba.wiai.lspi.puppetor.rmi.impl.AbstractTestImpl;
+import de.uniba.wiai.lspi.puppetor.rmi.impl.NetworkDescriptionImpl;
+import de.uniba.wiai.lspi.puppetor.rmi.tasks.AddHiddenServiceTask;
+
+public class StartingAndAccessingHiddenServiceOverPrivateTorNetworkTest extends
+		AbstractTestImpl {
+	/**
+	 * Required for serialization. Needs to change for new released versions.
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	public StartingAndAccessingHiddenServiceOverPrivateTorNetworkTest() {
+		super("Create a private Tor network, set up a hidden service, " +
+				"and access it", new NetworkDescriptionImpl(1, 3, 2));
+	}
+	
+	public void doTest() {
+		Network nw = exec.getCurrentNetwork();
+		Set<TorInstance> proxies = nw.getProxiesOnly();
+		try {
+			exec.executeTaskForTorInstances(proxies, AddHiddenServiceTask.class, null, null);
+			System.out.println("Accessing the hidden service succeeded.");
+		} catch (TaskExecutionNotSuccessfulException e) {
+			System.out.println("Accessing the hidden service failed.");
+			// Log this properly, especially where we failed
+		}
+	}
+}

Added: puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/TestRegistration.java
===================================================================
--- puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/TestRegistration.java	                        (rev 0)
+++ puppetor/branches/gsoc2008/src/de/uniba/wiai/lspi/puppetor/rmi/tests/TestRegistration.java	2008-08-18 17:24:21 UTC (rev 16587)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008, Sebastian Hahn
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package de.uniba.wiai.lspi.puppetor.rmi.tests;
+
+import de.uniba.wiai.lspi.puppetor.rmi.TestExecutor;
+
+public class TestRegistration {
+
+	private static TestRegistration instance = new TestRegistration();
+	
+	public void registerTests(TestExecutor testExecutor) {
+		testExecutor.registerTest(new AccessGoogleOverPublicTorNetwork());
+		testExecutor.registerTest(new
+				StartingAndAccessingHiddenServiceOverPrivateTorNetworkTest());
+	}
+	
+	/**
+	 * Singleton
+	 */
+	private TestRegistration() {}
+	
+	/**
+	 * @return
+	 * 		the <code>TestRegistration</code> instance.
+	 */
+	public static TestRegistration getInstance() {
+		return instance;
+	}
+
+}

Modified: puppetor/branches/gsoc2008/tools/create_keystores.sh
===================================================================
--- puppetor/branches/gsoc2008/tools/create_keystores.sh	2008-08-18 16:46:31 UTC (rev 16586)
+++ puppetor/branches/gsoc2008/tools/create_keystores.sh	2008-08-18 17:24:21 UTC (rev 16587)
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 # The number of slaves you want to use
-NUM_SLAVES=3
+NUM_SLAVES=2
 
 # How many days do you want the created certificates to be valid?
 DAYS_OF_VALIDITY=1000



More information about the tor-commits mailing list