[freenet-cvs] r11378 - in trunk/freenet: . src test test/freenet test/freenet/io
nextgens at freenetproject.org
nextgens at freenetproject.org
Wed Dec 13 19:38:16 UTC 2006
Author: nextgens
Date: 2006-12-13 19:38:15 +0000 (Wed, 13 Dec 2006)
New Revision: 11378
Added:
trunk/freenet/test/
trunk/freenet/test/DatastoreTest.java
trunk/freenet/test/PaddingSpeedTest.java
trunk/freenet/test/PingTest.java
trunk/freenet/test/PreNodeTest.java
trunk/freenet/test/PreQuasiNodeTest.java
trunk/freenet/test/QuasiNodeTest.java
trunk/freenet/test/TransferBlockTest.java
trunk/freenet/test/TransferSendTest.java
trunk/freenet/test/freenet/
trunk/freenet/test/freenet/io/
trunk/freenet/test/freenet/io/AddressIdentifierTest.java
trunk/freenet/test/freenet/io/Inet4AddressMatcherTest.java
trunk/freenet/test/freenet/io/Inet6AddressMatcherTest.java
Removed:
trunk/freenet/src/test/
trunk/freenet/test/AddressIdentifierTest.java
trunk/freenet/test/DatastoreTest.java
trunk/freenet/test/Inet4AddressMatcherTest.java
trunk/freenet/test/Inet6AddressMatcherTest.java
trunk/freenet/test/PaddingSpeedTest.java
trunk/freenet/test/PingTest.java
trunk/freenet/test/PreNodeTest.java
trunk/freenet/test/PreQuasiNodeTest.java
trunk/freenet/test/QuasiNodeTest.java
trunk/freenet/test/TransferBlockTest.java
trunk/freenet/test/TransferSendTest.java
Modified:
trunk/freenet/build.xml
Log:
Set up basic unit testing on a few classes : most of the tests have been written by Bombe
Modified: trunk/freenet/build.xml
===================================================================
--- trunk/freenet/build.xml 2006-12-13 19:33:17 UTC (rev 11377)
+++ trunk/freenet/build.xml 2006-12-13 19:38:15 UTC (rev 11378)
@@ -9,7 +9,10 @@
<!-- set global properties for this build -->
<property name="src" location="src"/>
+ <property name="test" location="test"/>
<property name="build" location="build"/>
+ <property name="build-test" location="build-test"/>
+ <property name="test-results" location="test-results"/>
<property name="lib" location="lib"/>
<property name="freenet-ext.location" location="${lib}/freenet-ext.jar"/>
<property name="javadoc" location="javadoc"/>
@@ -20,6 +23,8 @@
<target name="mkdir">
<mkdir dir="${build}"/>
+ <mkdir dir="${build-test}"/>
+ <mkdir dir="${test-results}"/>
<mkdir dir="${lib}"/>
</target>
@@ -48,6 +53,7 @@
</target>
<!-- ================================================== -->
+
<target name="compile" depends="get-extjar, generate-CSSTokenizerFilter">
<!-- Create the time stamp -->
<tstamp/>
@@ -83,7 +89,8 @@
<!-- ================================================== -->
- <target name="dist" depends="compile"
+
+ <target name="dist" depends="compile,unit"
description="generate the distribution" >
<!-- Create the distribution directory -->
<!--<mkdir dir="."/>-->
@@ -105,12 +112,44 @@
</target>
<!-- ================================================== -->
+
+ <target name="unit-build" depends="compile">
+ <javac srcdir="${test}" destdir="${build-test}" debug="off" optimize="on" source="1.4">
+ <classpath>
+ <pathelement path="${build}"/>
+ <pathelement location="${freenet-ext.location}"/>
+ </classpath>
+ <include name="**/*.java"/>
+ <exclude name="*.java"/>
+ </javac>
+ </target>
+
+ <target name="unit" depends="unit-build">
+ <junit printsummary="yes" fork="yes" haltonfailure="yes">
+ <classpath>
+ <pathelement path="${build}"/>
+ <pathelement path="${build-test}"/>
+ </classpath>
+
+ <formatter type="plain"/>
+
+ <batchtest fork="yes" todir="${test-results}">
+ <fileset dir="${build-test}">
+ <include name="**/*.java"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <!-- ================================================== -->
+
<target name="clean" description="Delete class files and docs dir.">
<delete dir="${build}"/>
</target>
<target name="distclean" description="Delete class files, lib dir and docs dir.">
<delete file="${CSSTokenizerFilter.java}"/>
<delete dir="${build}"/>
+ <delete dir="${build-test}"/>
<delete dir="${lib}"/>
<delete dir="${javadoc}"/>
</target>
Copied: trunk/freenet/test (from rev 11374, trunk/freenet/src/test)
Deleted: trunk/freenet/test/AddressIdentifierTest.java
===================================================================
--- trunk/freenet/src/test/AddressIdentifierTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/AddressIdentifierTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,54 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package test;
-
-import junit.framework.TestCase;
-import freenet.io.AddressIdentifier;
-import freenet.io.AddressIdentifier.AddressType;
-
-/**
- * Test case for the {@link freenet.io.AddressIdentifier} class.
- *
- * @author David Roden <droden at gmail.com>
- * @version $Id$
- */
-public class AddressIdentifierTest extends TestCase {
-
- public void test() {
- /* test real IPv4 addresses */
- assertEquals(AddressType.IPv4, AddressIdentifier.getAddressType("0.0.0.0"));
- assertEquals(AddressType.IPv4, AddressIdentifier.getAddressType("127.0.0.1"));
- assertEquals(AddressType.IPv4, AddressIdentifier.getAddressType("255.255.255.255"));
- /* in case you didn't know: 183.24.17 = 183.24.0.17 */
- assertEquals(AddressType.IPv4, AddressIdentifier.getAddressType("183.24.17"));
- /* and 127.1 = 127.0.0.1 */
- assertEquals(AddressType.IPv4, AddressIdentifier.getAddressType("127.1"));
-
- /* test fake IPv4 addresses */
- assertEquals(AddressType.OTHER, AddressIdentifier.getAddressType("192.168.370.12"));
- assertEquals(AddressType.OTHER, AddressIdentifier.getAddressType("127.0.0.0.1"));
-
- /* test real unabridged IPv6 addresses */
- assertEquals(AddressType.IPv6, AddressIdentifier.getAddressType("0:0:0:0:0:0:0:1"));
- assertEquals(AddressType.IPv6, AddressIdentifier.getAddressType("fe80:0:0:0:203:dff:fe22:420f"));
-
- /* test fake IPv6 addresses */
- assertEquals(AddressType.OTHER, AddressIdentifier.getAddressType("1:2:3:4:5:6:7:8:9"));
- assertEquals(AddressType.OTHER, AddressIdentifier.getAddressType("12345:6:7:8:9"));
- }
-
-}
Deleted: trunk/freenet/test/DatastoreTest.java
===================================================================
--- trunk/freenet/src/test/DatastoreTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/DatastoreTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,121 +0,0 @@
-package test;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-
-import freenet.keys.CHKDecodeException;
-import freenet.keys.CHKEncodeException;
-import freenet.keys.CHKVerifyException;
-import freenet.keys.ClientCHK;
-import freenet.keys.CHKBlock;
-import freenet.keys.ClientCHKBlock;
-import freenet.keys.FreenetURI;
-import freenet.store.FreenetStore;
-import freenet.support.Logger;
-
-/**
- * Create, or load, a datastore.
- * Command line interface, to do either:
- * a) Enter data, is encoded, store in datastore, return key.
- * b) Retrieve data by key.
- */
-public class DatastoreTest {
-
- public static void main(String[] args) throws Exception {
- // Setup datastore
- FreenetStore fs = new FreenetStore("datastore", "headerstore", 1024);
- // Setup logging
- Logger.setupStdoutLogging(Logger.DEBUG, "");
- printHeader();
- // Read command, and data
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- while(true) {
- String line = reader.readLine();
- if(line.toUpperCase().startsWith("GET:")) {
- // Should have a key next
- String key = line.substring("GET:".length());
- while(key.length() > 0 && key.charAt(0) == ' ')
- key = key.substring(1);
- while(key.length() > 0 && key.charAt(key.length()-1) == ' ')
- key = key.substring(0, key.length()-2);
- Logger.normal(DatastoreTest.class, "Key: "+key);
- FreenetURI uri = new FreenetURI(key);
- ClientCHK chk = new ClientCHK(uri);
- CHKBlock block;
- try {
- block = fs.fetch(chk.getNodeCHK());
- } catch (CHKVerifyException e1) {
- Logger.error(DatastoreTest.class, "Did not verify: "+e1, e1);
- continue;
- }
- if(block == null) {
- System.out.println("Not found in store: "+chk.getURI());
- } else {
- // Decode it
- byte[] decoded;
- try {
- decoded = block.decode(chk);
- } catch (CHKDecodeException e) {
- Logger.error(DatastoreTest.class, "Cannot decode: "+e, e);
- continue;
- }
- System.out.println("Decoded data:\n");
- System.out.println(new String(decoded));
- }
- } else if(line.toUpperCase().startsWith("QUIT")) {
- System.out.println("Goodbye.");
- System.exit(0);
- } else if(line.toUpperCase().startsWith("PUT:")) {
- line = line.substring("PUT:".length());
- while(line.length() > 0 && line.charAt(0) == ' ')
- line = line.substring(1);
- while(line.length() > 0 && line.charAt(line.length()-1) == ' ')
- line = line.substring(0, line.length()-2);
- String content;
- if(line.length() > 0) {
- // Single line insert
- content = line;
- } else {
- // Multiple line insert
- StringBuffer sb = new StringBuffer(1000);
- while(true) {
- line = reader.readLine();
- if(line.equals(".")) break;
- sb.append(line).append('\n');
- }
- content = sb.toString();
- }
- // Insert
- byte[] data = content.getBytes();
- ClientCHKBlock block;
- try {
- block = ClientCHKBlock.encode(data);
- } catch (CHKEncodeException e) {
- Logger.error(DatastoreTest.class, "Couldn't encode: "+e, e);
- continue;
- }
- ClientCHK chk = block.getClientKey();
- FreenetURI uri =
- chk.getURI();
- fs.put(block);
- // Definitely interface
- System.out.println("URI: "+uri);
- } else {
-
- }
- }
- }
-
- private static void printHeader() {
- // Write header
- System.out.println("Datastore tester");
- System.out.println("----------------");
- System.out.println();
- System.out.println("Enter one of the following commands:");
- System.out.println("FETCH:<Freenet key> - fetch a key from the store");
- System.out.println("PUT:\n<text, until a . on a line by itself> - We will insert the document and return the key.");
- System.out.println("PUT:<text> - put a single line of text to a CHK and return the key.");
- System.out.println("QUIT - exit the program");
- }
-}
Copied: trunk/freenet/test/DatastoreTest.java (from rev 11377, trunk/freenet/src/test/DatastoreTest.java)
===================================================================
--- trunk/freenet/test/DatastoreTest.java (rev 0)
+++ trunk/freenet/test/DatastoreTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -0,0 +1,121 @@
+package test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import freenet.keys.CHKDecodeException;
+import freenet.keys.CHKEncodeException;
+import freenet.keys.CHKVerifyException;
+import freenet.keys.ClientCHK;
+import freenet.keys.CHKBlock;
+import freenet.keys.ClientCHKBlock;
+import freenet.keys.FreenetURI;
+import freenet.store.FreenetStore;
+import freenet.support.Logger;
+
+/**
+ * Create, or load, a datastore.
+ * Command line interface, to do either:
+ * a) Enter data, is encoded, store in datastore, return key.
+ * b) Retrieve data by key.
+ */
+public class DatastoreTest {
+
+ public static void main(String[] args) throws Exception {
+ // Setup datastore
+ FreenetStore fs = new FreenetStore("datastore", "headerstore", 1024);
+ // Setup logging
+ Logger.setupStdoutLogging(Logger.DEBUG, "");
+ printHeader();
+ // Read command, and data
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ while(true) {
+ String line = reader.readLine();
+ if(line.toUpperCase().startsWith("GET:")) {
+ // Should have a key next
+ String key = line.substring("GET:".length());
+ while(key.length() > 0 && key.charAt(0) == ' ')
+ key = key.substring(1);
+ while(key.length() > 0 && key.charAt(key.length()-1) == ' ')
+ key = key.substring(0, key.length()-2);
+ Logger.normal(DatastoreTest.class, "Key: "+key);
+ FreenetURI uri = new FreenetURI(key);
+ ClientCHK chk = new ClientCHK(uri);
+ CHKBlock block;
+ try {
+ block = fs.fetch(chk.getNodeCHK());
+ } catch (CHKVerifyException e1) {
+ Logger.error(DatastoreTest.class, "Did not verify: "+e1, e1);
+ continue;
+ }
+ if(block == null) {
+ System.out.println("Not found in store: "+chk.getURI());
+ } else {
+ // Decode it
+ byte[] decoded;
+ try {
+ decoded = block.decode(chk);
+ } catch (CHKDecodeException e) {
+ Logger.error(DatastoreTest.class, "Cannot decode: "+e, e);
+ continue;
+ }
+ System.out.println("Decoded data:\n");
+ System.out.println(new String(decoded));
+ }
+ } else if(line.toUpperCase().startsWith("QUIT")) {
+ System.out.println("Goodbye.");
+ System.exit(0);
+ } else if(line.toUpperCase().startsWith("PUT:")) {
+ line = line.substring("PUT:".length());
+ while(line.length() > 0 && line.charAt(0) == ' ')
+ line = line.substring(1);
+ while(line.length() > 0 && line.charAt(line.length()-1) == ' ')
+ line = line.substring(0, line.length()-2);
+ String content;
+ if(line.length() > 0) {
+ // Single line insert
+ content = line;
+ } else {
+ // Multiple line insert
+ StringBuffer sb = new StringBuffer(1000);
+ while(true) {
+ line = reader.readLine();
+ if(line.equals(".")) break;
+ sb.append(line).append('\n');
+ }
+ content = sb.toString();
+ }
+ // Insert
+ byte[] data = content.getBytes();
+ ClientCHKBlock block;
+ try {
+ block = ClientCHKBlock.encode(data);
+ } catch (CHKEncodeException e) {
+ Logger.error(DatastoreTest.class, "Couldn't encode: "+e, e);
+ continue;
+ }
+ ClientCHK chk = block.getClientKey();
+ FreenetURI uri =
+ chk.getURI();
+ fs.put(block);
+ // Definitely interface
+ System.out.println("URI: "+uri);
+ } else {
+
+ }
+ }
+ }
+
+ private static void printHeader() {
+ // Write header
+ System.out.println("Datastore tester");
+ System.out.println("----------------");
+ System.out.println();
+ System.out.println("Enter one of the following commands:");
+ System.out.println("FETCH:<Freenet key> - fetch a key from the store");
+ System.out.println("PUT:\n<text, until a . on a line by itself> - We will insert the document and return the key.");
+ System.out.println("PUT:<text> - put a single line of text to a CHK and return the key.");
+ System.out.println("QUIT - exit the program");
+ }
+}
Deleted: trunk/freenet/test/Inet4AddressMatcherTest.java
===================================================================
--- trunk/freenet/src/test/Inet4AddressMatcherTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/Inet4AddressMatcherTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,74 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package freenet.io;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-
-import freenet.io.Inet4AddressMatcher;
-
-import junit.framework.TestCase;
-
-/**
- * @author David Roden <droden at gmail.com>
- * @version $Id$
- */
-public class Inet4AddressMatcherTest extends TestCase {
-
- public void test() throws Exception {
- Inet4AddressMatcher matcher = new Inet4AddressMatcher("192.168.1.2");
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("192.168.1.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.168.1.2")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("127.0.0.1")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("0.0.0.0")));
-
- matcher = new Inet4AddressMatcher("192.168.1.2/8");
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.168.1.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.168.1.2")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.168.2.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.16.81.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.255.255.255")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("172.16.1.1")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("127.0.0.1")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("0.0.0.0")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.0.0.0")));
-
- /* some fancy matching */
- matcher = new Inet4AddressMatcher("192.168.1.1/255.0.255.0");
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.168.1.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.16.1.1")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("192.168.2.1")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("192.16.2.1")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("127.0.0.1")));
-
- matcher = new Inet4AddressMatcher("127.0.0.1/8");
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("127.0.0.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("127.23.42.64")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("127.0.0.0")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("127.255.255.255")));
- assertEquals(false, matcher.matches((Inet4Address) InetAddress.getByName("28.0.0.1")));
-
- matcher = new Inet4AddressMatcher("0.0.0.0/0");
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("127.0.0.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.168.1.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("192.168.2.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("172.16.42.23")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("10.0.0.1")));
- assertEquals(true, matcher.matches((Inet4Address) InetAddress.getByName("224.0.0.1")));
- }
-
-}
Deleted: trunk/freenet/test/Inet6AddressMatcherTest.java
===================================================================
--- trunk/freenet/src/test/Inet6AddressMatcherTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/Inet6AddressMatcherTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,65 +0,0 @@
-/*
- * freenet0.7 -
- * Copyright (C) 2006 David Roden
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-package test;
-
-import java.net.InetAddress;
-
-import junit.framework.TestCase;
-import freenet.io.Inet6AddressMatcher;
-
-/**
- * Test case for the {@link freenet.io.Inet6AddressMatcher} class. Contains some
- * very basic tests. Feel free to add more complicated tests!
- *
- * @author David Roden <droden at gmail.com>
- * @version $Id$
- */
-public class Inet6AddressMatcherTest extends TestCase {
-
- public void test() throws Exception {
- Inet6AddressMatcher matcher = new Inet6AddressMatcher("0:0:0:0:0:0:0:0/0");
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:203:dff:fe22:420f")));
-
- matcher = new Inet6AddressMatcher("fe80:0:0:0:203:dff:fe22:420f/64");
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:203:dff:fe22:420f")));
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:0203:0dff:fe22:420f")));
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:0204:0dff:fe22:420f")));
- assertEquals(false, matcher.matches(InetAddress.getByName("fe81:0:0:0:0203:0dff:fe22:420f")));
- assertEquals(false, matcher.matches(InetAddress.getByName("0:0:0:0:0:0:0:1")));
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:0:0:0:1")));
-
- matcher = new Inet6AddressMatcher("fe80:0:0:0:203:dff:fe22:420f/ffff:ffff:ffff:ffff:0:0:0:0");
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:203:dff:fe22:420f")));
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:0203:0dff:fe22:420f")));
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:0204:0dff:fe22:420f")));
- assertEquals(false, matcher.matches(InetAddress.getByName("fe81:0:0:0:0203:0dff:fe22:420f")));
- assertEquals(false, matcher.matches(InetAddress.getByName("0:0:0:0:0:0:0:1")));
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:0:0:0:1")));
-
- matcher = new Inet6AddressMatcher("fe80:0:0:0:203:dff:fe22:420f/128");
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:203:dff:fe22:420f")));
- assertEquals(true, matcher.matches(InetAddress.getByName("fe80:0:0:0:0203:0dff:fe22:420f")));
- assertEquals(false, matcher.matches(InetAddress.getByName("fe80:0:0:0:0204:0dff:fe22:420f")));
- assertEquals(false, matcher.matches(InetAddress.getByName("fe81:0:0:0:0203:0dff:fe22:420f")));
- assertEquals(false, matcher.matches(InetAddress.getByName("0:0:0:0:0:0:0:1")));
- assertEquals(false, matcher.matches(InetAddress.getByName("fe80:0:0:0:0:0:0:1")));
- }
-
-}
Deleted: trunk/freenet/test/PaddingSpeedTest.java
===================================================================
--- trunk/freenet/src/test/PaddingSpeedTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/PaddingSpeedTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,94 +0,0 @@
-package test;
-
-import java.security.DigestException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Random;
-
-import org.spaceroots.mantissa.random.MersenneTwister;
-
-import freenet.support.SizeUtil;
-
-/**
- * Test the speed of RNGs and hashes.
- */
-public class PaddingSpeedTest {
-
- public static void main(String[] args) throws NoSuchAlgorithmException, DigestException {
- MessageDigest md160 = MessageDigest.getInstance("SHA-1");
- MessageDigest md256 = MessageDigest.getInstance("SHA-256");
- MessageDigest md384 = MessageDigest.getInstance("SHA-384");
- MessageDigest md512 = MessageDigest.getInstance("SHA-512");
- MessageDigest[] mds = new MessageDigest[] { md160, md256, md384, md512 };
- int[] sizes = new int[] { 160, 256, 384, 512 };
- for(int i=0;i<4;i++) {
- long timeStart = System.currentTimeMillis();
- int bits = sizes[i];
- MessageDigest md = mds[i];
- System.out.println("Algorithm "+i+": "+bits+" bits");
- int bytes = bits/8;
- byte[] buf = new byte[bytes];
- for(int x=0;x<buf.length;x++) buf[x] = 0;
- for(int j=0;j<512;j++) {
- for(int k=0;k<1024;k++) {
- md.update(buf);
- md.digest(buf, 0, buf.length);
- }
- }
- long timeEnd = System.currentTimeMillis();
- long interval = timeEnd - timeStart;
- System.out.println("Total time: "+interval);
- int bytesTotal = 512 * 1024 * bytes;
- printStats("SHA-"+bits, bytesTotal, interval);
- }
- // And a plain RNG
- Random r = new Random();
- long l = 0;
- long timeStart = System.currentTimeMillis();
- for(int q=0;q<50;q++) {
- for(int i=0;i<1024;i++) {
- for(int j=0;j<1024;j++) {
- l = l ^ r.nextLong();
- }
- }
- }
- long timeEnd = System.currentTimeMillis();
- long interval = timeEnd - timeStart;
- int bytesTotal = 50 * 1024 * 1024 * 8;
- printStats("java.util.Random", bytesTotal, interval);
- // Now a more interesting RNG
- byte[] buf = new byte[32]; // init from SHA-256
- r.nextBytes(buf);
- int[] seed = new int[8];
- for(int i=0;i<8;i++) {
- int x = buf[i*4] & 0xff;
- x = x << 8 + (buf[i*4+1] & 0xff);
- x = x << 8 + (buf[i*4+2] & 0xff);
- x = x << 8 + (buf[i*4+3] & 0xff);
- seed[i] = x;
- }
- MersenneTwister mt;
- mt = new MersenneTwister(seed);
- timeStart = System.currentTimeMillis();
- for(int q=0;q<50;q++) {
- for(int i=0;i<1024;i++) {
- for(int j=0;j<1024;j++) {
- l = l ^ mt.nextLong();
- }
- }
- }
- timeEnd = System.currentTimeMillis();
- interval = timeEnd - timeStart;
- bytesTotal = 50 * 1024 * 1024 * 8;
- printStats("Mersenne Twister", bytesTotal, interval);
- }
-
- /**
- * @param bytesTotal
- * @param interval
- */
- private static void printStats(String name, int bytesTotal, long interval) {
- double rate = bytesTotal / ((double)interval/1000);
- System.out.println(name+": "+bytesTotal+" in "+interval+"ms = "+SizeUtil.formatSize((long)rate,false)+"/s");
- }
-}
Copied: trunk/freenet/test/PaddingSpeedTest.java (from rev 11377, trunk/freenet/src/test/PaddingSpeedTest.java)
===================================================================
--- trunk/freenet/test/PaddingSpeedTest.java (rev 0)
+++ trunk/freenet/test/PaddingSpeedTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -0,0 +1,94 @@
+package test;
+
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Random;
+
+import org.spaceroots.mantissa.random.MersenneTwister;
+
+import freenet.support.SizeUtil;
+
+/**
+ * Test the speed of RNGs and hashes.
+ */
+public class PaddingSpeedTest {
+
+ public static void main(String[] args) throws NoSuchAlgorithmException, DigestException {
+ MessageDigest md160 = MessageDigest.getInstance("SHA-1");
+ MessageDigest md256 = MessageDigest.getInstance("SHA-256");
+ MessageDigest md384 = MessageDigest.getInstance("SHA-384");
+ MessageDigest md512 = MessageDigest.getInstance("SHA-512");
+ MessageDigest[] mds = new MessageDigest[] { md160, md256, md384, md512 };
+ int[] sizes = new int[] { 160, 256, 384, 512 };
+ for(int i=0;i<4;i++) {
+ long timeStart = System.currentTimeMillis();
+ int bits = sizes[i];
+ MessageDigest md = mds[i];
+ System.out.println("Algorithm "+i+": "+bits+" bits");
+ int bytes = bits/8;
+ byte[] buf = new byte[bytes];
+ for(int x=0;x<buf.length;x++) buf[x] = 0;
+ for(int j=0;j<512;j++) {
+ for(int k=0;k<1024;k++) {
+ md.update(buf);
+ md.digest(buf, 0, buf.length);
+ }
+ }
+ long timeEnd = System.currentTimeMillis();
+ long interval = timeEnd - timeStart;
+ System.out.println("Total time: "+interval);
+ int bytesTotal = 512 * 1024 * bytes;
+ printStats("SHA-"+bits, bytesTotal, interval);
+ }
+ // And a plain RNG
+ Random r = new Random();
+ long l = 0;
+ long timeStart = System.currentTimeMillis();
+ for(int q=0;q<50;q++) {
+ for(int i=0;i<1024;i++) {
+ for(int j=0;j<1024;j++) {
+ l = l ^ r.nextLong();
+ }
+ }
+ }
+ long timeEnd = System.currentTimeMillis();
+ long interval = timeEnd - timeStart;
+ int bytesTotal = 50 * 1024 * 1024 * 8;
+ printStats("java.util.Random", bytesTotal, interval);
+ // Now a more interesting RNG
+ byte[] buf = new byte[32]; // init from SHA-256
+ r.nextBytes(buf);
+ int[] seed = new int[8];
+ for(int i=0;i<8;i++) {
+ int x = buf[i*4] & 0xff;
+ x = x << 8 + (buf[i*4+1] & 0xff);
+ x = x << 8 + (buf[i*4+2] & 0xff);
+ x = x << 8 + (buf[i*4+3] & 0xff);
+ seed[i] = x;
+ }
+ MersenneTwister mt;
+ mt = new MersenneTwister(seed);
+ timeStart = System.currentTimeMillis();
+ for(int q=0;q<50;q++) {
+ for(int i=0;i<1024;i++) {
+ for(int j=0;j<1024;j++) {
+ l = l ^ mt.nextLong();
+ }
+ }
+ }
+ timeEnd = System.currentTimeMillis();
+ interval = timeEnd - timeStart;
+ bytesTotal = 50 * 1024 * 1024 * 8;
+ printStats("Mersenne Twister", bytesTotal, interval);
+ }
+
+ /**
+ * @param bytesTotal
+ * @param interval
+ */
+ private static void printStats(String name, int bytesTotal, long interval) {
+ double rate = bytesTotal / ((double)interval/1000);
+ System.out.println(name+": "+bytesTotal+" in "+interval+"ms = "+SizeUtil.formatSize((long)rate,false)+"/s");
+ }
+}
Deleted: trunk/freenet/test/PingTest.java
===================================================================
--- trunk/freenet/src/test/PingTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/PingTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,75 +0,0 @@
-package test;
-
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-
-import freenet.io.comm.Dispatcher;
-import freenet.io.comm.DumpDispatcher;
-import freenet.io.comm.Message;
-import freenet.io.comm.Peer;
-import freenet.io.comm.UdpSocketManager;
-import freenet.io.comm.DMT;
-import freenet.io.comm.MessageFilter;
-
-/**
- * Ping test.
- * Just me getting used to the Dijjer-derived messaging system really.
- * Takes two parameters: ourPort and hisPort.
- * Sends a ping message every second.
- * Prints out whenever we receive a ping message.
- * @author amphibian
- */
-public class PingTest {
-
-
- /**
- * @author root
- *
- * TODO To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
- */
- public static class PingingDispatcher implements Dispatcher {
- public boolean handleMessage(Message m) {
- if(m.getSpec() == DMT.ping) {
- usm.send(m.getSource(), DMT.createPong(m));
- return true;
- }
- return false;
- }
- }
-
- static UdpSocketManager usm;
-
- public PingTest() {
- // not much to initialize
- super();
- }
-
- public static void main(String[] args) throws SocketException, UnknownHostException {
- if(args.length < 2) {
- System.err.println("Syntax: PingTest <myPort> <hisPort>");
- System.exit(1);
- }
- int myPort = Integer.parseInt(args[0]);
- int hisPort = Integer.parseInt(args[1]);
- System.out.println("My port: "+myPort+", his port: "+hisPort);
- // Set up a UdpSocketManager
- usm = new UdpSocketManager(myPort);
- usm.setDispatcher(new PingingDispatcher());
- Peer otherSide;
- otherSide = new Peer(InetAddress.getByName("127.0.0.1"), hisPort);
- while(true) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- System.err.println("Sending ping");
- usm.send(otherSide, DMT.createPing());
- Message m = usm.waitFor(MessageFilter.create().setTimeout(1000).setType(DMT.pong).setSource(otherSide));
- if(m != null) {
- System.err.println("Got pong: "+m);
- }
- }
- }
-}
Copied: trunk/freenet/test/PingTest.java (from rev 11377, trunk/freenet/src/test/PingTest.java)
===================================================================
--- trunk/freenet/test/PingTest.java (rev 0)
+++ trunk/freenet/test/PingTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -0,0 +1,75 @@
+package test;
+
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+
+import freenet.io.comm.Dispatcher;
+import freenet.io.comm.DumpDispatcher;
+import freenet.io.comm.Message;
+import freenet.io.comm.Peer;
+import freenet.io.comm.UdpSocketManager;
+import freenet.io.comm.DMT;
+import freenet.io.comm.MessageFilter;
+
+/**
+ * Ping test.
+ * Just me getting used to the Dijjer-derived messaging system really.
+ * Takes two parameters: ourPort and hisPort.
+ * Sends a ping message every second.
+ * Prints out whenever we receive a ping message.
+ * @author amphibian
+ */
+public class PingTest {
+
+
+ /**
+ * @author root
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+ public static class PingingDispatcher implements Dispatcher {
+ public boolean handleMessage(Message m) {
+ if(m.getSpec() == DMT.ping) {
+ usm.send(m.getSource(), DMT.createPong(m));
+ return true;
+ }
+ return false;
+ }
+ }
+
+ static UdpSocketManager usm;
+
+ public PingTest() {
+ // not much to initialize
+ super();
+ }
+
+ public static void main(String[] args) throws SocketException, UnknownHostException {
+ if(args.length < 2) {
+ System.err.println("Syntax: PingTest <myPort> <hisPort>");
+ System.exit(1);
+ }
+ int myPort = Integer.parseInt(args[0]);
+ int hisPort = Integer.parseInt(args[1]);
+ System.out.println("My port: "+myPort+", his port: "+hisPort);
+ // Set up a UdpSocketManager
+ usm = new UdpSocketManager(myPort);
+ usm.setDispatcher(new PingingDispatcher());
+ Peer otherSide;
+ otherSide = new Peer(InetAddress.getByName("127.0.0.1"), hisPort);
+ while(true) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ System.err.println("Sending ping");
+ usm.send(otherSide, DMT.createPing());
+ Message m = usm.waitFor(MessageFilter.create().setTimeout(1000).setType(DMT.pong).setSource(otherSide));
+ if(m != null) {
+ System.err.println("Got pong: "+m);
+ }
+ }
+ }
+}
Deleted: trunk/freenet/test/PreNodeTest.java
===================================================================
--- trunk/freenet/src/test/PreNodeTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/PreNodeTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,845 +0,0 @@
-package test;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Random;
-
-import freenet.io.comm.DMT;
-import freenet.io.comm.Dispatcher;
-import freenet.io.comm.Message;
-import freenet.io.comm.MessageFilter;
-import freenet.io.comm.Peer;
-import freenet.io.comm.RetrievalException;
-import freenet.io.comm.UdpSocketManager;
-import freenet.io.xfer.BlockReceiver;
-import freenet.io.xfer.BlockTransmitter;
-import freenet.io.xfer.PartiallyReceivedBlock;
-import freenet.keys.CHKBlock;
-import freenet.keys.CHKDecodeException;
-import freenet.keys.CHKEncodeException;
-import freenet.keys.CHKVerifyException;
-import freenet.keys.ClientCHK;
-import freenet.keys.ClientCHKBlock;
-import freenet.keys.FreenetURI;
-import freenet.keys.NodeCHK;
-import freenet.store.FreenetStore;
-import freenet.support.Buffer;
-import freenet.support.Logger;
-
-/**
- * Invoker provides list of nodes to connect to (port #s).
- * Do handshake with each.. 5 consecutive pings.
- *
- * Then:
- * Take requests and inserts from stdin, like DatastoreTest.
- * Inserts:
- * - Just put to local store.
- * Requests:
- * - Choose a (random) peer to request from.
- *
- * Requests can now propagate.
- */
-public class PreNodeTest {
-
- /** SendJob: Send the DataReply, wait for the ack, send the
- * data, then report back. */
- public static class SendJob implements Runnable {
-
- final PartiallyReceivedBlock prb;
- final long id;
- final Peer peer;
- final byte[] header;
- final boolean silent;
- BlockTransmitter bt = null;
- boolean cancelled = false;
-
- public SendJob(PartiallyReceivedBlock prb, Peer peer, long id, byte[] header, boolean silent) {
- this.prb = prb;
- this.id = id;
- this.peer = peer;
- this.header = header;
- this.silent = silent;
- }
-
- public void run() {
- // First send the DataReply
- Message dataReply = DMT.createTestDataReply(id, header);
- // Yet another arbitrary timeout :(
- MessageFilter waitFor = MessageFilter.create().setSource(peer).setType(DMT.testDataReplyAck).setTimeout(1000);
- Message ack = null;
- for(int i=0;i<5;i++) {
- Logger.minor(this, "Waiting for DataReplyAck");
- usm.send(peer, dataReply);
- // Now wait for the ack
- ack = usm.waitFor(waitFor);
- if(ack != null)
- break;
- }
- Message completionNotification = null;
- if(silent) completionNotification = null;
- if(ack == null) {
- if(!silent)
- completionNotification =
- DMT.createTestSendCompleted(id, false, "No DataReplyAck");
- } else {
- // Got an acknowledgement
- bt = new BlockTransmitter(usm, peer, id, prb);
- bt.send();
- if(!silent)
- completionNotification =
- DMT.createTestSendCompleted(id, true, "");
- }
- if(!silent) usm.checkFilters(completionNotification);
- }
- }
-
- // ReceiveJob: Receive the entire file, then report back.
- public static class ReceiveJob implements Runnable {
-
- final PartiallyReceivedBlock prb;
- final Peer peer;
- final long id;
-
- public ReceiveJob(PartiallyReceivedBlock prb, Peer peer, long id) {
- this.prb = prb;
- this.peer = peer;
- this.id = id;
- }
-
- public void run() {
- BlockReceiver br = new BlockReceiver(usm, peer, id, prb);
- Message m = null;
- try {
- br.receive();
- } catch (RetrievalException e) {
- Logger.normal(this, "Receive failed: "+e);
- m = DMT.createTestReceiveCompleted(id, false, e.toString());
- }
- if(m == null)
- m = DMT.createTestReceiveCompleted(id, true, "");
- // Send notification
- usm.checkFilters(m);
- }
-
- }
- static Peer myPeer = null;
-
- /**
- * @author root
- *
- * TODO To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
- */
- public static class IDSet {
-
- HashMap items = new HashMap();
-
- public synchronized void register(long id, Peer source) {
- items.put(new Long(id), source);
- }
-
- public void unregister(long id) {
- items.remove(new Long(id));
- }
-
- public Peer getSource(long id) {
- return (Peer) items.get(new Long(id));
- }
- }
-
- static final IDSet idsRunning = new IDSet();
-
- static final HashSet previousIDs = new HashSet();
-
- /**
- * @author amphibian
- *
- * Keeps track of who we are connected to.
- * Also provides functionality for routing.
- * In a full implementation, we would keep estimators for
- * each node. In this version, we merely choose a peer
- * randomly.
- */
- public static class RoutingTable {
-
- PeerNode[] peerNodes = null;
-
- HashSet connectedNodes = new HashSet();
- PeerNode[] connectedNodesArray;
-
- public int connectedNodes() {
- return connectedNodes.size();
- }
-
- public PeerNode route(HashSet peerNodesExcluded) {
- PeerNode[] nodes = getConnectedNodes();
- int length = nodes.length;
- if(peerNodesExcluded.size() > 0) {
- PeerNode[] nodesNotExcluded = new PeerNode[length];
- int j=0;
- for(int i=0;i<length;i++) {
- PeerNode pn = nodes[i];
- if(peerNodesExcluded.contains(pn)) {
- Logger.minor(this, "Excluding: "+pn+" = "+pn.peer);
- continue;
- }
- nodesNotExcluded[j] = pn;
- j++;
- }
- nodes = nodesNotExcluded;
- length = j;
- }
- Logger.debug(this, "Route choices length: "+length);
- if(length == 0) return null;
- else return nodes[r.nextInt(length)];
- }
-
- public synchronized PeerNode[] getConnectedNodes() {
- if(connectedNodesArray == null) {
- connectedNodesArray = new PeerNode[connectedNodes.size()];
- connectedNodes.toArray(connectedNodesArray);
- }
- return connectedNodesArray;
- }
-
- /**
- * Try to connect to all nodes.
- */
- public synchronized void doInitialConnectAll() {
- // Connect to all peers
- if(peerNodes == null || peerNodes.length == 0) {
- Logger.error(this, "No peer nodes");
- return;
- }
- while(true) {
- boolean failedConnect = false;
- for(int i=0;i<peerNodes.length;i++) {
- PeerNode pn = peerNodes[i];
- Logger.debug(this, "["+i+"]: "+pn);
- if(!pn.isConnected()) {
- Logger.minor(this, "Trying to connect to "+pn);
- if(!pn.tryConnectOnce())
- failedConnect = true;
- }
- }
- if(!failedConnect) break;
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- // Ignore
- }
- }
- }
-
- public synchronized void addPeerNode(PeerNode p) {
- Logger.debug(this,"Adding "+p);
- if(peerNodes == null)
- Logger.debug(this, "peerNodes = null");
- else
- Logger.debug(this, "peerNodes size = "+peerNodes.length);
- int length;
- if(p == null) throw new NullPointerException();
- if(peerNodes == null) length = 0;
- else length = peerNodes.length;
- PeerNode[] newPeers = new PeerNode[length+1];
- if(length > 0)
- System.arraycopy(peerNodes, 0, newPeers, 0, peerNodes.length);
- newPeers[newPeers.length-1] = p;
- peerNodes = newPeers;
- for(int i=0;i<peerNodes.length;i++)
- Logger.debug(this, "peerNodes["+i+"] = "+peerNodes[i]);
- }
-
- public synchronized void onConnected(PeerNode p) {
- connectedNodes.add(p);
- connectedNodesArray = null;
- }
-
- public synchronized void onDisconnected(PeerNode p) {
- connectedNodesArray = null;
- // FIXME
- }
-
- /**
- * @return The total number of nodes known.
- */
- public int totalPeers() {
- return peerNodes.length;
- }
-
- /**
- * @param otherSide
- * @return
- */
- public PeerNode getPeerNode(Peer otherSide) {
- for(int i=0;i<peerNodes.length;i++) {
- PeerNode pn = peerNodes[i];
- if(pn.peer.equals(otherSide)) return pn;
- }
- return null;
- }
- }
-
- /**
- * A peer node. Would contain estimators as well as contact
- * details.
- * @author amphibian
- */
- public static class PeerNode {
- int portNumber;
- Peer peer;
-
- PeerNode(int portNum) {
- this.portNumber = portNum;
- try {
- peer = new Peer(InetAddress.getByName("127.0.0.1"), portNum);
- } catch (UnknownHostException e) {
- // WTF?
- throw new Error(e);
- }
- }
-
- public int hashCode() {
- return portNumber;
- }
-
- public String toString() {
- return super.toString()+":port="+portNumber;
- }
-
- public boolean equals(Object o) {
- // FIXME: do we need to actually compare content?
- // Probably not... there should only be one PeerNode for each peer.
- return (o == this);
- }
-
- /**
- * @return
- */
- public boolean isConnected() {
- return connected;
- }
-
- int consecutivePings = 0;
- boolean connected = false;
-
- /**
- * Attempt to connect to this node.
- * @return true if we have succeeded
- */
- public boolean tryConnectOnce() {
- if(!connected) {
- Logger.normal(TransferBlockTest.class, "Sending ping");
- usm.send(peer, DMT.createPing());
- Message m = usm.waitFor(MessageFilter.create().
- setTimeout(1000).setType(DMT.pong).setSource(peer));
- if(m != null) {
- consecutivePings++;
- Logger.normal(TransferBlockTest.class, "Got pong: "+m);
- } else {
- consecutivePings = 0;
- connected = false;
- }
- }
- if(consecutivePings >= 3) {
- connected = true;
- rt.onConnected(this);
- return true;
- }
- Logger.normal(TransferBlockTest.class, "Got "+consecutivePings+" consecutive pings to "+this);
- return false;
- }
- }
-
- static FreenetStore fs;
- static UdpSocketManager usm;
- final static Random r = new Random();
- static RoutingTable rt;
- static int myPort;
-
- public static void main(String[] args) throws Exception {
- Logger.setupStdoutLogging(Logger.DEBUG, "");
- rt = new RoutingTable();
- // Parse parameters.
- parseParameters(args);
- // Set up a UdpSocketManager
- usm = new UdpSocketManager(myPort);
- usm.setDispatcher(new MyDispatcher());
- //usm.setDropProbability(10);
- rt.doInitialConnectAll();
- // Setup datastore
- fs = new FreenetStore("datastore-"+myPort, "headerstore-"+myPort, 1024);
- printHeader();
- interfaceLoop();
- }
-
- private static void interfaceLoop() throws IOException {
- // Read command, and data
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- while(true) {
- String line = reader.readLine();
- if(line.startsWith("GET:")) {
- // Should have a key next
- String key = line.substring("GET:".length());
- while(key.length() > 0 && key.charAt(0) == ' ')
- key = key.substring(1);
- while(key.length() > 0 && key.charAt(key.length()-1) == ' ')
- key = key.substring(0, key.length()-2);
- Logger.normal(DatastoreTest.class, "Key: "+key);
- FreenetURI uri = new FreenetURI(key);
- ClientCHK chk = new ClientCHK(uri);
- CHKBlock block;
- try {
- // Fetch, possibly from other node.
- block = runRequest(chk.getNodeCHK(), 3, r.nextLong(), null, null);
- } catch (CHKVerifyException e1) {
- Logger.error(DatastoreTest.class, "Did not verify: "+e1, e1);
- continue;
- }
- if(block == null) {
- System.out.println("Not found in store: "+chk.getURI());
- } else {
- // Decode it
- byte[] decoded;
- try {
- decoded = block.decode(chk);
- } catch (CHKDecodeException e) {
- Logger.error(DatastoreTest.class, "Cannot decode: "+e, e);
- continue;
- }
- System.out.println("Decoded data:\n");
- System.out.println(new String(decoded));
- }
- } else if(line.startsWith("QUIT")) {
- System.out.println("Goodbye.");
- System.exit(0);
- } else if(line.startsWith("PUT:")) {
- // Just insert to local store
- line = line.substring("PUT:".length());
- while(line.length() > 0 && line.charAt(0) == ' ')
- line = line.substring(1);
- while(line.length() > 0 && line.charAt(line.length()-1) == ' ')
- line = line.substring(0, line.length()-2);
- String content;
- if(line.length() > 0) {
- // Single line insert
- content = line;
- } else {
- // Multiple line insert
- StringBuffer sb = new StringBuffer(1000);
- while(true) {
- line = reader.readLine();
- if(line.equals(".")) break;
- sb.append(line).append('\n');
- }
- content = sb.toString();
- }
- // Insert
- byte[] data = content.getBytes();
- ClientCHKBlock block;
- try {
- block = ClientCHKBlock.encode(data);
- } catch (CHKEncodeException e) {
- Logger.error(DatastoreTest.class, "Couldn't encode: "+e, e);
- continue;
- }
- ClientCHK chk = block.getClientKey();
- FreenetURI uri =
- chk.getURI();
- fs.put(block);
- // Definitely interface
- System.out.println("URI: "+uri);
- } else {
-
- }
- }
- }
-
- /**
- * Parse parameters.
- * The first one is my port number.
- * The second, third, fourth... are the port numbers of
- * nodes to add to the routing table.
- */
- private static void parseParameters(String[] args) throws UnknownHostException {
- if(args.length < 2) {
- System.err.println("Syntax: QuasiNodeTest <myPort> <node1's port> <node2's port> <node3's port>... ");
- System.exit(1);
- }
- myPort = Integer.parseInt(args[0]);
- myPeer = new Peer(InetAddress.getByName("127.0.0.1"), myPort);
- for(int i=1;i<args.length;i++) {
- int port = Integer.parseInt(args[i]);
- Logger.minor(PreNodeTest.class, "Adding node on port "+port);
- PeerNode p = new PeerNode(port);
- rt.addPeerNode(p);
- }
- Logger.normal(PreNodeTest.class, "Added "+rt.totalPeers()+" peers");
- }
-
- /**
- * Either fetch the key from the datastore, or request it from the other
- * node.
- *
- * @param nodeCHK
- * The key to fetch.
- * @param htl
- * The hops to live.
- * @return null if we can't find the data.
- */
- private static CHKBlock runRequest(NodeCHK nodeCHK, int htl, long id,
- Peer source, PeerNode sourceNode) throws IOException,
- CHKVerifyException {
- Logger.debug(PreNodeTest.class, "runRequest for "+nodeCHK+"@ HTL="+htl+" for "+source+" : "+sourceNode);
- previousIDs.add(new Long(id));
- idsRunning.register(id, source == null ? myPeer : source);
- // Send the ACK
- if (source != null) usm.send(source, DMT.createAcknowledgeRequest(id));
- try {
- HashSet peersSentTo = new HashSet();
- if (sourceNode != null) peersSentTo.add(sourceNode);
- // No source - catch any requests to this ID, check source later
- MessageFilter requestFilter = MessageFilter.create().setType(DMT.testRequest).setField(DMT.UID, id);
- while (true) {
- // First try the store
- CHKBlock block = fs.fetch(nodeCHK);
- if (block != null) {
- if(source != null) {
- // End node
- PartiallyReceivedBlock prb = new PartiallyReceivedBlock(32, 1024, block.getData());
- byte[] header = block.getHeader();
- SendJob sj = new SendJob(prb, source, id, header, true);
- Thread t = new Thread(sj);
- t.start();
- }
- return block;
- }
- if (htl <= 0) return block;
- // Otherwise...
- PeerNode pn = rt.route(peersSentTo);
- if (pn == null) {
- Logger.minor(PreNodeTest.class, "Ran out of peers");
- // FIXME: should this be a separate message? LateQueryRejected, perhaps?
- if(source != null) {
- Message dnf = DMT.createTestDataNotFound(id);
- usm.send(source, dnf);
- }
- return null;
- }
- Logger.minor(PreNodeTest.class, "Routing to " + pn);
- Peer peer = pn.peer;
- MessageFilter justReply = MessageFilter.create().setType(
- DMT.testDataReply).setField(DMT.UID, id)
- .setSource(peer);
- MessageFilter replyFilter = justReply.or(MessageFilter.create()
- .setField(DMT.UID, id).setType(DMT.testDataNotFound)
- .setSource(peer));
- Message request = DMT.createTestRequest(nodeCHK, id, htl);
- Message accepted = null;
- MessageFilter ackFilter = MessageFilter.create().setType(
- DMT.acknowledgeRequest).setSource(peer).setField(
- DMT.UID, id);
- MessageFilter qrFilter = MessageFilter.create().setType(
- DMT.rejectDueToLoop).setSource(peer).setField(DMT.UID,
- id);
- peersSentTo.add(pn);
- MessageFilter wait = qrFilter.or(ackFilter.or(replyFilter.or(requestFilter)));
- wait.setTimeout(1000);
- for (int i = 0; i < 5; i++) {
- usm.send(peer, request);
- // Wait for Accepted
- accepted = usm.waitFor(wait);
- if (accepted == null) continue;
- if (accepted.getSpec() == DMT.testRequest) {
- // Is a request
- if(accepted.getSource() == source) {
- // Is a rerequest.
- // Resend the Accepted.
- usm.send(source, DMT.createAcknowledgeRequest(id));
- } else {
- // Is a loop
- usm.send(accepted.getSource(), DMT.createRejectDueToLoop(id));
- }
- accepted = null;
- continue;
- }
- break;
- // Didn't get Accepted - probably didn't receive our request
- }
- Logger.debug(PreNodeTest.class, "Waiting for Accepted got "+accepted);
- if (accepted == null) {
- Logger.normal(PreNodeTest.class, "Did not get Accepted");
- // Try another node
- continue;
- }
- if (accepted.getSpec() == DMT.rejectDueToLoop) {
- Logger.minor(PreNodeTest.class, "Rejected: Loop");
- // Try another node
- continue;
- }
- Message reply;
- // If it's not Accepted, it's something else...
- if (accepted.getSpec() != DMT.acknowledgeRequest)
- reply = accepted;
- else {
- while (true) {
- Logger.debug(PreNodeTest.class, "Waiting for reply");
- reply = usm.waitFor(replyFilter.or(requestFilter)
- .setTimeout(5000));
- if (reply == null) break;
- if (reply.getSpec() == DMT.testRequest) {
- if(reply.getSource() == source) {
- // Rerequest from requestor; resend
- usm.send(source, DMT.createAcknowledgeRequest(id));
- } else {
- // Loop
- usm.send(reply.getSource(), DMT.createRejectDueToLoop(id));
- }
- continue;
- }
- break;
- }
- }
- Logger.debug(PreNodeTest.class, "Got reply: "+reply);
- // Process reply
- if (reply == null) {
- Logger.normal(PreNodeTest.class,
- "Partner node did not reply");
- // Same as if can't find enough nodes
- continue;
- //return null;
- } else if (reply.getSpec() == DMT.testDataNotFound) {
- // DNF
- Logger.normal(PreNodeTest.class, "Data Not Found");
- Message m = DMT.createTestDataNotFoundAck(id);
- usm.send(peer, m);
-
- if(source != null) {
- Message dnf = DMT.createTestDataNotFound(id);
- usm.send(source, dnf);
- }
- // If this gets lost, they'll send it again a few times...
- return null;
- } else if (reply.getSpec() == DMT.testDataReply) {
- Logger.debug(PreNodeTest.class, "Got DataReply");
- byte[] header = ((Buffer) reply
- .getObject(DMT.TEST_CHK_HEADERS)).getData();
- // Send the ack
- Message m = DMT.createTestDataReplyAck(id);
- usm.send(peer, m);
- // Now wait for the transfer; he will send me the data
- // Receive the data
- PartiallyReceivedBlock prb;
- prb = new PartiallyReceivedBlock(32, 1024);
- BlockReceiver br;
-
- // Receive
- // ReceiveJob: Receive the entire file, then report back.
- ReceiveJob rj = new ReceiveJob(prb, peer, id);
- Thread rjt = new Thread(rj);
- rjt.start();
-
- if(source != null) {
- // Send
- // SendJob: Send the DataReply, wait for the ack, send the
- // data, then report back.
- SendJob sj = new SendJob(prb, source, id, header, false);
- Thread sjt = new Thread(sj);
- sjt.start();
- }
-
- /**
- * We can now receive: - Resent DataRequest from request
- * source => resend - Resent DataReply from peer (data
- * source) - Completion notification from SendJob -
- * Completion notification from ReceiveJob SendJob handles
- * DataReplyAck
- */
-
- MessageFilter sentCompleteWait = MessageFilter.create()
- .setType(DMT.testSendCompleted).setField(DMT.UID,
- id);
- MessageFilter receiveCompleteWait = MessageFilter.create()
- .setType(DMT.testReceiveCompleted).setField(
- DMT.UID, id);
-
- // FIXME: totally arbitrary timeout :)
- MessageFilter waitingFor =
- justReply.or(sentCompleteWait.or(receiveCompleteWait.or(requestFilter)));
- waitingFor = waitingFor.setTimeout(30 * 1000);
-
- boolean sendCompleted = false;
- boolean recvCompleted = false;
-
- while (true) {
- m = null;
- m = usm.waitFor(waitingFor);
-
- if (m == null) {
- // Timeout
- Logger.error(PreNodeTest.class, "Timeout in final wait");
- if(!recvCompleted) {
- // Other side will see broken send
- return null;
- } else {
- // We got it, they didn't
- break;
- }
- } else if (m.getSpec() == DMT.testSendCompleted) {
- Logger.minor(PreNodeTest.class, "Send completed");
- // Finished send
- sendCompleted = true;
- if (recvCompleted) break;
- } else if (m.getSpec() == DMT.testReceiveCompleted) {
- Logger.minor(PreNodeTest.class, "Receive completed");
- if(!m.getBoolean(DMT.SUCCESS)) {
- prb.abort(RetrievalException.SENDER_DIED, "Sender died");
- return null;
- }
- recvCompleted = true;
- if (sendCompleted || source == null) break;
- } else if (m.getSpec() == DMT.testDataReply) {
- Logger.minor(PreNodeTest.class, "Got DataReply");
- // Data source didn't get the acknowledgement
- // Resend the acknowledgement
- Message ack = DMT.createTestDataReplyAck(id);
- usm.send(peer, ack);
- } else if (m.getSpec() == DMT.testRequest) {
- Logger.minor(PreNodeTest.class, "Got DataRequest");
- if(m.getSource() == source) {
- Logger.minor(PreNodeTest.class, "DataRequest from source");
- // Resend request
- // Source got neither the accepted nor the DataReply
- // Resend the accepted, and let SendJob resend the DataReply
- // Difficult to get it to resend it immediately because it might just have sent it so just let it time out.
- usm.send(source, DMT.createAcknowledgeRequest(id));
- } else {
- // Loop - shouldn't happen at this stage
- Logger.normal(PreNodeTest.class, "Loop after have started sending");
- usm.send(m.getSource(), DMT.createRejectDueToLoop(id));
- }
-
- }
- }
-
- // Got data
-
- byte[] data = prb.getBlock();
-
- if (data == null)
- Logger.error(PreQuasiNodeTest.class,
- "Could not receive data");
- System.err.println("Received " + data.length + " bytes");
- // Now decode it
- try {
- block = new CHKBlock(data, header, nodeCHK);
- } catch (CHKVerifyException e) {
- Logger.error(PreNodeTest.class, "Couldn't verify", e);
- return null;
- }
- return block;
- } else {
- Logger.error(PreNodeTest.class, "Message " + reply
- + " - WTF?");
- return null;
- }
- }
- } finally {
- idsRunning.unregister(id);
- }
- }
-
- private static void printHeader() {
- // Write header
- System.out.println("PreNode tester");
- System.out.println("--------------");
- System.out.println();
- System.out.println("Enter one of the following commands:");
- System.out.println("GET:<Freenet key> - fetch a key");
- System.out.println("PUT:\n<text, until a . on a line by itself> - We will insert the document and return the key.");
- System.out.println("PUT:<text> - put a single line of text to a CHK and return the key.");
- System.out.println("QUIT - exit the program");
- }
-
- public static class MyDispatcher implements Dispatcher {
- public boolean handleMessage(Message m) {
- if(m.getSpec() == DMT.ping) {
- usm.send(m.getSource(), DMT.createPong(m));
- return true;
- }
- if(m.getSpec() == DMT.testRequest) {
- Peer origSource = idsRunning.getSource(m.getLong(DMT.UID));
- Peer reqSource = m.getSource();
- if(reqSource == origSource)
- // Resent by request source; ignore
- return true;
- // Otherwise a genuine request, or a loop; either way needs further handling
- try {
- new Thread(new RequestHandler(m)).start();
- } catch (IllegalStateException e) {
- return true;
- }
- return true;
- }
- return false;
- }
- }
-
- /**
- * Handle a request.
- * Check the store, if we have anything, then send it back.
- * Otherwise send back DNF.
- */
- public static class RequestHandler implements Runnable {
-
- final long id;
- final NodeCHK key;
- final Peer otherSide;
- int htl;
-
- /**
- * Constructor
- * @param m
- */
- public RequestHandler(Message m) {
- if(m.getSpec() != DMT.testRequest)
- throw new IllegalArgumentException("Not a testRequest: "+m.getSpec().getName());
- id = m.getLong(DMT.UID);
- Object o = m.getObject(DMT.FREENET_ROUTING_KEY);
- if(o instanceof NodeCHK)
- key = (NodeCHK) o;
- else {
- // Ignore it
- Logger.error(RequestHandler.class, "Node sent testRequest but key not a key! Ignoring request.");
- throw new IllegalStateException("Node sent testRequest but key not a key! Ignoring request.");
- }
- otherSide = m.getSource();
- htl = m.getInt(DMT.HTL);
- htl--;
- }
-
- public void run() {
- // Check ID
- // FIXME: use an LRU
- Long lid = new Long(id);
- if(previousIDs.contains(lid)) {
- // Reject
- usm.send(otherSide, DMT.createRejectDueToLoop(id));
- return;
- }
- try {
- runRequest(key, htl, id, otherSide, rt.getPeerNode(otherSide));
- } catch (IOException e) {
- Logger.error(this, "IO error fetching: "+e,e);
- } catch (CHKVerifyException e) {
- Logger.error(this, "Couldn't verify data in store for "+key+": "+e,e);
- }
- }
-
- }
-}
Copied: trunk/freenet/test/PreNodeTest.java (from rev 11377, trunk/freenet/src/test/PreNodeTest.java)
===================================================================
--- trunk/freenet/test/PreNodeTest.java (rev 0)
+++ trunk/freenet/test/PreNodeTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -0,0 +1,845 @@
+package test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Random;
+
+import freenet.io.comm.DMT;
+import freenet.io.comm.Dispatcher;
+import freenet.io.comm.Message;
+import freenet.io.comm.MessageFilter;
+import freenet.io.comm.Peer;
+import freenet.io.comm.RetrievalException;
+import freenet.io.comm.UdpSocketManager;
+import freenet.io.xfer.BlockReceiver;
+import freenet.io.xfer.BlockTransmitter;
+import freenet.io.xfer.PartiallyReceivedBlock;
+import freenet.keys.CHKBlock;
+import freenet.keys.CHKDecodeException;
+import freenet.keys.CHKEncodeException;
+import freenet.keys.CHKVerifyException;
+import freenet.keys.ClientCHK;
+import freenet.keys.ClientCHKBlock;
+import freenet.keys.FreenetURI;
+import freenet.keys.NodeCHK;
+import freenet.store.FreenetStore;
+import freenet.support.Buffer;
+import freenet.support.Logger;
+
+/**
+ * Invoker provides list of nodes to connect to (port #s).
+ * Do handshake with each.. 5 consecutive pings.
+ *
+ * Then:
+ * Take requests and inserts from stdin, like DatastoreTest.
+ * Inserts:
+ * - Just put to local store.
+ * Requests:
+ * - Choose a (random) peer to request from.
+ *
+ * Requests can now propagate.
+ */
+public class PreNodeTest {
+
+ /** SendJob: Send the DataReply, wait for the ack, send the
+ * data, then report back. */
+ public static class SendJob implements Runnable {
+
+ final PartiallyReceivedBlock prb;
+ final long id;
+ final Peer peer;
+ final byte[] header;
+ final boolean silent;
+ BlockTransmitter bt = null;
+ boolean cancelled = false;
+
+ public SendJob(PartiallyReceivedBlock prb, Peer peer, long id, byte[] header, boolean silent) {
+ this.prb = prb;
+ this.id = id;
+ this.peer = peer;
+ this.header = header;
+ this.silent = silent;
+ }
+
+ public void run() {
+ // First send the DataReply
+ Message dataReply = DMT.createTestDataReply(id, header);
+ // Yet another arbitrary timeout :(
+ MessageFilter waitFor = MessageFilter.create().setSource(peer).setType(DMT.testDataReplyAck).setTimeout(1000);
+ Message ack = null;
+ for(int i=0;i<5;i++) {
+ Logger.minor(this, "Waiting for DataReplyAck");
+ usm.send(peer, dataReply);
+ // Now wait for the ack
+ ack = usm.waitFor(waitFor);
+ if(ack != null)
+ break;
+ }
+ Message completionNotification = null;
+ if(silent) completionNotification = null;
+ if(ack == null) {
+ if(!silent)
+ completionNotification =
+ DMT.createTestSendCompleted(id, false, "No DataReplyAck");
+ } else {
+ // Got an acknowledgement
+ bt = new BlockTransmitter(usm, peer, id, prb);
+ bt.send();
+ if(!silent)
+ completionNotification =
+ DMT.createTestSendCompleted(id, true, "");
+ }
+ if(!silent) usm.checkFilters(completionNotification);
+ }
+ }
+
+ // ReceiveJob: Receive the entire file, then report back.
+ public static class ReceiveJob implements Runnable {
+
+ final PartiallyReceivedBlock prb;
+ final Peer peer;
+ final long id;
+
+ public ReceiveJob(PartiallyReceivedBlock prb, Peer peer, long id) {
+ this.prb = prb;
+ this.peer = peer;
+ this.id = id;
+ }
+
+ public void run() {
+ BlockReceiver br = new BlockReceiver(usm, peer, id, prb);
+ Message m = null;
+ try {
+ br.receive();
+ } catch (RetrievalException e) {
+ Logger.normal(this, "Receive failed: "+e);
+ m = DMT.createTestReceiveCompleted(id, false, e.toString());
+ }
+ if(m == null)
+ m = DMT.createTestReceiveCompleted(id, true, "");
+ // Send notification
+ usm.checkFilters(m);
+ }
+
+ }
+ static Peer myPeer = null;
+
+ /**
+ * @author root
+ *
+ * TODO To change the template for this generated type comment go to
+ * Window - Preferences - Java - Code Generation - Code and Comments
+ */
+ public static class IDSet {
+
+ HashMap items = new HashMap();
+
+ public synchronized void register(long id, Peer source) {
+ items.put(new Long(id), source);
+ }
+
+ public void unregister(long id) {
+ items.remove(new Long(id));
+ }
+
+ public Peer getSource(long id) {
+ return (Peer) items.get(new Long(id));
+ }
+ }
+
+ static final IDSet idsRunning = new IDSet();
+
+ static final HashSet previousIDs = new HashSet();
+
+ /**
+ * @author amphibian
+ *
+ * Keeps track of who we are connected to.
+ * Also provides functionality for routing.
+ * In a full implementation, we would keep estimators for
+ * each node. In this version, we merely choose a peer
+ * randomly.
+ */
+ public static class RoutingTable {
+
+ PeerNode[] peerNodes = null;
+
+ HashSet connectedNodes = new HashSet();
+ PeerNode[] connectedNodesArray;
+
+ public int connectedNodes() {
+ return connectedNodes.size();
+ }
+
+ public PeerNode route(HashSet peerNodesExcluded) {
+ PeerNode[] nodes = getConnectedNodes();
+ int length = nodes.length;
+ if(peerNodesExcluded.size() > 0) {
+ PeerNode[] nodesNotExcluded = new PeerNode[length];
+ int j=0;
+ for(int i=0;i<length;i++) {
+ PeerNode pn = nodes[i];
+ if(peerNodesExcluded.contains(pn)) {
+ Logger.minor(this, "Excluding: "+pn+" = "+pn.peer);
+ continue;
+ }
+ nodesNotExcluded[j] = pn;
+ j++;
+ }
+ nodes = nodesNotExcluded;
+ length = j;
+ }
+ Logger.debug(this, "Route choices length: "+length);
+ if(length == 0) return null;
+ else return nodes[r.nextInt(length)];
+ }
+
+ public synchronized PeerNode[] getConnectedNodes() {
+ if(connectedNodesArray == null) {
+ connectedNodesArray = new PeerNode[connectedNodes.size()];
+ connectedNodes.toArray(connectedNodesArray);
+ }
+ return connectedNodesArray;
+ }
+
+ /**
+ * Try to connect to all nodes.
+ */
+ public synchronized void doInitialConnectAll() {
+ // Connect to all peers
+ if(peerNodes == null || peerNodes.length == 0) {
+ Logger.error(this, "No peer nodes");
+ return;
+ }
+ while(true) {
+ boolean failedConnect = false;
+ for(int i=0;i<peerNodes.length;i++) {
+ PeerNode pn = peerNodes[i];
+ Logger.debug(this, "["+i+"]: "+pn);
+ if(!pn.isConnected()) {
+ Logger.minor(this, "Trying to connect to "+pn);
+ if(!pn.tryConnectOnce())
+ failedConnect = true;
+ }
+ }
+ if(!failedConnect) break;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+
+ public synchronized void addPeerNode(PeerNode p) {
+ Logger.debug(this,"Adding "+p);
+ if(peerNodes == null)
+ Logger.debug(this, "peerNodes = null");
+ else
+ Logger.debug(this, "peerNodes size = "+peerNodes.length);
+ int length;
+ if(p == null) throw new NullPointerException();
+ if(peerNodes == null) length = 0;
+ else length = peerNodes.length;
+ PeerNode[] newPeers = new PeerNode[length+1];
+ if(length > 0)
+ System.arraycopy(peerNodes, 0, newPeers, 0, peerNodes.length);
+ newPeers[newPeers.length-1] = p;
+ peerNodes = newPeers;
+ for(int i=0;i<peerNodes.length;i++)
+ Logger.debug(this, "peerNodes["+i+"] = "+peerNodes[i]);
+ }
+
+ public synchronized void onConnected(PeerNode p) {
+ connectedNodes.add(p);
+ connectedNodesArray = null;
+ }
+
+ public synchronized void onDisconnected(PeerNode p) {
+ connectedNodesArray = null;
+ // FIXME
+ }
+
+ /**
+ * @return The total number of nodes known.
+ */
+ public int totalPeers() {
+ return peerNodes.length;
+ }
+
+ /**
+ * @param otherSide
+ * @return
+ */
+ public PeerNode getPeerNode(Peer otherSide) {
+ for(int i=0;i<peerNodes.length;i++) {
+ PeerNode pn = peerNodes[i];
+ if(pn.peer.equals(otherSide)) return pn;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * A peer node. Would contain estimators as well as contact
+ * details.
+ * @author amphibian
+ */
+ public static class PeerNode {
+ int portNumber;
+ Peer peer;
+
+ PeerNode(int portNum) {
+ this.portNumber = portNum;
+ try {
+ peer = new Peer(InetAddress.getByName("127.0.0.1"), portNum);
+ } catch (UnknownHostException e) {
+ // WTF?
+ throw new Error(e);
+ }
+ }
+
+ public int hashCode() {
+ return portNumber;
+ }
+
+ public String toString() {
+ return super.toString()+":port="+portNumber;
+ }
+
+ public boolean equals(Object o) {
+ // FIXME: do we need to actually compare content?
+ // Probably not... there should only be one PeerNode for each peer.
+ return (o == this);
+ }
+
+ /**
+ * @return
+ */
+ public boolean isConnected() {
+ return connected;
+ }
+
+ int consecutivePings = 0;
+ boolean connected = false;
+
+ /**
+ * Attempt to connect to this node.
+ * @return true if we have succeeded
+ */
+ public boolean tryConnectOnce() {
+ if(!connected) {
+ Logger.normal(TransferBlockTest.class, "Sending ping");
+ usm.send(peer, DMT.createPing());
+ Message m = usm.waitFor(MessageFilter.create().
+ setTimeout(1000).setType(DMT.pong).setSource(peer));
+ if(m != null) {
+ consecutivePings++;
+ Logger.normal(TransferBlockTest.class, "Got pong: "+m);
+ } else {
+ consecutivePings = 0;
+ connected = false;
+ }
+ }
+ if(consecutivePings >= 3) {
+ connected = true;
+ rt.onConnected(this);
+ return true;
+ }
+ Logger.normal(TransferBlockTest.class, "Got "+consecutivePings+" consecutive pings to "+this);
+ return false;
+ }
+ }
+
+ static FreenetStore fs;
+ static UdpSocketManager usm;
+ final static Random r = new Random();
+ static RoutingTable rt;
+ static int myPort;
+
+ public static void main(String[] args) throws Exception {
+ Logger.setupStdoutLogging(Logger.DEBUG, "");
+ rt = new RoutingTable();
+ // Parse parameters.
+ parseParameters(args);
+ // Set up a UdpSocketManager
+ usm = new UdpSocketManager(myPort);
+ usm.setDispatcher(new MyDispatcher());
+ //usm.setDropProbability(10);
+ rt.doInitialConnectAll();
+ // Setup datastore
+ fs = new FreenetStore("datastore-"+myPort, "headerstore-"+myPort, 1024);
+ printHeader();
+ interfaceLoop();
+ }
+
+ private static void interfaceLoop() throws IOException {
+ // Read command, and data
+ BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+ while(true) {
+ String line = reader.readLine();
+ if(line.startsWith("GET:")) {
+ // Should have a key next
+ String key = line.substring("GET:".length());
+ while(key.length() > 0 && key.charAt(0) == ' ')
+ key = key.substring(1);
+ while(key.length() > 0 && key.charAt(key.length()-1) == ' ')
+ key = key.substring(0, key.length()-2);
+ Logger.normal(DatastoreTest.class, "Key: "+key);
+ FreenetURI uri = new FreenetURI(key);
+ ClientCHK chk = new ClientCHK(uri);
+ CHKBlock block;
+ try {
+ // Fetch, possibly from other node.
+ block = runRequest(chk.getNodeCHK(), 3, r.nextLong(), null, null);
+ } catch (CHKVerifyException e1) {
+ Logger.error(DatastoreTest.class, "Did not verify: "+e1, e1);
+ continue;
+ }
+ if(block == null) {
+ System.out.println("Not found in store: "+chk.getURI());
+ } else {
+ // Decode it
+ byte[] decoded;
+ try {
+ decoded = block.decode(chk);
+ } catch (CHKDecodeException e) {
+ Logger.error(DatastoreTest.class, "Cannot decode: "+e, e);
+ continue;
+ }
+ System.out.println("Decoded data:\n");
+ System.out.println(new String(decoded));
+ }
+ } else if(line.startsWith("QUIT")) {
+ System.out.println("Goodbye.");
+ System.exit(0);
+ } else if(line.startsWith("PUT:")) {
+ // Just insert to local store
+ line = line.substring("PUT:".length());
+ while(line.length() > 0 && line.charAt(0) == ' ')
+ line = line.substring(1);
+ while(line.length() > 0 && line.charAt(line.length()-1) == ' ')
+ line = line.substring(0, line.length()-2);
+ String content;
+ if(line.length() > 0) {
+ // Single line insert
+ content = line;
+ } else {
+ // Multiple line insert
+ StringBuffer sb = new StringBuffer(1000);
+ while(true) {
+ line = reader.readLine();
+ if(line.equals(".")) break;
+ sb.append(line).append('\n');
+ }
+ content = sb.toString();
+ }
+ // Insert
+ byte[] data = content.getBytes();
+ ClientCHKBlock block;
+ try {
+ block = ClientCHKBlock.encode(data);
+ } catch (CHKEncodeException e) {
+ Logger.error(DatastoreTest.class, "Couldn't encode: "+e, e);
+ continue;
+ }
+ ClientCHK chk = block.getClientKey();
+ FreenetURI uri =
+ chk.getURI();
+ fs.put(block);
+ // Definitely interface
+ System.out.println("URI: "+uri);
+ } else {
+
+ }
+ }
+ }
+
+ /**
+ * Parse parameters.
+ * The first one is my port number.
+ * The second, third, fourth... are the port numbers of
+ * nodes to add to the routing table.
+ */
+ private static void parseParameters(String[] args) throws UnknownHostException {
+ if(args.length < 2) {
+ System.err.println("Syntax: QuasiNodeTest <myPort> <node1's port> <node2's port> <node3's port>... ");
+ System.exit(1);
+ }
+ myPort = Integer.parseInt(args[0]);
+ myPeer = new Peer(InetAddress.getByName("127.0.0.1"), myPort);
+ for(int i=1;i<args.length;i++) {
+ int port = Integer.parseInt(args[i]);
+ Logger.minor(PreNodeTest.class, "Adding node on port "+port);
+ PeerNode p = new PeerNode(port);
+ rt.addPeerNode(p);
+ }
+ Logger.normal(PreNodeTest.class, "Added "+rt.totalPeers()+" peers");
+ }
+
+ /**
+ * Either fetch the key from the datastore, or request it from the other
+ * node.
+ *
+ * @param nodeCHK
+ * The key to fetch.
+ * @param htl
+ * The hops to live.
+ * @return null if we can't find the data.
+ */
+ private static CHKBlock runRequest(NodeCHK nodeCHK, int htl, long id,
+ Peer source, PeerNode sourceNode) throws IOException,
+ CHKVerifyException {
+ Logger.debug(PreNodeTest.class, "runRequest for "+nodeCHK+"@ HTL="+htl+" for "+source+" : "+sourceNode);
+ previousIDs.add(new Long(id));
+ idsRunning.register(id, source == null ? myPeer : source);
+ // Send the ACK
+ if (source != null) usm.send(source, DMT.createAcknowledgeRequest(id));
+ try {
+ HashSet peersSentTo = new HashSet();
+ if (sourceNode != null) peersSentTo.add(sourceNode);
+ // No source - catch any requests to this ID, check source later
+ MessageFilter requestFilter = MessageFilter.create().setType(DMT.testRequest).setField(DMT.UID, id);
+ while (true) {
+ // First try the store
+ CHKBlock block = fs.fetch(nodeCHK);
+ if (block != null) {
+ if(source != null) {
+ // End node
+ PartiallyReceivedBlock prb = new PartiallyReceivedBlock(32, 1024, block.getData());
+ byte[] header = block.getHeader();
+ SendJob sj = new SendJob(prb, source, id, header, true);
+ Thread t = new Thread(sj);
+ t.start();
+ }
+ return block;
+ }
+ if (htl <= 0) return block;
+ // Otherwise...
+ PeerNode pn = rt.route(peersSentTo);
+ if (pn == null) {
+ Logger.minor(PreNodeTest.class, "Ran out of peers");
+ // FIXME: should this be a separate message? LateQueryRejected, perhaps?
+ if(source != null) {
+ Message dnf = DMT.createTestDataNotFound(id);
+ usm.send(source, dnf);
+ }
+ return null;
+ }
+ Logger.minor(PreNodeTest.class, "Routing to " + pn);
+ Peer peer = pn.peer;
+ MessageFilter justReply = MessageFilter.create().setType(
+ DMT.testDataReply).setField(DMT.UID, id)
+ .setSource(peer);
+ MessageFilter replyFilter = justReply.or(MessageFilter.create()
+ .setField(DMT.UID, id).setType(DMT.testDataNotFound)
+ .setSource(peer));
+ Message request = DMT.createTestRequest(nodeCHK, id, htl);
+ Message accepted = null;
+ MessageFilter ackFilter = MessageFilter.create().setType(
+ DMT.acknowledgeRequest).setSource(peer).setField(
+ DMT.UID, id);
+ MessageFilter qrFilter = MessageFilter.create().setType(
+ DMT.rejectDueToLoop).setSource(peer).setField(DMT.UID,
+ id);
+ peersSentTo.add(pn);
+ MessageFilter wait = qrFilter.or(ackFilter.or(replyFilter.or(requestFilter)));
+ wait.setTimeout(1000);
+ for (int i = 0; i < 5; i++) {
+ usm.send(peer, request);
+ // Wait for Accepted
+ accepted = usm.waitFor(wait);
+ if (accepted == null) continue;
+ if (accepted.getSpec() == DMT.testRequest) {
+ // Is a request
+ if(accepted.getSource() == source) {
+ // Is a rerequest.
+ // Resend the Accepted.
+ usm.send(source, DMT.createAcknowledgeRequest(id));
+ } else {
+ // Is a loop
+ usm.send(accepted.getSource(), DMT.createRejectDueToLoop(id));
+ }
+ accepted = null;
+ continue;
+ }
+ break;
+ // Didn't get Accepted - probably didn't receive our request
+ }
+ Logger.debug(PreNodeTest.class, "Waiting for Accepted got "+accepted);
+ if (accepted == null) {
+ Logger.normal(PreNodeTest.class, "Did not get Accepted");
+ // Try another node
+ continue;
+ }
+ if (accepted.getSpec() == DMT.rejectDueToLoop) {
+ Logger.minor(PreNodeTest.class, "Rejected: Loop");
+ // Try another node
+ continue;
+ }
+ Message reply;
+ // If it's not Accepted, it's something else...
+ if (accepted.getSpec() != DMT.acknowledgeRequest)
+ reply = accepted;
+ else {
+ while (true) {
+ Logger.debug(PreNodeTest.class, "Waiting for reply");
+ reply = usm.waitFor(replyFilter.or(requestFilter)
+ .setTimeout(5000));
+ if (reply == null) break;
+ if (reply.getSpec() == DMT.testRequest) {
+ if(reply.getSource() == source) {
+ // Rerequest from requestor; resend
+ usm.send(source, DMT.createAcknowledgeRequest(id));
+ } else {
+ // Loop
+ usm.send(reply.getSource(), DMT.createRejectDueToLoop(id));
+ }
+ continue;
+ }
+ break;
+ }
+ }
+ Logger.debug(PreNodeTest.class, "Got reply: "+reply);
+ // Process reply
+ if (reply == null) {
+ Logger.normal(PreNodeTest.class,
+ "Partner node did not reply");
+ // Same as if can't find enough nodes
+ continue;
+ //return null;
+ } else if (reply.getSpec() == DMT.testDataNotFound) {
+ // DNF
+ Logger.normal(PreNodeTest.class, "Data Not Found");
+ Message m = DMT.createTestDataNotFoundAck(id);
+ usm.send(peer, m);
+
+ if(source != null) {
+ Message dnf = DMT.createTestDataNotFound(id);
+ usm.send(source, dnf);
+ }
+ // If this gets lost, they'll send it again a few times...
+ return null;
+ } else if (reply.getSpec() == DMT.testDataReply) {
+ Logger.debug(PreNodeTest.class, "Got DataReply");
+ byte[] header = ((Buffer) reply
+ .getObject(DMT.TEST_CHK_HEADERS)).getData();
+ // Send the ack
+ Message m = DMT.createTestDataReplyAck(id);
+ usm.send(peer, m);
+ // Now wait for the transfer; he will send me the data
+ // Receive the data
+ PartiallyReceivedBlock prb;
+ prb = new PartiallyReceivedBlock(32, 1024);
+ BlockReceiver br;
+
+ // Receive
+ // ReceiveJob: Receive the entire file, then report back.
+ ReceiveJob rj = new ReceiveJob(prb, peer, id);
+ Thread rjt = new Thread(rj);
+ rjt.start();
+
+ if(source != null) {
+ // Send
+ // SendJob: Send the DataReply, wait for the ack, send the
+ // data, then report back.
+ SendJob sj = new SendJob(prb, source, id, header, false);
+ Thread sjt = new Thread(sj);
+ sjt.start();
+ }
+
+ /**
+ * We can now receive: - Resent DataRequest from request
+ * source => resend - Resent DataReply from peer (data
+ * source) - Completion notification from SendJob -
+ * Completion notification from ReceiveJob SendJob handles
+ * DataReplyAck
+ */
+
+ MessageFilter sentCompleteWait = MessageFilter.create()
+ .setType(DMT.testSendCompleted).setField(DMT.UID,
+ id);
+ MessageFilter receiveCompleteWait = MessageFilter.create()
+ .setType(DMT.testReceiveCompleted).setField(
+ DMT.UID, id);
+
+ // FIXME: totally arbitrary timeout :)
+ MessageFilter waitingFor =
+ justReply.or(sentCompleteWait.or(receiveCompleteWait.or(requestFilter)));
+ waitingFor = waitingFor.setTimeout(30 * 1000);
+
+ boolean sendCompleted = false;
+ boolean recvCompleted = false;
+
+ while (true) {
+ m = null;
+ m = usm.waitFor(waitingFor);
+
+ if (m == null) {
+ // Timeout
+ Logger.error(PreNodeTest.class, "Timeout in final wait");
+ if(!recvCompleted) {
+ // Other side will see broken send
+ return null;
+ } else {
+ // We got it, they didn't
+ break;
+ }
+ } else if (m.getSpec() == DMT.testSendCompleted) {
+ Logger.minor(PreNodeTest.class, "Send completed");
+ // Finished send
+ sendCompleted = true;
+ if (recvCompleted) break;
+ } else if (m.getSpec() == DMT.testReceiveCompleted) {
+ Logger.minor(PreNodeTest.class, "Receive completed");
+ if(!m.getBoolean(DMT.SUCCESS)) {
+ prb.abort(RetrievalException.SENDER_DIED, "Sender died");
+ return null;
+ }
+ recvCompleted = true;
+ if (sendCompleted || source == null) break;
+ } else if (m.getSpec() == DMT.testDataReply) {
+ Logger.minor(PreNodeTest.class, "Got DataReply");
+ // Data source didn't get the acknowledgement
+ // Resend the acknowledgement
+ Message ack = DMT.createTestDataReplyAck(id);
+ usm.send(peer, ack);
+ } else if (m.getSpec() == DMT.testRequest) {
+ Logger.minor(PreNodeTest.class, "Got DataRequest");
+ if(m.getSource() == source) {
+ Logger.minor(PreNodeTest.class, "DataRequest from source");
+ // Resend request
+ // Source got neither the accepted nor the DataReply
+ // Resend the accepted, and let SendJob resend the DataReply
+ // Difficult to get it to resend it immediately because it might just have sent it so just let it time out.
+ usm.send(source, DMT.createAcknowledgeRequest(id));
+ } else {
+ // Loop - shouldn't happen at this stage
+ Logger.normal(PreNodeTest.class, "Loop after have started sending");
+ usm.send(m.getSource(), DMT.createRejectDueToLoop(id));
+ }
+
+ }
+ }
+
+ // Got data
+
+ byte[] data = prb.getBlock();
+
+ if (data == null)
+ Logger.error(PreQuasiNodeTest.class,
+ "Could not receive data");
+ System.err.println("Received " + data.length + " bytes");
+ // Now decode it
+ try {
+ block = new CHKBlock(data, header, nodeCHK);
+ } catch (CHKVerifyException e) {
+ Logger.error(PreNodeTest.class, "Couldn't verify", e);
+ return null;
+ }
+ return block;
+ } else {
+ Logger.error(PreNodeTest.class, "Message " + reply
+ + " - WTF?");
+ return null;
+ }
+ }
+ } finally {
+ idsRunning.unregister(id);
+ }
+ }
+
+ private static void printHeader() {
+ // Write header
+ System.out.println("PreNode tester");
+ System.out.println("--------------");
+ System.out.println();
+ System.out.println("Enter one of the following commands:");
+ System.out.println("GET:<Freenet key> - fetch a key");
+ System.out.println("PUT:\n<text, until a . on a line by itself> - We will insert the document and return the key.");
+ System.out.println("PUT:<text> - put a single line of text to a CHK and return the key.");
+ System.out.println("QUIT - exit the program");
+ }
+
+ public static class MyDispatcher implements Dispatcher {
+ public boolean handleMessage(Message m) {
+ if(m.getSpec() == DMT.ping) {
+ usm.send(m.getSource(), DMT.createPong(m));
+ return true;
+ }
+ if(m.getSpec() == DMT.testRequest) {
+ Peer origSource = idsRunning.getSource(m.getLong(DMT.UID));
+ Peer reqSource = m.getSource();
+ if(reqSource == origSource)
+ // Resent by request source; ignore
+ return true;
+ // Otherwise a genuine request, or a loop; either way needs further handling
+ try {
+ new Thread(new RequestHandler(m)).start();
+ } catch (IllegalStateException e) {
+ return true;
+ }
+ return true;
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Handle a request.
+ * Check the store, if we have anything, then send it back.
+ * Otherwise send back DNF.
+ */
+ public static class RequestHandler implements Runnable {
+
+ final long id;
+ final NodeCHK key;
+ final Peer otherSide;
+ int htl;
+
+ /**
+ * Constructor
+ * @param m
+ */
+ public RequestHandler(Message m) {
+ if(m.getSpec() != DMT.testRequest)
+ throw new IllegalArgumentException("Not a testRequest: "+m.getSpec().getName());
+ id = m.getLong(DMT.UID);
+ Object o = m.getObject(DMT.FREENET_ROUTING_KEY);
+ if(o instanceof NodeCHK)
+ key = (NodeCHK) o;
+ else {
+ // Ignore it
+ Logger.error(RequestHandler.class, "Node sent testRequest but key not a key! Ignoring request.");
+ throw new IllegalStateException("Node sent testRequest but key not a key! Ignoring request.");
+ }
+ otherSide = m.getSource();
+ htl = m.getInt(DMT.HTL);
+ htl--;
+ }
+
+ public void run() {
+ // Check ID
+ // FIXME: use an LRU
+ Long lid = new Long(id);
+ if(previousIDs.contains(lid)) {
+ // Reject
+ usm.send(otherSide, DMT.createRejectDueToLoop(id));
+ return;
+ }
+ try {
+ runRequest(key, htl, id, otherSide, rt.getPeerNode(otherSide));
+ } catch (IOException e) {
+ Logger.error(this, "IO error fetching: "+e,e);
+ } catch (CHKVerifyException e) {
+ Logger.error(this, "Couldn't verify data in store for "+key+": "+e,e);
+ }
+ }
+
+ }
+}
Deleted: trunk/freenet/test/PreQuasiNodeTest.java
===================================================================
--- trunk/freenet/src/test/PreQuasiNodeTest.java 2006-12-13 18:27:21 UTC (rev 11374)
+++ trunk/freenet/test/PreQuasiNodeTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -1,349 +0,0 @@
-package test;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.InetAddress;
-import java.util.Random;
-
-import freenet.io.comm.DMT;
-import freenet.io.comm.Dispatcher;
-import freenet.io.comm.Message;
-import freenet.io.comm.MessageFilter;
-import freenet.io.comm.Peer;
-import freenet.io.comm.RetrievalException;
-import freenet.io.comm.UdpSocketManager;
-import freenet.io.xfer.BlockReceiver;
-import freenet.io.xfer.BlockTransmitter;
-import freenet.io.xfer.PartiallyReceivedBlock;
-import freenet.keys.CHKBlock;
-import freenet.keys.CHKDecodeException;
-import freenet.keys.CHKEncodeException;
-import freenet.keys.CHKVerifyException;
-import freenet.keys.ClientCHK;
-import freenet.keys.ClientCHKBlock;
-import freenet.keys.FreenetURI;
-import freenet.keys.NodeCHK;
-import freenet.store.FreenetStore;
-import freenet.support.Buffer;
-import freenet.support.Logger;
-
-/**
- * First do 5 consecutive pings. Then:
- * Take requests and inserts from stdin text interface, like
- * DatastoreTest.
- * Requests:
- * - If can answer from local datastore, do so.
- * - Otherwise route request to partner node.
- * - Partner node may return data, in which case use that.
- * Inserts:
- * - Insert goes just to this node.
- */
-public class PreQuasiNodeTest {
-
- static FreenetStore fs;
- static UdpSocketManager usm;
- static Peer otherSide;
- final static Random r = new Random();
-
- public static void main(String[] args) throws Exception {
- if(args.length < 2) {
- System.err.println("Syntax: PingTest <myPort> <hisPort>");
- System.exit(1);
- }
- Logger.setupStdoutLogging(Logger.DEBUG, "");
- int myPort = Integer.parseInt(args[0]);
- int hisPort = Integer.parseInt(args[1]);
- Logger.minor(TransferBlockTest.class, "My port: "+myPort+", his port: "+hisPort);
- // Set up a UdpSocketManager
- usm = new UdpSocketManager(myPort);
- usm.setDropProbability(5);
- usm.setDispatcher(new PingingReceivingDispatcher());
- otherSide = new Peer(InetAddress.getByName("127.0.0.1"), hisPort);
- int consecutivePings = 0;
- while(consecutivePings < 3) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- Logger.normal(TransferBlockTest.class, "Sending ping");
- usm.send(otherSide, DMT.createPing());
- Message m = usm.waitFor(MessageFilter.create().setTimeout(1000).setType(DMT.pong).setSource(otherSide));
- if(m != null) {
- consecutivePings++;
- Logger.normal(TransferBlockTest.class, "Got pong: "+m);
- } else consecutivePings = 0;
- }
- Logger.normal(TransferBlockTest.class, "Got "+consecutivePings+" consecutive pings");
-
- // Setup datastore
- fs = new FreenetStore("datastore-"+myPort, "headerstore-"+myPort, 1024);
- // Setup logging
- Logger.setupStdoutLogging(Logger.DEBUG, "");
- printHeader();
- // Read command, and data
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- while(true) {
- String line = reader.readLine();
- if(line.startsWith("GET:")) {
- // Should have a key next
- String key = line.substring("GET:".length());
- while(key.length() > 0 && key.charAt(0) == ' ')
- key = key.substring(1);
- while(key.length() > 0 && key.charAt(key.length()-1) == ' ')
- key = key.substring(0, key.length()-2);
- Logger.normal(DatastoreTest.class, "Key: "+key);
- FreenetURI uri = new FreenetURI(key);
- ClientCHK chk = new ClientCHK(uri);
- CHKBlock block;
- try {
- // Fetch, possibly from other node.
- block = fetch(chk.getNodeCHK());
- } catch (CHKVerifyException e1) {
- Logger.error(DatastoreTest.class, "Did not verify: "+e1, e1);
- continue;
- }
- if(block == null) {
- System.out.println("Not found in store: "+chk.getURI());
- } else {
- // Decode it
- byte[] decoded;
- try {
- decoded = block.decode(chk);
- } catch (CHKDecodeException e) {
- Logger.error(DatastoreTest.class, "Cannot decode: "+e, e);
- continue;
- }
- System.out.println("Decoded data:\n");
- System.out.println(new String(decoded));
- }
- } else if(line.startsWith("QUIT")) {
- System.out.println("Goodbye.");
- System.exit(0);
- } else if(line.startsWith("PUT:")) {
- // Just insert to local store
- line = line.substring("PUT:".length());
- while(line.length() > 0 && line.charAt(0) == ' ')
- line = line.substring(1);
- while(line.length() > 0 && line.charAt(line.length()-1) == ' ')
- line = line.substring(0, line.length()-2);
- String content;
- if(line.length() > 0) {
- // Single line insert
- content = line;
- } else {
- // Multiple line insert
- StringBuffer sb = new StringBuffer(1000);
- while(true) {
- line = reader.readLine();
- if(line.equals(".")) break;
- sb.append(line).append('\n');
- }
- content = sb.toString();
- }
- // Insert
- byte[] data = content.getBytes();
- ClientCHKBlock block;
- try {
- block = ClientCHKBlock.encode(data);
- } catch (CHKEncodeException e) {
- Logger.error(DatastoreTest.class, "Couldn't encode: "+e, e);
- continue;
- }
- ClientCHK chk = block.getClientKey();
- FreenetURI uri =
- chk.getURI();
- fs.put(block);
- // Definitely interface
- System.out.println("URI: "+uri);
- } else {
-
- }
- }
- }
-
- /**
- * Either fetch the key from the datastore, or request it
- * from the other node.
- * @param nodeCHK The key to fetch.
- * @return null if we can't find the data.
- */
- private static CHKBlock fetch(NodeCHK nodeCHK) throws IOException, CHKVerifyException {
- // First try the store
- CHKBlock block = fs.fetch(nodeCHK);
- if(block != null) return block;
- // Otherwise...
- long id = r.nextLong();
- Message request = DMT.createTestRequest(nodeCHK, id, -1);
- usm.send(otherSide, request);
- // Wait for response
- Message reply = usm.waitFor(MessageFilter.create().setTimeout(5000).setType(DMT.testDataReply).setField(DMT.UID, id).
- or(MessageFilter.create().setField(DMT.UID, id).setType(DMT.testDataNotFound)));
- // Process reply
- if(reply == null) {
- Logger.normal(PreQuasiNodeTest.class, "Partner node did not reply");
- return null;
- } else if(reply.getSpec() == DMT.testDataNotFound) {
- // DNF
- Logger.normal(PreQuasiNodeTest.class, "Data Not Found");
- Message m = DMT.createTestDataNotFound(id);
- usm.send(otherSide, m);
- // If this gets lost, they'll send it again a few times...
- return null;
- } else if(reply.getSpec() == DMT.testDataReply) {
- byte[] header = ((Buffer)reply.getObject(DMT.TEST_CHK_HEADERS)).getData();
- // Send the ack
- Message m = DMT.createTestDataReplyAck(id);
- usm.send(otherSide, m);
- // Now wait for the transfer; he will send me the data
- // Receive the data
- PartiallyReceivedBlock prb;
- prb = new PartiallyReceivedBlock(32, 1024);
- BlockReceiver br;
- br = new BlockReceiver(usm, otherSide, id, prb);
- byte[] data = null;
- for(int i=0;i<5;i++) {
- try {
- data = br.receive();
- break;
- } catch (RetrievalException e1) {
- if(e1.getReason() == RetrievalException.SENDER_DIED) continue;
- Logger.error(PreQuasiNodeTest.class, "Failed to receive", e1);
- return null;
- }
- }
- if(data == null)
- Logger.error(PreQuasiNodeTest.class, "Could not receive data");
- System.err.println("Received "+data.length+" bytes");
- // Now decode it
- try {
- block = new CHKBlock(data, header, nodeCHK);
- } catch (CHKVerifyException e) {
- Logger.error(PreQuasiNodeTest.class, "Couldn't verify", e);
- return null;
- }
- return block;
- } else {
- Logger.error(PreQuasiNodeTest.class, "Message "+reply+" - WTF?");
- return null;
- }
- }
-
- private static void printHeader() {
- // Write header
- System.out.println("PreQuasiNode tester");
- System.out.println("-------------------");
- System.out.println();
- System.out.println("Enter one of the following commands:");
- System.out.println("GET:<Freenet key> - fetch a key");
- System.out.println("PUT:\n<text, until a . on a line by itself> - We will insert the document and return the key.");
- System.out.println("PUT:<text> - put a single line of text to a CHK and return the key.");
- System.out.println("QUIT - exit the program");
- }
- /**
- * @author root
- *
- * TODO To change the template for this generated type comment go to
- * Window - Preferences - Java - Code Generation - Code and Comments
- */
- public static class PingingReceivingDispatcher implements Dispatcher {
- public boolean handleMessage(Message m) {
- if(m.getSpec() == DMT.ping) {
- usm.send(m.getSource(), DMT.createPong(m));
- return true;
- }
- if(m.getSpec() == DMT.testRequest) {
- // Handle it
- try {
- new Thread(new RequestHandler(m)).start();
- } catch (IllegalStateException e) {
- return true;
- }
- return true;
- }
- return false;
- }
- }
-
- /**
- * Handle a request.
- * Check the store, if we have anything, then send it back.
- * Otherwise send back DNF.
- */
- public static class RequestHandler implements Runnable {
-
- final long id;
- final NodeCHK key;
-
- /**
- * Constructor
- * @param m
- */
- public RequestHandler(Message m) {
- if(m.getSpec() != DMT.testRequest)
- throw new IllegalArgumentException("Not a testRequest: "+m.getSpec().getName());
- id = m.getLong(DMT.UID);
- Object o = m.getObject(DMT.FREENET_ROUTING_KEY);
- if(o instanceof NodeCHK)
- key = (NodeCHK) o;
- else {
- // Ignore it
- Logger.error(RequestHandler.class, "Node sent testRequest but key not a key! Ignoring request.");
- throw new IllegalStateException("Node sent testRequest but key not a key! Ignoring request.");
- }
- }
-
- public void run() {
- CHKBlock block = null;
- try {
- // First try the store
- block = fs.fetch(key);
- } catch (IOException e) {
- Logger.error(this, "IO error fetching: "+e,e);
- } catch (CHKVerifyException e) {
- Logger.error(this, "Couldn't verify data in store for "+key+": "+e,e);
- }
- if(block != null) {
- byte[] header = block.getHeader();
- // First send the header
- Message m = DMT.createTestDataReply(id, header);
- Message ack = null;
- for(int i=0;i<5;i++) {
- usm.send(otherSide, m);
- // Wait for the ack
- ack = usm.waitFor(MessageFilter.create().setType(DMT.testDataReplyAck).setTimeout(1000).setField(DMT.UID, id));
- if(ack == null) {
- // They didn't receive it.
- // Try again.
- usm.send(otherSide, m);
- } else break;
- }
- if(ack == null) {
- // ack still null
- Logger.error(this, "Other side not acknowledging DataReply");
- return;
- }
- // Now send the actual data
- byte[] data = block.getData();
- PartiallyReceivedBlock prb = new PartiallyReceivedBlock(32, 1024, data);
- BlockTransmitter bt = new BlockTransmitter(usm, otherSide, id, prb);
- bt.send();
- // All done
- return;
- } else {
- // block == null
- Message m = DMT.createTestDataNotFound(id);
- for(int i=0;i<5;i++) {
- usm.send(otherSide, m);
- // Wait for the ack
- Message ack = usm.waitFor(MessageFilter.create().setType(DMT.testDataNotFoundAck).setField(DMT.UID, id).setTimeout(1000));
- if(ack != null) return; // done :(
- // Go around again;
- }
- // Still here, so they didn't ack
- Logger.error(this, "Other side not acknowledging DNF");
- }
- }
-
- }
-}
Copied: trunk/freenet/test/PreQuasiNodeTest.java (from rev 11377, trunk/freenet/src/test/PreQuasiNodeTest.java)
===================================================================
--- trunk/freenet/test/PreQuasiNodeTest.java (rev 0)
+++ trunk/freenet/test/PreQuasiNodeTest.java 2006-12-13 19:38:15 UTC (rev 11378)
@@ -0,0 +1,349 @@
+package test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.util.Random;
+
+import freenet.io.comm.DMT;
+import freenet.io.comm.Dispatcher;
+import