diff options
author | Florian Dold <florian.dold@gmail.com> | 2012-07-17 15:38:02 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2012-07-17 15:38:02 +0000 |
commit | 19c310288ed6d289a4f663141662cdaca2aabdf9 (patch) | |
tree | 71b108827321d2621bc29cdb47cc13e5152dba9b | |
parent | 30eee67b8fbe4fcfc77b1e3045772a36b2d34bb8 (diff) | |
download | gnunet-java-19c310288ed6d289a4f663141662cdaca2aabdf9.tar.gz gnunet-java-19c310288ed6d289a4f663141662cdaca2aabdf9.zip |
started implementing mesh, implemented file pipe
29 files changed, 678 insertions, 29 deletions
@@ -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 | |||
228 | I 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 | |||
245 | cp a x ; cp b x | ||
246 | is not the same as | ||
247 | cp b x ; cp a x | ||
248 | if 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 @@ | |||
21 | package org.gnunet.construct; | 21 | package org.gnunet.construct; |
22 | 22 | ||
23 | 23 | ||
24 | import java.lang.Integer; | ||
25 | import java.lang.reflect.Array; | ||
24 | import java.lang.reflect.Field; | 26 | import java.lang.reflect.Field; |
25 | import java.lang.reflect.InvocationTargetException; | 27 | import java.lang.reflect.InvocationTargetException; |
26 | import java.math.BigInteger; | 28 | import java.math.BigInteger; |
27 | import java.util.ArrayList; | 29 | import java.util.ArrayList; |
28 | import java.util.List; | 30 | import 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 | */ | ||
30 | public class ReflectUtil { | 36 | public 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 | |||
21 | package org.gnunet.construct; | ||
22 | |||
23 | import java.lang.annotation.ElementType; | ||
24 | import java.lang.annotation.Retention; | ||
25 | import java.lang.annotation.RetentionPolicy; | ||
26 | import 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) | ||
37 | public @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 | |||
21 | package org.gnunet.construct.parsers; | ||
22 | |||
23 | import org.gnunet.construct.Message; | ||
24 | import org.gnunet.construct.ReflectUtil; | ||
25 | |||
26 | import java.lang.reflect.Array; | ||
27 | import java.lang.reflect.Field; | ||
28 | import java.nio.ByteBuffer; | ||
29 | import java.util.List; | ||
30 | |||
31 | public 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 @@ | |||
1 | package org.gnunet.mesh; | 1 | package org.gnunet.mesh; |
2 | 2 | ||
3 | import org.gnunet.construct.FixedSizeArray; | ||
3 | import org.gnunet.construct.UInt16; | 4 | import org.gnunet.construct.UInt16; |
5 | import org.gnunet.construct.UnionCase; | ||
6 | import org.gnunet.construct.VariableSizeArray; | ||
4 | import org.gnunet.util.GnunetMessage; | 7 | import 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) | ||
11 | public class ClientConnectMessage implements GnunetMessage.Body { | 15 | public 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 @@ | |||
1 | package org.gnunet.mesh; | ||
2 | |||
3 | import org.gnunet.util.PeerIdentity; | ||
4 | |||
5 | /** | ||
6 | * ... | ||
7 | * | ||
8 | * @author Florian Dold | ||
9 | */ | ||
10 | public 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 | ||
21 | package org.gnunet.mesh; | 21 | package org.gnunet.mesh; |
22 | 22 | ||
23 | import org.gnunet.util.Cancelable; | 23 | import org.gnunet.requests.Request; |
24 | import org.gnunet.util.Configuration; | 24 | import org.gnunet.requests.RequestQueue; |
25 | import org.gnunet.util.*; | ||
26 | import org.grothoff.Runabout; | ||
27 | |||
28 | import java.util.List; | ||
25 | 29 | ||
26 | /** | 30 | /** |
27 | * @author Florian Dold | 31 | * @author Florian Dold |
28 | */ | 32 | */ |
29 | public class Mesh { | 33 | public 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 @@ | |||
1 | package org.gnunet.mesh; | ||
2 | |||
3 | import org.gnunet.construct.UInt32; | ||
4 | import org.gnunet.construct.UnionCase; | ||
5 | import org.gnunet.util.GnunetMessage; | ||
6 | |||
7 | /** | ||
8 | * ... | ||
9 | * | ||
10 | * @author Florian Dold | ||
11 | */ | ||
12 | @UnionCase(273) | ||
13 | public 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 @@ | |||
1 | package org.gnunet.mesh; | ||
2 | |||
3 | import org.gnunet.construct.UInt32; | ||
4 | import org.gnunet.construct.UnionCase; | ||
5 | import org.gnunet.util.GnunetMessage; | ||
6 | |||
7 | /** | ||
8 | * ... | ||
9 | * | ||
10 | * @author Florian Dold | ||
11 | */ | ||
12 | @UnionCase(274) | ||
13 | public 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 @@ | |||
1 | package org.gnunet.mesh; | ||
2 | |||
3 | /** | ||
4 | * ... | ||
5 | * | ||
6 | * @author Florian Dold | ||
7 | */ | ||
8 | public 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 @@ | |||
1 | package org.gnunet.mesh; | ||
2 | |||
3 | import org.gnunet.construct.NestedMessage; | ||
4 | import org.gnunet.construct.UInt32; | ||
5 | import org.gnunet.util.GnunetMessage; | ||
6 | import org.gnunet.util.PeerIdentity; | ||
7 | |||
8 | /** | ||
9 | * ... | ||
10 | * | ||
11 | * @author Florian Dold | ||
12 | */ | ||
13 | public 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 | */ |
28 | public class Client { | 31 | public 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; | |||
23 | import org.slf4j.Logger; | 23 | import org.slf4j.Logger; |
24 | import org.slf4j.LoggerFactory; | 24 | import org.slf4j.LoggerFactory; |
25 | 25 | ||
26 | import java.io.IOError; | 26 | import java.io.*; |
27 | import java.io.IOException; | 27 | import java.nio.ByteBuffer; |
28 | import java.nio.channels.*; | 28 | import java.nio.channels.*; |
29 | import java.nio.channels.spi.SelectorProvider; | 29 | import java.nio.channels.spi.SelectorProvider; |
30 | import java.util.*; | 30 | import 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; | |||
3 | import org.junit.Assert; | 3 | import org.junit.Assert; |
4 | import org.junit.Test; | 4 | import org.junit.Test; |
5 | 5 | ||
6 | import 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 @@ | |||
1 | package org.gnunet.construct; | ||
2 | |||
3 | /** | ||
4 | * ... | ||
5 | * | ||
6 | * @author Florian Dold | ||
7 | */ | ||
8 | public 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 @@ | |||
1 | package org.gnunet.construct; | ||
2 | |||
3 | /** | ||
4 | * ... | ||
5 | * | ||
6 | * @author Florian Dold | ||
7 | */ | ||
8 | public 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 @@ | |||
1 | package org.gnunet.construct; | ||
2 | |||
3 | /** | ||
4 | * ... | ||
5 | * | ||
6 | * @author Florian Dold | ||
7 | */ | ||
8 | public 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; | |||
26 | import org.gnunet.util.*; | 26 | import org.gnunet.util.*; |
27 | import org.grothoff.Runabout; | 27 | import org.grothoff.Runabout; |
28 | import org.junit.Assert; | 28 | import org.junit.Assert; |
29 | import org.junit.Ignore; | ||
29 | import org.junit.Test; | 30 | import org.junit.Test; |
30 | 31 | ||
31 | import static org.junit.Assert.assertTrue; | 32 | import 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 | */ |
13 | public class ClientServerTest { | 13 | public 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 @@ | |||
1 | package org.gnunet.util; | ||
2 | |||
3 | import java.io.File; | ||
4 | import java.io.IOError; | ||
5 | import java.io.IOException; | ||
6 | import java.nio.ByteBuffer; | ||
7 | |||
8 | /** | ||
9 | * ... | ||
10 | * | ||
11 | * @author Florian Dold | ||
12 | */ | ||
13 | public 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 @@ | |||
1 | package org.gnunet.util; | ||
2 | |||
3 | import junit.framework.Assert; | ||
4 | import org.junit.Test; | ||
5 | |||
6 | /** | ||
7 | * ... | ||
8 | * | ||
9 | * @author Florian Dold | ||
10 | */ | ||
11 | public 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! | |
10 | set -e | ||
7 | 11 | ||
8 | BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/.. | 12 | BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/.. |
9 | 13 | ||
10 | # collect all source files | ||
11 | SOURCES=`find "$BASEDIR/src/" "$BASEDIR/test/" -name "*.java"` | ||
12 | 14 | ||
15 | # collect all source files | ||
16 | SOURCES_PROD=`find "$BASEDIR/src/" -name "*.java"` | ||
17 | SOURCES_TEST=`find "$BASEDIR/test/" -name "*.java"` | ||
13 | 18 | ||
14 | 19 | ||
20 | mkdir -p "$BASEDIR/build" | ||
21 | mkdir -p "$BASEDIR/build-test" | ||
15 | 22 | ||
16 | mkdir -p $BASEDIR/build | 23 | javac -g $JFLAGS -cp "$BASEDIR/lib/*" -d "$BASEDIR/build/" $SOURCES_PROD |
17 | 24 | ||
18 | javac -g $JFLAGS -cp "$BASEDIR/build/:$BASEDIR/lib/*" -d $BASEDIR/build/ $SOURCES || exit 1 | 25 | javac -g $JFLAGS -cp "$BASEDIR/build:$BASEDIR/lib/*" -d "$BASEDIR/build-test/" $SOURCES_TEST |
19 | 26 | ||
20 | cd "$BASEDIR/src/" | 27 | cd "$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 | 42 | echo 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 | ||
3 | BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/.. | 3 | BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/.. |
4 | 4 | ||
5 | INSTRUMENT_CMD="sh $BASEDIR/cobertura/cobertura-instrument.sh --datafile $BASEDIR/coverage.data --destination $BASEDIR/build-instrumented --ignore assert " | 5 | INSTRUMENT_CMD="sh $BASEDIR/cobertura/cobertura-instrument.sh --datafile $BASEDIR/coverage.data --destination $BASEDIR/build-instrumented --ignore .*assert.*" |
6 | 6 | ||
7 | echo $INSTRUMENT_CMD | 7 | echo $INSTRUMENT_CMD |
8 | 8 | ||
9 | set -x | ||
10 | |||
9 | 11 | ||
10 | case "$1" in | 12 | case "$1" in |
11 | instrument) | 13 | instrument) |
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 | ;; |
15 | clean) | 32 | clean) |
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 | ||
10 | echo Testing classes: $TESTS | 10 | echo Testing classes: $TESTS |
11 | 11 | ||
12 | java -cp "$BASEDIR/build:$BASEDIR/lib/*" org.junit.runner.JUnitCore $TESTS | 12 | java -cp "$BASEDIR/build:$BASEDIR/build-test:$BASEDIR/lib/*" org.junit.runner.JUnitCore $TESTS |
13 | 13 | ||
14 | cd $OLDPWD | 14 | cd $OLDPWD |
15 | 15 | ||