aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2012-07-17 15:38:02 +0000
committerFlorian Dold <florian.dold@gmail.com>2012-07-17 15:38:02 +0000
commit19c310288ed6d289a4f663141662cdaca2aabdf9 (patch)
tree71b108827321d2621bc29cdb47cc13e5152dba9b
parent30eee67b8fbe4fcfc77b1e3045772a36b2d34bb8 (diff)
downloadgnunet-java-19c310288ed6d289a4f663141662cdaca2aabdf9.tar.gz
gnunet-java-19c310288ed6d289a4f663141662cdaca2aabdf9.zip
started implementing mesh, implemented file pipe
-rw-r--r--ISSUES38
-rw-r--r--cobertura/coberturaFlush.warbin3471 -> 0 bytes
-rw-r--r--src/org/gnunet/construct/Construct.java14
-rw-r--r--src/org/gnunet/construct/ReflectUtil.java27
-rw-r--r--src/org/gnunet/construct/VariableSizeIntegerArray.java41
-rw-r--r--src/org/gnunet/construct/parsers/VariableSizeIntegerArrayParser.java104
-rw-r--r--src/org/gnunet/mesh/ClientConnectMessage.java9
-rw-r--r--src/org/gnunet/mesh/InboundTunnelHandler.java12
-rw-r--r--src/org/gnunet/mesh/Mesh.java71
-rw-r--r--src/org/gnunet/mesh/TunnelCreateMessage.java16
-rw-r--r--src/org/gnunet/mesh/TunnelDestroyMessage.java16
-rw-r--r--src/org/gnunet/mesh/TunnelEndHandler.java10
-rw-r--r--src/org/gnunet/mesh/TunnelNotificationMessage.java22
-rw-r--r--src/org/gnunet/testing/TestingSubsystem.java1
-rw-r--r--src/org/gnunet/util/Client.java3
-rw-r--r--src/org/gnunet/util/Scheduler.java83
-rw-r--r--test/org/gnunet/construct/ConstructTest.java52
-rw-r--r--test/org/gnunet/construct/IntMessage.java25
-rw-r--r--test/org/gnunet/construct/PrivateMemberMessage.java13
-rw-r--r--test/org/gnunet/construct/VariableSizeMessage.java17
-rw-r--r--test/org/gnunet/core/CoreTest.java5
-rw-r--r--test/org/gnunet/testing/TestingSetupTest.java2
-rw-r--r--test/org/gnunet/util/ClientServerTest.java12
-rw-r--r--test/org/gnunet/util/FilePipeExample.java40
-rw-r--r--test/org/gnunet/util/ServerExample.java1
-rw-r--r--test/org/gnunet/util/TimeTest.java29
-rwxr-xr-xtools/build19
-rwxr-xr-xtools/coverage23
-rwxr-xr-xtools/run-tests2
29 files changed, 678 insertions, 29 deletions
diff --git a/ISSUES b/ISSUES
index b6673a1..2528f68 100644
--- a/ISSUES
+++ b/ISSUES
@@ -196,21 +196,53 @@ PEERINFO_GET vs PEERINFO_GET_ALL
196* where should TESTMessage and HELLOMessage, PeerIdentity, HashCode go? 196* where should TESTMessage and HELLOMessage, PeerIdentity, HashCode go?
197 * and do we want to call them TESTMessage or TestMessage? 197 * and do we want to call them TESTMessage or TestMessage?
198 198
199
200* had a bug in the IPv6 address parsing code 199* had a bug in the IPv6 address parsing code
201 * tried to fix it / rewrite it, eventually got frustrating 200 * tried to fix it / rewrite it, eventually got frustrating
202 * found out guava has an implementation of this :) 201 * found out guava has an implementation of this :)
203 * also implements shortening (like ::1) 202 * also implements shortening (like ::1)
204 * by reading the code: implementing all this correctly would not have been a fun time 203 * by reading the code: implementing all this correctly would not have been a fun time
205 204
206
207* TestingServer now allows the client/connection/server to be tested easily 205* TestingServer now allows the client/connection/server to be tested easily
208 * found quite some bugs during this 206 * found quite some bugs during this
209 207
210* thoughts about exponential backoff / the client-connection stuff in GNUnet and gnunet-java 208* thoughts about exponential backoff / the client-connection stuff in GNUnet and gnunet-java
211 * why do we wait the entire backoff period, if the connection could be available earlier? 209 * why do we wait the entire backoff period, if the connection could be available earlier?
212 210
213
214* discuss what mesh does, what transport does 211* discuss what mesh does, what transport does
215 * i found the documentation for transport on gnunet.org 212 * i found the documentation for transport on gnunet.org
216 * the is not much information about mesh, except for the source code 213 * the is not much information about mesh, except for the source code
214
215---------------------------------------------------------------
216
217* reference count / receive_done behavior is a bit strange / confusing
218 * clients are disconnected only when refcnt==0 *and* shutdown is requested?
219 * behavior on receive done: when success=1 but refcnt=0, why don't we disconnect the client?
220
221 /**
222 * Was processing if incoming messages suspended while
223 * we were still processing data already received?
224 * This is a counter saying how often processing was
225 * suspended (once per handler invoked).
226 */
227
228I don't understand that comment!
229
230
231
232* im currently confused about the different layers of GNUnet / I don't get the big picture
233 * e.g. transport's distance vector plugin vs mesh
234 * peerinfo / mesh
235 * assuming a large network, doesn't a client have to store a large amout of information?
236
237* how to test MESH?
238 * maybe talk to Harsha about testbed? :)
239
240* interesting things happen with JUnit
241 * failure of one test causes timeout in another
242
243* review org.gnunet.testing
244
245cp a x ; cp b x
246is not the same as
247cp b x ; cp a x
248if x does not exist prior to copying
diff --git a/cobertura/coberturaFlush.war b/cobertura/coberturaFlush.war
deleted file mode 100644
index 3deb909..0000000
--- a/cobertura/coberturaFlush.war
+++ /dev/null
Binary files differ
diff --git a/src/org/gnunet/construct/Construct.java b/src/org/gnunet/construct/Construct.java
index 137f3bc..603f5a5 100644
--- a/src/org/gnunet/construct/Construct.java
+++ b/src/org/gnunet/construct/Construct.java
@@ -291,6 +291,7 @@ public class Construct {
291 parser = new FixedSizeByteArrayParser(elemNumber, f); 291 parser = new FixedSizeByteArrayParser(elemNumber, f);
292 } 292 }
293 293
294
294 public void visit(Double d) { 295 public void visit(Double d) {
295 if (!field.getType().equals(java.lang.Double.TYPE)) { 296 if (!field.getType().equals(java.lang.Double.TYPE)) {
296 throw new AssertionError("@Double target must be a primitive 'double' field"); 297 throw new AssertionError("@Double target must be a primitive 'double' field");
@@ -337,6 +338,17 @@ public class Construct {
337 } 338 }
338 } 339 }
339 340
341
342 public void visit(VariableSizeIntegerArray a) {
343 try {
344 parser = new VariableSizeIntegerArrayParser(c.getField(a.lengthField()), field, a.signed(), a.bitSize() / 8);
345 } catch (NoSuchFieldException e) {
346 throw new AssertionError(String.format(
347 "VariableSizeIntegerArray: length field '%s' does not exist in class %s",
348 a.lengthField(), c));
349 }
350 }
351
340 /* 352 /*
341 * We override this to improve the error message, otherwise obfuscated by internal java proxy objects 353 * We override this to improve the error message, otherwise obfuscated by internal java proxy objects
342 */ 354 */
@@ -432,7 +444,7 @@ public class Construct {
432 * @param m the message of interest 444 * @param m the message of interest
433 * @return the static minimum size of the message 445 * @return the static minimum size of the message
434 */ 446 */
435 public int getStaticSize(Message m) { 447 public static int getStaticSize(Message m) {
436 Parser p = getParser(m.getClass()); 448 Parser p = getParser(m.getClass());
437 return p.getStaticSize(); 449 return p.getStaticSize();
438 } 450 }
diff --git a/src/org/gnunet/construct/ReflectUtil.java b/src/org/gnunet/construct/ReflectUtil.java
index 223e7f1..0bc50bc 100644
--- a/src/org/gnunet/construct/ReflectUtil.java
+++ b/src/org/gnunet/construct/ReflectUtil.java
@@ -21,12 +21,18 @@
21package org.gnunet.construct; 21package org.gnunet.construct;
22 22
23 23
24import java.lang.Integer;
25import java.lang.reflect.Array;
24import java.lang.reflect.Field; 26import java.lang.reflect.Field;
25import java.lang.reflect.InvocationTargetException; 27import java.lang.reflect.InvocationTargetException;
26import java.math.BigInteger; 28import java.math.BigInteger;
27import java.util.ArrayList; 29import java.util.ArrayList;
28import java.util.List; 30import java.util.List;
29 31
32/**
33 * Utilities for convenient use of the java reflection API.
34 * All methods only throw non-checked exceptions.
35 */
30public class ReflectUtil { 36public class ReflectUtil {
31 public static <T> T justInstantiate(Class<T> c) { 37 public static <T> T justInstantiate(Class<T> c) {
32 try { 38 try {
@@ -45,6 +51,25 @@ public class ReflectUtil {
45 } 51 }
46 } 52 }
47 53
54 public static void justSetArray(Object arr, int i, long v) {
55 Class t = arr.getClass().getComponentType();
56 if (t.equals(Long.TYPE)) {
57 Array.setLong(arr, i, v);
58 } else if (t.equals(Integer.TYPE)) {
59 Array.setInt(arr, i, (int) v);
60 } else if (t.equals(Short.TYPE)) {
61 Array.setInt(arr, i, (short) v);
62 } else if (t.equals(Byte.TYPE)) {
63 Array.setInt(arr, i, (byte) v);
64 } else if (t.equals(Character.TYPE)) {
65 Array.setInt(arr, i, (char) v);
66 }
67 }
68
69 public static long justGetArrayLong(Object arr, int i) {
70 return Array.getLong(arr, i);
71 }
72
48 /** 73 /**
49 * assign an enum value to each numeric type we want to serialize in 74 * assign an enum value to each numeric type we want to serialize in
50 * order do switch statements on field types 75 * order do switch statements on field types
@@ -69,7 +94,7 @@ public class ReflectUtil {
69 this.targetField = f; 94 this.targetField = f;
70 if (f.getType().equals(Long.TYPE)) { 95 if (f.getType().equals(Long.TYPE)) {
71 targetType = NumFieldType.LONG_PRIM; 96 targetType = NumFieldType.LONG_PRIM;
72 } else if (f.getType().equals(java.lang.Integer.TYPE)) { 97 } else if (f.getType().equals(Integer.TYPE)) {
73 targetType = NumFieldType.INT_PRIM; 98 targetType = NumFieldType.INT_PRIM;
74 } else if (f.getType().equals(Short.TYPE)) { 99 } else if (f.getType().equals(Short.TYPE)) {
75 targetType = NumFieldType.SHORT_PRIM; 100 targetType = NumFieldType.SHORT_PRIM;
diff --git a/src/org/gnunet/construct/VariableSizeIntegerArray.java b/src/org/gnunet/construct/VariableSizeIntegerArray.java
new file mode 100644
index 0000000..a3a9f28
--- /dev/null
+++ b/src/org/gnunet/construct/VariableSizeIntegerArray.java
@@ -0,0 +1,41 @@
1/*
2 This file is part of GNUnet.
3 (C) 2011, 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.construct;
22
23import java.lang.annotation.ElementType;
24import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
26import java.lang.annotation.Target;
27
28/**
29 * An array of integers, where the length of the array is specified in a
30 * field of the containing message.
31 *
32 * @author Florian Dold
33 *
34 */
35@Retention(RetentionPolicy.RUNTIME)
36@Target(ElementType.FIELD)
37public @interface VariableSizeIntegerArray {
38 String lengthField();
39 boolean signed();
40 int bitSize();
41}
diff --git a/src/org/gnunet/construct/parsers/VariableSizeIntegerArrayParser.java b/src/org/gnunet/construct/parsers/VariableSizeIntegerArrayParser.java
new file mode 100644
index 0000000..e5d49bd
--- /dev/null
+++ b/src/org/gnunet/construct/parsers/VariableSizeIntegerArrayParser.java
@@ -0,0 +1,104 @@
1/*
2 This file is part of GNUnet.
3 (C) 2011, 2012 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21package org.gnunet.construct.parsers;
22
23import org.gnunet.construct.Message;
24import org.gnunet.construct.ReflectUtil;
25
26import java.lang.reflect.Array;
27import java.lang.reflect.Field;
28import java.nio.ByteBuffer;
29import java.util.List;
30
31public class VariableSizeIntegerArrayParser implements Parser {
32 private final Field targetField;
33 private ReflectUtil.NumField sizeField;
34 private int byteSize;
35 private boolean signed;
36
37
38 public VariableSizeIntegerArrayParser(Field sizeField, Field arrayField,
39 boolean signed, int byteSize) {
40 targetField = arrayField;
41 this.sizeField = new ReflectUtil.NumField(sizeField);
42 this.signed = signed;
43 this.byteSize = byteSize;
44 }
45
46 @Override
47 public int getSize(final Message src) {
48 int size = 0;
49 final Object arr = ReflectUtil.justGet(src, targetField);
50
51 if (arr == null) {
52 throw new RuntimeException("array not initialized");
53 }
54
55 return Array.getLength(arr) * (byteSize);
56 }
57
58 @Override
59 public int parse(final ByteBuffer srcBuf, int frameOffset, Message frameObj, final Message dstObj, List<Field>
60 frameSizePath) {
61 final int elemNumber = (int) sizeField.get(dstObj);
62
63
64 @SuppressWarnings("unchecked")
65 final Class<Message> arrayElementType = (Class<Message>) targetField.getType().getComponentType();
66
67 if (!arrayElementType.isPrimitive()) {
68 throw new AssertionError("VariableSizeIntegerArray is expected to be of primitive type, not " + arrayElementType);
69 }
70
71 final Object arr = Array.newInstance(arrayElementType, elemNumber);
72 ReflectUtil.justSet(dstObj, targetField, arr);
73
74 for (int i = 0; i < elemNumber; ++i) {
75 long v = IntegerUtil.readLong(srcBuf, signed, byteSize);
76 ReflectUtil.justSetArray(arr, i, v);
77 }
78
79 return byteSize * elemNumber;
80 }
81
82 @Override
83 public int write(final ByteBuffer dstBuf, final Message src) {
84 int size = 0;
85 final Object arr = ReflectUtil.justGet(src, targetField);
86 for (int i = 0; i < Array.getLength(arr); ++i) {
87 IntegerUtil.writeLong(ReflectUtil.justGetArrayLong(arr, i), dstBuf, signed, byteSize);
88 size += byteSize;
89 }
90 return size;
91 }
92
93 @Override
94 public void patch(Message m, int frameSize, List<Field> frameSizePath, Message frameObj) {
95 int size = Array.getLength(ReflectUtil.justGet(m, targetField));
96 sizeField.set(m, size);
97 }
98
99 @Override
100 public int getStaticSize() {
101 return 0;
102 }
103
104}
diff --git a/src/org/gnunet/mesh/ClientConnectMessage.java b/src/org/gnunet/mesh/ClientConnectMessage.java
index d0c9521..3a09373 100644
--- a/src/org/gnunet/mesh/ClientConnectMessage.java
+++ b/src/org/gnunet/mesh/ClientConnectMessage.java
@@ -1,6 +1,9 @@
1package org.gnunet.mesh; 1package org.gnunet.mesh;
2 2
3import org.gnunet.construct.FixedSizeArray;
3import org.gnunet.construct.UInt16; 4import org.gnunet.construct.UInt16;
5import org.gnunet.construct.UnionCase;
6import org.gnunet.construct.VariableSizeArray;
4import org.gnunet.util.GnunetMessage; 7import org.gnunet.util.GnunetMessage;
5 8
6/** 9/**
@@ -8,8 +11,14 @@ import org.gnunet.util.GnunetMessage;
8 * 11 *
9 * @author Florian Dold 12 * @author Florian Dold
10 */ 13 */
14@UnionCase(272)
11public class ClientConnectMessage implements GnunetMessage.Body { 15public class ClientConnectMessage implements GnunetMessage.Body {
12 @UInt16 16 @UInt16
13 public int applications; 17 public int applications;
18 @UInt16
14 public int types; 19 public int types;
20 @VariableSizeArray(lengthField = "applications")
21 public int[] apps_list;
22 @VariableSizeArray(lengthField = "types")
23 public int[] types_list;
15} 24}
diff --git a/src/org/gnunet/mesh/InboundTunnelHandler.java b/src/org/gnunet/mesh/InboundTunnelHandler.java
new file mode 100644
index 0000000..ebcf225
--- /dev/null
+++ b/src/org/gnunet/mesh/InboundTunnelHandler.java
@@ -0,0 +1,12 @@
1package org.gnunet.mesh;
2
3import org.gnunet.util.PeerIdentity;
4
5/**
6 * ...
7 *
8 * @author Florian Dold
9 */
10public interface InboundTunnelHandler {
11 void onInboundTunnel(Mesh.Tunnel tunnel, PeerIdentity initiator);
12}
diff --git a/src/org/gnunet/mesh/Mesh.java b/src/org/gnunet/mesh/Mesh.java
index a0f1e13..d739b61 100644
--- a/src/org/gnunet/mesh/Mesh.java
+++ b/src/org/gnunet/mesh/Mesh.java
@@ -20,30 +20,89 @@
20 20
21package org.gnunet.mesh; 21package org.gnunet.mesh;
22 22
23import org.gnunet.util.Cancelable; 23import org.gnunet.requests.Request;
24import org.gnunet.util.Configuration; 24import org.gnunet.requests.RequestQueue;
25import org.gnunet.util.*;
26import org.grothoff.Runabout;
27
28import java.util.List;
25 29
26/** 30/**
27 * @author Florian Dold 31 * @author Florian Dold
28 */ 32 */
29public class Mesh { 33public class Mesh {
30 public static class Tunnel { 34 private RequestQueue requestQueue;
35 private TunnelEndHandler tunnelEndHandler;
36 private Runabout messageReceiver;
37 private List<Integer> applications;
38 private InboundTunnelHandler inboundTunnelHandler;
39
40
41 public static class RootTunnel {
42 int tunnel_id;
43 public void addPeer(PeerIdentity peerIdentity) {
44
45 }
46 public void blacklist(PeerIdentity peerIdentity) {
47
48 }
31 public void destroy() { 49 public void destroy() {
32 // ... 50 // ...
33 } 51 }
34 public Cancelable notifyTransmitReady(/* ... */) { 52 }
53
54 public static class Tunnel extends RootTunnel {
55 public Cancelable notifyTransmitReady(PeerIdentity target) {
35 return null; 56 return null;
36 } 57 }
37 } 58 }
38 59
39 public Mesh(Configuration cfg, int queueSize) { 60
61 public class ClientConnectRequest extends Request {
62
63 @Override
64 public void transmit(Connection.MessageSink sink) {
65 //To change body of implemented methods use File | Settings | File Templates.
66 }
67 }
68
69
70 private class MeshMessageReceiver extends RunaboutMessageReceiver {
71
72 @Override
73 public void handleError() {
74 }
75 }
76
77
78 public Mesh(Configuration cfg, InboundTunnelHandler inboundTunnelHandler,
79 TunnelEndHandler tunnelEndHandler, Runabout messageReceiver, List<Integer> applications) {
80 this.tunnelEndHandler = tunnelEndHandler;
81 this.messageReceiver = messageReceiver;
82 this.applications = applications;
83 this.inboundTunnelHandler = inboundTunnelHandler;
84
85 Client client = new Client("mesh", cfg);
86 requestQueue = new RequestQueue(client, new MeshMessageReceiver());
87
88 requestQueue.add(new ClientConnectRequest());
40 89
41 } 90 }
42 91
43 public Tunnel createTunnel(/* ... */) { 92 /**
93 * Create a new tunnel (we're initiator and will be allowed to add/remove peers
94 * and to broadcast).
95 */
96 public RootTunnel createTunnel(/* ... */) {
44 return null; 97 return null;
45 } 98 }
46 99
100 /**
101 * Disconnect from the mesh service. All tunnels will be destroyed. All tunnel
102 * disconnect callbacks will be called on any still connected peers, notifying
103 * about their disconnection. The registered inbound tunnel cleaner will be
104 * called should any inbound tunnels still exist.
105 */
47 public void disconnect() { 106 public void disconnect() {
48 107
49 } 108 }
diff --git a/src/org/gnunet/mesh/TunnelCreateMessage.java b/src/org/gnunet/mesh/TunnelCreateMessage.java
new file mode 100644
index 0000000..96d821c
--- /dev/null
+++ b/src/org/gnunet/mesh/TunnelCreateMessage.java
@@ -0,0 +1,16 @@
1package org.gnunet.mesh;
2
3import org.gnunet.construct.UInt32;
4import org.gnunet.construct.UnionCase;
5import org.gnunet.util.GnunetMessage;
6
7/**
8 * ...
9 *
10 * @author Florian Dold
11 */
12@UnionCase(273)
13public class TunnelCreateMessage implements GnunetMessage.Body {
14 @UInt32
15 public int tunnel_id;
16}
diff --git a/src/org/gnunet/mesh/TunnelDestroyMessage.java b/src/org/gnunet/mesh/TunnelDestroyMessage.java
new file mode 100644
index 0000000..bce60bb
--- /dev/null
+++ b/src/org/gnunet/mesh/TunnelDestroyMessage.java
@@ -0,0 +1,16 @@
1package org.gnunet.mesh;
2
3import org.gnunet.construct.UInt32;
4import org.gnunet.construct.UnionCase;
5import org.gnunet.util.GnunetMessage;
6
7/**
8 * ...
9 *
10 * @author Florian Dold
11 */
12@UnionCase(274)
13public class TunnelDestroyMessage implements GnunetMessage.Body {
14 @UInt32
15 public int tunnel_id;
16}
diff --git a/src/org/gnunet/mesh/TunnelEndHandler.java b/src/org/gnunet/mesh/TunnelEndHandler.java
new file mode 100644
index 0000000..e56fdd4
--- /dev/null
+++ b/src/org/gnunet/mesh/TunnelEndHandler.java
@@ -0,0 +1,10 @@
1package org.gnunet.mesh;
2
3/**
4 * ...
5 *
6 * @author Florian Dold
7 */
8public interface TunnelEndHandler {
9 void onTunnelEnd(Mesh.Tunnel tunnel);
10}
diff --git a/src/org/gnunet/mesh/TunnelNotificationMessage.java b/src/org/gnunet/mesh/TunnelNotificationMessage.java
new file mode 100644
index 0000000..8846088
--- /dev/null
+++ b/src/org/gnunet/mesh/TunnelNotificationMessage.java
@@ -0,0 +1,22 @@
1package org.gnunet.mesh;
2
3import org.gnunet.construct.NestedMessage;
4import org.gnunet.construct.UInt32;
5import org.gnunet.util.GnunetMessage;
6import org.gnunet.util.PeerIdentity;
7
8/**
9 * ...
10 *
11 * @author Florian Dold
12 */
13public class TunnelNotificationMessage implements GnunetMessage.Body {
14 @UInt32
15 public int tunnel_id;
16 /**
17 * Peer at the other end, if any
18 * TODO: ask bart what 'if any' means here
19 */
20 @NestedMessage
21 public PeerIdentity peer;
22}
diff --git a/src/org/gnunet/testing/TestingSubsystem.java b/src/org/gnunet/testing/TestingSubsystem.java
index 3bd809b..f38ac43 100644
--- a/src/org/gnunet/testing/TestingSubsystem.java
+++ b/src/org/gnunet/testing/TestingSubsystem.java
@@ -102,6 +102,7 @@ public class TestingSubsystem {
102 if (!line.equals("bye")) { 102 if (!line.equals("bye")) {
103 throw new TestingSetup.SetupException("service not destroyed correctly"); 103 throw new TestingSetup.SetupException("service not destroyed correctly");
104 } 104 }
105 System.out.println("read bye");
105 try { 106 try {
106 p.waitFor(); 107 p.waitFor();
107 } catch (InterruptedException e) { 108 } catch (InterruptedException e) {
diff --git a/src/org/gnunet/util/Client.java b/src/org/gnunet/util/Client.java
index 82b3ce1..d2e1308 100644
--- a/src/org/gnunet/util/Client.java
+++ b/src/org/gnunet/util/Client.java
@@ -24,6 +24,9 @@ import org.slf4j.LoggerFactory;
24 24
25/** 25/**
26 * A connection to a gnunet service. 26 * A connection to a gnunet service.
27 *
28 * Wraps a Connection, and is responsible for waiting until the underlying connection has been made
29 * and allows reconnects.
27 */ 30 */
28public class Client { 31public class Client {
29 private static final Logger logger = LoggerFactory 32 private static final Logger logger = LoggerFactory
diff --git a/src/org/gnunet/util/Scheduler.java b/src/org/gnunet/util/Scheduler.java
index 25faee2..611467e 100644
--- a/src/org/gnunet/util/Scheduler.java
+++ b/src/org/gnunet/util/Scheduler.java
@@ -23,8 +23,8 @@ package org.gnunet.util;
23import org.slf4j.Logger; 23import org.slf4j.Logger;
24import org.slf4j.LoggerFactory; 24import org.slf4j.LoggerFactory;
25 25
26import java.io.IOError; 26import java.io.*;
27import java.io.IOException; 27import java.nio.ByteBuffer;
28import java.nio.channels.*; 28import java.nio.channels.*;
29import java.nio.channels.spi.SelectorProvider; 29import java.nio.channels.spi.SelectorProvider;
30import java.util.*; 30import java.util.*;
@@ -241,12 +241,15 @@ public class Scheduler {
241 public void selectRead(SelectableChannel channel) { 241 public void selectRead(SelectableChannel channel) {
242 addChannelEvent(channel, EVENT_READ); 242 addChannelEvent(channel, EVENT_READ);
243 } 243 }
244
244 public void selectWrite(SelectableChannel channel) { 245 public void selectWrite(SelectableChannel channel) {
245 addChannelEvent(channel, EVENT_WRITE); 246 addChannelEvent(channel, EVENT_WRITE);
246 } 247 }
248
247 public void selectConnect(SelectableChannel channel) { 249 public void selectConnect(SelectableChannel channel) {
248 addChannelEvent(channel, EVENT_CONNECT); 250 addChannelEvent(channel, EVENT_CONNECT);
249 } 251 }
252
250 public void selectAccept(SelectableChannel channel) { 253 public void selectAccept(SelectableChannel channel) {
251 addChannelEvent(channel, EVENT_ACCEPT); 254 addChannelEvent(channel, EVENT_ACCEPT);
252 } 255 }
@@ -304,7 +307,7 @@ public class Scheduler {
304 } 307 }
305 308
306 public static TaskConfiguration addRead(RelativeTime timeout, 309 public static TaskConfiguration addRead(RelativeTime timeout,
307 SelectableChannel chan, Task task) { 310 SelectableChannel chan, Task task) {
308 TaskConfiguration tid = new TaskConfiguration(timeout, task); 311 TaskConfiguration tid = new TaskConfiguration(timeout, task);
309 tid.addChannelEvent(chan, EVENT_READ); 312 tid.addChannelEvent(chan, EVENT_READ);
310 tid.schedule(); 313 tid.schedule();
@@ -312,7 +315,7 @@ public class Scheduler {
312 } 315 }
313 316
314 public static TaskConfiguration addWrite(RelativeTime timeout, 317 public static TaskConfiguration addWrite(RelativeTime timeout,
315 SelectableChannel chan, Task task) { 318 SelectableChannel chan, Task task) {
316 TaskConfiguration tid = new TaskConfiguration(timeout, task); 319 TaskConfiguration tid = new TaskConfiguration(timeout, task);
317 tid.addChannelEvent(chan, EVENT_WRITE); 320 tid.addChannelEvent(chan, EVENT_WRITE);
318 tid.schedule(); 321 tid.schedule();
@@ -519,4 +522,76 @@ public class Scheduler {
519 } 522 }
520 pending.clear(); 523 pending.clear();
521 } 524 }
525
526
527 /**
528 * A handle to a file system object that can be selected on.
529 */
530 public static class FilePipe {
531 private FilePipeThread filePipeThread;
532
533 private FilePipe(FilePipeThread filePipeThread) {
534 this.filePipeThread = filePipeThread;
535 }
536
537 public Pipe.SourceChannel getSource() {
538 return filePipeThread.pipe.source();
539 }
540
541 }
542
543 private static class FilePipeThread extends Thread {
544 public File file;
545 public Pipe pipe;
546
547 FilePipeThread(File file) {
548 this.file = file;
549 try {
550 pipe = SelectorProvider.provider().openPipe();
551 pipe.source().configureBlocking(false);
552 pipe.sink().configureBlocking(false);
553 } catch (IOException e) {
554 throw new RuntimeException("selector provider has no pipes");
555 }
556 }
557
558 @Override
559 public void run() {
560 // has to be done in thread, blocks if file is a fifo
561 FileChannel fileChannel;
562
563 try {
564 FileInputStream stream;
565 stream = new FileInputStream(file);
566 fileChannel = stream.getChannel();
567 } catch (FileNotFoundException e) {
568 throw new IOError(e);
569 }
570
571 ByteBuffer buffer = ByteBuffer.allocate(256);
572
573 try {
574 while (true) {
575 buffer.clear();
576
577 fileChannel.read(buffer);
578
579 buffer.flip();
580
581 pipe.sink().write(buffer);
582 }
583 } catch (IOException e) {
584 throw new IOError(e);
585 }
586
587 }
588 }
589
590
591 public static FilePipe createFilePipe(File file) {
592 FilePipeThread fpt = new FilePipeThread(file);
593 fpt.setDaemon(true);
594 fpt.start();
595 return new FilePipe(fpt);
596 }
522} 597}
diff --git a/test/org/gnunet/construct/ConstructTest.java b/test/org/gnunet/construct/ConstructTest.java
index 470df5e..c7f9853 100644
--- a/test/org/gnunet/construct/ConstructTest.java
+++ b/test/org/gnunet/construct/ConstructTest.java
@@ -3,6 +3,8 @@ package org.gnunet.construct;
3import org.junit.Assert; 3import org.junit.Assert;
4import org.junit.Test; 4import org.junit.Test;
5 5
6import java.util.Random;
7
6/** 8/**
7 * @author Florian Dold 9 * @author Florian Dold
8 */ 10 */
@@ -27,4 +29,54 @@ public class ConstructTest {
27 Assert.assertArrayEquals(new byte[]{0,1,2,3}, msg_r.bytes); 29 Assert.assertArrayEquals(new byte[]{0,1,2,3}, msg_r.bytes);
28 } 30 }
29 31
32
33 @Test
34 public void test_IntMessage() {
35 IntMessage im = new IntMessage();
36 Random r = new Random();
37 im.i1 = r.nextLong();
38 im.i2 = r.nextLong();
39 im.i3 = r.nextLong();
40 im.i4 = r.nextLong();
41 im.i5 = r.nextLong();
42 im.i6 = r.nextLong();
43 im.i7 = r.nextLong();
44 im.i8 = r.nextLong();
45
46 byte[] data = Construct.toBinary(im);
47
48 IntMessage im_new = Construct.parseAs(data, IntMessage.class);
49
50 Assert.assertEquals((1+2+4+8)*2, data.length);
51 Assert.assertEquals((1+2+4+8)*2, Construct.getStaticSize(im));
52 }
53
54 @Test(expected = AssertionError.class)
55 public void test_PrivateMemberMessage() {
56 PrivateMemberMessage m1 = new PrivateMemberMessage();
57 byte[] data = Construct.toBinary(m1);
58 PrivateMemberMessage m2 = Construct.parseAs(data, PrivateMemberMessage.class);
59 }
60
61
62 @Test
63 public void test_variable_size() {
64 VariableSizeMessage m1 = new VariableSizeMessage();
65 m1.n1 = 2;
66 m1.n2 = 3;
67 m1.a1 = new int[]{42,43};
68 m1.a2 = new int[]{1,2,1000};
69
70 byte[] data = Construct.toBinary(m1);
71
72 VariableSizeMessage m2 = Construct.parseAs(data, VariableSizeMessage.class);
73
74 Assert.assertEquals(m1.n1, m2.n1);
75 Assert.assertEquals(m1.n2, m2.n2);
76 Assert.assertArrayEquals(m1.a1, m2.a1);
77 Assert.assertArrayEquals(m1.a2, m2.a2);
78 }
79
80
30} 81}
82
diff --git a/test/org/gnunet/construct/IntMessage.java b/test/org/gnunet/construct/IntMessage.java
new file mode 100644
index 0000000..14971b2
--- /dev/null
+++ b/test/org/gnunet/construct/IntMessage.java
@@ -0,0 +1,25 @@
1package org.gnunet.construct;
2
3/**
4 * ...
5 *
6 * @author Florian Dold
7 */
8public class IntMessage implements Message {
9 @UInt64
10 public long i1;
11 @UInt32
12 public long i2;
13 @UInt16
14 public long i3;
15 @UInt8
16 public long i4;
17 @Int64
18 public long i5;
19 @Int32
20 public long i6;
21 @Int16
22 public long i7;
23 @Int8
24 public long i8;
25}
diff --git a/test/org/gnunet/construct/PrivateMemberMessage.java b/test/org/gnunet/construct/PrivateMemberMessage.java
new file mode 100644
index 0000000..726d1b7
--- /dev/null
+++ b/test/org/gnunet/construct/PrivateMemberMessage.java
@@ -0,0 +1,13 @@
1package org.gnunet.construct;
2
3/**
4 * ...
5 *
6 * @author Florian Dold
7 */
8public class PrivateMemberMessage implements Message {
9 @UInt32
10 public int foo;
11 @UInt32
12 private int bar;
13}
diff --git a/test/org/gnunet/construct/VariableSizeMessage.java b/test/org/gnunet/construct/VariableSizeMessage.java
new file mode 100644
index 0000000..9444108
--- /dev/null
+++ b/test/org/gnunet/construct/VariableSizeMessage.java
@@ -0,0 +1,17 @@
1package org.gnunet.construct;
2
3/**
4 * ...
5 *
6 * @author Florian Dold
7 */
8public class VariableSizeMessage implements Message {
9 @UInt16
10 public int n1;
11 @VariableSizeIntegerArray(lengthField = "n1", signed = false, bitSize = 16)
12 public int[] a1;
13 @UInt16
14 public int n2;
15 @VariableSizeIntegerArray(lengthField = "n2", signed = false, bitSize = 16)
16 public int[] a2;
17}
diff --git a/test/org/gnunet/core/CoreTest.java b/test/org/gnunet/core/CoreTest.java
index 59a0d5d..e4a9142 100644
--- a/test/org/gnunet/core/CoreTest.java
+++ b/test/org/gnunet/core/CoreTest.java
@@ -26,6 +26,7 @@ import org.gnunet.testing.TestingSubsystem;
26import org.gnunet.util.*; 26import org.gnunet.util.*;
27import org.grothoff.Runabout; 27import org.grothoff.Runabout;
28import org.junit.Assert; 28import org.junit.Assert;
29import org.junit.Ignore;
29import org.junit.Test; 30import org.junit.Test;
30 31
31import static org.junit.Assert.assertTrue; 32import static org.junit.Assert.assertTrue;
@@ -58,6 +59,8 @@ public class CoreTest {
58 59
59 Scheduler.run(); 60 Scheduler.run();
60 61
62 ts.destroy();
63
61 assertTrue(res.value); 64 assertTrue(res.value);
62 } 65 }
63 66
@@ -96,6 +99,8 @@ public class CoreTest {
96 99
97 Scheduler.run(); 100 Scheduler.run();
98 101
102 ts.destroy();
103
99 assertTrue(gotResponse.get()); 104 assertTrue(gotResponse.get());
100 105
101 } 106 }
diff --git a/test/org/gnunet/testing/TestingSetupTest.java b/test/org/gnunet/testing/TestingSetupTest.java
index 7b4b646..b23b543 100644
--- a/test/org/gnunet/testing/TestingSetupTest.java
+++ b/test/org/gnunet/testing/TestingSetupTest.java
@@ -48,7 +48,7 @@ public class TestingSetupTest {
48 // could be any service, just use statistics 48 // could be any service, just use statistics
49 TestingSetup testing = new TestingSetup(); 49 TestingSetup testing = new TestingSetup();
50 TestingSubsystem ts = testing.startSubsystem("statistics"); 50 TestingSubsystem ts = testing.startSubsystem("statistics");
51 ts.restart(); 51 //ts.restart();
52 ts.destroy(); 52 ts.destroy();
53 } 53 }
54} 54}
diff --git a/test/org/gnunet/util/ClientServerTest.java b/test/org/gnunet/util/ClientServerTest.java
index 677131e..f073a3c 100644
--- a/test/org/gnunet/util/ClientServerTest.java
+++ b/test/org/gnunet/util/ClientServerTest.java
@@ -11,10 +11,15 @@ import org.junit.Test;
11 * @author Florian Dold 11 * @author Florian Dold
12 */ 12 */
13public class ClientServerTest { 13public class ClientServerTest {
14
15 /**
16 * Test if the server receives a message sent by a client.
17 */
14 @Test(timeout = 1000) 18 @Test(timeout = 1000)
15 public void test_testing_server() { 19 public void test_testing_server() {
16 final TestingSetup setup = new TestingSetup(); 20 final TestingSetup setup = new TestingSetup();
17 Program.configureLogging("DEBUG", null); 21 Program.configureLogging("DEBUG", null);
22
18 final TestingServer srv = setup.createServer(); 23 final TestingServer srv = setup.createServer();
19 24
20 final Wrapper<Boolean> gotMessage = new Wrapper<Boolean>(false); 25 final Wrapper<Boolean> gotMessage = new Wrapper<Boolean>(false);
@@ -39,7 +44,7 @@ public class ClientServerTest {
39 44
40 @Override 45 @Override
41 public void handleError() { 46 public void handleError() {
42 47 Assert.fail();
43 } 48 }
44 }); 49 });
45 System.out.println("done"); 50 System.out.println("done");
@@ -50,6 +55,10 @@ public class ClientServerTest {
50 } 55 }
51 56
52 57
58 /**
59 * Test what happens when a client calls notifyTransmitReady, but does not send
60 * a message in the callback but disconnects.
61 */
53 @Test(timeout = 1000) 62 @Test(timeout = 1000)
54 public void test_premature_disconnect() { 63 public void test_premature_disconnect() {
55 final TestingSetup setup = new TestingSetup(); 64 final TestingSetup setup = new TestingSetup();
@@ -79,7 +88,6 @@ public class ClientServerTest {
79 Assert.fail(); 88 Assert.fail();
80 } 89 }
81 }); 90 });
82
83 } 91 }
84 }); 92 });
85 } 93 }
diff --git a/test/org/gnunet/util/FilePipeExample.java b/test/org/gnunet/util/FilePipeExample.java
new file mode 100644
index 0000000..4b72163
--- /dev/null
+++ b/test/org/gnunet/util/FilePipeExample.java
@@ -0,0 +1,40 @@
1package org.gnunet.util;
2
3import java.io.File;
4import java.io.IOError;
5import java.io.IOException;
6import java.nio.ByteBuffer;
7
8/**
9 * ...
10 *
11 * @author Florian Dold
12 */
13public class FilePipeExample {
14 public static void main(String... args) {
15
16
17 final Scheduler.FilePipe fp = Scheduler.createFilePipe(new File("test.pipe"));
18
19
20 Scheduler.addRead(RelativeTime.FOREVER, fp.getSource(), new Scheduler.Task() {
21 @Override
22 public void run(Scheduler.RunContext ctx) {
23 ByteBuffer b = ByteBuffer.allocate(1);
24 b.clear();
25 try {
26 fp.getSource().read(b);
27 } catch (IOException e) {
28 throw new IOError(e);
29 }
30 b.flip();
31 System.out.println("got: " + b.get());
32
33 Scheduler.addRead(RelativeTime.FOREVER, fp.getSource(), this);
34
35 }
36 });
37
38 Scheduler.run();
39 }
40}
diff --git a/test/org/gnunet/util/ServerExample.java b/test/org/gnunet/util/ServerExample.java
index 8af3b6d..be74b61 100644
--- a/test/org/gnunet/util/ServerExample.java
+++ b/test/org/gnunet/util/ServerExample.java
@@ -39,7 +39,6 @@ public class ServerExample {
39 new Program(args) { 39 new Program(args) {
40 @Override 40 @Override
41 public void run() { 41 public void run() {
42
43 Server s = new Server(Arrays.asList(new SocketAddress[]{new InetSocketAddress("127.0.0.1", 3456)}), 42 Server s = new Server(Arrays.asList(new SocketAddress[]{new InetSocketAddress("127.0.0.1", 3456)}),
44 RelativeTime.MINUTE, 43 RelativeTime.MINUTE,
45 false); 44 false);
diff --git a/test/org/gnunet/util/TimeTest.java b/test/org/gnunet/util/TimeTest.java
new file mode 100644
index 0000000..6663c93
--- /dev/null
+++ b/test/org/gnunet/util/TimeTest.java
@@ -0,0 +1,29 @@
1package org.gnunet.util;
2
3import junit.framework.Assert;
4import org.junit.Test;
5
6/**
7 * ...
8 *
9 * @author Florian Dold
10 */
11public class TimeTest {
12
13 @Test
14 public void test_absolute_add_subtract() {
15 AbsoluteTime t1 = AbsoluteTime.now().add(RelativeTime.FOREVER);
16 Assert.assertEquals(t1, AbsoluteTime.FOREVER);
17 Assert.assertTrue(t1.isForever());
18
19 t1 = AbsoluteTime.FOREVER.add(RelativeTime.SECOND);
20 Assert.assertEquals(t1, AbsoluteTime.FOREVER);
21 Assert.assertTrue(t1.isForever());
22
23 AbsoluteTime t2 = (new AbsoluteTime(123000)).add(RelativeTime.SECOND);
24 Assert.assertEquals(124000, t2.getMilliseconds());
25
26 AbsoluteTime t3 = (new AbsoluteTime(123000)).subtract(RelativeTime.SECOND);
27 Assert.assertEquals(122000, t3.getMilliseconds());
28 }
29}
diff --git a/tools/build b/tools/build
index 9e631d0..225be8e 100755
--- a/tools/build
+++ b/tools/build
@@ -1,21 +1,28 @@
1#!/bin/bash 1#!/bin/bash
2 2
3# everything from src/ is compiled to build,
4# everything from test/ is compiled to build-test
5
3# environment variables: 6# environment variables:
4# $JFLAGS: additional flags passed to the java compiler 7# $JFLAGS: additional flags passed to the java compiler
5 8
6 9# exit when something goes wrong!
10set -e
7 11
8BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/.. 12BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
9 13
10# collect all source files
11SOURCES=`find "$BASEDIR/src/" "$BASEDIR/test/" -name "*.java"`
12 14
15# collect all source files
16SOURCES_PROD=`find "$BASEDIR/src/" -name "*.java"`
17SOURCES_TEST=`find "$BASEDIR/test/" -name "*.java"`
13 18
14 19
20mkdir -p "$BASEDIR/build"
21mkdir -p "$BASEDIR/build-test"
15 22
16mkdir -p $BASEDIR/build 23javac -g $JFLAGS -cp "$BASEDIR/lib/*" -d "$BASEDIR/build/" $SOURCES_PROD
17 24
18javac -g $JFLAGS -cp "$BASEDIR/build/:$BASEDIR/lib/*" -d $BASEDIR/build/ $SOURCES || exit 1 25javac -g $JFLAGS -cp "$BASEDIR/build:$BASEDIR/lib/*" -d "$BASEDIR/build-test/" $SOURCES_TEST
19 26
20cd "$BASEDIR/src/" 27cd "$BASEDIR/src/"
21 28
@@ -32,4 +39,4 @@ cd $OLDPWD
32# make jar 39# make jar
33./tools/make-jar 40./tools/make-jar
34 41
35 42echo ok
diff --git a/tools/coverage b/tools/coverage
index f8906d5..4834adc 100755
--- a/tools/coverage
+++ b/tools/coverage
@@ -2,15 +2,32 @@
2 2
3BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/.. 3BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
4 4
5INSTRUMENT_CMD="sh $BASEDIR/cobertura/cobertura-instrument.sh --datafile $BASEDIR/coverage.data --destination $BASEDIR/build-instrumented --ignore assert " 5INSTRUMENT_CMD="sh $BASEDIR/cobertura/cobertura-instrument.sh --datafile $BASEDIR/coverage.data --destination $BASEDIR/build-instrumented --ignore .*assert.*"
6 6
7echo $INSTRUMENT_CMD 7echo $INSTRUMENT_CMD
8 8
9set -x
10
9 11
10case "$1" in 12case "$1" in
11instrument) 13instrument)
12 cp -r "$BASEDIR/build/" "$BASEDIR/build-instrumented/" 14 echo "instrumenteing"
13 find $BASEDIR/build/ -name *.class | grep -v .*Test.* | xargs $INSTRUMENT_CMD 15
16 mkdir -p "build-instrumented"
17
18 cp -r -t "$BASEDIR/build-instrumented/" "$BASEDIR/build/"* "$BASEDIR/build-test/"*
19
20 find $BASEDIR/build/ -name *.class |
21 grep -v .*Test.* |
22 grep -v .*test/.* |
23 grep -v .*Benchmark.* |
24 grep -v .*Example.* |
25 grep -v .*Exception.* |
26 grep -v .*AnnotationProcessor.* |
27 xargs $INSTRUMENT_CMD
28
29 echo "instrumenteing end"
30
14 ;; 31 ;;
15clean) 32clean)
16 rm -r $BASEDIR/build-instrumented &>/dev/null 33 rm -r $BASEDIR/build-instrumented &>/dev/null
diff --git a/tools/run-tests b/tools/run-tests
index 9ff5178..32f2044 100755
--- a/tools/run-tests
+++ b/tools/run-tests
@@ -9,7 +9,7 @@ TESTS=$( find . -name "*Test.java" | sed -e 's/\.java//' -e 's/..//' -e 's/\//\.
9 9
10echo Testing classes: $TESTS 10echo Testing classes: $TESTS
11 11
12java -cp "$BASEDIR/build:$BASEDIR/lib/*" org.junit.runner.JUnitCore $TESTS 12java -cp "$BASEDIR/build:$BASEDIR/build-test:$BASEDIR/lib/*" org.junit.runner.JUnitCore $TESTS
13 13
14cd $OLDPWD 14cd $OLDPWD
15 15