propagate from branch 'i2p.i2p' (head ec664ddfcb1f460b67cfcb0a5be1d162bb361b5a)

to branch 'i2p.i2p.slumlord' (head c521652f676d8c99cc31916977229cca561dc31b)
This commit is contained in:
slumlord
2018-08-17 09:23:45 +00:00
10 changed files with 883 additions and 8 deletions

View File

@@ -32,7 +32,8 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
* replacement for dests
*/
private final List<I2PSocketAddress> _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) {

View File

@@ -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();

View File

@@ -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

View File

@@ -30,7 +30,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase {
/** list of Destination objects that we point at */
private final List<I2PSocketAddress> _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;

View File

@@ -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

View File

@@ -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() {

View File

@@ -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<Integer, LocalAddress>(8);
_resume = new ConcurrentHashMap<Integer, LocalAddress>(8);
_sockList = new CopyOnWriteArrayList<I2PSocket>();
readTimeout = DEFAULT_DCC_READ_TIMEOUT;
}
/**

View File

@@ -159,8 +159,8 @@ class TunnelRenderer {
lifetime = 1;
if (lifetime > 10*60)
lifetime = 10*60;
int bps = 1024 * count / lifetime;
out.write("<td class=\"cells\" align=\"center\">" + bps + " Bps</td>");
long bps = 1024L * count / lifetime;
out.write("<td class=\"cells\" align=\"center\">" + DataHelper.formatSize2Decimal(bps) + "Bps</td>");
if (cfg.getSendTo() == null)
out.write("<td class=\"cells\" align=\"center\">" + _t("Outbound Endpoint") + "</td>");
else if (cfg.getReceiveFrom() == null)
@@ -286,7 +286,7 @@ class TunnelRenderer {
maxLength = length;
}
out.write("<table class=\"tunneldisplay tunnels_client\"><tr><th title=\"" + _t("Inbound or outbound?") + ("\">") + _t("In/Out")
+ "</th><th>" + _t("Expiry") + "</th><th>" + _t("Usage") + "</th><th>" + _t("Gateway") + "</th>");
+ "</th><th>" + _t("Expiration") + "</th><th>" + _t("Usage") + "</th><th>" + _t("Gateway") + "</th>");
if (maxLength > 3) {
out.write("<th align=\"center\" colspan=\"" + (maxLength - 2));
out.write("\">" + _t("Participants") + "</th>");

View File

@@ -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

View File

@@ -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<String> 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<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 1);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 1);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
ArrayList<String> stringArrayList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
String s = "test" + i;
stringArrayList.add(s);
}
testCollection1.addAll(stringArrayList);
// Iterator test
Iterator<String> 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<String> 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<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 1);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 1);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
Iterator<String> testCollection1Itr1 = testCollection1.iterator();
Iterator<String> testCollection1Itr2 = testCollection1.iterator();
Iterator<String> testCollection1Itr3 = testCollection1.iterator();
Iterator<String> testCollection1Itr4 = testCollection1.iterator();
assertSame(testCollection1Itr1,testCollection1Itr2);
assertSame(testCollection1Itr2,testCollection1Itr3);
assertSame(testCollection1Itr3,testCollection1Itr4);
// LinkedList object's iterator should return different objects
LinkedList<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
Iterator<String> testCollection2Itr1 = testCollection2.iterator();
Iterator<String> testCollection2Itr2 = testCollection2.iterator();
Iterator<String> testCollection2Itr3 = testCollection2.iterator();
Iterator<String> testCollection2Itr4 = testCollection2.iterator();
assertNotSame(testCollection2Itr1,testCollection2Itr2);
assertNotSame(testCollection2Itr2,testCollection2Itr3);
assertNotSame(testCollection2Itr3,testCollection2Itr4);
}
//@DisplayName("Restart Iterator Test")
@Test
public void Restart() {
CachedIteratorCollection<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
String testString = "";
// Iterator test
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
testString = "";
// Iterator test
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
Iterator<String> 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<String> testCollection1 = new CachedIteratorCollection<>();
AddNObjects(testCollection1, 10);
Iterator<String> 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<String> testCollection2 = new LinkedList<>();
AddNObjectsLL(testCollection2, 10);
Iterator<String> 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());
}
}