1 package net.pterodactylus.fcp.quelaton;
3 import static org.hamcrest.MatcherAssert.assertThat;
4 import static org.hamcrest.Matchers.contains;
5 import static org.hamcrest.Matchers.containsInAnyOrder;
6 import static org.hamcrest.Matchers.hasItem;
7 import static org.hamcrest.Matchers.hasSize;
8 import static org.hamcrest.Matchers.is;
9 import static org.hamcrest.Matchers.not;
10 import static org.hamcrest.Matchers.notNullValue;
11 import static org.hamcrest.Matchers.startsWith;
13 import java.io.ByteArrayInputStream;
15 import java.io.IOException;
17 import java.nio.charset.StandardCharsets;
18 import java.util.Collection;
19 import java.util.List;
20 import java.util.Optional;
21 import java.util.concurrent.CopyOnWriteArrayList;
22 import java.util.concurrent.ExecutionException;
23 import java.util.concurrent.ExecutorService;
24 import java.util.concurrent.Executors;
25 import java.util.concurrent.Future;
26 import java.util.function.Supplier;
27 import java.util.stream.Collectors;
29 import net.pterodactylus.fcp.ARK;
30 import net.pterodactylus.fcp.ConfigData;
31 import net.pterodactylus.fcp.DSAGroup;
32 import net.pterodactylus.fcp.FcpKeyPair;
33 import net.pterodactylus.fcp.Key;
34 import net.pterodactylus.fcp.NodeData;
35 import net.pterodactylus.fcp.NodeRef;
36 import net.pterodactylus.fcp.Peer;
37 import net.pterodactylus.fcp.PeerNote;
38 import net.pterodactylus.fcp.PluginInfo;
39 import net.pterodactylus.fcp.Priority;
40 import net.pterodactylus.fcp.fake.FakeTcpServer;
41 import net.pterodactylus.fcp.quelaton.ClientGetCommand.Data;
43 import com.google.common.io.ByteStreams;
44 import com.google.common.io.Files;
45 import com.nitorcreations.junit.runners.NestedRunner;
46 import org.hamcrest.Description;
47 import org.hamcrest.Matcher;
48 import org.hamcrest.TypeSafeDiagnosingMatcher;
49 import org.junit.After;
50 import org.junit.Assert;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
55 * Unit test for {@link DefaultFcpClient}.
57 * @author <a href="bombe@freenetproject.org">David ‘Bombe’ Roden</a>
59 @RunWith(NestedRunner.class)
60 public class DefaultFcpClientTest {
62 private static final String INSERT_URI =
63 "SSK@RVCHbJdkkyTCeNN9AYukEg76eyqmiosSaNKgE3U9zUw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQECAAE/";
64 private static final String REQUEST_URI =
65 "SSK@wtbgd2loNcJCXvtQVOftl2tuWBomDQHfqS6ytpPRhfw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQACAAE/";
67 private int threadCounter = 0;
68 private final ExecutorService threadPool =
69 Executors.newCachedThreadPool(r -> new Thread(r, "Test-Thread-" + threadCounter++));
70 private final FakeTcpServer fcpServer;
71 private final DefaultFcpClient fcpClient;
73 public DefaultFcpClientTest() throws IOException {
74 fcpServer = new FakeTcpServer(threadPool);
75 fcpClient = new DefaultFcpClient(threadPool, "localhost", fcpServer.getPort(), () -> "Test");
79 public void tearDown() throws IOException {
81 threadPool.shutdown();
84 @Test(expected = ExecutionException.class)
85 public void defaultFcpClientThrowsExceptionIfItCanNotConnect()
86 throws IOException, ExecutionException, InterruptedException {
87 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
88 fcpServer.connect().get();
89 fcpServer.collectUntil(is("EndMessage"));
91 "CloseConnectionDuplicateClientName",
97 @Test(expected = ExecutionException.class)
98 public void defaultFcpClientThrowsExceptionIfConnectionIsClosed()
99 throws IOException, ExecutionException, InterruptedException {
100 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
101 fcpServer.connect().get();
102 fcpServer.collectUntil(is("EndMessage"));
108 public void defaultFcpClientCanGenerateKeypair() throws ExecutionException, InterruptedException, IOException {
109 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
111 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
112 String identifier = extractIdentifier(lines);
113 fcpServer.writeLine("SSKKeypair",
114 "InsertURI=" + INSERT_URI + "",
115 "RequestURI=" + REQUEST_URI + "",
116 "Identifier=" + identifier,
118 FcpKeyPair keyPair = keyPairFuture.get();
119 assertThat(keyPair.getPublicKey(), is(REQUEST_URI));
120 assertThat(keyPair.getPrivateKey(), is(INSERT_URI));
123 private void connectNode() throws InterruptedException, ExecutionException, IOException {
124 fcpServer.connect().get();
125 fcpServer.collectUntil(is("EndMessage"));
126 fcpServer.writeLine("NodeHello",
127 "CompressionCodecs=4 - GZIP(0), BZIP2(1), LZMA(2), LZMA_NEW(3)",
128 "Revision=build01466",
130 "Version=Fred,0.7,1.0,1466",
132 "ConnectionIdentifier=14318898267048452a81b36e7f13a3f0",
136 "NodeLanguage=ENGLISH",
143 public void clientGetCanDownloadData() throws InterruptedException, ExecutionException, IOException {
144 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
146 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
147 assertThat(lines, matchesFcpMessage("ClientGet", "ReturnType=direct", "URI=KSK@foo.txt"));
148 String identifier = extractIdentifier(lines);
151 "Identifier=" + identifier,
153 "StartupTime=1435610539000",
154 "CompletionTime=1435610540000",
155 "Metadata.ContentType=text/plain;charset=utf-8",
159 Optional<Data> data = dataFuture.get();
160 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
161 assertThat(data.get().size(), is(6L));
162 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
163 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
166 private String extractIdentifier(List<String> lines) {
167 return lines.stream()
168 .filter(s -> s.startsWith("Identifier="))
169 .map(s -> s.substring(s.indexOf('=') + 1))
175 public void clientGetDownloadsDataForCorrectIdentifier()
176 throws InterruptedException, ExecutionException, IOException {
177 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
179 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
180 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
181 String identifier = extractIdentifier(lines);
184 "Identifier=not-test",
186 "StartupTime=1435610539000",
187 "CompletionTime=1435610540000",
188 "Metadata.ContentType=text/plain;charset=latin-9",
194 "Identifier=" + identifier,
196 "StartupTime=1435610539000",
197 "CompletionTime=1435610540000",
198 "Metadata.ContentType=text/plain;charset=utf-8",
202 Optional<Data> data = dataFuture.get();
203 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
204 assertThat(data.get().size(), is(6L));
205 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
206 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
210 public void clientGetRecognizesGetFailed() throws InterruptedException, ExecutionException, IOException {
211 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
213 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
214 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
215 String identifier = extractIdentifier(lines);
218 "Identifier=" + identifier,
222 Optional<Data> data = dataFuture.get();
223 assertThat(data.isPresent(), is(false));
227 public void clientGetRecognizesGetFailedForCorrectIdentifier()
228 throws InterruptedException, ExecutionException, IOException {
229 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
231 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
232 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
233 String identifier = extractIdentifier(lines);
236 "Identifier=not-test",
242 "Identifier=" + identifier,
246 Optional<Data> data = dataFuture.get();
247 assertThat(data.isPresent(), is(false));
250 @Test(expected = ExecutionException.class)
251 public void clientGetRecognizesConnectionClosed() throws InterruptedException, ExecutionException, IOException {
252 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
254 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
255 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
261 public void defaultFcpClientReusesConnection() throws InterruptedException, ExecutionException, IOException {
262 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
264 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
265 String identifier = extractIdentifier(lines);
268 "InsertURI=" + INSERT_URI + "",
269 "RequestURI=" + REQUEST_URI + "",
270 "Identifier=" + identifier,
274 keyPair = fcpClient.generateKeypair().execute();
275 lines = fcpServer.collectUntil(is("EndMessage"));
276 identifier = extractIdentifier(lines);
279 "InsertURI=" + INSERT_URI + "",
280 "RequestURI=" + REQUEST_URI + "",
281 "Identifier=" + identifier,
288 public void defaultFcpClientCanReconnectAfterConnectionHasBeenClosed()
289 throws InterruptedException, ExecutionException, IOException {
290 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
292 fcpServer.collectUntil(is("EndMessage"));
297 } catch (ExecutionException e) {
299 keyPair = fcpClient.generateKeypair().execute();
301 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
302 String identifier = extractIdentifier(lines);
305 "InsertURI=" + INSERT_URI + "",
306 "RequestURI=" + REQUEST_URI + "",
307 "Identifier=" + identifier,
314 public void clientGetWithIgnoreDataStoreSettingSendsCorrectCommands()
315 throws InterruptedException, ExecutionException, IOException {
316 fcpClient.clientGet().ignoreDataStore().uri("KSK@foo.txt").execute();
318 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
319 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "IgnoreDS=true"));
323 public void clientGetWithDataStoreOnlySettingSendsCorrectCommands()
324 throws InterruptedException, ExecutionException, IOException {
325 fcpClient.clientGet().dataStoreOnly().uri("KSK@foo.txt").execute();
327 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
328 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "DSonly=true"));
332 public void clientGetWithMaxSizeSettingSendsCorrectCommands()
333 throws InterruptedException, ExecutionException, IOException {
334 fcpClient.clientGet().maxSize(1048576).uri("KSK@foo.txt").execute();
336 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
337 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "MaxSize=1048576"));
341 public void clientGetWithPrioritySettingSendsCorrectCommands()
342 throws InterruptedException, ExecutionException, IOException {
343 fcpClient.clientGet().priority(Priority.interactive).uri("KSK@foo.txt").execute();
345 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
346 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "PriorityClass=1"));
350 public void clientGetWithRealTimeSettingSendsCorrectCommands()
351 throws InterruptedException, ExecutionException, IOException {
352 fcpClient.clientGet().realTime().uri("KSK@foo.txt").execute();
354 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
355 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "RealTimeFlag=true"));
359 public void clientGetWithGlobalSettingSendsCorrectCommands()
360 throws InterruptedException, ExecutionException, IOException {
361 fcpClient.clientGet().global().uri("KSK@foo.txt").execute();
363 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
364 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "Global=true"));
367 private Matcher<List<String>> matchesFcpMessage(String name, String... requiredLines) {
368 return new TypeSafeDiagnosingMatcher<List<String>>() {
370 protected boolean matchesSafely(List<String> item, Description mismatchDescription) {
371 if (!item.get(0).equals(name)) {
372 mismatchDescription.appendText("FCP message is named ").appendValue(item.get(0));
375 for (String requiredLine : requiredLines) {
376 if (item.indexOf(requiredLine) < 1) {
377 mismatchDescription.appendText("FCP message does not contain ").appendValue(requiredLine);
385 public void describeTo(Description description) {
386 description.appendText("FCP message named ").appendValue(name);
387 description.appendValueList(", containing the lines ", ", ", "", requiredLines);
393 public void clientPutWithDirectDataSendsCorrectCommand()
394 throws IOException, ExecutionException, InterruptedException {
395 fcpClient.clientPut()
396 .from(new ByteArrayInputStream("Hello\n".getBytes()))
401 List<String> lines = fcpServer.collectUntil(is("Hello"));
402 assertThat(lines, matchesFcpMessage("ClientPut", "UploadFrom=direct", "DataLength=6", "URI=KSK@foo.txt"));
406 public void clientPutWithDirectDataSucceedsOnCorrectIdentifier()
407 throws InterruptedException, ExecutionException, IOException {
408 Future<Optional<Key>> key = fcpClient.clientPut()
409 .from(new ByteArrayInputStream("Hello\n".getBytes()))
414 List<String> lines = fcpServer.collectUntil(is("Hello"));
415 String identifier = extractIdentifier(lines);
418 "Identifier=not-the-right-one",
424 "Identifier=" + identifier,
427 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
431 public void clientPutWithDirectDataFailsOnCorrectIdentifier()
432 throws InterruptedException, ExecutionException, IOException {
433 Future<Optional<Key>> key = fcpClient.clientPut()
434 .from(new ByteArrayInputStream("Hello\n".getBytes()))
439 List<String> lines = fcpServer.collectUntil(is("Hello"));
440 String identifier = extractIdentifier(lines);
443 "Identifier=not-the-right-one",
449 "Identifier=" + identifier,
452 assertThat(key.get().isPresent(), is(false));
456 public void clientPutWithRenamedDirectDataSendsCorrectCommand()
457 throws InterruptedException, ExecutionException, IOException {
458 fcpClient.clientPut()
459 .named("otherName.txt")
460 .from(new ByteArrayInputStream("Hello\n".getBytes()))
465 List<String> lines = fcpServer.collectUntil(is("Hello"));
466 assertThat(lines, matchesFcpMessage("ClientPut", "TargetFilename=otherName.txt", "UploadFrom=direct",
467 "DataLength=6", "URI=KSK@foo.txt"));
471 public void clientPutWithRedirectSendsCorrectCommand()
472 throws IOException, ExecutionException, InterruptedException {
473 fcpClient.clientPut().redirectTo("KSK@bar.txt").uri("KSK@foo.txt").execute();
475 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
477 matchesFcpMessage("ClientPut", "UploadFrom=redirect", "URI=KSK@foo.txt", "TargetURI=KSK@bar.txt"));
481 public void clientPutWithFileSendsCorrectCommand() throws InterruptedException, ExecutionException, IOException {
482 fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
484 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
486 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt", "Filename=/tmp/data.txt"));
490 public void clientPutWithFileCanCompleteTestDdaSequence()
491 throws IOException, ExecutionException, InterruptedException {
492 File tempFile = createTempFile();
493 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
495 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
496 String identifier = extractIdentifier(lines);
499 "Identifier=" + identifier,
503 lines = fcpServer.collectUntil(is("EndMessage"));
504 assertThat(lines, matchesFcpMessage(
506 "Directory=" + tempFile.getParent(),
507 "WantReadDirectory=true",
508 "WantWriteDirectory=false",
513 "Directory=" + tempFile.getParent(),
514 "ReadFilename=" + tempFile,
517 lines = fcpServer.collectUntil(is("EndMessage"));
518 assertThat(lines, matchesFcpMessage(
520 "Directory=" + tempFile.getParent(),
521 "ReadContent=test-content",
526 "Directory=" + tempFile.getParent(),
527 "ReadDirectoryAllowed=true",
530 lines = fcpServer.collectUntil(is("EndMessage"));
532 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt",
533 "Filename=" + new File(tempFile.getParent(), "test.dat")));
536 private File createTempFile() throws IOException {
537 File tempFile = File.createTempFile("test-dda-", ".dat");
538 tempFile.deleteOnExit();
539 Files.write("test-content", tempFile, StandardCharsets.UTF_8);
544 public void clientPutDoesNotReactToProtocolErrorForDifferentIdentifier()
545 throws InterruptedException, ExecutionException, IOException {
546 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
548 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
549 String identifier = extractIdentifier(lines);
552 "Identifier=not-the-right-one",
558 "Identifier=" + identifier,
562 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
566 public void clientPutAbortsOnProtocolErrorOtherThan25()
567 throws InterruptedException, ExecutionException, IOException {
568 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
570 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
571 String identifier = extractIdentifier(lines);
574 "Identifier=" + identifier,
578 assertThat(key.get().isPresent(), is(false));
582 public void clientPutDoesNotReplyToWrongTestDdaReply() throws IOException, ExecutionException,
583 InterruptedException {
584 File tempFile = createTempFile();
585 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
587 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
588 String identifier = extractIdentifier(lines);
591 "Identifier=" + identifier,
595 lines = fcpServer.collectUntil(is("EndMessage"));
596 assertThat(lines, matchesFcpMessage(
598 "Directory=" + tempFile.getParent(),
599 "WantReadDirectory=true",
600 "WantWriteDirectory=false",
605 "Directory=/some-other-directory",
606 "ReadFilename=" + tempFile,
611 "Directory=" + tempFile.getParent(),
612 "ReadFilename=" + tempFile,
615 lines = fcpServer.collectUntil(is("EndMessage"));
616 assertThat(lines, matchesFcpMessage(
618 "Directory=" + tempFile.getParent(),
619 "ReadContent=test-content",
625 public void clientPutSendsResponseEvenIfFileCanNotBeRead()
626 throws IOException, ExecutionException, InterruptedException {
627 File tempFile = createTempFile();
628 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
630 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
631 String identifier = extractIdentifier(lines);
634 "Identifier=" + identifier,
638 lines = fcpServer.collectUntil(is("EndMessage"));
639 assertThat(lines, matchesFcpMessage(
641 "Directory=" + tempFile.getParent(),
642 "WantReadDirectory=true",
643 "WantWriteDirectory=false",
648 "Directory=" + tempFile.getParent(),
649 "ReadFilename=" + tempFile + ".foo",
652 lines = fcpServer.collectUntil(is("EndMessage"));
653 assertThat(lines, matchesFcpMessage(
655 "Directory=" + tempFile.getParent(),
656 "ReadContent=failed-to-read",
662 public void clientPutDoesNotResendOriginalClientPutOnTestDDACompleteWithWrongDirectory()
663 throws IOException, ExecutionException, InterruptedException {
664 File tempFile = createTempFile();
665 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
667 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
668 String identifier = extractIdentifier(lines);
671 "Directory=/some-other-directory",
676 "Identifier=" + identifier,
680 lines = fcpServer.collectUntil(is("EndMessage"));
681 assertThat(lines, matchesFcpMessage(
683 "Directory=" + tempFile.getParent(),
684 "WantReadDirectory=true",
685 "WantWriteDirectory=false",
691 public void clientPutSendsNotificationsForGeneratedKeys()
692 throws InterruptedException, ExecutionException, IOException {
693 List<String> generatedKeys = new CopyOnWriteArrayList<>();
694 Future<Optional<Key>> key = fcpClient.clientPut()
695 .onKeyGenerated(generatedKeys::add)
696 .from(new ByteArrayInputStream("Hello\n".getBytes()))
701 List<String> lines = fcpServer.collectUntil(is("Hello"));
702 String identifier = extractIdentifier(lines);
705 "Identifier=" + identifier,
712 "Identifier=" + identifier,
715 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
716 assertThat(generatedKeys, contains("KSK@foo.txt"));
720 public void clientCanListPeers() throws IOException, ExecutionException, InterruptedException {
721 Future<Collection<Peer>> peers = fcpClient.listPeers().execute();
723 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
724 assertThat(lines, matchesFcpMessage(
726 "WithVolatile=false",
727 "WithMetadata=false",
730 String identifier = extractIdentifier(lines);
733 "Identifier=" + identifier,
739 "Identifier=" + identifier,
745 "Identifier=" + identifier,
748 assertThat(peers.get(), hasSize(2));
749 assertThat(peers.get().stream().map(Peer::getIdentity).collect(Collectors.toList()),
750 containsInAnyOrder("id1", "id2"));
754 public void clientCanListPeersWithMetadata() throws IOException, ExecutionException, InterruptedException {
755 Future<Collection<Peer>> peers = fcpClient.listPeers().includeMetadata().execute();
757 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
758 assertThat(lines, matchesFcpMessage(
760 "WithVolatile=false",
764 String identifier = extractIdentifier(lines);
767 "Identifier=" + identifier,
774 "Identifier=" + identifier,
781 "Identifier=" + identifier,
784 assertThat(peers.get(), hasSize(2));
785 assertThat(peers.get().stream().map(peer -> peer.getMetadata("foo")).collect(Collectors.toList()),
786 containsInAnyOrder("bar1", "bar2"));
790 public void clientCanListPeersWithVolatiles() throws IOException, ExecutionException, InterruptedException {
791 Future<Collection<Peer>> peers = fcpClient.listPeers().includeVolatile().execute();
793 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
794 assertThat(lines, matchesFcpMessage(
797 "WithMetadata=false",
800 String identifier = extractIdentifier(lines);
803 "Identifier=" + identifier,
810 "Identifier=" + identifier,
817 "Identifier=" + identifier,
820 assertThat(peers.get(), hasSize(2));
821 assertThat(peers.get().stream().map(peer -> peer.getVolatile("foo")).collect(Collectors.toList()),
822 containsInAnyOrder("bar1", "bar2"));
826 public void defaultFcpClientCanGetNodeInformation() throws InterruptedException, ExecutionException, IOException {
827 Future<NodeData> nodeData = fcpClient.getNode().execute();
829 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
830 String identifier = extractIdentifier(lines);
831 assertThat(lines, matchesFcpMessage(
833 "Identifier=" + identifier,
834 "GiveOpennetRef=false",
836 "WithVolatile=false",
841 "Identifier=" + identifier,
842 "ark.pubURI=SSK@3YEf.../ark",
845 "version=Fred,0.7,1.0,1466",
846 "lastGoodVersion=Fred,0.7,1.0,1466",
849 assertThat(nodeData.get(), notNullValue());
853 public void defaultFcpClientCanGetNodeInformationWithOpennetRef()
854 throws InterruptedException, ExecutionException, IOException {
855 Future<NodeData> nodeData = fcpClient.getNode().opennetRef().execute();
857 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
858 String identifier = extractIdentifier(lines);
859 assertThat(lines, matchesFcpMessage(
861 "Identifier=" + identifier,
862 "GiveOpennetRef=true",
864 "WithVolatile=false",
869 "Identifier=" + identifier,
871 "ark.pubURI=SSK@3YEf.../ark",
874 "version=Fred,0.7,1.0,1466",
875 "lastGoodVersion=Fred,0.7,1.0,1466",
878 assertThat(nodeData.get().getVersion().toString(), is("Fred,0.7,1.0,1466"));
882 public void defaultFcpClientCanGetNodeInformationWithPrivateData()
883 throws InterruptedException, ExecutionException, IOException {
884 Future<NodeData> nodeData = fcpClient.getNode().includePrivate().execute();
886 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
887 String identifier = extractIdentifier(lines);
888 assertThat(lines, matchesFcpMessage(
890 "Identifier=" + identifier,
891 "GiveOpennetRef=false",
893 "WithVolatile=false",
898 "Identifier=" + identifier,
900 "ark.pubURI=SSK@3YEf.../ark",
903 "version=Fred,0.7,1.0,1466",
904 "lastGoodVersion=Fred,0.7,1.0,1466",
905 "ark.privURI=SSK@XdHMiRl",
908 assertThat(nodeData.get().getARK().getPrivateURI(), is("SSK@XdHMiRl"));
912 public void defaultFcpClientCanGetNodeInformationWithVolatileData()
913 throws InterruptedException, ExecutionException, IOException {
914 Future<NodeData> nodeData = fcpClient.getNode().includeVolatile().execute();
916 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
917 String identifier = extractIdentifier(lines);
918 assertThat(lines, matchesFcpMessage(
920 "Identifier=" + identifier,
921 "GiveOpennetRef=false",
928 "Identifier=" + identifier,
930 "ark.pubURI=SSK@3YEf.../ark",
933 "version=Fred,0.7,1.0,1466",
934 "lastGoodVersion=Fred,0.7,1.0,1466",
935 "volatile.freeJavaMemory=205706528",
938 assertThat(nodeData.get().getVolatile("freeJavaMemory"), is("205706528"));
942 public void defaultFcpClientCanListSinglePeerByIdentity()
943 throws InterruptedException, ExecutionException, IOException {
944 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id1").execute();
946 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
947 String identifier = extractIdentifier(lines);
948 assertThat(lines, matchesFcpMessage(
950 "Identifier=" + identifier,
951 "NodeIdentifier=id1",
956 "Identifier=" + identifier,
959 "ark.pubURI=SSK@3YEf.../ark",
962 "version=Fred,0.7,1.0,1466",
963 "lastGoodVersion=Fred,0.7,1.0,1466",
966 assertThat(peer.get().get().getIdentity(), is("id1"));
970 public void defaultFcpClientCanListSinglePeerByHostAndPort()
971 throws InterruptedException, ExecutionException, IOException {
972 Future<Optional<Peer>> peer = fcpClient.listPeer().byHostAndPort("host.free.net", 12345).execute();
974 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
975 String identifier = extractIdentifier(lines);
976 assertThat(lines, matchesFcpMessage(
978 "Identifier=" + identifier,
979 "NodeIdentifier=host.free.net:12345",
984 "Identifier=" + identifier,
987 "ark.pubURI=SSK@3YEf.../ark",
990 "version=Fred,0.7,1.0,1466",
991 "lastGoodVersion=Fred,0.7,1.0,1466",
994 assertThat(peer.get().get().getIdentity(), is("id1"));
998 public void defaultFcpClientCanListSinglePeerByName()
999 throws InterruptedException, ExecutionException, IOException {
1000 Future<Optional<Peer>> peer = fcpClient.listPeer().byName("FriendNode").execute();
1002 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1003 String identifier = extractIdentifier(lines);
1004 assertThat(lines, matchesFcpMessage(
1006 "Identifier=" + identifier,
1007 "NodeIdentifier=FriendNode",
1010 fcpServer.writeLine(
1012 "Identifier=" + identifier,
1015 "ark.pubURI=SSK@3YEf.../ark",
1018 "version=Fred,0.7,1.0,1466",
1019 "lastGoodVersion=Fred,0.7,1.0,1466",
1022 assertThat(peer.get().get().getIdentity(), is("id1"));
1026 public void defaultFcpClientRecognizesUnknownNodeIdentifiers()
1027 throws InterruptedException, ExecutionException, IOException {
1028 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id2").execute();
1030 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1031 String identifier = extractIdentifier(lines);
1032 assertThat(lines, matchesFcpMessage(
1034 "Identifier=" + identifier,
1035 "NodeIdentifier=id2",
1038 fcpServer.writeLine(
1039 "UnknownNodeIdentifier",
1040 "Identifier=" + identifier,
1041 "NodeIdentifier=id2",
1044 assertThat(peer.get().isPresent(), is(false));
1048 public void defaultFcpClientCanAddPeerFromFile() throws InterruptedException, ExecutionException, IOException {
1049 Future<Optional<Peer>> peer = fcpClient.addPeer().fromFile(new File("/tmp/ref.txt")).execute();
1051 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1052 String identifier = extractIdentifier(lines);
1053 assertThat(lines, matchesFcpMessage(
1055 "Identifier=" + identifier,
1056 "File=/tmp/ref.txt",
1059 fcpServer.writeLine(
1061 "Identifier=" + identifier,
1064 "ark.pubURI=SSK@3YEf.../ark",
1067 "version=Fred,0.7,1.0,1466",
1068 "lastGoodVersion=Fred,0.7,1.0,1466",
1071 assertThat(peer.get().get().getIdentity(), is("id1"));
1075 public void defaultFcpClientCanAddPeerFromURL() throws InterruptedException, ExecutionException, IOException {
1076 Future<Optional<Peer>> peer = fcpClient.addPeer().fromURL(new URL("http://node.ref/")).execute();
1078 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1079 String identifier = extractIdentifier(lines);
1080 assertThat(lines, matchesFcpMessage(
1082 "Identifier=" + identifier,
1083 "URL=http://node.ref/",
1086 fcpServer.writeLine(
1088 "Identifier=" + identifier,
1091 "ark.pubURI=SSK@3YEf.../ark",
1094 "version=Fred,0.7,1.0,1466",
1095 "lastGoodVersion=Fred,0.7,1.0,1466",
1098 assertThat(peer.get().get().getIdentity(), is("id1"));
1102 public void defaultFcpClientCanAddPeerFromNodeRef() throws InterruptedException, ExecutionException, IOException {
1103 NodeRef nodeRef = new NodeRef();
1104 nodeRef.setIdentity("id1");
1105 nodeRef.setName("name");
1106 nodeRef.setARK(new ARK("public", "1"));
1107 nodeRef.setDSAGroup(new DSAGroup("base", "prime", "subprime"));
1108 nodeRef.setNegotiationTypes(new int[] { 3, 5 });
1109 nodeRef.setPhysicalUDP("1.2.3.4:5678");
1110 nodeRef.setDSAPublicKey("dsa-public");
1111 nodeRef.setSignature("sig");
1112 Future<Optional<Peer>> peer = fcpClient.addPeer().fromNodeRef(nodeRef).execute();
1114 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1115 String identifier = extractIdentifier(lines);
1116 assertThat(lines, matchesFcpMessage(
1118 "Identifier=" + identifier,
1121 "ark.pubURI=public",
1125 "dsaGroup.q=subprime",
1126 "dsaPubKey.y=dsa-public",
1127 "physical.udp=1.2.3.4:5678",
1128 "auth.negTypes=3;5",
1132 fcpServer.writeLine(
1134 "Identifier=" + identifier,
1137 "ark.pubURI=SSK@3YEf.../ark",
1140 "version=Fred,0.7,1.0,1466",
1141 "lastGoodVersion=Fred,0.7,1.0,1466",
1144 assertThat(peer.get().get().getIdentity(), is("id1"));
1148 public void listPeerNotesCanGetPeerNotesByNodeName() throws InterruptedException, ExecutionException, IOException {
1149 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute();
1151 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1152 String identifier = extractIdentifier(lines);
1153 assertThat(lines, matchesFcpMessage(
1155 "NodeIdentifier=Friend1",
1158 fcpServer.writeLine(
1160 "Identifier=" + identifier,
1161 "NodeIdentifier=Friend1",
1162 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1166 fcpServer.writeLine(
1168 "Identifier=" + identifier,
1171 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1172 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1176 public void listPeerNotesReturnsEmptyOptionalWhenNodeIdenfierUnknown()
1177 throws InterruptedException, ExecutionException,
1179 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute();
1181 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1182 String identifier = extractIdentifier(lines);
1183 assertThat(lines, matchesFcpMessage(
1185 "NodeIdentifier=Friend1",
1188 fcpServer.writeLine(
1189 "UnknownNodeIdentifier",
1190 "Identifier=" + identifier,
1191 "NodeIdentifier=Friend1",
1194 assertThat(peerNote.get().isPresent(), is(false));
1198 public void listPeerNotesCanGetPeerNotesByNodeIdentifier()
1199 throws InterruptedException, ExecutionException, IOException {
1200 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byIdentity("id1").execute();
1202 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1203 String identifier = extractIdentifier(lines);
1204 assertThat(lines, matchesFcpMessage(
1206 "NodeIdentifier=id1",
1209 fcpServer.writeLine(
1211 "Identifier=" + identifier,
1212 "NodeIdentifier=id1",
1213 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1217 fcpServer.writeLine(
1219 "Identifier=" + identifier,
1222 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1223 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1227 public void listPeerNotesCanGetPeerNotesByHostNameAndPortNumber()
1228 throws InterruptedException, ExecutionException, IOException {
1229 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byHostAndPort("1.2.3.4", 5678).execute();
1231 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1232 String identifier = extractIdentifier(lines);
1233 assertThat(lines, matchesFcpMessage(
1235 "NodeIdentifier=1.2.3.4:5678",
1238 fcpServer.writeLine(
1240 "Identifier=" + identifier,
1241 "NodeIdentifier=id1",
1242 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1246 fcpServer.writeLine(
1248 "Identifier=" + identifier,
1251 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1252 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1256 public void defaultFcpClientCanEnablePeerByName() throws InterruptedException, ExecutionException, IOException {
1257 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byName("Friend1").execute();
1259 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1260 String identifier = extractIdentifier(lines);
1261 assertThat(lines, matchesFcpMessage(
1263 "Identifier=" + identifier,
1264 "NodeIdentifier=Friend1",
1268 fcpServer.writeLine(
1270 "Identifier=" + identifier,
1271 "NodeIdentifier=Friend1",
1275 assertThat(peer.get().get().getIdentity(), is("id1"));
1279 public void defaultFcpClientCanDisablePeerByName() throws InterruptedException, ExecutionException, IOException {
1280 Future<Optional<Peer>> peer = fcpClient.modifyPeer().disable().byName("Friend1").execute();
1282 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1283 String identifier = extractIdentifier(lines);
1284 assertThat(lines, matchesFcpMessage(
1286 "Identifier=" + identifier,
1287 "NodeIdentifier=Friend1",
1291 fcpServer.writeLine(
1293 "Identifier=" + identifier,
1294 "NodeIdentifier=Friend1",
1298 assertThat(peer.get().get().getIdentity(), is("id1"));
1302 public void defaultFcpClientCanEnablePeerByIdentity() throws InterruptedException, ExecutionException, IOException {
1303 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byIdentity("id1").execute();
1305 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1306 String identifier = extractIdentifier(lines);
1307 assertThat(lines, matchesFcpMessage(
1309 "Identifier=" + identifier,
1310 "NodeIdentifier=id1",
1314 fcpServer.writeLine(
1316 "Identifier=" + identifier,
1317 "NodeIdentifier=Friend1",
1321 assertThat(peer.get().get().getIdentity(), is("id1"));
1325 public void defaultFcpClientCanEnablePeerByHostAndPort()
1326 throws InterruptedException, ExecutionException, IOException {
1327 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byHostAndPort("1.2.3.4", 5678).execute();
1329 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1330 String identifier = extractIdentifier(lines);
1331 assertThat(lines, matchesFcpMessage(
1333 "Identifier=" + identifier,
1334 "NodeIdentifier=1.2.3.4:5678",
1338 fcpServer.writeLine(
1340 "Identifier=" + identifier,
1341 "NodeIdentifier=Friend1",
1345 assertThat(peer.get().get().getIdentity(), is("id1"));
1349 public void defaultFcpClientCanNotModifyPeerOfUnknownNode()
1350 throws InterruptedException, ExecutionException, IOException {
1351 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byIdentity("id1").execute();
1353 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1354 String identifier = extractIdentifier(lines);
1355 assertThat(lines, matchesFcpMessage(
1357 "Identifier=" + identifier,
1358 "NodeIdentifier=id1",
1362 fcpServer.writeLine(
1363 "UnknownNodeIdentifier",
1364 "Identifier=" + identifier,
1365 "NodeIdentifier=id1",
1368 assertThat(peer.get().isPresent(), is(false));
1372 public void defaultFcpClientCanAllowLocalAddressesOfPeer()
1373 throws InterruptedException, ExecutionException, IOException {
1374 Future<Optional<Peer>> peer = fcpClient.modifyPeer().allowLocalAddresses().byIdentity("id1").execute();
1376 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1377 String identifier = extractIdentifier(lines);
1378 assertThat(lines, matchesFcpMessage(
1380 "Identifier=" + identifier,
1381 "NodeIdentifier=id1",
1382 "AllowLocalAddresses=true",
1385 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1386 fcpServer.writeLine(
1388 "Identifier=" + identifier,
1389 "NodeIdentifier=Friend1",
1393 assertThat(peer.get().get().getIdentity(), is("id1"));
1397 public void defaultFcpClientCanDisallowLocalAddressesOfPeer()
1398 throws InterruptedException, ExecutionException, IOException {
1399 Future<Optional<Peer>> peer = fcpClient.modifyPeer().disallowLocalAddresses().byIdentity("id1").execute();
1401 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1402 String identifier = extractIdentifier(lines);
1403 assertThat(lines, matchesFcpMessage(
1405 "Identifier=" + identifier,
1406 "NodeIdentifier=id1",
1407 "AllowLocalAddresses=false",
1410 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1411 fcpServer.writeLine(
1413 "Identifier=" + identifier,
1414 "NodeIdentifier=Friend1",
1418 assertThat(peer.get().get().getIdentity(), is("id1"));
1422 public void defaultFcpClientCanSetBurstOnlyForPeer()
1423 throws InterruptedException, ExecutionException, IOException {
1424 Future<Optional<Peer>> peer = fcpClient.modifyPeer().setBurstOnly().byIdentity("id1").execute();
1426 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1427 String identifier = extractIdentifier(lines);
1428 assertThat(lines, matchesFcpMessage(
1430 "Identifier=" + identifier,
1431 "NodeIdentifier=id1",
1435 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1436 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1437 fcpServer.writeLine(
1439 "Identifier=" + identifier,
1440 "NodeIdentifier=Friend1",
1444 assertThat(peer.get().get().getIdentity(), is("id1"));
1448 public void defaultFcpClientCanClearBurstOnlyForPeer()
1449 throws InterruptedException, ExecutionException, IOException {
1450 Future<Optional<Peer>> peer = fcpClient.modifyPeer().clearBurstOnly().byIdentity("id1").execute();
1452 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1453 String identifier = extractIdentifier(lines);
1454 assertThat(lines, matchesFcpMessage(
1456 "Identifier=" + identifier,
1457 "NodeIdentifier=id1",
1458 "IsBurstOnly=false",
1461 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1462 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1463 fcpServer.writeLine(
1465 "Identifier=" + identifier,
1466 "NodeIdentifier=Friend1",
1470 assertThat(peer.get().get().getIdentity(), is("id1"));
1474 public void defaultFcpClientCanSetListenOnlyForPeer()
1475 throws InterruptedException, ExecutionException, IOException {
1476 Future<Optional<Peer>> peer = fcpClient.modifyPeer().setListenOnly().byIdentity("id1").execute();
1478 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1479 String identifier = extractIdentifier(lines);
1480 assertThat(lines, matchesFcpMessage(
1482 "Identifier=" + identifier,
1483 "NodeIdentifier=id1",
1484 "IsListenOnly=true",
1487 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1488 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1489 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1490 fcpServer.writeLine(
1492 "Identifier=" + identifier,
1493 "NodeIdentifier=Friend1",
1497 assertThat(peer.get().get().getIdentity(), is("id1"));
1501 public void defaultFcpClientCanClearListenOnlyForPeer()
1502 throws InterruptedException, ExecutionException, IOException {
1503 Future<Optional<Peer>> peer = fcpClient.modifyPeer().clearListenOnly().byIdentity("id1").execute();
1505 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1506 String identifier = extractIdentifier(lines);
1507 assertThat(lines, matchesFcpMessage(
1509 "Identifier=" + identifier,
1510 "NodeIdentifier=id1",
1511 "IsListenOnly=false",
1514 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1515 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1516 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1517 fcpServer.writeLine(
1519 "Identifier=" + identifier,
1520 "NodeIdentifier=Friend1",
1524 assertThat(peer.get().get().getIdentity(), is("id1"));
1528 public void defaultFcpClientCanIgnoreSourceForPeer()
1529 throws InterruptedException, ExecutionException, IOException {
1530 Future<Optional<Peer>> peer = fcpClient.modifyPeer().ignoreSource().byIdentity("id1").execute();
1532 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1533 String identifier = extractIdentifier(lines);
1534 assertThat(lines, matchesFcpMessage(
1536 "Identifier=" + identifier,
1537 "NodeIdentifier=id1",
1538 "IgnoreSourcePort=true",
1541 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1542 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1543 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1544 assertThat(lines, not(contains(startsWith("IsListenOnly="))));
1545 fcpServer.writeLine(
1547 "Identifier=" + identifier,
1548 "NodeIdentifier=Friend1",
1552 assertThat(peer.get().get().getIdentity(), is("id1"));
1556 public void defaultFcpClientCanUseSourceForPeer()
1557 throws InterruptedException, ExecutionException, IOException {
1558 Future<Optional<Peer>> peer = fcpClient.modifyPeer().useSource().byIdentity("id1").execute();
1560 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1561 String identifier = extractIdentifier(lines);
1562 assertThat(lines, matchesFcpMessage(
1564 "Identifier=" + identifier,
1565 "NodeIdentifier=id1",
1566 "IgnoreSourcePort=false",
1569 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1570 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1571 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1572 assertThat(lines, not(contains(startsWith("IsListenOnly="))));
1573 fcpServer.writeLine(
1575 "Identifier=" + identifier,
1576 "NodeIdentifier=Friend1",
1580 assertThat(peer.get().get().getIdentity(), is("id1"));
1584 public void defaultFcpClientCanRemovePeerByName() throws InterruptedException, ExecutionException, IOException {
1585 Future<Boolean> peer = fcpClient.removePeer().byName("Friend1").execute();
1587 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1588 String identifier = extractIdentifier(lines);
1589 assertThat(lines, matchesFcpMessage(
1591 "Identifier=" + identifier,
1592 "NodeIdentifier=Friend1",
1595 fcpServer.writeLine(
1597 "Identifier=" + identifier,
1598 "NodeIdentifier=Friend1",
1601 assertThat(peer.get(), is(true));
1605 public void defaultFcpClientCanNotRemovePeerByInvalidName()
1606 throws InterruptedException, ExecutionException, IOException {
1607 Future<Boolean> peer = fcpClient.removePeer().byName("NotFriend1").execute();
1609 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1610 String identifier = extractIdentifier(lines);
1611 assertThat(lines, matchesFcpMessage(
1613 "Identifier=" + identifier,
1614 "NodeIdentifier=NotFriend1",
1617 fcpServer.writeLine(
1618 "UnknownNodeIdentifier",
1619 "Identifier=" + identifier,
1622 assertThat(peer.get(), is(false));
1626 public void defaultFcpClientCanRemovePeerByIdentity() throws InterruptedException, ExecutionException, IOException {
1627 Future<Boolean> peer = fcpClient.removePeer().byIdentity("id1").execute();
1629 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1630 String identifier = extractIdentifier(lines);
1631 assertThat(lines, matchesFcpMessage(
1633 "Identifier=" + identifier,
1634 "NodeIdentifier=id1",
1637 fcpServer.writeLine(
1639 "Identifier=" + identifier,
1640 "NodeIdentifier=Friend1",
1643 assertThat(peer.get(), is(true));
1647 public void defaultFcpClientCanRemovePeerByHostAndPort()
1648 throws InterruptedException, ExecutionException, IOException {
1649 Future<Boolean> peer = fcpClient.removePeer().byHostAndPort("1.2.3.4", 5678).execute();
1651 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1652 String identifier = extractIdentifier(lines);
1653 assertThat(lines, matchesFcpMessage(
1655 "Identifier=" + identifier,
1656 "NodeIdentifier=1.2.3.4:5678",
1659 fcpServer.writeLine(
1661 "Identifier=" + identifier,
1662 "NodeIdentifier=Friend1",
1665 assertThat(peer.get(), is(true));
1669 public void defaultFcpClientCanModifyPeerNoteByName()
1670 throws InterruptedException, ExecutionException, IOException {
1671 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byName("Friend1").execute();
1673 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1674 String identifier = extractIdentifier(lines);
1675 assertThat(lines, matchesFcpMessage(
1677 "Identifier=" + identifier,
1678 "NodeIdentifier=Friend1",
1683 fcpServer.writeLine(
1685 "Identifier=" + identifier,
1686 "NodeIdentifier=Friend1",
1691 assertThat(noteUpdated.get(), is(true));
1695 public void defaultFcpClientKnowsPeerNoteWasNotModifiedOnUnknownNodeIdentifier()
1696 throws InterruptedException, ExecutionException, IOException {
1697 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byName("Friend1").execute();
1699 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1700 String identifier = extractIdentifier(lines);
1701 assertThat(lines, matchesFcpMessage(
1703 "Identifier=" + identifier,
1704 "NodeIdentifier=Friend1",
1709 fcpServer.writeLine(
1710 "UnknownNodeIdentifier",
1711 "Identifier=" + identifier,
1712 "NodeIdentifier=Friend1",
1715 assertThat(noteUpdated.get(), is(false));
1719 public void defaultFcpClientFailsToModifyPeerNoteWithoutPeerNote()
1720 throws InterruptedException, ExecutionException, IOException {
1721 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().byName("Friend1").execute();
1722 assertThat(noteUpdated.get(), is(false));
1726 public void defaultFcpClientCanModifyPeerNoteByIdentifier()
1727 throws InterruptedException, ExecutionException, IOException {
1728 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byIdentifier("id1").execute();
1730 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1731 String identifier = extractIdentifier(lines);
1732 assertThat(lines, matchesFcpMessage(
1734 "Identifier=" + identifier,
1735 "NodeIdentifier=id1",
1740 fcpServer.writeLine(
1742 "Identifier=" + identifier,
1743 "NodeIdentifier=id1",
1748 assertThat(noteUpdated.get(), is(true));
1752 public void defaultFcpClientCanModifyPeerNoteByHostAndPort()
1753 throws InterruptedException, ExecutionException, IOException {
1754 Future<Boolean> noteUpdated =
1755 fcpClient.modifyPeerNote().darknetComment("foo").byHostAndPort("1.2.3.4", 5678).execute();
1757 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1758 String identifier = extractIdentifier(lines);
1759 assertThat(lines, matchesFcpMessage(
1761 "Identifier=" + identifier,
1762 "NodeIdentifier=1.2.3.4:5678",
1767 fcpServer.writeLine(
1769 "Identifier=" + identifier,
1770 "NodeIdentifier=1.2.3.4:5678",
1775 assertThat(noteUpdated.get(), is(true));
1779 public void defaultFcpClientCanGetConfigWithoutDetails()
1780 throws InterruptedException, ExecutionException, IOException {
1781 Future<ConfigData> configData = fcpClient.getConfig().execute();
1783 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1784 String identifier = extractIdentifier(lines);
1785 assertThat(lines, matchesFcpMessage(
1787 "Identifier=" + identifier,
1790 fcpServer.writeLine(
1792 "Identifier=" + identifier,
1795 assertThat(configData.get(), notNullValue());
1799 public void defaultFcpClientCanGetConfigWithCurrent()
1800 throws InterruptedException, ExecutionException, IOException {
1801 Future<ConfigData> configData = fcpClient.getConfig().withCurrent().execute();
1803 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1804 String identifier = extractIdentifier(lines);
1805 assertThat(lines, matchesFcpMessage(
1807 "Identifier=" + identifier,
1811 fcpServer.writeLine(
1813 "Identifier=" + identifier,
1817 assertThat(configData.get().getCurrent("foo"), is("bar"));
1821 public void defaultFcpClientCanGetConfigWithDefaults()
1822 throws InterruptedException, ExecutionException, IOException {
1823 Future<ConfigData> configData = fcpClient.getConfig().withDefaults().execute();
1825 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1826 String identifier = extractIdentifier(lines);
1827 assertThat(lines, matchesFcpMessage(
1829 "Identifier=" + identifier,
1830 "WithDefaults=true",
1833 fcpServer.writeLine(
1835 "Identifier=" + identifier,
1839 assertThat(configData.get().getDefault("foo"), is("bar"));
1843 public void defaultFcpClientCanGetConfigWithSortOrder()
1844 throws InterruptedException, ExecutionException, IOException {
1845 Future<ConfigData> configData = fcpClient.getConfig().withSortOrder().execute();
1847 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1848 String identifier = extractIdentifier(lines);
1849 assertThat(lines, matchesFcpMessage(
1851 "Identifier=" + identifier,
1852 "WithSortOrder=true",
1855 fcpServer.writeLine(
1857 "Identifier=" + identifier,
1861 assertThat(configData.get().getSortOrder("foo"), is(17));
1865 public void defaultFcpClientCanGetConfigWithExpertFlag()
1866 throws InterruptedException, ExecutionException, IOException {
1867 Future<ConfigData> configData = fcpClient.getConfig().withExpertFlag().execute();
1869 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1870 String identifier = extractIdentifier(lines);
1871 assertThat(lines, matchesFcpMessage(
1873 "Identifier=" + identifier,
1874 "WithExpertFlag=true",
1877 fcpServer.writeLine(
1879 "Identifier=" + identifier,
1880 "expertFlag.foo=true",
1883 assertThat(configData.get().getExpertFlag("foo"), is(true));
1887 public void defaultFcpClientCanGetConfigWithForceWriteFlag()
1888 throws InterruptedException, ExecutionException, IOException {
1889 Future<ConfigData> configData = fcpClient.getConfig().withForceWriteFlag().execute();
1891 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1892 String identifier = extractIdentifier(lines);
1893 assertThat(lines, matchesFcpMessage(
1895 "Identifier=" + identifier,
1896 "WithForceWriteFlag=true",
1899 fcpServer.writeLine(
1901 "Identifier=" + identifier,
1902 "forceWriteFlag.foo=true",
1905 assertThat(configData.get().getForceWriteFlag("foo"), is(true));
1909 public void defaultFcpClientCanGetConfigWithShortDescription()
1910 throws InterruptedException, ExecutionException, IOException {
1911 Future<ConfigData> configData = fcpClient.getConfig().withShortDescription().execute();
1913 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1914 String identifier = extractIdentifier(lines);
1915 assertThat(lines, matchesFcpMessage(
1917 "Identifier=" + identifier,
1918 "WithShortDescription=true",
1921 fcpServer.writeLine(
1923 "Identifier=" + identifier,
1924 "shortDescription.foo=bar",
1927 assertThat(configData.get().getShortDescription("foo"), is("bar"));
1931 public void defaultFcpClientCanGetConfigWithLongDescription()
1932 throws InterruptedException, ExecutionException, IOException {
1933 Future<ConfigData> configData = fcpClient.getConfig().withLongDescription().execute();
1935 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1936 String identifier = extractIdentifier(lines);
1937 assertThat(lines, matchesFcpMessage(
1939 "Identifier=" + identifier,
1940 "WithLongDescription=true",
1943 fcpServer.writeLine(
1945 "Identifier=" + identifier,
1946 "longDescription.foo=bar",
1949 assertThat(configData.get().getLongDescription("foo"), is("bar"));
1953 public void defaultFcpClientCanGetConfigWithDataTypes()
1954 throws InterruptedException, ExecutionException, IOException {
1955 Future<ConfigData> configData = fcpClient.getConfig().withDataTypes().execute();
1957 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1958 String identifier = extractIdentifier(lines);
1959 assertThat(lines, matchesFcpMessage(
1961 "Identifier=" + identifier,
1962 "WithDataTypes=true",
1965 fcpServer.writeLine(
1967 "Identifier=" + identifier,
1968 "dataType.foo=number",
1971 assertThat(configData.get().getDataType("foo"), is("number"));
1975 public void defaultFcpClientCanModifyConfigData() throws InterruptedException, ExecutionException, IOException {
1976 Future<ConfigData> newConfigData = fcpClient.modifyConfig().set("foo.bar").to("baz").execute();
1978 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1979 String identifier = extractIdentifier(lines);
1980 assertThat(lines, matchesFcpMessage(
1982 "Identifier=" + identifier,
1986 fcpServer.writeLine(
1988 "Identifier=" + identifier,
1989 "current.foo.bar=baz",
1992 assertThat(newConfigData.get().getCurrent("foo.bar"), is("baz"));
1995 public class LoadPlugin {
1997 private List<String> lines;
1998 private String identifier;
2000 private void connectAndAssert(Supplier<Matcher<List<String>>> requestMatcher)
2001 throws InterruptedException, ExecutionException, IOException {
2003 lines = fcpServer.collectUntil(is("EndMessage"));
2004 identifier = extractIdentifier(lines);
2005 assertThat(lines, requestMatcher.get());
2008 public class OfficialPlugins {
2011 public void fromFreenet() throws ExecutionException, InterruptedException, IOException {
2012 Future<Optional<PluginInfo>> pluginInfo =
2013 fcpClient.loadPlugin().officialFromFreenet("superPlugin").execute();
2014 connectAndAssert(() -> createMatcherForOfficialSource("freenet"));
2015 assertThat(lines, not(contains(startsWith("Store="))));
2016 replyWithPluginInfo(identifier);
2017 verifyPluginInfo(pluginInfo);
2021 public void persistentFromFreenet() throws ExecutionException, InterruptedException, IOException {
2022 Future<Optional<PluginInfo>> pluginInfo =
2023 fcpClient.loadPlugin().addToConfig().officialFromFreenet("superPlugin").execute();
2024 connectAndAssert(() -> createMatcherForOfficialSource("freenet"));
2025 assertThat(lines, hasItem("Store=true"));
2026 replyWithPluginInfo(identifier);
2027 verifyPluginInfo(pluginInfo);
2031 public void fromHttps() throws ExecutionException, InterruptedException, IOException {
2032 Future<Optional<PluginInfo>> pluginInfo =
2033 fcpClient.loadPlugin().officialFromHttps("superPlugin").execute();
2034 connectAndAssert(() -> createMatcherForOfficialSource("https"));
2035 replyWithPluginInfo(identifier);
2036 verifyPluginInfo(pluginInfo);
2039 private Matcher<List<String>> createMatcherForOfficialSource(String officialSource) {
2040 return matchesFcpMessage(
2042 "Identifier=" + identifier,
2043 "PluginURL=superPlugin",
2045 "OfficialSource=" + officialSource,
2052 public class FromOtherSources {
2054 private static final String FILE_PATH = "/path/to/plugin.jar";
2055 private static final String URL = "http://server.com/plugin.jar";
2056 private static final String KEY = "KSK@plugin.jar";
2059 public void fromFile() throws ExecutionException, InterruptedException, IOException {
2060 Future<Optional<PluginInfo>> pluginInfo = fcpClient.loadPlugin().fromFile(FILE_PATH).execute();
2061 connectAndAssert(() -> createMatcher("file", FILE_PATH));
2062 replyWithPluginInfo(identifier);
2063 verifyPluginInfo(pluginInfo);
2067 public void fromUrl() throws ExecutionException, InterruptedException, IOException {
2068 Future<Optional<PluginInfo>> pluginInfo = fcpClient.loadPlugin().fromUrl(URL).execute();
2069 connectAndAssert(() -> createMatcher("url", URL));
2070 replyWithPluginInfo(identifier);
2071 verifyPluginInfo(pluginInfo);
2075 public void fromFreenet() throws ExecutionException, InterruptedException, IOException {
2076 Future<Optional<PluginInfo>> pluginInfo = fcpClient.loadPlugin().fromFreenet(KEY).execute();
2077 connectAndAssert(() -> createMatcher("freenet", KEY));
2078 replyWithPluginInfo(identifier);
2079 verifyPluginInfo(pluginInfo);
2082 private Matcher<List<String>> createMatcher(String urlType, String url) {
2083 return matchesFcpMessage(
2085 "Identifier=" + identifier,
2087 "URLType=" + urlType,
2094 public class Failed {
2097 public void failedLoad() throws ExecutionException, InterruptedException, IOException {
2098 Future<Optional<PluginInfo>> pluginInfo =
2099 fcpClient.loadPlugin().officialFromFreenet("superPlugin").execute();
2101 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
2102 String identifier = extractIdentifier(lines);
2103 fcpServer.writeLine(
2105 "Identifier=" + identifier,
2108 assertThat(pluginInfo.get().isPresent(), is(false));
2113 private void replyWithPluginInfo(String identifier) throws IOException {
2114 fcpServer.writeLine(
2116 "Identifier=" + identifier,
2117 "PluginName=superPlugin",
2119 "LongVersion=1.2.3",
2121 "OriginUri=superPlugin",
2127 private void verifyPluginInfo(Future<Optional<PluginInfo>> pluginInfo)
2128 throws InterruptedException, ExecutionException {
2129 assertThat(pluginInfo.get().get().getPluginName(), is("superPlugin"));
2130 assertThat(pluginInfo.get().get().getOriginalURI(), is("superPlugin"));
2131 assertThat(pluginInfo.get().get().isTalkable(), is(true));
2132 assertThat(pluginInfo.get().get().getVersion(), is("42"));
2133 assertThat(pluginInfo.get().get().getLongVersion(), is("1.2.3"));
2134 assertThat(pluginInfo.get().get().isStarted(), is(true));