X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Ftest%2Fjava%2Fnet%2Fpterodactylus%2Ffcp%2Fquelaton%2FDefaultFcpClientTest.java;h=9a9986457f810bda44143738bcc2b15a28fad96d;hb=136c29e739af8397a2a1a1d318629e7394fe37c2;hp=6632d594730c090a7c96b567321b725e737549a8;hpb=a9e24cccfca7217fcfee9e8115ce7ef40cc7a4d8;p=jFCPlib.git diff --git a/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java b/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java index 6632d59..9a99864 100644 --- a/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java +++ b/src/test/java/net/pterodactylus/fcp/quelaton/DefaultFcpClientTest.java @@ -1,45 +1,60 @@ package net.pterodactylus.fcp.quelaton; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.stream.Collectors; +import net.pterodactylus.fcp.ARK; +import net.pterodactylus.fcp.ConfigData; +import net.pterodactylus.fcp.DSAGroup; import net.pterodactylus.fcp.FcpKeyPair; import net.pterodactylus.fcp.Key; +import net.pterodactylus.fcp.NodeData; +import net.pterodactylus.fcp.NodeRef; import net.pterodactylus.fcp.Peer; +import net.pterodactylus.fcp.PeerNote; +import net.pterodactylus.fcp.PluginInfo; import net.pterodactylus.fcp.Priority; import net.pterodactylus.fcp.fake.FakeTcpServer; import net.pterodactylus.fcp.quelaton.ClientGetCommand.Data; import com.google.common.io.ByteStreams; import com.google.common.io.Files; +import com.nitorcreations.junit.runners.NestedRunner; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeDiagnosingMatcher; import org.junit.After; +import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; /** * Unit test for {@link DefaultFcpClient}. * * @author David ‘Bombe’ Roden */ +@RunWith(NestedRunner.class) public class DefaultFcpClientTest { private static final String INSERT_URI = @@ -47,7 +62,7 @@ public class DefaultFcpClientTest { private static final String REQUEST_URI = "SSK@wtbgd2loNcJCXvtQVOftl2tuWBomDQHfqS6ytpPRhfw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQACAAE/"; - private static int threadCounter = 0; + private int threadCounter = 0; private final ExecutorService threadPool = Executors.newCachedThreadPool(r -> new Thread(r, "Test-Thread-" + threadCounter++)); private final FakeTcpServer fcpServer; @@ -61,13 +76,12 @@ public class DefaultFcpClientTest { @After public void tearDown() throws IOException { fcpServer.close(); + threadPool.shutdown(); } @Test(expected = ExecutionException.class) public void defaultFcpClientThrowsExceptionIfItCanNotConnect() throws IOException, ExecutionException, InterruptedException { - Logger.getAnonymousLogger().getParent().setLevel(Level.FINEST); - Logger.getAnonymousLogger().getParent().getHandlers()[0].setLevel(Level.FINEST); Future keyPairFuture = fcpClient.generateKeypair().execute(); fcpServer.connect().get(); fcpServer.collectUntil(is("EndMessage")); @@ -78,6 +92,16 @@ public class DefaultFcpClientTest { keyPairFuture.get(); } + @Test(expected = ExecutionException.class) + public void defaultFcpClientThrowsExceptionIfConnectionIsClosed() + throws IOException, ExecutionException, InterruptedException { + Future keyPairFuture = fcpClient.generateKeypair().execute(); + fcpServer.connect().get(); + fcpServer.collectUntil(is("EndMessage")); + fcpServer.close(); + keyPairFuture.get(); + } + @Test public void defaultFcpClientCanGenerateKeypair() throws ExecutionException, InterruptedException, IOException { Future keyPairFuture = fcpClient.generateKeypair().execute(); @@ -115,7 +139,7 @@ public class DefaultFcpClientTest { @Test public void clientGetCanDownloadData() throws InterruptedException, ExecutionException, IOException { - Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt"); + Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "ReturnType=direct", "URI=KSK@foo.txt")); @@ -148,7 +172,7 @@ public class DefaultFcpClientTest { @Test public void clientGetDownloadsDataForCorrectIdentifier() throws InterruptedException, ExecutionException, IOException { - Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt"); + Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt")); @@ -182,7 +206,7 @@ public class DefaultFcpClientTest { @Test public void clientGetRecognizesGetFailed() throws InterruptedException, ExecutionException, IOException { - Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt"); + Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt")); @@ -200,7 +224,7 @@ public class DefaultFcpClientTest { @Test public void clientGetRecognizesGetFailedForCorrectIdentifier() throws InterruptedException, ExecutionException, IOException { - Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt"); + Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt")); @@ -221,21 +245,73 @@ public class DefaultFcpClientTest { assertThat(data.isPresent(), is(false)); } - @Test + @Test(expected = ExecutionException.class) public void clientGetRecognizesConnectionClosed() throws InterruptedException, ExecutionException, IOException { - Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt"); + Future> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt")); fcpServer.close(); - Optional data = dataFuture.get(); - assertThat(data.isPresent(), is(false)); + dataFuture.get(); + } + + @Test + public void defaultFcpClientReusesConnection() throws InterruptedException, ExecutionException, IOException { + Future keyPair = fcpClient.generateKeypair().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + fcpServer.writeLine( + "SSKKeypair", + "InsertURI=" + INSERT_URI + "", + "RequestURI=" + REQUEST_URI + "", + "Identifier=" + identifier, + "EndMessage" + ); + keyPair.get(); + keyPair = fcpClient.generateKeypair().execute(); + lines = fcpServer.collectUntil(is("EndMessage")); + identifier = extractIdentifier(lines); + fcpServer.writeLine( + "SSKKeypair", + "InsertURI=" + INSERT_URI + "", + "RequestURI=" + REQUEST_URI + "", + "Identifier=" + identifier, + "EndMessage" + ); + keyPair.get(); + } + + @Test + public void defaultFcpClientCanReconnectAfterConnectionHasBeenClosed() + throws InterruptedException, ExecutionException, IOException { + Future keyPair = fcpClient.generateKeypair().execute(); + connectNode(); + fcpServer.collectUntil(is("EndMessage")); + fcpServer.close(); + try { + keyPair.get(); + Assert.fail(); + } catch (ExecutionException e) { + } + keyPair = fcpClient.generateKeypair().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + fcpServer.writeLine( + "SSKKeypair", + "InsertURI=" + INSERT_URI + "", + "RequestURI=" + REQUEST_URI + "", + "Identifier=" + identifier, + "EndMessage" + ); + keyPair.get(); } @Test public void clientGetWithIgnoreDataStoreSettingSendsCorrectCommands() throws InterruptedException, ExecutionException, IOException { - fcpClient.clientGet().ignoreDataStore().uri("KSK@foo.txt"); + fcpClient.clientGet().ignoreDataStore().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "IgnoreDS=true")); @@ -244,7 +320,7 @@ public class DefaultFcpClientTest { @Test public void clientGetWithDataStoreOnlySettingSendsCorrectCommands() throws InterruptedException, ExecutionException, IOException { - fcpClient.clientGet().dataStoreOnly().uri("KSK@foo.txt"); + fcpClient.clientGet().dataStoreOnly().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "DSonly=true")); @@ -253,7 +329,7 @@ public class DefaultFcpClientTest { @Test public void clientGetWithMaxSizeSettingSendsCorrectCommands() throws InterruptedException, ExecutionException, IOException { - fcpClient.clientGet().maxSize(1048576).uri("KSK@foo.txt"); + fcpClient.clientGet().maxSize(1048576).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "MaxSize=1048576")); @@ -262,7 +338,7 @@ public class DefaultFcpClientTest { @Test public void clientGetWithPrioritySettingSendsCorrectCommands() throws InterruptedException, ExecutionException, IOException { - fcpClient.clientGet().priority(Priority.interactive).uri("KSK@foo.txt"); + fcpClient.clientGet().priority(Priority.interactive).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "PriorityClass=1")); @@ -271,7 +347,7 @@ public class DefaultFcpClientTest { @Test public void clientGetWithRealTimeSettingSendsCorrectCommands() throws InterruptedException, ExecutionException, IOException { - fcpClient.clientGet().realTime().uri("KSK@foo.txt"); + fcpClient.clientGet().realTime().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "RealTimeFlag=true")); @@ -280,7 +356,7 @@ public class DefaultFcpClientTest { @Test public void clientGetWithGlobalSettingSendsCorrectCommands() throws InterruptedException, ExecutionException, IOException { - fcpClient.clientGet().global().uri("KSK@foo.txt"); + fcpClient.clientGet().global().uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "Global=true")); @@ -317,7 +393,8 @@ public class DefaultFcpClientTest { fcpClient.clientPut() .from(new ByteArrayInputStream("Hello\n".getBytes())) .length(6) - .uri("KSK@foo.txt"); + .uri("KSK@foo.txt") + .execute(); connectNode(); List lines = fcpServer.collectUntil(is("Hello")); assertThat(lines, matchesFcpMessage("ClientPut", "UploadFrom=direct", "DataLength=6", "URI=KSK@foo.txt")); @@ -329,7 +406,8 @@ public class DefaultFcpClientTest { Future> key = fcpClient.clientPut() .from(new ByteArrayInputStream("Hello\n".getBytes())) .length(6) - .uri("KSK@foo.txt"); + .uri("KSK@foo.txt") + .execute(); connectNode(); List lines = fcpServer.collectUntil(is("Hello")); String identifier = extractIdentifier(lines); @@ -353,7 +431,8 @@ public class DefaultFcpClientTest { Future> key = fcpClient.clientPut() .from(new ByteArrayInputStream("Hello\n".getBytes())) .length(6) - .uri("KSK@foo.txt"); + .uri("KSK@foo.txt") + .execute(); connectNode(); List lines = fcpServer.collectUntil(is("Hello")); String identifier = extractIdentifier(lines); @@ -378,7 +457,8 @@ public class DefaultFcpClientTest { .named("otherName.txt") .from(new ByteArrayInputStream("Hello\n".getBytes())) .length(6) - .uri("KSK@foo.txt"); + .uri("KSK@foo.txt") + .execute(); connectNode(); List lines = fcpServer.collectUntil(is("Hello")); assertThat(lines, matchesFcpMessage("ClientPut", "TargetFilename=otherName.txt", "UploadFrom=direct", @@ -388,7 +468,7 @@ public class DefaultFcpClientTest { @Test public void clientPutWithRedirectSendsCorrectCommand() throws IOException, ExecutionException, InterruptedException { - fcpClient.clientPut().redirectTo("KSK@bar.txt").uri("KSK@foo.txt"); + fcpClient.clientPut().redirectTo("KSK@bar.txt").uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, @@ -397,7 +477,7 @@ public class DefaultFcpClientTest { @Test public void clientPutWithFileSendsCorrectCommand() throws InterruptedException, ExecutionException, IOException { - fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt"); + fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); assertThat(lines, @@ -408,7 +488,7 @@ public class DefaultFcpClientTest { public void clientPutWithFileCanCompleteTestDdaSequence() throws IOException, ExecutionException, InterruptedException { File tempFile = createTempFile(); - fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt"); + fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); String identifier = extractIdentifier(lines); @@ -461,7 +541,7 @@ public class DefaultFcpClientTest { @Test public void clientPutDoesNotReactToProtocolErrorForDifferentIdentifier() throws InterruptedException, ExecutionException, IOException { - Future> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt"); + Future> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); String identifier = extractIdentifier(lines); @@ -483,7 +563,7 @@ public class DefaultFcpClientTest { @Test public void clientPutAbortsOnProtocolErrorOtherThan25() throws InterruptedException, ExecutionException, IOException { - Future> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt"); + Future> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); String identifier = extractIdentifier(lines); @@ -500,7 +580,7 @@ public class DefaultFcpClientTest { public void clientPutDoesNotReplyToWrongTestDdaReply() throws IOException, ExecutionException, InterruptedException { File tempFile = createTempFile(); - fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt"); + fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); String identifier = extractIdentifier(lines); @@ -543,7 +623,7 @@ public class DefaultFcpClientTest { public void clientPutSendsResponseEvenIfFileCanNotBeRead() throws IOException, ExecutionException, InterruptedException { File tempFile = createTempFile(); - fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt"); + fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); String identifier = extractIdentifier(lines); @@ -580,7 +660,7 @@ public class DefaultFcpClientTest { public void clientPutDoesNotResendOriginalClientPutOnTestDDACompleteWithWrongDirectory() throws IOException, ExecutionException, InterruptedException { File tempFile = createTempFile(); - fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt"); + fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute(); connectNode(); List lines = fcpServer.collectUntil(is("EndMessage")); String identifier = extractIdentifier(lines); @@ -606,6 +686,35 @@ public class DefaultFcpClientTest { } @Test + public void clientPutSendsNotificationsForGeneratedKeys() + throws InterruptedException, ExecutionException, IOException { + List generatedKeys = new CopyOnWriteArrayList<>(); + Future> key = fcpClient.clientPut() + .onKeyGenerated(generatedKeys::add) + .from(new ByteArrayInputStream("Hello\n".getBytes())) + .length(6) + .uri("KSK@foo.txt") + .execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("Hello")); + String identifier = extractIdentifier(lines); + fcpServer.writeLine( + "URIGenerated", + "Identifier=" + identifier, + "URI=KSK@foo.txt", + "EndMessage" + ); + fcpServer.writeLine( + "PutSuccessful", + "URI=KSK@foo.txt", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(key.get().get().getKey(), is("KSK@foo.txt")); + assertThat(generatedKeys, contains("KSK@foo.txt")); + } + + @Test public void clientCanListPeers() throws IOException, ExecutionException, InterruptedException { Future> peers = fcpClient.listPeers().execute(); connectNode(); @@ -711,4 +820,1311 @@ public class DefaultFcpClientTest { containsInAnyOrder("bar1", "bar2")); } + @Test + public void defaultFcpClientCanGetNodeInformation() throws InterruptedException, ExecutionException, IOException { + Future nodeData = fcpClient.getNode().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetNode", + "Identifier=" + identifier, + "GiveOpennetRef=false", + "WithPrivate=false", + "WithVolatile=false", + "EndMessage" + )); + fcpServer.writeLine( + "NodeData", + "Identifier=" + identifier, + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(nodeData.get(), notNullValue()); + } + + @Test + public void defaultFcpClientCanGetNodeInformationWithOpennetRef() + throws InterruptedException, ExecutionException, IOException { + Future nodeData = fcpClient.getNode().opennetRef().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetNode", + "Identifier=" + identifier, + "GiveOpennetRef=true", + "WithPrivate=false", + "WithVolatile=false", + "EndMessage" + )); + fcpServer.writeLine( + "NodeData", + "Identifier=" + identifier, + "opennet=true", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(nodeData.get().getVersion().toString(), is("Fred,0.7,1.0,1466")); + } + + @Test + public void defaultFcpClientCanGetNodeInformationWithPrivateData() + throws InterruptedException, ExecutionException, IOException { + Future nodeData = fcpClient.getNode().includePrivate().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetNode", + "Identifier=" + identifier, + "GiveOpennetRef=false", + "WithPrivate=true", + "WithVolatile=false", + "EndMessage" + )); + fcpServer.writeLine( + "NodeData", + "Identifier=" + identifier, + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "ark.privURI=SSK@XdHMiRl", + "EndMessage" + ); + assertThat(nodeData.get().getARK().getPrivateURI(), is("SSK@XdHMiRl")); + } + + @Test + public void defaultFcpClientCanGetNodeInformationWithVolatileData() + throws InterruptedException, ExecutionException, IOException { + Future nodeData = fcpClient.getNode().includeVolatile().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetNode", + "Identifier=" + identifier, + "GiveOpennetRef=false", + "WithPrivate=false", + "WithVolatile=true", + "EndMessage" + )); + fcpServer.writeLine( + "NodeData", + "Identifier=" + identifier, + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "volatile.freeJavaMemory=205706528", + "EndMessage" + ); + assertThat(nodeData.get().getVolatile("freeJavaMemory"), is("205706528")); + } + + @Test + public void defaultFcpClientCanListSinglePeerByIdentity() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.listPeer().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanListSinglePeerByHostAndPort() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.listPeer().byHostAndPort("host.free.net", 12345).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeer", + "Identifier=" + identifier, + "NodeIdentifier=host.free.net:12345", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanListSinglePeerByName() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.listPeer().byName("FriendNode").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeer", + "Identifier=" + identifier, + "NodeIdentifier=FriendNode", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientRecognizesUnknownNodeIdentifiers() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.listPeer().byIdentity("id2").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeer", + "Identifier=" + identifier, + "NodeIdentifier=id2", + "EndMessage" + )); + fcpServer.writeLine( + "UnknownNodeIdentifier", + "Identifier=" + identifier, + "NodeIdentifier=id2", + "EndMessage" + ); + assertThat(peer.get().isPresent(), is(false)); + } + + @Test + public void defaultFcpClientCanAddPeerFromFile() throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.addPeer().fromFile(new File("/tmp/ref.txt")).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "AddPeer", + "Identifier=" + identifier, + "File=/tmp/ref.txt", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanAddPeerFromURL() throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.addPeer().fromURL(new URL("http://node.ref/")).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "AddPeer", + "Identifier=" + identifier, + "URL=http://node.ref/", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanAddPeerFromNodeRef() throws InterruptedException, ExecutionException, IOException { + NodeRef nodeRef = new NodeRef(); + nodeRef.setIdentity("id1"); + nodeRef.setName("name"); + nodeRef.setARK(new ARK("public", "1")); + nodeRef.setDSAGroup(new DSAGroup("base", "prime", "subprime")); + nodeRef.setNegotiationTypes(new int[] { 3, 5 }); + nodeRef.setPhysicalUDP("1.2.3.4:5678"); + nodeRef.setDSAPublicKey("dsa-public"); + nodeRef.setSignature("sig"); + Future> peer = fcpClient.addPeer().fromNodeRef(nodeRef).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "AddPeer", + "Identifier=" + identifier, + "identity=id1", + "myName=name", + "ark.pubURI=public", + "ark.number=1", + "dsaGroup.g=base", + "dsaGroup.p=prime", + "dsaGroup.q=subprime", + "dsaPubKey.y=dsa-public", + "physical.udp=1.2.3.4:5678", + "auth.negTypes=3;5", + "sig=sig", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "identity=id1", + "opennet=false", + "ark.pubURI=SSK@3YEf.../ark", + "ark.number=78", + "auth.negTypes=2", + "version=Fred,0.7,1.0,1466", + "lastGoodVersion=Fred,0.7,1.0,1466", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void listPeerNotesCanGetPeerNotesByNodeName() throws InterruptedException, ExecutionException, IOException { + Future> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeerNotes", + "NodeIdentifier=Friend1", + "EndMessage" + )); + fcpServer.writeLine( + "PeerNote", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "NoteText=RXhhbXBsZSBUZXh0Lg==", + "PeerNoteType=1", + "EndMessage" + ); + fcpServer.writeLine( + "EndListPeerNotes", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg==")); + assertThat(peerNote.get().get().getPeerNoteType(), is(1)); + } + + @Test + public void listPeerNotesReturnsEmptyOptionalWhenNodeIdenfierUnknown() + throws InterruptedException, ExecutionException, + IOException { + Future> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeerNotes", + "NodeIdentifier=Friend1", + "EndMessage" + )); + fcpServer.writeLine( + "UnknownNodeIdentifier", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "EndMessage" + ); + assertThat(peerNote.get().isPresent(), is(false)); + } + + @Test + public void listPeerNotesCanGetPeerNotesByNodeIdentifier() + throws InterruptedException, ExecutionException, IOException { + Future> peerNote = fcpClient.listPeerNotes().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeerNotes", + "NodeIdentifier=id1", + "EndMessage" + )); + fcpServer.writeLine( + "PeerNote", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "NoteText=RXhhbXBsZSBUZXh0Lg==", + "PeerNoteType=1", + "EndMessage" + ); + fcpServer.writeLine( + "EndListPeerNotes", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg==")); + assertThat(peerNote.get().get().getPeerNoteType(), is(1)); + } + + @Test + public void listPeerNotesCanGetPeerNotesByHostNameAndPortNumber() + throws InterruptedException, ExecutionException, IOException { + Future> peerNote = fcpClient.listPeerNotes().byHostAndPort("1.2.3.4", 5678).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ListPeerNotes", + "NodeIdentifier=1.2.3.4:5678", + "EndMessage" + )); + fcpServer.writeLine( + "PeerNote", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "NoteText=RXhhbXBsZSBUZXh0Lg==", + "PeerNoteType=1", + "EndMessage" + ); + fcpServer.writeLine( + "EndListPeerNotes", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg==")); + assertThat(peerNote.get().get().getPeerNoteType(), is(1)); + } + + @Test + public void defaultFcpClientCanEnablePeerByName() throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().enable().byName("Friend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "IsDisabled=false", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanDisablePeerByName() throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().disable().byName("Friend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "IsDisabled=true", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanEnablePeerByIdentity() throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().enable().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IsDisabled=false", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanEnablePeerByHostAndPort() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().enable().byHostAndPort("1.2.3.4", 5678).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=1.2.3.4:5678", + "IsDisabled=false", + "EndMessage" + )); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanNotModifyPeerOfUnknownNode() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().enable().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IsDisabled=false", + "EndMessage" + )); + fcpServer.writeLine( + "UnknownNodeIdentifier", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "EndMessage" + ); + assertThat(peer.get().isPresent(), is(false)); + } + + @Test + public void defaultFcpClientCanAllowLocalAddressesOfPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().allowLocalAddresses().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "AllowLocalAddresses=true", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanDisallowLocalAddressesOfPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().disallowLocalAddresses().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "AllowLocalAddresses=false", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanSetBurstOnlyForPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().setBurstOnly().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IsBurstOnly=true", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("AllowLocalAddresses=")))); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanClearBurstOnlyForPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().clearBurstOnly().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IsBurstOnly=false", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("AllowLocalAddresses=")))); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanSetListenOnlyForPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().setListenOnly().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IsListenOnly=true", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("AllowLocalAddresses=")))); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + assertThat(lines, not(contains(startsWith("IsBurstOnly=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanClearListenOnlyForPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().clearListenOnly().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IsListenOnly=false", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("AllowLocalAddresses=")))); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + assertThat(lines, not(contains(startsWith("IsBurstOnly=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanIgnoreSourceForPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().ignoreSource().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IgnoreSourcePort=true", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("AllowLocalAddresses=")))); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + assertThat(lines, not(contains(startsWith("IsBurstOnly=")))); + assertThat(lines, not(contains(startsWith("IsListenOnly=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanUseSourceForPeer() + throws InterruptedException, ExecutionException, IOException { + Future> peer = fcpClient.modifyPeer().useSource().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "IgnoreSourcePort=false", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("AllowLocalAddresses=")))); + assertThat(lines, not(contains(startsWith("IsDisabled=")))); + assertThat(lines, not(contains(startsWith("IsBurstOnly=")))); + assertThat(lines, not(contains(startsWith("IsListenOnly=")))); + fcpServer.writeLine( + "Peer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "identity=id1", + "EndMessage" + ); + assertThat(peer.get().get().getIdentity(), is("id1")); + } + + @Test + public void defaultFcpClientCanRemovePeerByName() throws InterruptedException, ExecutionException, IOException { + Future peer = fcpClient.removePeer().byName("Friend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "RemovePeer", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "EndMessage" + )); + fcpServer.writeLine( + "PeerRemoved", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "EndMessage" + ); + assertThat(peer.get(), is(true)); + } + + @Test + public void defaultFcpClientCanNotRemovePeerByInvalidName() + throws InterruptedException, ExecutionException, IOException { + Future peer = fcpClient.removePeer().byName("NotFriend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "RemovePeer", + "Identifier=" + identifier, + "NodeIdentifier=NotFriend1", + "EndMessage" + )); + fcpServer.writeLine( + "UnknownNodeIdentifier", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(peer.get(), is(false)); + } + + @Test + public void defaultFcpClientCanRemovePeerByIdentity() throws InterruptedException, ExecutionException, IOException { + Future peer = fcpClient.removePeer().byIdentity("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "RemovePeer", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "EndMessage" + )); + fcpServer.writeLine( + "PeerRemoved", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "EndMessage" + ); + assertThat(peer.get(), is(true)); + } + + @Test + public void defaultFcpClientCanRemovePeerByHostAndPort() + throws InterruptedException, ExecutionException, IOException { + Future peer = fcpClient.removePeer().byHostAndPort("1.2.3.4", 5678).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "RemovePeer", + "Identifier=" + identifier, + "NodeIdentifier=1.2.3.4:5678", + "EndMessage" + )); + fcpServer.writeLine( + "PeerRemoved", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "EndMessage" + ); + assertThat(peer.get(), is(true)); + } + + @Test + public void defaultFcpClientCanModifyPeerNoteByName() + throws InterruptedException, ExecutionException, IOException { + Future noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byName("Friend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeerNote", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "PeerNoteType=1", + "NoteText=Zm9v", + "EndMessage" + )); + fcpServer.writeLine( + "PeerNote", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "NoteText=Zm9v", + "PeerNoteType=1", + "EndMessage" + ); + assertThat(noteUpdated.get(), is(true)); + } + + @Test + public void defaultFcpClientKnowsPeerNoteWasNotModifiedOnUnknownNodeIdentifier() + throws InterruptedException, ExecutionException, IOException { + Future noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byName("Friend1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeerNote", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "PeerNoteType=1", + "NoteText=Zm9v", + "EndMessage" + )); + fcpServer.writeLine( + "UnknownNodeIdentifier", + "Identifier=" + identifier, + "NodeIdentifier=Friend1", + "EndMessage" + ); + assertThat(noteUpdated.get(), is(false)); + } + + @Test + public void defaultFcpClientFailsToModifyPeerNoteWithoutPeerNote() + throws InterruptedException, ExecutionException, IOException { + Future noteUpdated = fcpClient.modifyPeerNote().byName("Friend1").execute(); + assertThat(noteUpdated.get(), is(false)); + } + + @Test + public void defaultFcpClientCanModifyPeerNoteByIdentifier() + throws InterruptedException, ExecutionException, IOException { + Future noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byIdentifier("id1").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeerNote", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "PeerNoteType=1", + "NoteText=Zm9v", + "EndMessage" + )); + fcpServer.writeLine( + "PeerNote", + "Identifier=" + identifier, + "NodeIdentifier=id1", + "NoteText=Zm9v", + "PeerNoteType=1", + "EndMessage" + ); + assertThat(noteUpdated.get(), is(true)); + } + + @Test + public void defaultFcpClientCanModifyPeerNoteByHostAndPort() + throws InterruptedException, ExecutionException, IOException { + Future noteUpdated = + fcpClient.modifyPeerNote().darknetComment("foo").byHostAndPort("1.2.3.4", 5678).execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyPeerNote", + "Identifier=" + identifier, + "NodeIdentifier=1.2.3.4:5678", + "PeerNoteType=1", + "NoteText=Zm9v", + "EndMessage" + )); + fcpServer.writeLine( + "PeerNote", + "Identifier=" + identifier, + "NodeIdentifier=1.2.3.4:5678", + "NoteText=Zm9v", + "PeerNoteType=1", + "EndMessage" + ); + assertThat(noteUpdated.get(), is(true)); + } + + @Test + public void defaultFcpClientCanGetConfigWithoutDetails() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(configData.get(), notNullValue()); + } + + @Test + public void defaultFcpClientCanGetConfigWithCurrent() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withCurrent().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithCurrent=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "current.foo=bar", + "EndMessage" + ); + assertThat(configData.get().getCurrent("foo"), is("bar")); + } + + @Test + public void defaultFcpClientCanGetConfigWithDefaults() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withDefaults().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithDefaults=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "default.foo=bar", + "EndMessage" + ); + assertThat(configData.get().getDefault("foo"), is("bar")); + } + + @Test + public void defaultFcpClientCanGetConfigWithSortOrder() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withSortOrder().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithSortOrder=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "sortOrder.foo=17", + "EndMessage" + ); + assertThat(configData.get().getSortOrder("foo"), is(17)); + } + + @Test + public void defaultFcpClientCanGetConfigWithExpertFlag() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withExpertFlag().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithExpertFlag=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "expertFlag.foo=true", + "EndMessage" + ); + assertThat(configData.get().getExpertFlag("foo"), is(true)); + } + + @Test + public void defaultFcpClientCanGetConfigWithForceWriteFlag() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withForceWriteFlag().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithForceWriteFlag=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "forceWriteFlag.foo=true", + "EndMessage" + ); + assertThat(configData.get().getForceWriteFlag("foo"), is(true)); + } + + @Test + public void defaultFcpClientCanGetConfigWithShortDescription() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withShortDescription().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithShortDescription=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "shortDescription.foo=bar", + "EndMessage" + ); + assertThat(configData.get().getShortDescription("foo"), is("bar")); + } + + @Test + public void defaultFcpClientCanGetConfigWithLongDescription() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withLongDescription().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithLongDescription=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "longDescription.foo=bar", + "EndMessage" + ); + assertThat(configData.get().getLongDescription("foo"), is("bar")); + } + + @Test + public void defaultFcpClientCanGetConfigWithDataTypes() + throws InterruptedException, ExecutionException, IOException { + Future configData = fcpClient.getConfig().withDataTypes().execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "GetConfig", + "Identifier=" + identifier, + "WithDataTypes=true", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "dataType.foo=number", + "EndMessage" + ); + assertThat(configData.get().getDataType("foo"), is("number")); + } + + @Test + public void defaultFcpClientCanModifyConfigData() throws InterruptedException, ExecutionException, IOException { + Future newConfigData = fcpClient.modifyConfig().set("foo.bar").to("baz").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "ModifyConfig", + "Identifier=" + identifier, + "foo.bar=baz", + "EndMessage" + )); + fcpServer.writeLine( + "ConfigData", + "Identifier=" + identifier, + "current.foo.bar=baz", + "EndMessage" + ); + assertThat(newConfigData.get().getCurrent("foo.bar"), is("baz")); + } + + public class LoadPlugin { + + @Test + public void officialFromFreenet() throws ExecutionException, InterruptedException, IOException { + Future> pluginInfo = + fcpClient.loadPlugin().officialFromFreenet("superPlugin").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "LoadPlugin", + "Identifier=" + identifier, + "PluginURL=superPlugin", + "URLType=official", + "OfficialSource=freenet", + "EndMessage" + )); + assertThat(lines, not(contains(startsWith("Store=")))); + replyWithPluginInfo(identifier); + verifyPluginInfo(pluginInfo); + } + + @Test + public void persistentOfficialFromFreenet() throws ExecutionException, InterruptedException, + IOException { + Future> pluginInfo = + fcpClient.loadPlugin().addToConfig().officialFromFreenet("superPlugin").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "LoadPlugin", + "Identifier=" + identifier, + "PluginURL=superPlugin", + "URLType=official", + "OfficialSource=freenet", + "Store=true", + "EndMessage" + )); + replyWithPluginInfo(identifier); + verifyPluginInfo(pluginInfo); + } + + @Test + public void officialFromHttps() throws ExecutionException, InterruptedException, IOException { + Future> pluginInfo = fcpClient.loadPlugin().officialFromHttps("superPlugin").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "LoadPlugin", + "Identifier=" + identifier, + "PluginURL=superPlugin", + "URLType=official", + "OfficialSource=https", + "EndMessage" + )); + replyWithPluginInfo(identifier); + verifyPluginInfo(pluginInfo); + } + + @Test + public void fromFile() throws ExecutionException, InterruptedException, IOException { + Future> pluginInfo = fcpClient.loadPlugin().fromFile("/path/to/plugin.jar").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "LoadPlugin", + "Identifier=" + identifier, + "PluginURL=/path/to/plugin.jar", + "URLType=file", + "EndMessage" + )); + replyWithPluginInfo(identifier); + verifyPluginInfo(pluginInfo); + } + + @Test + public void fromUrl() throws ExecutionException, InterruptedException, IOException { + Future> pluginInfo = + fcpClient.loadPlugin().fromUrl("http://server.com/plugin.jar").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + assertThat(lines, matchesFcpMessage( + "LoadPlugin", + "Identifier=" + identifier, + "PluginURL=http://server.com/plugin.jar", + "URLType=url", + "EndMessage" + )); + replyWithPluginInfo(identifier); + verifyPluginInfo(pluginInfo); + } + + @Test + public void failedLoad() throws ExecutionException, InterruptedException, IOException { + Future> pluginInfo = + fcpClient.loadPlugin().officialFromFreenet("superPlugin").execute(); + connectNode(); + List lines = fcpServer.collectUntil(is("EndMessage")); + String identifier = extractIdentifier(lines); + fcpServer.writeLine( + "ProtocolError", + "Identifier=" + identifier, + "EndMessage" + ); + assertThat(pluginInfo.get().isPresent(), is(false)); + } + + private void replyWithPluginInfo(String identifier) throws IOException { + fcpServer.writeLine( + "PluginInfo", + "Identifier=" + identifier, + "PluginName=superPlugin", + "IsTalkable=true", + "LongVersion=1.2.3", + "Version=42", + "OriginUri=superPlugin", + "Started=true", + "EndMessage" + ); + } + + private void verifyPluginInfo(Future> pluginInfo) + throws InterruptedException, ExecutionException { + assertThat(pluginInfo.get().get().getPluginName(), is("superPlugin")); + assertThat(pluginInfo.get().get().getOriginalURI(), is("superPlugin")); + assertThat(pluginInfo.get().get().isTalkable(), is(true)); + assertThat(pluginInfo.get().get().getVersion(), is("42")); + assertThat(pluginInfo.get().get().getLongVersion(), is("1.2.3")); + assertThat(pluginInfo.get().get().isStarted(), is(true)); + } + + } + }