From e310a6ab310cbeb9f9e2ac17bb35cc0ec9483fae Mon Sep 17 00:00:00 2001 From: slumlord Date: Mon, 13 Aug 2018 08:38:24 +0000 Subject: [PATCH 1/3] Add CachedIteratorCollectionTest --- .../util/CachedIteratorCollectionTest.java | 799 ++++++++++++++++++ 1 file changed, 799 insertions(+) create mode 100644 router/java/test/junit/net/i2p/router/util/CachedIteratorCollectionTest.java diff --git a/router/java/test/junit/net/i2p/router/util/CachedIteratorCollectionTest.java b/router/java/test/junit/net/i2p/router/util/CachedIteratorCollectionTest.java new file mode 100644 index 0000000000..6b8d4689bd --- /dev/null +++ b/router/java/test/junit/net/i2p/router/util/CachedIteratorCollectionTest.java @@ -0,0 +1,799 @@ +package net.i2p.router.util; + +import static org.junit.Assert.*; +import org.junit.Test; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.ArrayList; +import java.util.NoSuchElementException; + +/* when using with JUnit5+Idea +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.DisplayName; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.fail; +*/ + + + +/** + * A set of tests to ensure that the CachedIteratorCollection class is + * functioning as intended + */ + +public class CachedIteratorCollectionTest { + + /* Add n-number of objects to the given CachedIteratorCollection object + * + */ + private void AddNObjects(CachedIteratorCollection a, int n) { + if (n > 0) { + for (int j = 0; j < n; j++) { + String s = "test" + j; + a.add(s); + } + } else { + throw new UnsupportedOperationException("Please use a positive integer"); + } + } + + private void AddNObjectsLL(LinkedList a, int n) { + if (n > 0) { + for (int j = 0; j < n; j++) { + String s = "test" + j; + a.add(s); + } + } else { + throw new UnsupportedOperationException("Please use a positive integer"); + } + } + + //@DisplayName("Add 1 Element Test") + @Test + public void Add1Test() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 1); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + while(testCollection1Itr.hasNext()) { + testString += testCollection1Itr.next(); + } + + assertEquals("test0", testString); + assertEquals(1, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 1); + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + while(testCollection2Itr.hasNext()) { + testString += testCollection2Itr.next(); + } + + assertEquals("test0", testString); + assertEquals(1, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } + + //@DisplayName("Add 10 Elements Test") + @Test + public void Add10Test() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + while(testCollection1Itr.hasNext()) { + testString += testCollection1Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList OBject + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + while(testCollection2Itr.hasNext()) { + testString += testCollection2Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } + + //@DisplayName("AddAll() Test") + @Test + public void AddAll() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + ArrayList stringArrayList = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + String s = "test" + i; + stringArrayList.add(s); + } + + testCollection1.addAll(stringArrayList); + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + String testString = ""; + + while(testCollection1Itr.hasNext()) { + testString += testCollection1Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + stringArrayList = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + String s = "test" + i; + stringArrayList.add(s); + } + + testCollection2.addAll(stringArrayList); + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + testString = ""; + + while(testCollection2Itr.hasNext()) { + testString += testCollection2Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } + + //@DisplayName("Single Element Remove Test - Size 1 Collection") + @Test + public void SingleRemove() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 1); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + while(testCollection1Itr.hasNext()) { + testString += testCollection1Itr.next(); + testCollection1Itr.remove(); + } + + assertEquals("test0", testString); + assertEquals(0, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertTrue(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 1); + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + while(testCollection2Itr.hasNext()) { + testString += testCollection2Itr.next(); + testCollection2Itr.remove(); + } + + assertEquals("test0", testString); + assertEquals(0, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertTrue(testCollection2.isEmpty()); + } + + //@DisplayName("Single Element Remove From Start Test - Size 10 Collection") + @Test + public void RemoveFromStart() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + String s = ""; + while (testCollection1Itr.hasNext()) { + s = testCollection1Itr.next(); + if (s.equals("test0")) { + testCollection1Itr.remove(); + } else { + testString += s; + } + } + + assertEquals("test1test2test3test4test5test6test7test8test9", testString); + assertEquals(9, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + s = ""; + while (testCollection2Itr.hasNext()) { + s = testCollection2Itr.next(); + if (s.equals("test0")) { + testCollection2Itr.remove(); + } else { + testString += s; + } + } + + assertEquals("test1test2test3test4test5test6test7test8test9", testString); + assertEquals(9, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } + + //@DisplayName("Single Element Remove From Middle Test") + @Test + public void RemoveFromMiddle() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + String s = ""; + while (testCollection1Itr.hasNext()) { + s = testCollection1Itr.next(); + if (s.equals("test5")) { + testCollection1Itr.remove(); + } else { + testString += s; + } + } + + assertEquals("test0test1test2test3test4test6test7test8test9", testString); + assertEquals(9, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + s = ""; + while (testCollection2Itr.hasNext()) { + s = testCollection2Itr.next(); + if (s.equals("test5")) { + testCollection2Itr.remove(); + } else { + testString += s; + } + } + + assertEquals("test0test1test2test3test4test6test7test8test9", testString); + assertEquals(9, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } + + //@DisplayName("Multiple Elements Remove From Middle Test") + @Test + public void RemoveMultipleFromMiddle() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + String s = ""; + while (testCollection1Itr.hasNext()) { + s = testCollection1Itr.next(); + if (s.equals("test5") || s.equals("test6")) { + testCollection1Itr.remove(); + } else { + testString += s; + } + } + + assertEquals("test0test1test2test3test4test7test8test9", testString); + assertEquals(8, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + s = ""; + while (testCollection2Itr.hasNext()) { + s = testCollection2Itr.next(); + if (s.equals("test5") || s.equals("test6")) { + testCollection2Itr.remove(); + } else { + testString += s; + } + } + + assertEquals(8, testCollection2.size()); + assertEquals("test0test1test2test3test4test7test8test9", testString); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } + + //@DisplayName("Single Element Remove From End Test") + @Test + public void RemoveFromEnd() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + String s = ""; + while (testCollection1Itr.hasNext()) { + s = testCollection1Itr.next(); + if (s.equals("test9")) { + testCollection1Itr.remove(); + } else { + testString += s; + } + } + + assertEquals("test0test1test2test3test4test5test6test7test8", testString); + assertEquals(9, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + s = ""; + while (testCollection2Itr.hasNext()) { + s = testCollection2Itr.next(); + if (s.equals("test9")) { + testCollection2Itr.remove(); + } else { + testString += s; + } + } + + assertEquals(9, testCollection2.size()); + assertEquals("test0test1test2test3test4test5test6test7test8", testString); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } + + //@DisplayName("Remove All - Size 10 Collection") + @Test + public void RemoveAll() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + assertEquals(10, testCollection1.size()); + assertTrue(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Remove all test + while (testCollection1Itr.hasNext()) { + testCollection1Itr.next(); + testCollection1Itr.remove(); + } + + assertEquals(0, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertTrue(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + assertEquals(10, testCollection2.size()); + assertTrue(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + + // Remove all test + while (testCollection2Itr.hasNext()) { + testCollection2Itr.next(); + testCollection2Itr.remove(); + } + + assertEquals(0, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertTrue(testCollection2.isEmpty()); + } + + //@DisplayName("Test Iterator Equality/Inequality") + @Test + public void Equality() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + Iterator testCollection1Itr1 = testCollection1.iterator(); + Iterator testCollection1Itr2 = testCollection1.iterator(); + Iterator testCollection1Itr3 = testCollection1.iterator(); + Iterator testCollection1Itr4 = testCollection1.iterator(); + + assertSame(testCollection1Itr1,testCollection1Itr2); + assertSame(testCollection1Itr2,testCollection1Itr3); + assertSame(testCollection1Itr3,testCollection1Itr4); + + // LinkedList object's iterator should return different objects + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + Iterator testCollection2Itr1 = testCollection2.iterator(); + Iterator testCollection2Itr2 = testCollection2.iterator(); + Iterator testCollection2Itr3 = testCollection2.iterator(); + Iterator testCollection2Itr4 = testCollection2.iterator(); + + assertNotSame(testCollection2Itr1,testCollection2Itr2); + assertNotSame(testCollection2Itr2,testCollection2Itr3); + assertNotSame(testCollection2Itr3,testCollection2Itr4); + } + + //@DisplayName("Restart Iterator Test") + @Test + public void Restart() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + String s = ""; + while(testCollection1Itr.hasNext()) { + testString += testCollection1Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Restart Iterator + testCollection1Itr = testCollection1.iterator(); + + assertTrue("test0".equals(testCollection1Itr.next())); + assertEquals(10, testCollection1.size()); + assertTrue(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + while(testCollection2Itr.hasNext()) { + testString += testCollection2Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + + // Restart Iterator + testCollection2Itr = testCollection2.iterator(); + + assertEquals(10, testCollection2.size()); + assertTrue("test0".equals(testCollection2Itr.next())); + assertTrue(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + + } + + //@DisplayName("Clear Test") + @Test + public void Clear() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + + String testString = ""; + + // Iterator test + Iterator testCollection1Itr = testCollection1.iterator(); + + assertEquals(10, testCollection1.size()); + assertTrue(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Clear + testCollection1.clear(); + + assertEquals(0, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertTrue(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + + testString = ""; + + // Iterator test + Iterator testCollection2Itr = testCollection2.iterator(); + + assertEquals(10, testCollection2.size()); + assertFalse(testCollection2.isEmpty()); + assertTrue(testCollection2Itr.hasNext()); + + // Clear + testCollection2.clear(); + + assertEquals(0, testCollection2.size()); + assertTrue(testCollection2.isEmpty()); + assertFalse(testCollection2Itr.hasNext()); + } + + //@DisplayName("Remove Twice Before next() Test") + @Test + public void RemoveTwice() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + + Iterator testCollection1Itr = testCollection1.iterator(); + testCollection1Itr.next(); + testCollection1Itr.remove(); + testCollection1Itr.next(); + testCollection1Itr.remove(); + + /* Junit5 + java8+ + assertThrows(IllegalStateException.class, () -> { + // Remove called once more here before a next() + testCollection1Itr.remove(); + }); + */ + + try { + testCollection1Itr.remove(); + fail("Exception should be caught; This should not print."); + } catch (IllegalStateException e) { + System.out.println("RemoveTwice()+CachedIteratorCollection: IllegalStateException caught successfully." + e); + } + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + + Iterator testCollection2Itr = testCollection2.iterator(); + testCollection2Itr.next(); + testCollection2Itr.remove(); + testCollection2Itr.next(); + testCollection2Itr.remove(); + + /* Junit5 + java8+ + assertThrows(IllegalStateException.class, () -> { + // Remove called once more here before a next() + testCollection2Itr.remove(); + }); + */ + + try { + testCollection2Itr.remove(); + fail("Exception should be caught; This should not print."); + } catch (IllegalStateException e) { + System.out.println("RemoveTwice()+LinkedList: IllegalStateException caught successfully." + e); + } + } + + //@DisplayName("next() When No Elements Left Test") + @Test + public void NextWhenNone() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + + Iterator testCollection1Itr = testCollection1.iterator(); + + while(testCollection1Itr.hasNext()) { + testCollection1Itr.next(); + } + + assertEquals(10, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + /* JUnit5 java8+ + // next() should throw an exception as there are no more nodes + assertThrows(NoSuchElementException.class, () -> { testCollection1Itr.next(); }); + */ + + try { + testCollection1Itr.next(); + fail("Exception should be caught; This should not print."); + } catch (NoSuchElementException e) { + System.out.println("NextWhenNone()+CachedIteratorCollection: NoSuchElementException caught successfully." + e); + } + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + + Iterator testCollection2Itr = testCollection2.iterator(); + + while(testCollection2Itr.hasNext()) { + testCollection2Itr.next(); + } + + assertEquals(10, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + /* JUnit5 java8+ + // next() should throw an exception as there are no more nodes + assertThrows(NoSuchElementException.class, () -> { testCollection2Itr.next(); }); + */ + + try { + testCollection2Itr.next(); + fail("Exception should be caught; This should not print."); + } catch (NoSuchElementException e) { + System.out.println("NextWhenNone()+LinkedList: NoSuchElementException caught successfully." + e); + } + } + + //@DisplayName("Add, Remove All and Add Again Test") + @Test + public void ReAdd() { + CachedIteratorCollection testCollection1 = new CachedIteratorCollection<>(); + + AddNObjects(testCollection1, 10); + + Iterator testCollection1Itr = testCollection1.iterator(); + + String testString = ""; + + while (testCollection1Itr.hasNext()) { + testString += testCollection1Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection1.size()); + + // Reset and remove all + testCollection1Itr = testCollection1.iterator(); + + while(testCollection1Itr.hasNext()) { + testCollection1Itr.next(); + testCollection1Itr.remove(); + } + + assertEquals(0, testCollection1.size()); + assertFalse(testCollection1Itr.hasNext()); + assertTrue(testCollection1.isEmpty()); + + // Re-add + AddNObjects(testCollection1, 10); + testCollection1Itr = testCollection1.iterator(); + + assertEquals(10, testCollection1.size()); + assertTrue("test0".equals(testCollection1Itr.next())); + assertTrue(testCollection1Itr.hasNext()); + assertFalse(testCollection1.isEmpty()); + + // Compare behavior with LinkedList object + LinkedList testCollection2 = new LinkedList<>(); + + AddNObjectsLL(testCollection2, 10); + + Iterator testCollection2Itr = testCollection2.iterator(); + + testString = ""; + + while (testCollection2Itr.hasNext()) { + testString += testCollection2Itr.next(); + } + + assertEquals("test0test1test2test3test4test5test6test7test8test9", testString); + assertEquals(10, testCollection2.size()); + + testCollection2Itr = testCollection2.iterator(); + + while(testCollection2Itr.hasNext()) { + testCollection2Itr.next(); + testCollection2Itr.remove(); + } + + assertEquals(0, testCollection2.size()); + assertFalse(testCollection2Itr.hasNext()); + assertTrue(testCollection2.isEmpty()); + + // Re-add + AddNObjectsLL(testCollection2, 10); + testCollection2Itr = testCollection2.iterator(); + + assertEquals(10, testCollection2.size()); + assertTrue("test0".equals(testCollection2Itr.next())); + assertTrue(testCollection2Itr.hasNext()); + assertFalse(testCollection2.isEmpty()); + } +} From 30fefa44ec357a888ae083108c64a209a793f918 Mon Sep 17 00:00:00 2001 From: zzz Date: Mon, 13 Aug 2018 17:38:57 +0000 Subject: [PATCH 2/3] Console: Format part. tunnel rate Make table headers consistent --- .../java/src/net/i2p/router/web/helpers/TunnelRenderer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java index 1c8dcb89d5..24046bba25 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/helpers/TunnelRenderer.java @@ -159,8 +159,8 @@ class TunnelRenderer { lifetime = 1; if (lifetime > 10*60) lifetime = 10*60; - int bps = 1024 * count / lifetime; - out.write("" + bps + " Bps"); + long bps = 1024L * count / lifetime; + out.write("" + DataHelper.formatSize2Decimal(bps) + "Bps"); if (cfg.getSendTo() == null) out.write("" + _t("Outbound Endpoint") + ""); else if (cfg.getReceiveFrom() == null) @@ -286,7 +286,7 @@ class TunnelRenderer { maxLength = length; } out.write(""); + + ""); if (maxLength > 3) { out.write(""); From c455f15b2aff5ab88220d0a4cfc852f66caa366b Mon Sep 17 00:00:00 2001 From: zzz Date: Thu, 16 Aug 2018 18:39:07 +0000 Subject: [PATCH 3/3] i2ptunnel: Change read timeout defaults now that streaming read timeout works --- .../net/i2p/i2ptunnel/I2PTunnelClient.java | 32 ++++++++++++++++++- .../i2ptunnel/I2PTunnelHTTPClientBase.java | 6 +++- .../i2p/i2ptunnel/I2PTunnelHTTPServer.java | 5 +++ .../net/i2p/i2ptunnel/I2PTunnelIRCClient.java | 3 +- .../net/i2p/i2ptunnel/I2PTunnelIRCServer.java | 3 ++ .../net/i2p/i2ptunnel/I2PTunnelServer.java | 21 ++++++++++-- .../i2p/i2ptunnel/irc/I2PTunnelDCCServer.java | 3 ++ history.txt | 13 ++++++++ .../src/net/i2p/router/RouterVersion.java | 2 +- 9 files changed, 82 insertions(+), 6 deletions(-) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java index 7af54060cf..c3d359f641 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java @@ -32,7 +32,8 @@ public class I2PTunnelClient extends I2PTunnelClientBase { * replacement for dests */ private final List _addrs; - private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1 + // We don't know what protocol, so we assume the application has its own timeout mechanism + private static final long DEFAULT_READ_TIMEOUT = -1; protected long readTimeout = DEFAULT_READ_TIMEOUT; private InternalSocketRunner _isr; @@ -107,7 +108,36 @@ public class I2PTunnelClient extends I2PTunnelClientBase { } } + /** + * Set the read idle timeout for newly-created connections (in + * milliseconds). After this time expires without data being reached from + * the I2P network, the connection itself will be closed. + * + * Less than or equal to 0 means forever. + * Default -1 (forever) as of 0.9.36 for standard tunnels, + * but extending classes may override. + * Prior to that, default was 5 minutes, but did not work + * due to streaming bugs. + * + * Applies only to future connections; + * calling this does not affect existing connections. + * + * @param ms in ms + */ public void setReadTimeout(long ms) { readTimeout = ms; } + + /** + * Get the read idle timeout for newly-created connections (in + * milliseconds). + * + * Less than or equal to 0 means forever. + * Default -1 (forever) as of 0.9.36 for standard tunnels, + * but extending classes may override. + * Prior to that, default was 5 minutes, but did not work + * due to streaming bugs. + * + * @return in ms + */ public long getReadTimeout() { return readTimeout; } protected void clientConnectionRun(Socket s) { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java index 60a63ab2d4..3e64286aed 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java @@ -137,7 +137,11 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem } } - protected static final int DEFAULT_READ_TIMEOUT = 5*60*1000; + /** + * -1 (forever) as of 0.9.36, + * so that large POSTs won't timeout on the read side + */ + protected static final int DEFAULT_READ_TIMEOUT = -1; protected static final AtomicLong __requestId = new AtomicLong(); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java index 1d51e776fe..a27201c307 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java @@ -88,6 +88,10 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer { private static final int MAX_HEADERS = 60; /** Includes request, just to prevent OOM DOS @since 0.9.20 */ private static final int MAX_TOTAL_HEADER_SIZE = 32*1024; + // Does not apply to header reads. + // We set it to forever so that it won't timeout when sending a large response. + // The server will presumably have its own timeout implemented for POST + private static final long DEFAULT_HTTP_READ_TIMEOUT = -1; private long _startedOn = 0L; private ConnThrottler _postThrottler; @@ -205,6 +209,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer { private void setupI2PTunnelHTTPServer(String spoofHost) { _spoofHost = (spoofHost != null && spoofHost.trim().length() > 0) ? spoofHost.trim() : null; getTunnel().getContext().statManager().createRateStat("i2ptunnel.httpserver.blockingHandleTime", "how long the blocking handle takes to complete", "I2PTunnel.HTTPServer", new long[] { 60*1000, 10*60*1000, 3*60*60*1000 }); + readTimeout = DEFAULT_HTTP_READ_TIMEOUT; } @Override diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java index 5e31425265..9007c7a4c1 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java @@ -30,7 +30,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase { /** list of Destination objects that we point at */ private final List _addrs; - private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1 + // application should ping timeout before this + private static final long DEFAULT_READ_TIMEOUT = 10*60*1000; protected long readTimeout = DEFAULT_READ_TIMEOUT; private final boolean _dccEnabled; private I2PTunnelDCCServer _DCCServer; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java index 6d541b583c..09e964fc4a 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCServer.java @@ -73,6 +73,8 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable { private static final long HEADER_TIMEOUT = 15*1000; private static final long TOTAL_HEADER_TIMEOUT = 2 * HEADER_TIMEOUT; private static final int MAX_LINE_LENGTH = 1024; + // application should ping timeout before this + private static final long DEFAULT_IRC_READ_TIMEOUT = 10*60*1000; private final static String ERR_UNAVAILABLE = ":ircserver.i2p 499 you :" + @@ -134,6 +136,7 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable { // get the fake hostmask to use this.hostname = opts.getProperty(PROP_HOSTNAME, PROP_HOSTNAME_DEFAULT); + readTimeout = DEFAULT_IRC_READ_TIMEOUT; } @Override diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java index 381f514d0c..6f881bafef 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelServer.java @@ -62,8 +62,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { protected final Logging l; private I2PSSLSocketFactory _sslFactory; - private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; - /** default timeout to 5 minutes - override if desired */ + private static final long DEFAULT_READ_TIMEOUT = -1; + /** default timeout - override if desired */ protected long readTimeout = DEFAULT_READ_TIMEOUT; /** do we use threads? default true (ignored for standard servers, always false) */ @@ -371,6 +371,17 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { * Set the read idle timeout for newly-created connections (in * milliseconds). After this time expires without data being reached from * the I2P network, the connection itself will be closed. + * + * Less than or equal to 0 means forever. + * Default -1 (forever) as of 0.9.36 for standard tunnels, + * but extending classes may override. + * Prior to that, default was 5 minutes, but did not work + * due to streaming bugs. + * + * Applies only to future connections; + * calling this does not affect existing connections. + * + * @param ms in ms */ public void setReadTimeout(long ms) { readTimeout = ms; @@ -380,6 +391,12 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable { * Get the read idle timeout for newly-created connections (in * milliseconds). * + * Less than or equal to 0 means forever. + * Default -1 (forever) as of 0.9.36 for standard tunnels, + * but extending classes may override. + * Prior to that, default was 5 minutes, but did not work + * due to streaming bugs. + * * @return The read timeout used for connections */ public long getReadTimeout() { diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java index 8b49b6995d..f548692236 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/irc/I2PTunnelDCCServer.java @@ -64,6 +64,8 @@ public class I2PTunnelDCCServer extends I2PTunnelServer { private static final int MAX_OUTGOING_PENDING = 20; private static final int MAX_OUTGOING_ACTIVE = 20; private static final long OUTBOUND_EXPIRE = 30*60*1000; + private static final long DEFAULT_DCC_READ_TIMEOUT = -1; + /** * There's no support for unsolicited incoming I2P connections, * so there's no server host or port parameters. @@ -79,6 +81,7 @@ public class I2PTunnelDCCServer extends I2PTunnelServer { _active = new ConcurrentHashMap(8); _resume = new ConcurrentHashMap(8); _sockList = new CopyOnWriteArrayList(); + readTimeout = DEFAULT_DCC_READ_TIMEOUT; } /** diff --git a/history.txt b/history.txt index 4ff4128974..b8a97b8a76 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,16 @@ +2018-08-16 zzz + * i2ptunnel: Change read timeout defaults now that streaming timeout works + +2018-08-13 zzz + * Console: Format part. tunnel rate + +2018-08-04 zzz + * Data: Check sooner for unknown sig type + * I2NP: Remove unused Stream methods + +2018-08-03 zzz + * NTCP2: Fix termination handling and padding calculation + 2018-08-02 zzz * i2psnark: Don't disconnect seeds if comments enabled (ticket #2288) * NTCP2: Send termination on idle timeout diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 9535f12e9f..f7d70ed0aa 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 23; + public final static long BUILD = 24; /** for example "-test" */ public final static String EXTRA = "-rc";
") + _t("In/Out") - + "" + _t("Expiry") + "" + _t("Usage") + "" + _t("Gateway") + "" + _t("Expiration") + "" + _t("Usage") + "" + _t("Gateway") + "" + _t("Participants") + "