Author: toad
Date: 2008-08-08 23:21:35 +0000 (Fri, 08 Aug 2008)
New Revision: 21681

Added:
   trunk/freenet/src/freenet/node/simulator/BootstrapPullTest.java
Log:
Another tester, this time we insert through a well-established node via FCP, 
and then pull via a bootstrapped newbie node.


Added: trunk/freenet/src/freenet/node/simulator/BootstrapPullTest.java
===================================================================
--- trunk/freenet/src/freenet/node/simulator/BootstrapPullTest.java             
                (rev 0)
+++ trunk/freenet/src/freenet/node/simulator/BootstrapPullTest.java     
2008-08-08 23:21:35 UTC (rev 21681)
@@ -0,0 +1,198 @@
+package freenet.node.simulator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.InetAddress;
+import java.net.Socket;
+
+import org.spaceroots.mantissa.random.MersenneTwister;
+
+import freenet.client.FetchException;
+import freenet.client.HighLevelSimpleClient;
+import freenet.crypt.RandomSource;
+import freenet.keys.FreenetURI;
+import freenet.node.Node;
+import freenet.node.NodeCrypto;
+import freenet.node.NodeInitException;
+import freenet.node.NodeStarter;
+import freenet.support.Logger;
+import freenet.support.PooledExecutor;
+import freenet.support.SimpleFieldSet;
+import freenet.support.TimeUtil;
+import freenet.support.LoggerHook.InvalidThresholdException;
+import freenet.support.io.FileUtil;
+import freenet.support.io.LineReadingInputStream;
+
+/**
+ * Insert a random block of data to an established node via FCP, then
+ * bootstrap a newbie node and pull it from that.
+ * @author Matthew Toseland <toad at amphibian.dyndns.org> (0xE43DA450)
+ */
+public class BootstrapPullTest {
+
+       public static int TARGET_PEERS = 10;
+       public static int TEST_SIZE = 1024*1024;
+       
+       public static int EXIT_NO_SEEDNODES = 257;
+       public static int EXIT_FAILED_TARGET = 258;
+       public static int EXIT_INSERT_FAILED = 259;
+       public static int EXIT_FETCH_FAILED = 260;
+       public static int EXIT_INSERTER_PROBLEM = 261;
+       
+       public static int DARKNET_PORT = 5004;
+       public static int OPENNET_PORT = 5005;
+       
+       /**
+        * @param args
+        * @throws InvalidThresholdException 
+        * @throws IOException 
+        * @throws NodeInitException 
+        * @throws InterruptedException 
+        */
+       public static void main(String[] args) throws 
InvalidThresholdException, IOException, NodeInitException, InterruptedException 
{
+        File dir = new File("bootstrap-pull-test");
+        FileUtil.removeAll(dir);
+        RandomSource random = NodeStarter.globalTestInit(dir.getPath(), false, 
Logger.ERROR, "");
+        byte[] seed = new byte[64];
+        random.nextBytes(seed);
+        MersenneTwister fastRandom = new MersenneTwister(seed);
+        File seednodes = new File("seednodes.fref");
+        if(!seednodes.exists() || seednodes.length() == 0 || 
!seednodes.canRead()) {
+               System.err.println("Unable to read seednodes.fref, it doesn't 
exist, or is empty");
+               System.exit(EXIT_NO_SEEDNODES);
+        }
+        File secondInnerDir = new File(dir, Integer.toString(DARKNET_PORT));
+        secondInnerDir.mkdir();
+        FileInputStream fis = new FileInputStream(seednodes);
+        FileUtil.writeTo(fis, new File(secondInnerDir, "seednodes.fref"));
+        fis.close();
+        NodeCrypto.DISABLE_GROUP_STRIP = true;
+        
+        // Create the test data
+        System.out.println("Creating test data.");
+        File dataFile = File.createTempFile("testdata", ".tmp", dir);
+        OutputStream os = new FileOutputStream(dataFile);
+        byte[] buf = new byte[4096];
+        for(long written = 0; written < TEST_SIZE;) {
+               fastRandom.nextBytes(buf);
+               int toWrite = (int) Math.min(TEST_SIZE - written, buf.length);
+               os.write(buf, 0, toWrite);
+               written += toWrite;
+        }
+        os.close();
+        
+        // Insert it to the established node.
+        System.out.println("Inserting test data to an established node.");
+        FreenetURI uri = insertData(dataFile);
+        
+        // Bootstrap a second node.
+        secondInnerDir.mkdir();
+        fis = new FileInputStream(seednodes);
+        FileUtil.writeTo(fis, new File(secondInnerDir, "seednodes.fref"));
+        fis.close();
+        PooledExecutor executor = new PooledExecutor();
+        Node secondNode = NodeStarter.createTestNode(DARKNET_PORT, 
OPENNET_PORT, dir.getPath(), true, false, false, Node.DEFAULT_MAX_HTL, 0, 
random, executor, 1000, 5*1024*1024, true, true, true, true, true, true, true, 
12*1024, false, true);        
+        secondNode.start(true);
+        waitForTenNodes(secondNode);
+        
+        // Fetch the data
+        long startFetchTime = System.currentTimeMillis();
+        HighLevelSimpleClient client = 
secondNode.clientCore.makeClient((short)0);
+        try {
+                       client.fetch(uri);
+               } catch (FetchException e) {
+                       System.err.println("FETCH FAILED: "+e);
+                       e.printStackTrace();
+                       System.exit(EXIT_FETCH_FAILED);
+                       return;
+               }
+               long endFetchTime = System.currentTimeMillis();
+               System.out.println("RESULT: Fetch took 
"+(endFetchTime-startFetchTime)+"ms 
("+TimeUtil.formatTime(endFetchTime-startFetchTime)+") of "+uri+" .");
+               secondNode.park();
+               System.exit(0);
+
+       }
+
+       private static FreenetURI insertData(File dataFile) throws IOException {
+        long startInsertTime = System.currentTimeMillis();
+        InetAddress localhost = InetAddress.getByName("127.0.0.1");
+        Socket sock = new Socket(localhost, 9481);
+        OutputStream sockOS = sock.getOutputStream();
+        InputStream sockIS = sock.getInputStream();
+        System.out.println("Connected to node.");
+        LineReadingInputStream lis = new LineReadingInputStream(sockIS);
+        OutputStreamWriter osw = new OutputStreamWriter(sockOS, "UTF-8");
+        
osw.write("ClientHello\nExpectedVersion=0.7\nName=BootstrapPullTest-"+System.currentTimeMillis()+"\nEnd\n");
+        osw.flush();
+               String name = lis.readLine(65536, 128, true);
+               SimpleFieldSet fs = new SimpleFieldSet(lis, 65536, 128, true, 
true, false, true);
+               if(!name.equals("NodeHello")) {
+                       System.err.println("No NodeHello from insertor node!");
+                       System.exit(EXIT_INSERTER_PROBLEM);
+               }
+               System.out.println("Connected to "+sock);
+               
osw.write("ClientPut\nIdentifier=test-insert\nURI=CHK@\nVerbosity=1023\nUploadFrom=direct\nMaxRetries=-1\nDataLength="+TEST_SIZE+"\nData\n");
+               osw.flush();
+               InputStream is = new FileInputStream(dataFile);
+               FileUtil.copy(is, sockOS, TEST_SIZE);
+               System.out.println("Sent data");
+               while(true) {
+               name = lis.readLine(65536, 128, true);
+               fs = new SimpleFieldSet(lis, 65536, 128, true, true, false, 
true);
+                       System.out.println("Got FCP message: \n"+name);
+                       System.out.print(fs.toOrderedString());
+                       if(name.equals("ProtocolError")) {
+                               System.err.println("Protocol error when 
inserting data.");
+                               System.exit(EXIT_INSERTER_PROBLEM);
+                       }
+                       if(name.equals("PutFailed")) {
+                               System.err.println("Insert failed");
+                               System.exit(EXIT_INSERT_FAILED);
+                       }
+                       if(name.equals("PutSuccessful")) {
+                       long endInsertTime = System.currentTimeMillis();
+                               FreenetURI uri = new FreenetURI(fs.get("URI"));
+                       System.out.println("RESULT: Insert took 
"+(endInsertTime-startInsertTime)+"ms 
("+TimeUtil.formatTime(endInsertTime-startInsertTime)+") to "+uri+" .");
+                               sockOS.close();
+                               sockIS.close();
+                               sock.close();
+                               return uri;
+                       }
+               }
+       }
+       
+       private static void waitForTenNodes(Node node) throws 
InterruptedException {
+       long startTime = System.currentTimeMillis();
+        // Wait until we have 10 connected nodes...
+        int seconds = 0;
+        boolean success = false;
+        while(seconds < 600) {
+               Thread.sleep(1000);
+               int seeds = node.peers.countSeednodes();
+               int seedConns = 
node.peers.getConnectedSeedServerPeersVector(null).size();
+               int opennetPeers = node.peers.countValidPeers();
+               int opennetConns = node.peers.countConnectedOpennetPeers();
+               System.err.println(""+seconds+" : seeds: "+seeds+", connected: 
"+seedConns
+                               +" opennet: peers: "+opennetPeers+", connected: 
"+opennetConns);
+               seconds++;
+               if(opennetConns >= TARGET_PEERS) {
+                       long timeTaken = System.currentTimeMillis()-startTime;
+                       System.out.println("RESULT: Completed bootstrap 
("+TARGET_PEERS+" peers) in "+timeTaken+"ms 
("+TimeUtil.formatTime(timeTaken)+")");
+                       success = true;
+                       break;
+               }
+        }
+        if(!success) {
+               System.err.println("Failed to reach target peers count 
"+TARGET_PEERS+" in 10 minutes.");
+               node.park();
+               System.exit(EXIT_FAILED_TARGET);
+        }
+       }
+
+
+}


Reply via email to