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.hasSize;
7 import static org.hamcrest.Matchers.is;
8 import static org.hamcrest.Matchers.not;
9 import static org.hamcrest.Matchers.notNullValue;
10 import static org.hamcrest.Matchers.startsWith;
12 import java.io.ByteArrayInputStream;
14 import java.io.IOException;
16 import java.nio.charset.StandardCharsets;
17 import java.util.Collection;
18 import java.util.List;
19 import java.util.Optional;
20 import java.util.concurrent.CopyOnWriteArrayList;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.ExecutorService;
23 import java.util.concurrent.Executors;
24 import java.util.concurrent.Future;
25 import java.util.stream.Collectors;
27 import net.pterodactylus.fcp.ARK;
28 import net.pterodactylus.fcp.ConfigData;
29 import net.pterodactylus.fcp.DSAGroup;
30 import net.pterodactylus.fcp.FcpKeyPair;
31 import net.pterodactylus.fcp.Key;
32 import net.pterodactylus.fcp.NodeData;
33 import net.pterodactylus.fcp.NodeRef;
34 import net.pterodactylus.fcp.Peer;
35 import net.pterodactylus.fcp.PeerNote;
36 import net.pterodactylus.fcp.Priority;
37 import net.pterodactylus.fcp.fake.FakeTcpServer;
38 import net.pterodactylus.fcp.quelaton.ClientGetCommand.Data;
40 import com.google.common.io.ByteStreams;
41 import com.google.common.io.Files;
42 import org.hamcrest.Description;
43 import org.hamcrest.Matcher;
44 import org.hamcrest.TypeSafeDiagnosingMatcher;
45 import org.junit.After;
46 import org.junit.Assert;
47 import org.junit.Test;
50 * Unit test for {@link DefaultFcpClient}.
52 * @author <a href="bombe@freenetproject.org">David ‘Bombe’ Roden</a>
54 public class DefaultFcpClientTest {
56 private static final String INSERT_URI =
57 "SSK@RVCHbJdkkyTCeNN9AYukEg76eyqmiosSaNKgE3U9zUw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQECAAE/";
58 private static final String REQUEST_URI =
59 "SSK@wtbgd2loNcJCXvtQVOftl2tuWBomDQHfqS6ytpPRhfw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQACAAE/";
61 private int threadCounter = 0;
62 private final ExecutorService threadPool =
63 Executors.newCachedThreadPool(r -> new Thread(r, "Test-Thread-" + threadCounter++));
64 private final FakeTcpServer fcpServer;
65 private final DefaultFcpClient fcpClient;
67 public DefaultFcpClientTest() throws IOException {
68 fcpServer = new FakeTcpServer(threadPool);
69 fcpClient = new DefaultFcpClient(threadPool, "localhost", fcpServer.getPort(), () -> "Test");
73 public void tearDown() throws IOException {
75 threadPool.shutdown();
78 @Test(expected = ExecutionException.class)
79 public void defaultFcpClientThrowsExceptionIfItCanNotConnect()
80 throws IOException, ExecutionException, InterruptedException {
81 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
82 fcpServer.connect().get();
83 fcpServer.collectUntil(is("EndMessage"));
85 "CloseConnectionDuplicateClientName",
91 @Test(expected = ExecutionException.class)
92 public void defaultFcpClientThrowsExceptionIfConnectionIsClosed()
93 throws IOException, ExecutionException, InterruptedException {
94 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
95 fcpServer.connect().get();
96 fcpServer.collectUntil(is("EndMessage"));
102 public void defaultFcpClientCanGenerateKeypair() throws ExecutionException, InterruptedException, IOException {
103 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
105 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
106 String identifier = extractIdentifier(lines);
107 fcpServer.writeLine("SSKKeypair",
108 "InsertURI=" + INSERT_URI + "",
109 "RequestURI=" + REQUEST_URI + "",
110 "Identifier=" + identifier,
112 FcpKeyPair keyPair = keyPairFuture.get();
113 assertThat(keyPair.getPublicKey(), is(REQUEST_URI));
114 assertThat(keyPair.getPrivateKey(), is(INSERT_URI));
117 private void connectNode() throws InterruptedException, ExecutionException, IOException {
118 fcpServer.connect().get();
119 fcpServer.collectUntil(is("EndMessage"));
120 fcpServer.writeLine("NodeHello",
121 "CompressionCodecs=4 - GZIP(0), BZIP2(1), LZMA(2), LZMA_NEW(3)",
122 "Revision=build01466",
124 "Version=Fred,0.7,1.0,1466",
126 "ConnectionIdentifier=14318898267048452a81b36e7f13a3f0",
130 "NodeLanguage=ENGLISH",
137 public void clientGetCanDownloadData() throws InterruptedException, ExecutionException, IOException {
138 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
140 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
141 assertThat(lines, matchesFcpMessage("ClientGet", "ReturnType=direct", "URI=KSK@foo.txt"));
142 String identifier = extractIdentifier(lines);
145 "Identifier=" + identifier,
147 "StartupTime=1435610539000",
148 "CompletionTime=1435610540000",
149 "Metadata.ContentType=text/plain;charset=utf-8",
153 Optional<Data> data = dataFuture.get();
154 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
155 assertThat(data.get().size(), is(6L));
156 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
157 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
160 private String extractIdentifier(List<String> lines) {
161 return lines.stream()
162 .filter(s -> s.startsWith("Identifier="))
163 .map(s -> s.substring(s.indexOf('=') + 1))
169 public void clientGetDownloadsDataForCorrectIdentifier()
170 throws InterruptedException, ExecutionException, IOException {
171 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
173 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
174 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
175 String identifier = extractIdentifier(lines);
178 "Identifier=not-test",
180 "StartupTime=1435610539000",
181 "CompletionTime=1435610540000",
182 "Metadata.ContentType=text/plain;charset=latin-9",
188 "Identifier=" + identifier,
190 "StartupTime=1435610539000",
191 "CompletionTime=1435610540000",
192 "Metadata.ContentType=text/plain;charset=utf-8",
196 Optional<Data> data = dataFuture.get();
197 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
198 assertThat(data.get().size(), is(6L));
199 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
200 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
204 public void clientGetRecognizesGetFailed() throws InterruptedException, ExecutionException, IOException {
205 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
207 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
208 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
209 String identifier = extractIdentifier(lines);
212 "Identifier=" + identifier,
216 Optional<Data> data = dataFuture.get();
217 assertThat(data.isPresent(), is(false));
221 public void clientGetRecognizesGetFailedForCorrectIdentifier()
222 throws InterruptedException, ExecutionException, IOException {
223 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
225 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
226 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
227 String identifier = extractIdentifier(lines);
230 "Identifier=not-test",
236 "Identifier=" + identifier,
240 Optional<Data> data = dataFuture.get();
241 assertThat(data.isPresent(), is(false));
244 @Test(expected = ExecutionException.class)
245 public void clientGetRecognizesConnectionClosed() throws InterruptedException, ExecutionException, IOException {
246 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
248 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
249 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
255 public void defaultFcpClientReusesConnection() throws InterruptedException, ExecutionException, IOException {
256 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
258 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
259 String identifier = extractIdentifier(lines);
262 "InsertURI=" + INSERT_URI + "",
263 "RequestURI=" + REQUEST_URI + "",
264 "Identifier=" + identifier,
268 keyPair = fcpClient.generateKeypair().execute();
269 lines = fcpServer.collectUntil(is("EndMessage"));
270 identifier = extractIdentifier(lines);
273 "InsertURI=" + INSERT_URI + "",
274 "RequestURI=" + REQUEST_URI + "",
275 "Identifier=" + identifier,
282 public void defaultFcpClientCanReconnectAfterConnectionHasBeenClosed()
283 throws InterruptedException, ExecutionException, IOException {
284 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
286 fcpServer.collectUntil(is("EndMessage"));
291 } catch (ExecutionException e) {
293 keyPair = fcpClient.generateKeypair().execute();
295 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
296 String identifier = extractIdentifier(lines);
299 "InsertURI=" + INSERT_URI + "",
300 "RequestURI=" + REQUEST_URI + "",
301 "Identifier=" + identifier,
308 public void clientGetWithIgnoreDataStoreSettingSendsCorrectCommands()
309 throws InterruptedException, ExecutionException, IOException {
310 fcpClient.clientGet().ignoreDataStore().uri("KSK@foo.txt").execute();
312 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
313 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "IgnoreDS=true"));
317 public void clientGetWithDataStoreOnlySettingSendsCorrectCommands()
318 throws InterruptedException, ExecutionException, IOException {
319 fcpClient.clientGet().dataStoreOnly().uri("KSK@foo.txt").execute();
321 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
322 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "DSonly=true"));
326 public void clientGetWithMaxSizeSettingSendsCorrectCommands()
327 throws InterruptedException, ExecutionException, IOException {
328 fcpClient.clientGet().maxSize(1048576).uri("KSK@foo.txt").execute();
330 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
331 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "MaxSize=1048576"));
335 public void clientGetWithPrioritySettingSendsCorrectCommands()
336 throws InterruptedException, ExecutionException, IOException {
337 fcpClient.clientGet().priority(Priority.interactive).uri("KSK@foo.txt").execute();
339 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
340 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "PriorityClass=1"));
344 public void clientGetWithRealTimeSettingSendsCorrectCommands()
345 throws InterruptedException, ExecutionException, IOException {
346 fcpClient.clientGet().realTime().uri("KSK@foo.txt").execute();
348 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
349 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "RealTimeFlag=true"));
353 public void clientGetWithGlobalSettingSendsCorrectCommands()
354 throws InterruptedException, ExecutionException, IOException {
355 fcpClient.clientGet().global().uri("KSK@foo.txt").execute();
357 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
358 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "Global=true"));
361 private Matcher<List<String>> matchesFcpMessage(String name, String... requiredLines) {
362 return new TypeSafeDiagnosingMatcher<List<String>>() {
364 protected boolean matchesSafely(List<String> item, Description mismatchDescription) {
365 if (!item.get(0).equals(name)) {
366 mismatchDescription.appendText("FCP message is named ").appendValue(item.get(0));
369 for (String requiredLine : requiredLines) {
370 if (item.indexOf(requiredLine) < 1) {
371 mismatchDescription.appendText("FCP message does not contain ").appendValue(requiredLine);
379 public void describeTo(Description description) {
380 description.appendText("FCP message named ").appendValue(name);
381 description.appendValueList(", containing the lines ", ", ", "", requiredLines);
387 public void clientPutWithDirectDataSendsCorrectCommand()
388 throws IOException, ExecutionException, InterruptedException {
389 fcpClient.clientPut()
390 .from(new ByteArrayInputStream("Hello\n".getBytes()))
395 List<String> lines = fcpServer.collectUntil(is("Hello"));
396 assertThat(lines, matchesFcpMessage("ClientPut", "UploadFrom=direct", "DataLength=6", "URI=KSK@foo.txt"));
400 public void clientPutWithDirectDataSucceedsOnCorrectIdentifier()
401 throws InterruptedException, ExecutionException, IOException {
402 Future<Optional<Key>> key = fcpClient.clientPut()
403 .from(new ByteArrayInputStream("Hello\n".getBytes()))
408 List<String> lines = fcpServer.collectUntil(is("Hello"));
409 String identifier = extractIdentifier(lines);
412 "Identifier=not-the-right-one",
418 "Identifier=" + identifier,
421 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
425 public void clientPutWithDirectDataFailsOnCorrectIdentifier()
426 throws InterruptedException, ExecutionException, IOException {
427 Future<Optional<Key>> key = fcpClient.clientPut()
428 .from(new ByteArrayInputStream("Hello\n".getBytes()))
433 List<String> lines = fcpServer.collectUntil(is("Hello"));
434 String identifier = extractIdentifier(lines);
437 "Identifier=not-the-right-one",
443 "Identifier=" + identifier,
446 assertThat(key.get().isPresent(), is(false));
450 public void clientPutWithRenamedDirectDataSendsCorrectCommand()
451 throws InterruptedException, ExecutionException, IOException {
452 fcpClient.clientPut()
453 .named("otherName.txt")
454 .from(new ByteArrayInputStream("Hello\n".getBytes()))
459 List<String> lines = fcpServer.collectUntil(is("Hello"));
460 assertThat(lines, matchesFcpMessage("ClientPut", "TargetFilename=otherName.txt", "UploadFrom=direct",
461 "DataLength=6", "URI=KSK@foo.txt"));
465 public void clientPutWithRedirectSendsCorrectCommand()
466 throws IOException, ExecutionException, InterruptedException {
467 fcpClient.clientPut().redirectTo("KSK@bar.txt").uri("KSK@foo.txt").execute();
469 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
471 matchesFcpMessage("ClientPut", "UploadFrom=redirect", "URI=KSK@foo.txt", "TargetURI=KSK@bar.txt"));
475 public void clientPutWithFileSendsCorrectCommand() throws InterruptedException, ExecutionException, IOException {
476 fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
478 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
480 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt", "Filename=/tmp/data.txt"));
484 public void clientPutWithFileCanCompleteTestDdaSequence()
485 throws IOException, ExecutionException, InterruptedException {
486 File tempFile = createTempFile();
487 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
489 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
490 String identifier = extractIdentifier(lines);
493 "Identifier=" + identifier,
497 lines = fcpServer.collectUntil(is("EndMessage"));
498 assertThat(lines, matchesFcpMessage(
500 "Directory=" + tempFile.getParent(),
501 "WantReadDirectory=true",
502 "WantWriteDirectory=false",
507 "Directory=" + tempFile.getParent(),
508 "ReadFilename=" + tempFile,
511 lines = fcpServer.collectUntil(is("EndMessage"));
512 assertThat(lines, matchesFcpMessage(
514 "Directory=" + tempFile.getParent(),
515 "ReadContent=test-content",
520 "Directory=" + tempFile.getParent(),
521 "ReadDirectoryAllowed=true",
524 lines = fcpServer.collectUntil(is("EndMessage"));
526 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt",
527 "Filename=" + new File(tempFile.getParent(), "test.dat")));
530 private File createTempFile() throws IOException {
531 File tempFile = File.createTempFile("test-dda-", ".dat");
532 tempFile.deleteOnExit();
533 Files.write("test-content", tempFile, StandardCharsets.UTF_8);
538 public void clientPutDoesNotReactToProtocolErrorForDifferentIdentifier()
539 throws InterruptedException, ExecutionException, IOException {
540 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
542 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
543 String identifier = extractIdentifier(lines);
546 "Identifier=not-the-right-one",
552 "Identifier=" + identifier,
556 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
560 public void clientPutAbortsOnProtocolErrorOtherThan25()
561 throws InterruptedException, ExecutionException, IOException {
562 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
564 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
565 String identifier = extractIdentifier(lines);
568 "Identifier=" + identifier,
572 assertThat(key.get().isPresent(), is(false));
576 public void clientPutDoesNotReplyToWrongTestDdaReply() throws IOException, ExecutionException,
577 InterruptedException {
578 File tempFile = createTempFile();
579 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
581 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
582 String identifier = extractIdentifier(lines);
585 "Identifier=" + identifier,
589 lines = fcpServer.collectUntil(is("EndMessage"));
590 assertThat(lines, matchesFcpMessage(
592 "Directory=" + tempFile.getParent(),
593 "WantReadDirectory=true",
594 "WantWriteDirectory=false",
599 "Directory=/some-other-directory",
600 "ReadFilename=" + tempFile,
605 "Directory=" + tempFile.getParent(),
606 "ReadFilename=" + tempFile,
609 lines = fcpServer.collectUntil(is("EndMessage"));
610 assertThat(lines, matchesFcpMessage(
612 "Directory=" + tempFile.getParent(),
613 "ReadContent=test-content",
619 public void clientPutSendsResponseEvenIfFileCanNotBeRead()
620 throws IOException, ExecutionException, InterruptedException {
621 File tempFile = createTempFile();
622 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
624 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
625 String identifier = extractIdentifier(lines);
628 "Identifier=" + identifier,
632 lines = fcpServer.collectUntil(is("EndMessage"));
633 assertThat(lines, matchesFcpMessage(
635 "Directory=" + tempFile.getParent(),
636 "WantReadDirectory=true",
637 "WantWriteDirectory=false",
642 "Directory=" + tempFile.getParent(),
643 "ReadFilename=" + tempFile + ".foo",
646 lines = fcpServer.collectUntil(is("EndMessage"));
647 assertThat(lines, matchesFcpMessage(
649 "Directory=" + tempFile.getParent(),
650 "ReadContent=failed-to-read",
656 public void clientPutDoesNotResendOriginalClientPutOnTestDDACompleteWithWrongDirectory()
657 throws IOException, ExecutionException, InterruptedException {
658 File tempFile = createTempFile();
659 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
661 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
662 String identifier = extractIdentifier(lines);
665 "Directory=/some-other-directory",
670 "Identifier=" + identifier,
674 lines = fcpServer.collectUntil(is("EndMessage"));
675 assertThat(lines, matchesFcpMessage(
677 "Directory=" + tempFile.getParent(),
678 "WantReadDirectory=true",
679 "WantWriteDirectory=false",
685 public void clientPutSendsNotificationsForGeneratedKeys()
686 throws InterruptedException, ExecutionException, IOException {
687 List<String> generatedKeys = new CopyOnWriteArrayList<>();
688 Future<Optional<Key>> key = fcpClient.clientPut()
689 .onKeyGenerated(generatedKeys::add)
690 .from(new ByteArrayInputStream("Hello\n".getBytes()))
695 List<String> lines = fcpServer.collectUntil(is("Hello"));
696 String identifier = extractIdentifier(lines);
699 "Identifier=" + identifier,
706 "Identifier=" + identifier,
709 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
710 assertThat(generatedKeys, contains("KSK@foo.txt"));
714 public void clientCanListPeers() throws IOException, ExecutionException, InterruptedException {
715 Future<Collection<Peer>> peers = fcpClient.listPeers().execute();
717 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
718 assertThat(lines, matchesFcpMessage(
720 "WithVolatile=false",
721 "WithMetadata=false",
724 String identifier = extractIdentifier(lines);
727 "Identifier=" + identifier,
733 "Identifier=" + identifier,
739 "Identifier=" + identifier,
742 assertThat(peers.get(), hasSize(2));
743 assertThat(peers.get().stream().map(Peer::getIdentity).collect(Collectors.toList()),
744 containsInAnyOrder("id1", "id2"));
748 public void clientCanListPeersWithMetadata() throws IOException, ExecutionException, InterruptedException {
749 Future<Collection<Peer>> peers = fcpClient.listPeers().includeMetadata().execute();
751 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
752 assertThat(lines, matchesFcpMessage(
754 "WithVolatile=false",
758 String identifier = extractIdentifier(lines);
761 "Identifier=" + identifier,
768 "Identifier=" + identifier,
775 "Identifier=" + identifier,
778 assertThat(peers.get(), hasSize(2));
779 assertThat(peers.get().stream().map(peer -> peer.getMetadata("foo")).collect(Collectors.toList()),
780 containsInAnyOrder("bar1", "bar2"));
784 public void clientCanListPeersWithVolatiles() throws IOException, ExecutionException, InterruptedException {
785 Future<Collection<Peer>> peers = fcpClient.listPeers().includeVolatile().execute();
787 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
788 assertThat(lines, matchesFcpMessage(
791 "WithMetadata=false",
794 String identifier = extractIdentifier(lines);
797 "Identifier=" + identifier,
804 "Identifier=" + identifier,
811 "Identifier=" + identifier,
814 assertThat(peers.get(), hasSize(2));
815 assertThat(peers.get().stream().map(peer -> peer.getVolatile("foo")).collect(Collectors.toList()),
816 containsInAnyOrder("bar1", "bar2"));
820 public void defaultFcpClientCanGetNodeInformation() throws InterruptedException, ExecutionException, IOException {
821 Future<NodeData> nodeData = fcpClient.getNode().execute();
823 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
824 String identifier = extractIdentifier(lines);
825 assertThat(lines, matchesFcpMessage(
827 "Identifier=" + identifier,
828 "GiveOpennetRef=false",
830 "WithVolatile=false",
835 "Identifier=" + identifier,
836 "ark.pubURI=SSK@3YEf.../ark",
839 "version=Fred,0.7,1.0,1466",
840 "lastGoodVersion=Fred,0.7,1.0,1466",
843 assertThat(nodeData.get(), notNullValue());
847 public void defaultFcpClientCanGetNodeInformationWithOpennetRef()
848 throws InterruptedException, ExecutionException, IOException {
849 Future<NodeData> nodeData = fcpClient.getNode().opennetRef().execute();
851 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
852 String identifier = extractIdentifier(lines);
853 assertThat(lines, matchesFcpMessage(
855 "Identifier=" + identifier,
856 "GiveOpennetRef=true",
858 "WithVolatile=false",
863 "Identifier=" + identifier,
865 "ark.pubURI=SSK@3YEf.../ark",
868 "version=Fred,0.7,1.0,1466",
869 "lastGoodVersion=Fred,0.7,1.0,1466",
872 assertThat(nodeData.get().getVersion().toString(), is("Fred,0.7,1.0,1466"));
876 public void defaultFcpClientCanGetNodeInformationWithPrivateData()
877 throws InterruptedException, ExecutionException, IOException {
878 Future<NodeData> nodeData = fcpClient.getNode().includePrivate().execute();
880 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
881 String identifier = extractIdentifier(lines);
882 assertThat(lines, matchesFcpMessage(
884 "Identifier=" + identifier,
885 "GiveOpennetRef=false",
887 "WithVolatile=false",
892 "Identifier=" + identifier,
894 "ark.pubURI=SSK@3YEf.../ark",
897 "version=Fred,0.7,1.0,1466",
898 "lastGoodVersion=Fred,0.7,1.0,1466",
899 "ark.privURI=SSK@XdHMiRl",
902 assertThat(nodeData.get().getARK().getPrivateURI(), is("SSK@XdHMiRl"));
906 public void defaultFcpClientCanGetNodeInformationWithVolatileData()
907 throws InterruptedException, ExecutionException, IOException {
908 Future<NodeData> nodeData = fcpClient.getNode().includeVolatile().execute();
910 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
911 String identifier = extractIdentifier(lines);
912 assertThat(lines, matchesFcpMessage(
914 "Identifier=" + identifier,
915 "GiveOpennetRef=false",
922 "Identifier=" + identifier,
924 "ark.pubURI=SSK@3YEf.../ark",
927 "version=Fred,0.7,1.0,1466",
928 "lastGoodVersion=Fred,0.7,1.0,1466",
929 "volatile.freeJavaMemory=205706528",
932 assertThat(nodeData.get().getVolatile("freeJavaMemory"), is("205706528"));
936 public void defaultFcpClientCanListSinglePeerByIdentity()
937 throws InterruptedException, ExecutionException, IOException {
938 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id1").execute();
940 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
941 String identifier = extractIdentifier(lines);
942 assertThat(lines, matchesFcpMessage(
944 "Identifier=" + identifier,
945 "NodeIdentifier=id1",
950 "Identifier=" + identifier,
953 "ark.pubURI=SSK@3YEf.../ark",
956 "version=Fred,0.7,1.0,1466",
957 "lastGoodVersion=Fred,0.7,1.0,1466",
960 assertThat(peer.get().get().getIdentity(), is("id1"));
964 public void defaultFcpClientCanListSinglePeerByHostAndPort()
965 throws InterruptedException, ExecutionException, IOException {
966 Future<Optional<Peer>> peer = fcpClient.listPeer().byHostAndPort("host.free.net", 12345).execute();
968 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
969 String identifier = extractIdentifier(lines);
970 assertThat(lines, matchesFcpMessage(
972 "Identifier=" + identifier,
973 "NodeIdentifier=host.free.net:12345",
978 "Identifier=" + identifier,
981 "ark.pubURI=SSK@3YEf.../ark",
984 "version=Fred,0.7,1.0,1466",
985 "lastGoodVersion=Fred,0.7,1.0,1466",
988 assertThat(peer.get().get().getIdentity(), is("id1"));
992 public void defaultFcpClientCanListSinglePeerByName()
993 throws InterruptedException, ExecutionException, IOException {
994 Future<Optional<Peer>> peer = fcpClient.listPeer().byName("FriendNode").execute();
996 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
997 String identifier = extractIdentifier(lines);
998 assertThat(lines, matchesFcpMessage(
1000 "Identifier=" + identifier,
1001 "NodeIdentifier=FriendNode",
1004 fcpServer.writeLine(
1006 "Identifier=" + identifier,
1009 "ark.pubURI=SSK@3YEf.../ark",
1012 "version=Fred,0.7,1.0,1466",
1013 "lastGoodVersion=Fred,0.7,1.0,1466",
1016 assertThat(peer.get().get().getIdentity(), is("id1"));
1020 public void defaultFcpClientRecognizesUnknownNodeIdentifiers()
1021 throws InterruptedException, ExecutionException, IOException {
1022 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id2").execute();
1024 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1025 String identifier = extractIdentifier(lines);
1026 assertThat(lines, matchesFcpMessage(
1028 "Identifier=" + identifier,
1029 "NodeIdentifier=id2",
1032 fcpServer.writeLine(
1033 "UnknownNodeIdentifier",
1034 "Identifier=" + identifier,
1035 "NodeIdentifier=id2",
1038 assertThat(peer.get().isPresent(), is(false));
1042 public void defaultFcpClientCanAddPeerFromFile() throws InterruptedException, ExecutionException, IOException {
1043 Future<Optional<Peer>> peer = fcpClient.addPeer().fromFile(new File("/tmp/ref.txt")).execute();
1045 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1046 String identifier = extractIdentifier(lines);
1047 assertThat(lines, matchesFcpMessage(
1049 "Identifier=" + identifier,
1050 "File=/tmp/ref.txt",
1053 fcpServer.writeLine(
1055 "Identifier=" + identifier,
1058 "ark.pubURI=SSK@3YEf.../ark",
1061 "version=Fred,0.7,1.0,1466",
1062 "lastGoodVersion=Fred,0.7,1.0,1466",
1065 assertThat(peer.get().get().getIdentity(), is("id1"));
1069 public void defaultFcpClientCanAddPeerFromURL() throws InterruptedException, ExecutionException, IOException {
1070 Future<Optional<Peer>> peer = fcpClient.addPeer().fromURL(new URL("http://node.ref/")).execute();
1072 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1073 String identifier = extractIdentifier(lines);
1074 assertThat(lines, matchesFcpMessage(
1076 "Identifier=" + identifier,
1077 "URL=http://node.ref/",
1080 fcpServer.writeLine(
1082 "Identifier=" + identifier,
1085 "ark.pubURI=SSK@3YEf.../ark",
1088 "version=Fred,0.7,1.0,1466",
1089 "lastGoodVersion=Fred,0.7,1.0,1466",
1092 assertThat(peer.get().get().getIdentity(), is("id1"));
1096 public void defaultFcpClientCanAddPeerFromNodeRef() throws InterruptedException, ExecutionException, IOException {
1097 NodeRef nodeRef = new NodeRef();
1098 nodeRef.setIdentity("id1");
1099 nodeRef.setName("name");
1100 nodeRef.setARK(new ARK("public", "1"));
1101 nodeRef.setDSAGroup(new DSAGroup("base", "prime", "subprime"));
1102 nodeRef.setNegotiationTypes(new int[] { 3, 5 });
1103 nodeRef.setPhysicalUDP("1.2.3.4:5678");
1104 nodeRef.setDSAPublicKey("dsa-public");
1105 nodeRef.setSignature("sig");
1106 Future<Optional<Peer>> peer = fcpClient.addPeer().fromNodeRef(nodeRef).execute();
1108 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1109 String identifier = extractIdentifier(lines);
1110 assertThat(lines, matchesFcpMessage(
1112 "Identifier=" + identifier,
1115 "ark.pubURI=public",
1119 "dsaGroup.q=subprime",
1120 "dsaPubKey.y=dsa-public",
1121 "physical.udp=1.2.3.4:5678",
1122 "auth.negTypes=3;5",
1126 fcpServer.writeLine(
1128 "Identifier=" + identifier,
1131 "ark.pubURI=SSK@3YEf.../ark",
1134 "version=Fred,0.7,1.0,1466",
1135 "lastGoodVersion=Fred,0.7,1.0,1466",
1138 assertThat(peer.get().get().getIdentity(), is("id1"));
1142 public void listPeerNotesCanGetPeerNotesByNodeName() throws InterruptedException, ExecutionException, IOException {
1143 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute();
1145 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1146 String identifier = extractIdentifier(lines);
1147 assertThat(lines, matchesFcpMessage(
1149 "NodeIdentifier=Friend1",
1152 fcpServer.writeLine(
1154 "Identifier=" + identifier,
1155 "NodeIdentifier=Friend1",
1156 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1160 fcpServer.writeLine(
1162 "Identifier=" + identifier,
1165 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1166 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1170 public void listPeerNotesReturnsEmptyOptionalWhenNodeIdenfierUnknown()
1171 throws InterruptedException, ExecutionException,
1173 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute();
1175 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1176 String identifier = extractIdentifier(lines);
1177 assertThat(lines, matchesFcpMessage(
1179 "NodeIdentifier=Friend1",
1182 fcpServer.writeLine(
1183 "UnknownNodeIdentifier",
1184 "Identifier=" + identifier,
1185 "NodeIdentifier=Friend1",
1188 assertThat(peerNote.get().isPresent(), is(false));
1192 public void listPeerNotesCanGetPeerNotesByNodeIdentifier()
1193 throws InterruptedException, ExecutionException, IOException {
1194 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byIdentity("id1").execute();
1196 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1197 String identifier = extractIdentifier(lines);
1198 assertThat(lines, matchesFcpMessage(
1200 "NodeIdentifier=id1",
1203 fcpServer.writeLine(
1205 "Identifier=" + identifier,
1206 "NodeIdentifier=id1",
1207 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1211 fcpServer.writeLine(
1213 "Identifier=" + identifier,
1216 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1217 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1221 public void listPeerNotesCanGetPeerNotesByHostNameAndPortNumber()
1222 throws InterruptedException, ExecutionException, IOException {
1223 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byHostAndPort("1.2.3.4", 5678).execute();
1225 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1226 String identifier = extractIdentifier(lines);
1227 assertThat(lines, matchesFcpMessage(
1229 "NodeIdentifier=1.2.3.4:5678",
1232 fcpServer.writeLine(
1234 "Identifier=" + identifier,
1235 "NodeIdentifier=id1",
1236 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1240 fcpServer.writeLine(
1242 "Identifier=" + identifier,
1245 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1246 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1250 public void defaultFcpClientCanEnablePeerByName() throws InterruptedException, ExecutionException, IOException {
1251 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byName("Friend1").execute();
1253 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1254 String identifier = extractIdentifier(lines);
1255 assertThat(lines, matchesFcpMessage(
1257 "Identifier=" + identifier,
1258 "NodeIdentifier=Friend1",
1262 fcpServer.writeLine(
1264 "Identifier=" + identifier,
1265 "NodeIdentifier=Friend1",
1269 assertThat(peer.get().get().getIdentity(), is("id1"));
1273 public void defaultFcpClientCanDisablePeerByName() throws InterruptedException, ExecutionException, IOException {
1274 Future<Optional<Peer>> peer = fcpClient.modifyPeer().disable().byName("Friend1").execute();
1276 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1277 String identifier = extractIdentifier(lines);
1278 assertThat(lines, matchesFcpMessage(
1280 "Identifier=" + identifier,
1281 "NodeIdentifier=Friend1",
1285 fcpServer.writeLine(
1287 "Identifier=" + identifier,
1288 "NodeIdentifier=Friend1",
1292 assertThat(peer.get().get().getIdentity(), is("id1"));
1296 public void defaultFcpClientCanEnablePeerByIdentity() throws InterruptedException, ExecutionException, IOException {
1297 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byIdentity("id1").execute();
1299 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1300 String identifier = extractIdentifier(lines);
1301 assertThat(lines, matchesFcpMessage(
1303 "Identifier=" + identifier,
1304 "NodeIdentifier=id1",
1308 fcpServer.writeLine(
1310 "Identifier=" + identifier,
1311 "NodeIdentifier=Friend1",
1315 assertThat(peer.get().get().getIdentity(), is("id1"));
1319 public void defaultFcpClientCanEnablePeerByHostAndPort()
1320 throws InterruptedException, ExecutionException, IOException {
1321 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byHostAndPort("1.2.3.4", 5678).execute();
1323 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1324 String identifier = extractIdentifier(lines);
1325 assertThat(lines, matchesFcpMessage(
1327 "Identifier=" + identifier,
1328 "NodeIdentifier=1.2.3.4:5678",
1332 fcpServer.writeLine(
1334 "Identifier=" + identifier,
1335 "NodeIdentifier=Friend1",
1339 assertThat(peer.get().get().getIdentity(), is("id1"));
1343 public void defaultFcpClientCanNotModifyPeerOfUnknownNode()
1344 throws InterruptedException, ExecutionException, IOException {
1345 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byIdentity("id1").execute();
1347 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1348 String identifier = extractIdentifier(lines);
1349 assertThat(lines, matchesFcpMessage(
1351 "Identifier=" + identifier,
1352 "NodeIdentifier=id1",
1356 fcpServer.writeLine(
1357 "UnknownNodeIdentifier",
1358 "Identifier=" + identifier,
1359 "NodeIdentifier=id1",
1362 assertThat(peer.get().isPresent(), is(false));
1366 public void defaultFcpClientCanAllowLocalAddressesOfPeer()
1367 throws InterruptedException, ExecutionException, IOException {
1368 Future<Optional<Peer>> peer = fcpClient.modifyPeer().allowLocalAddresses().byIdentity("id1").execute();
1370 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1371 String identifier = extractIdentifier(lines);
1372 assertThat(lines, matchesFcpMessage(
1374 "Identifier=" + identifier,
1375 "NodeIdentifier=id1",
1376 "AllowLocalAddresses=true",
1379 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1380 fcpServer.writeLine(
1382 "Identifier=" + identifier,
1383 "NodeIdentifier=Friend1",
1387 assertThat(peer.get().get().getIdentity(), is("id1"));
1391 public void defaultFcpClientCanDisallowLocalAddressesOfPeer()
1392 throws InterruptedException, ExecutionException, IOException {
1393 Future<Optional<Peer>> peer = fcpClient.modifyPeer().disallowLocalAddresses().byIdentity("id1").execute();
1395 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1396 String identifier = extractIdentifier(lines);
1397 assertThat(lines, matchesFcpMessage(
1399 "Identifier=" + identifier,
1400 "NodeIdentifier=id1",
1401 "AllowLocalAddresses=false",
1404 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1405 fcpServer.writeLine(
1407 "Identifier=" + identifier,
1408 "NodeIdentifier=Friend1",
1412 assertThat(peer.get().get().getIdentity(), is("id1"));
1416 public void defaultFcpClientCanSetBurstOnlyForPeer()
1417 throws InterruptedException, ExecutionException, IOException {
1418 Future<Optional<Peer>> peer = fcpClient.modifyPeer().setBurstOnly().byIdentity("id1").execute();
1420 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1421 String identifier = extractIdentifier(lines);
1422 assertThat(lines, matchesFcpMessage(
1424 "Identifier=" + identifier,
1425 "NodeIdentifier=id1",
1429 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1430 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1431 fcpServer.writeLine(
1433 "Identifier=" + identifier,
1434 "NodeIdentifier=Friend1",
1438 assertThat(peer.get().get().getIdentity(), is("id1"));
1442 public void defaultFcpClientCanClearBurstOnlyForPeer()
1443 throws InterruptedException, ExecutionException, IOException {
1444 Future<Optional<Peer>> peer = fcpClient.modifyPeer().clearBurstOnly().byIdentity("id1").execute();
1446 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1447 String identifier = extractIdentifier(lines);
1448 assertThat(lines, matchesFcpMessage(
1450 "Identifier=" + identifier,
1451 "NodeIdentifier=id1",
1452 "IsBurstOnly=false",
1455 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1456 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1457 fcpServer.writeLine(
1459 "Identifier=" + identifier,
1460 "NodeIdentifier=Friend1",
1464 assertThat(peer.get().get().getIdentity(), is("id1"));
1468 public void defaultFcpClientCanSetListenOnlyForPeer()
1469 throws InterruptedException, ExecutionException, IOException {
1470 Future<Optional<Peer>> peer = fcpClient.modifyPeer().setListenOnly().byIdentity("id1").execute();
1472 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1473 String identifier = extractIdentifier(lines);
1474 assertThat(lines, matchesFcpMessage(
1476 "Identifier=" + identifier,
1477 "NodeIdentifier=id1",
1478 "IsListenOnly=true",
1481 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1482 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1483 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1484 fcpServer.writeLine(
1486 "Identifier=" + identifier,
1487 "NodeIdentifier=Friend1",
1491 assertThat(peer.get().get().getIdentity(), is("id1"));
1495 public void defaultFcpClientCanClearListenOnlyForPeer()
1496 throws InterruptedException, ExecutionException, IOException {
1497 Future<Optional<Peer>> peer = fcpClient.modifyPeer().clearListenOnly().byIdentity("id1").execute();
1499 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1500 String identifier = extractIdentifier(lines);
1501 assertThat(lines, matchesFcpMessage(
1503 "Identifier=" + identifier,
1504 "NodeIdentifier=id1",
1505 "IsListenOnly=false",
1508 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1509 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1510 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1511 fcpServer.writeLine(
1513 "Identifier=" + identifier,
1514 "NodeIdentifier=Friend1",
1518 assertThat(peer.get().get().getIdentity(), is("id1"));
1522 public void defaultFcpClientCanIgnoreSourceForPeer()
1523 throws InterruptedException, ExecutionException, IOException {
1524 Future<Optional<Peer>> peer = fcpClient.modifyPeer().ignoreSource().byIdentity("id1").execute();
1526 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1527 String identifier = extractIdentifier(lines);
1528 assertThat(lines, matchesFcpMessage(
1530 "Identifier=" + identifier,
1531 "NodeIdentifier=id1",
1532 "IgnoreSourcePort=true",
1535 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1536 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1537 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1538 assertThat(lines, not(contains(startsWith("IsListenOnly="))));
1539 fcpServer.writeLine(
1541 "Identifier=" + identifier,
1542 "NodeIdentifier=Friend1",
1546 assertThat(peer.get().get().getIdentity(), is("id1"));
1550 public void defaultFcpClientCanUseSourceForPeer()
1551 throws InterruptedException, ExecutionException, IOException {
1552 Future<Optional<Peer>> peer = fcpClient.modifyPeer().useSource().byIdentity("id1").execute();
1554 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1555 String identifier = extractIdentifier(lines);
1556 assertThat(lines, matchesFcpMessage(
1558 "Identifier=" + identifier,
1559 "NodeIdentifier=id1",
1560 "IgnoreSourcePort=false",
1563 assertThat(lines, not(contains(startsWith("AllowLocalAddresses="))));
1564 assertThat(lines, not(contains(startsWith("IsDisabled="))));
1565 assertThat(lines, not(contains(startsWith("IsBurstOnly="))));
1566 assertThat(lines, not(contains(startsWith("IsListenOnly="))));
1567 fcpServer.writeLine(
1569 "Identifier=" + identifier,
1570 "NodeIdentifier=Friend1",
1574 assertThat(peer.get().get().getIdentity(), is("id1"));
1578 public void defaultFcpClientCanRemovePeerByName() throws InterruptedException, ExecutionException, IOException {
1579 Future<Boolean> peer = fcpClient.removePeer().byName("Friend1").execute();
1581 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1582 String identifier = extractIdentifier(lines);
1583 assertThat(lines, matchesFcpMessage(
1585 "Identifier=" + identifier,
1586 "NodeIdentifier=Friend1",
1589 fcpServer.writeLine(
1591 "Identifier=" + identifier,
1592 "NodeIdentifier=Friend1",
1595 assertThat(peer.get(), is(true));
1599 public void defaultFcpClientCanNotRemovePeerByInvalidName()
1600 throws InterruptedException, ExecutionException, IOException {
1601 Future<Boolean> peer = fcpClient.removePeer().byName("NotFriend1").execute();
1603 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1604 String identifier = extractIdentifier(lines);
1605 assertThat(lines, matchesFcpMessage(
1607 "Identifier=" + identifier,
1608 "NodeIdentifier=NotFriend1",
1611 fcpServer.writeLine(
1612 "UnknownNodeIdentifier",
1613 "Identifier=" + identifier,
1616 assertThat(peer.get(), is(false));
1620 public void defaultFcpClientCanRemovePeerByIdentity() throws InterruptedException, ExecutionException, IOException {
1621 Future<Boolean> peer = fcpClient.removePeer().byIdentity("id1").execute();
1623 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1624 String identifier = extractIdentifier(lines);
1625 assertThat(lines, matchesFcpMessage(
1627 "Identifier=" + identifier,
1628 "NodeIdentifier=id1",
1631 fcpServer.writeLine(
1633 "Identifier=" + identifier,
1634 "NodeIdentifier=Friend1",
1637 assertThat(peer.get(), is(true));
1641 public void defaultFcpClientCanRemovePeerByHostAndPort()
1642 throws InterruptedException, ExecutionException, IOException {
1643 Future<Boolean> peer = fcpClient.removePeer().byHostAndPort("1.2.3.4", 5678).execute();
1645 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1646 String identifier = extractIdentifier(lines);
1647 assertThat(lines, matchesFcpMessage(
1649 "Identifier=" + identifier,
1650 "NodeIdentifier=1.2.3.4:5678",
1653 fcpServer.writeLine(
1655 "Identifier=" + identifier,
1656 "NodeIdentifier=Friend1",
1659 assertThat(peer.get(), is(true));
1663 public void defaultFcpClientCanModifyPeerNoteByName()
1664 throws InterruptedException, ExecutionException, IOException {
1665 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byName("Friend1").execute();
1667 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1668 String identifier = extractIdentifier(lines);
1669 assertThat(lines, matchesFcpMessage(
1671 "Identifier=" + identifier,
1672 "NodeIdentifier=Friend1",
1677 fcpServer.writeLine(
1679 "Identifier=" + identifier,
1680 "NodeIdentifier=Friend1",
1685 assertThat(noteUpdated.get(), is(true));
1689 public void defaultFcpClientKnowsPeerNoteWasNotModifiedOnUnknownNodeIdentifier()
1690 throws InterruptedException, ExecutionException, IOException {
1691 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byName("Friend1").execute();
1693 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1694 String identifier = extractIdentifier(lines);
1695 assertThat(lines, matchesFcpMessage(
1697 "Identifier=" + identifier,
1698 "NodeIdentifier=Friend1",
1703 fcpServer.writeLine(
1704 "UnknownNodeIdentifier",
1705 "Identifier=" + identifier,
1706 "NodeIdentifier=Friend1",
1709 assertThat(noteUpdated.get(), is(false));
1713 public void defaultFcpClientFailsToModifyPeerNoteWithoutPeerNote()
1714 throws InterruptedException, ExecutionException, IOException {
1715 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().byName("Friend1").execute();
1716 assertThat(noteUpdated.get(), is(false));
1720 public void defaultFcpClientCanModifyPeerNoteByIdentifier()
1721 throws InterruptedException, ExecutionException, IOException {
1722 Future<Boolean> noteUpdated = fcpClient.modifyPeerNote().darknetComment("foo").byIdentifier("id1").execute();
1724 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1725 String identifier = extractIdentifier(lines);
1726 assertThat(lines, matchesFcpMessage(
1728 "Identifier=" + identifier,
1729 "NodeIdentifier=id1",
1734 fcpServer.writeLine(
1736 "Identifier=" + identifier,
1737 "NodeIdentifier=id1",
1742 assertThat(noteUpdated.get(), is(true));
1746 public void defaultFcpClientCanModifyPeerNoteByHostAndPort()
1747 throws InterruptedException, ExecutionException, IOException {
1748 Future<Boolean> noteUpdated =
1749 fcpClient.modifyPeerNote().darknetComment("foo").byHostAndPort("1.2.3.4", 5678).execute();
1751 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1752 String identifier = extractIdentifier(lines);
1753 assertThat(lines, matchesFcpMessage(
1755 "Identifier=" + identifier,
1756 "NodeIdentifier=1.2.3.4:5678",
1761 fcpServer.writeLine(
1763 "Identifier=" + identifier,
1764 "NodeIdentifier=1.2.3.4:5678",
1769 assertThat(noteUpdated.get(), is(true));
1773 public void defaultFcpClientCanGetConfigWithoutDetails()
1774 throws InterruptedException, ExecutionException, IOException {
1775 Future<ConfigData> configData = fcpClient.getConfig().execute();
1777 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1778 String identifier = extractIdentifier(lines);
1779 assertThat(lines, matchesFcpMessage(
1781 "Identifier=" + identifier,
1784 fcpServer.writeLine(
1786 "Identifier=" + identifier,
1789 assertThat(configData.get(), notNullValue());
1793 public void defaultFcpClientCanGetConfigWithCurrent()
1794 throws InterruptedException, ExecutionException, IOException {
1795 Future<ConfigData> configData = fcpClient.getConfig().withCurrent().execute();
1797 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1798 String identifier = extractIdentifier(lines);
1799 assertThat(lines, matchesFcpMessage(
1801 "Identifier=" + identifier,
1805 fcpServer.writeLine(
1807 "Identifier=" + identifier,
1811 assertThat(configData.get().getCurrent("foo"), is("bar"));
1815 public void defaultFcpClientCanGetConfigWithDefaults()
1816 throws InterruptedException, ExecutionException, IOException {
1817 Future<ConfigData> configData = fcpClient.getConfig().withDefaults().execute();
1819 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1820 String identifier = extractIdentifier(lines);
1821 assertThat(lines, matchesFcpMessage(
1823 "Identifier=" + identifier,
1824 "WithDefaults=true",
1827 fcpServer.writeLine(
1829 "Identifier=" + identifier,
1833 assertThat(configData.get().getDefault("foo"), is("bar"));
1837 public void defaultFcpClientCanGetConfigWithSortOrder()
1838 throws InterruptedException, ExecutionException, IOException {
1839 Future<ConfigData> configData = fcpClient.getConfig().withSortOrder().execute();
1841 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1842 String identifier = extractIdentifier(lines);
1843 assertThat(lines, matchesFcpMessage(
1845 "Identifier=" + identifier,
1846 "WithSortOrder=true",
1849 fcpServer.writeLine(
1851 "Identifier=" + identifier,
1855 assertThat(configData.get().getSortOrder("foo"), is(17));
1859 public void defaultFcpClientCanGetConfigWithExpertFlag()
1860 throws InterruptedException, ExecutionException, IOException {
1861 Future<ConfigData> configData = fcpClient.getConfig().withExpertFlag().execute();
1863 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1864 String identifier = extractIdentifier(lines);
1865 assertThat(lines, matchesFcpMessage(
1867 "Identifier=" + identifier,
1868 "WithExpertFlag=true",
1871 fcpServer.writeLine(
1873 "Identifier=" + identifier,
1874 "expertFlag.foo=true",
1877 assertThat(configData.get().getExpertFlag("foo"), is(true));
1881 public void defaultFcpClientCanGetConfigWithForceWriteFlag()
1882 throws InterruptedException, ExecutionException, IOException {
1883 Future<ConfigData> configData = fcpClient.getConfig().withForceWriteFlag().execute();
1885 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1886 String identifier = extractIdentifier(lines);
1887 assertThat(lines, matchesFcpMessage(
1889 "Identifier=" + identifier,
1890 "WithForceWriteFlag=true",
1893 fcpServer.writeLine(
1895 "Identifier=" + identifier,
1896 "forceWriteFlag.foo=true",
1899 assertThat(configData.get().getForceWriteFlag("foo"), is(true));
1903 public void defaultFcpClientCanGetConfigWithShortDescription()
1904 throws InterruptedException, ExecutionException, IOException {
1905 Future<ConfigData> configData = fcpClient.getConfig().withShortDescription().execute();
1907 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1908 String identifier = extractIdentifier(lines);
1909 assertThat(lines, matchesFcpMessage(
1911 "Identifier=" + identifier,
1912 "WithShortDescription=true",
1915 fcpServer.writeLine(
1917 "Identifier=" + identifier,
1918 "shortDescription.foo=bar",
1921 assertThat(configData.get().getShortDescription("foo"), is("bar"));
1925 public void defaultFcpClientCanGetConfigWithLongDescription()
1926 throws InterruptedException, ExecutionException, IOException {
1927 Future<ConfigData> configData = fcpClient.getConfig().withLongDescription().execute();
1929 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1930 String identifier = extractIdentifier(lines);
1931 assertThat(lines, matchesFcpMessage(
1933 "Identifier=" + identifier,
1934 "WithLongDescription=true",
1937 fcpServer.writeLine(
1939 "Identifier=" + identifier,
1940 "longDescription.foo=bar",
1943 assertThat(configData.get().getLongDescription("foo"), is("bar"));
1947 public void defaultFcpClientCanGetConfigWithDataTypes()
1948 throws InterruptedException, ExecutionException, IOException {
1949 Future<ConfigData> configData = fcpClient.getConfig().withDataTypes().execute();
1951 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1952 String identifier = extractIdentifier(lines);
1953 assertThat(lines, matchesFcpMessage(
1955 "Identifier=" + identifier,
1956 "WithDataTypes=true",
1959 fcpServer.writeLine(
1961 "Identifier=" + identifier,
1962 "dataType.foo=number",
1965 assertThat(configData.get().getDataType("foo"), is("number"));
1969 public void defaultFcpClientCanModifyConfigData() throws InterruptedException, ExecutionException, IOException {
1970 Future<ConfigData> newConfigData = fcpClient.modifyConfig().set("foo.bar").to("baz").execute();
1972 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1973 String identifier = extractIdentifier(lines);
1974 assertThat(lines, matchesFcpMessage(
1976 "Identifier=" + identifier,
1980 fcpServer.writeLine(
1982 "Identifier=" + identifier,
1983 "current.foo.bar=baz",
1986 assertThat(newConfigData.get().getCurrent("foo.bar"), is("baz"));