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.notNullValue;
10 import java.io.ByteArrayInputStream;
12 import java.io.IOException;
14 import java.nio.charset.StandardCharsets;
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.Optional;
18 import java.util.concurrent.CopyOnWriteArrayList;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.Executors;
22 import java.util.concurrent.Future;
23 import java.util.stream.Collectors;
25 import net.pterodactylus.fcp.ARK;
26 import net.pterodactylus.fcp.DSAGroup;
27 import net.pterodactylus.fcp.FcpKeyPair;
28 import net.pterodactylus.fcp.Key;
29 import net.pterodactylus.fcp.NodeData;
30 import net.pterodactylus.fcp.NodeRef;
31 import net.pterodactylus.fcp.Peer;
32 import net.pterodactylus.fcp.Priority;
33 import net.pterodactylus.fcp.fake.FakeTcpServer;
34 import net.pterodactylus.fcp.quelaton.ClientGetCommand.Data;
36 import com.google.common.io.ByteStreams;
37 import com.google.common.io.Files;
38 import org.hamcrest.Description;
39 import org.hamcrest.Matcher;
40 import org.hamcrest.TypeSafeDiagnosingMatcher;
41 import org.junit.After;
42 import org.junit.Assert;
43 import org.junit.Test;
46 * Unit test for {@link DefaultFcpClient}.
48 * @author <a href="bombe@freenetproject.org">David ‘Bombe’ Roden</a>
50 public class DefaultFcpClientTest {
52 private static final String INSERT_URI =
53 "SSK@RVCHbJdkkyTCeNN9AYukEg76eyqmiosSaNKgE3U9zUw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQECAAE/";
54 private static final String REQUEST_URI =
55 "SSK@wtbgd2loNcJCXvtQVOftl2tuWBomDQHfqS6ytpPRhfw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQACAAE/";
57 private static int threadCounter = 0;
58 private final FakeTcpServer fcpServer;
59 private final DefaultFcpClient fcpClient;
61 public DefaultFcpClientTest() throws IOException {
62 ExecutorService threadPool =
63 Executors.newCachedThreadPool(r -> new Thread(r, "Test-Thread-" + threadCounter++));
64 fcpServer = new FakeTcpServer(threadPool);
65 fcpClient = new DefaultFcpClient(threadPool, "localhost", fcpServer.getPort(), () -> "Test");
69 public void tearDown() throws IOException {
73 @Test(expected = ExecutionException.class)
74 public void defaultFcpClientThrowsExceptionIfItCanNotConnect()
75 throws IOException, ExecutionException, InterruptedException {
76 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
77 fcpServer.connect().get();
78 fcpServer.collectUntil(is("EndMessage"));
80 "CloseConnectionDuplicateClientName",
86 @Test(expected = ExecutionException.class)
87 public void defaultFcpClientThrowsExceptionIfConnectionIsClosed()
88 throws IOException, ExecutionException, InterruptedException {
89 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
90 fcpServer.connect().get();
91 fcpServer.collectUntil(is("EndMessage"));
97 public void defaultFcpClientCanGenerateKeypair() throws ExecutionException, InterruptedException, IOException {
98 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
100 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
101 String identifier = extractIdentifier(lines);
102 fcpServer.writeLine("SSKKeypair",
103 "InsertURI=" + INSERT_URI + "",
104 "RequestURI=" + REQUEST_URI + "",
105 "Identifier=" + identifier,
107 FcpKeyPair keyPair = keyPairFuture.get();
108 assertThat(keyPair.getPublicKey(), is(REQUEST_URI));
109 assertThat(keyPair.getPrivateKey(), is(INSERT_URI));
112 private void connectNode() throws InterruptedException, ExecutionException, IOException {
113 fcpServer.connect().get();
114 fcpServer.collectUntil(is("EndMessage"));
115 fcpServer.writeLine("NodeHello",
116 "CompressionCodecs=4 - GZIP(0), BZIP2(1), LZMA(2), LZMA_NEW(3)",
117 "Revision=build01466",
119 "Version=Fred,0.7,1.0,1466",
121 "ConnectionIdentifier=14318898267048452a81b36e7f13a3f0",
125 "NodeLanguage=ENGLISH",
132 public void clientGetCanDownloadData() throws InterruptedException, ExecutionException, IOException {
133 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
135 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
136 assertThat(lines, matchesFcpMessage("ClientGet", "ReturnType=direct", "URI=KSK@foo.txt"));
137 String identifier = extractIdentifier(lines);
140 "Identifier=" + identifier,
142 "StartupTime=1435610539000",
143 "CompletionTime=1435610540000",
144 "Metadata.ContentType=text/plain;charset=utf-8",
148 Optional<Data> data = dataFuture.get();
149 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
150 assertThat(data.get().size(), is(6L));
151 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
152 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
155 private String extractIdentifier(List<String> lines) {
156 return lines.stream()
157 .filter(s -> s.startsWith("Identifier="))
158 .map(s -> s.substring(s.indexOf('=') + 1))
164 public void clientGetDownloadsDataForCorrectIdentifier()
165 throws InterruptedException, ExecutionException, IOException {
166 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
168 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
169 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
170 String identifier = extractIdentifier(lines);
173 "Identifier=not-test",
175 "StartupTime=1435610539000",
176 "CompletionTime=1435610540000",
177 "Metadata.ContentType=text/plain;charset=latin-9",
183 "Identifier=" + identifier,
185 "StartupTime=1435610539000",
186 "CompletionTime=1435610540000",
187 "Metadata.ContentType=text/plain;charset=utf-8",
191 Optional<Data> data = dataFuture.get();
192 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
193 assertThat(data.get().size(), is(6L));
194 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
195 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
199 public void clientGetRecognizesGetFailed() throws InterruptedException, ExecutionException, IOException {
200 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
202 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
203 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
204 String identifier = extractIdentifier(lines);
207 "Identifier=" + identifier,
211 Optional<Data> data = dataFuture.get();
212 assertThat(data.isPresent(), is(false));
216 public void clientGetRecognizesGetFailedForCorrectIdentifier()
217 throws InterruptedException, ExecutionException, IOException {
218 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
220 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
221 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
222 String identifier = extractIdentifier(lines);
225 "Identifier=not-test",
231 "Identifier=" + identifier,
235 Optional<Data> data = dataFuture.get();
236 assertThat(data.isPresent(), is(false));
239 @Test(expected = ExecutionException.class)
240 public void clientGetRecognizesConnectionClosed() throws InterruptedException, ExecutionException, IOException {
241 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
243 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
244 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
250 public void defaultFcpClientReusesConnection() throws InterruptedException, ExecutionException, IOException {
251 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
253 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
254 String identifier = extractIdentifier(lines);
257 "InsertURI=" + INSERT_URI + "",
258 "RequestURI=" + REQUEST_URI + "",
259 "Identifier=" + identifier,
263 keyPair = fcpClient.generateKeypair().execute();
264 lines = fcpServer.collectUntil(is("EndMessage"));
265 identifier = extractIdentifier(lines);
268 "InsertURI=" + INSERT_URI + "",
269 "RequestURI=" + REQUEST_URI + "",
270 "Identifier=" + identifier,
277 public void defaultFcpClientCanReconnectAfterConnectionHasBeenClosed()
278 throws InterruptedException, ExecutionException, IOException {
279 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
281 fcpServer.collectUntil(is("EndMessage"));
286 } catch (ExecutionException e) {
288 keyPair = fcpClient.generateKeypair().execute();
290 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
291 String identifier = extractIdentifier(lines);
294 "InsertURI=" + INSERT_URI + "",
295 "RequestURI=" + REQUEST_URI + "",
296 "Identifier=" + identifier,
303 public void clientGetWithIgnoreDataStoreSettingSendsCorrectCommands()
304 throws InterruptedException, ExecutionException, IOException {
305 fcpClient.clientGet().ignoreDataStore().uri("KSK@foo.txt").execute();
307 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
308 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "IgnoreDS=true"));
312 public void clientGetWithDataStoreOnlySettingSendsCorrectCommands()
313 throws InterruptedException, ExecutionException, IOException {
314 fcpClient.clientGet().dataStoreOnly().uri("KSK@foo.txt").execute();
316 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
317 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "DSonly=true"));
321 public void clientGetWithMaxSizeSettingSendsCorrectCommands()
322 throws InterruptedException, ExecutionException, IOException {
323 fcpClient.clientGet().maxSize(1048576).uri("KSK@foo.txt").execute();
325 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
326 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "MaxSize=1048576"));
330 public void clientGetWithPrioritySettingSendsCorrectCommands()
331 throws InterruptedException, ExecutionException, IOException {
332 fcpClient.clientGet().priority(Priority.interactive).uri("KSK@foo.txt").execute();
334 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
335 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "PriorityClass=1"));
339 public void clientGetWithRealTimeSettingSendsCorrectCommands()
340 throws InterruptedException, ExecutionException, IOException {
341 fcpClient.clientGet().realTime().uri("KSK@foo.txt").execute();
343 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
344 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "RealTimeFlag=true"));
348 public void clientGetWithGlobalSettingSendsCorrectCommands()
349 throws InterruptedException, ExecutionException, IOException {
350 fcpClient.clientGet().global().uri("KSK@foo.txt").execute();
352 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
353 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "Global=true"));
356 private Matcher<List<String>> matchesFcpMessage(String name, String... requiredLines) {
357 return new TypeSafeDiagnosingMatcher<List<String>>() {
359 protected boolean matchesSafely(List<String> item, Description mismatchDescription) {
360 if (!item.get(0).equals(name)) {
361 mismatchDescription.appendText("FCP message is named ").appendValue(item.get(0));
364 for (String requiredLine : requiredLines) {
365 if (item.indexOf(requiredLine) < 1) {
366 mismatchDescription.appendText("FCP message does not contain ").appendValue(requiredLine);
374 public void describeTo(Description description) {
375 description.appendText("FCP message named ").appendValue(name);
376 description.appendValueList(", containing the lines ", ", ", "", requiredLines);
382 public void clientPutWithDirectDataSendsCorrectCommand()
383 throws IOException, ExecutionException, InterruptedException {
384 fcpClient.clientPut()
385 .from(new ByteArrayInputStream("Hello\n".getBytes()))
390 List<String> lines = fcpServer.collectUntil(is("Hello"));
391 assertThat(lines, matchesFcpMessage("ClientPut", "UploadFrom=direct", "DataLength=6", "URI=KSK@foo.txt"));
395 public void clientPutWithDirectDataSucceedsOnCorrectIdentifier()
396 throws InterruptedException, ExecutionException, IOException {
397 Future<Optional<Key>> key = fcpClient.clientPut()
398 .from(new ByteArrayInputStream("Hello\n".getBytes()))
403 List<String> lines = fcpServer.collectUntil(is("Hello"));
404 String identifier = extractIdentifier(lines);
407 "Identifier=not-the-right-one",
413 "Identifier=" + identifier,
416 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
420 public void clientPutWithDirectDataFailsOnCorrectIdentifier()
421 throws InterruptedException, ExecutionException, IOException {
422 Future<Optional<Key>> key = fcpClient.clientPut()
423 .from(new ByteArrayInputStream("Hello\n".getBytes()))
428 List<String> lines = fcpServer.collectUntil(is("Hello"));
429 String identifier = extractIdentifier(lines);
432 "Identifier=not-the-right-one",
438 "Identifier=" + identifier,
441 assertThat(key.get().isPresent(), is(false));
445 public void clientPutWithRenamedDirectDataSendsCorrectCommand()
446 throws InterruptedException, ExecutionException, IOException {
447 fcpClient.clientPut()
448 .named("otherName.txt")
449 .from(new ByteArrayInputStream("Hello\n".getBytes()))
454 List<String> lines = fcpServer.collectUntil(is("Hello"));
455 assertThat(lines, matchesFcpMessage("ClientPut", "TargetFilename=otherName.txt", "UploadFrom=direct",
456 "DataLength=6", "URI=KSK@foo.txt"));
460 public void clientPutWithRedirectSendsCorrectCommand()
461 throws IOException, ExecutionException, InterruptedException {
462 fcpClient.clientPut().redirectTo("KSK@bar.txt").uri("KSK@foo.txt").execute();
464 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
466 matchesFcpMessage("ClientPut", "UploadFrom=redirect", "URI=KSK@foo.txt", "TargetURI=KSK@bar.txt"));
470 public void clientPutWithFileSendsCorrectCommand() throws InterruptedException, ExecutionException, IOException {
471 fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
473 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
475 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt", "Filename=/tmp/data.txt"));
479 public void clientPutWithFileCanCompleteTestDdaSequence()
480 throws IOException, ExecutionException, InterruptedException {
481 File tempFile = createTempFile();
482 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
484 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
485 String identifier = extractIdentifier(lines);
488 "Identifier=" + identifier,
492 lines = fcpServer.collectUntil(is("EndMessage"));
493 assertThat(lines, matchesFcpMessage(
495 "Directory=" + tempFile.getParent(),
496 "WantReadDirectory=true",
497 "WantWriteDirectory=false",
502 "Directory=" + tempFile.getParent(),
503 "ReadFilename=" + tempFile,
506 lines = fcpServer.collectUntil(is("EndMessage"));
507 assertThat(lines, matchesFcpMessage(
509 "Directory=" + tempFile.getParent(),
510 "ReadContent=test-content",
515 "Directory=" + tempFile.getParent(),
516 "ReadDirectoryAllowed=true",
519 lines = fcpServer.collectUntil(is("EndMessage"));
521 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt",
522 "Filename=" + new File(tempFile.getParent(), "test.dat")));
525 private File createTempFile() throws IOException {
526 File tempFile = File.createTempFile("test-dda-", ".dat");
527 tempFile.deleteOnExit();
528 Files.write("test-content", tempFile, StandardCharsets.UTF_8);
533 public void clientPutDoesNotReactToProtocolErrorForDifferentIdentifier()
534 throws InterruptedException, ExecutionException, IOException {
535 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
537 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
538 String identifier = extractIdentifier(lines);
541 "Identifier=not-the-right-one",
547 "Identifier=" + identifier,
551 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
555 public void clientPutAbortsOnProtocolErrorOtherThan25()
556 throws InterruptedException, ExecutionException, IOException {
557 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
559 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
560 String identifier = extractIdentifier(lines);
563 "Identifier=" + identifier,
567 assertThat(key.get().isPresent(), is(false));
571 public void clientPutDoesNotReplyToWrongTestDdaReply() throws IOException, ExecutionException,
572 InterruptedException {
573 File tempFile = createTempFile();
574 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
576 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
577 String identifier = extractIdentifier(lines);
580 "Identifier=" + identifier,
584 lines = fcpServer.collectUntil(is("EndMessage"));
585 assertThat(lines, matchesFcpMessage(
587 "Directory=" + tempFile.getParent(),
588 "WantReadDirectory=true",
589 "WantWriteDirectory=false",
594 "Directory=/some-other-directory",
595 "ReadFilename=" + tempFile,
600 "Directory=" + tempFile.getParent(),
601 "ReadFilename=" + tempFile,
604 lines = fcpServer.collectUntil(is("EndMessage"));
605 assertThat(lines, matchesFcpMessage(
607 "Directory=" + tempFile.getParent(),
608 "ReadContent=test-content",
614 public void clientPutSendsResponseEvenIfFileCanNotBeRead()
615 throws IOException, ExecutionException, InterruptedException {
616 File tempFile = createTempFile();
617 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
619 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
620 String identifier = extractIdentifier(lines);
623 "Identifier=" + identifier,
627 lines = fcpServer.collectUntil(is("EndMessage"));
628 assertThat(lines, matchesFcpMessage(
630 "Directory=" + tempFile.getParent(),
631 "WantReadDirectory=true",
632 "WantWriteDirectory=false",
637 "Directory=" + tempFile.getParent(),
638 "ReadFilename=" + tempFile + ".foo",
641 lines = fcpServer.collectUntil(is("EndMessage"));
642 assertThat(lines, matchesFcpMessage(
644 "Directory=" + tempFile.getParent(),
645 "ReadContent=failed-to-read",
651 public void clientPutDoesNotResendOriginalClientPutOnTestDDACompleteWithWrongDirectory()
652 throws IOException, ExecutionException, InterruptedException {
653 File tempFile = createTempFile();
654 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
656 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
657 String identifier = extractIdentifier(lines);
660 "Directory=/some-other-directory",
665 "Identifier=" + identifier,
669 lines = fcpServer.collectUntil(is("EndMessage"));
670 assertThat(lines, matchesFcpMessage(
672 "Directory=" + tempFile.getParent(),
673 "WantReadDirectory=true",
674 "WantWriteDirectory=false",
680 public void clientPutSendsNotificationsForGeneratedKeys()
681 throws InterruptedException, ExecutionException, IOException {
682 List<String> generatedKeys = new CopyOnWriteArrayList<>();
683 Future<Optional<Key>> key = fcpClient.clientPut()
684 .onKeyGenerated(generatedKeys::add)
685 .from(new ByteArrayInputStream("Hello\n".getBytes()))
690 List<String> lines = fcpServer.collectUntil(is("Hello"));
691 String identifier = extractIdentifier(lines);
694 "Identifier="+identifier,
701 "Identifier=" + identifier,
704 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
705 assertThat(generatedKeys, contains("KSK@foo.txt"));
709 public void clientCanListPeers() throws IOException, ExecutionException, InterruptedException {
710 Future<Collection<Peer>> peers = fcpClient.listPeers().execute();
712 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
713 assertThat(lines, matchesFcpMessage(
715 "WithVolatile=false",
716 "WithMetadata=false",
719 String identifier = extractIdentifier(lines);
722 "Identifier=" + identifier,
728 "Identifier=" + identifier,
734 "Identifier=" + identifier,
737 assertThat(peers.get(), hasSize(2));
738 assertThat(peers.get().stream().map(Peer::getIdentity).collect(Collectors.toList()),
739 containsInAnyOrder("id1", "id2"));
743 public void clientCanListPeersWithMetadata() throws IOException, ExecutionException, InterruptedException {
744 Future<Collection<Peer>> peers = fcpClient.listPeers().includeMetadata().execute();
746 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
747 assertThat(lines, matchesFcpMessage(
749 "WithVolatile=false",
753 String identifier = extractIdentifier(lines);
756 "Identifier=" + identifier,
763 "Identifier=" + identifier,
770 "Identifier=" + identifier,
773 assertThat(peers.get(), hasSize(2));
774 assertThat(peers.get().stream().map(peer -> peer.getMetadata("foo")).collect(Collectors.toList()),
775 containsInAnyOrder("bar1", "bar2"));
779 public void clientCanListPeersWithVolatiles() throws IOException, ExecutionException, InterruptedException {
780 Future<Collection<Peer>> peers = fcpClient.listPeers().includeVolatile().execute();
782 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
783 assertThat(lines, matchesFcpMessage(
786 "WithMetadata=false",
789 String identifier = extractIdentifier(lines);
792 "Identifier=" + identifier,
799 "Identifier=" + identifier,
806 "Identifier=" + identifier,
809 assertThat(peers.get(), hasSize(2));
810 assertThat(peers.get().stream().map(peer -> peer.getVolatile("foo")).collect(Collectors.toList()),
811 containsInAnyOrder("bar1", "bar2"));
815 public void defaultFcpClientCanGetNodeInformation() throws InterruptedException, ExecutionException, IOException {
816 Future<NodeData> nodeData = fcpClient.getNode().execute();
818 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
819 String identifier = extractIdentifier(lines);
820 assertThat(lines, matchesFcpMessage(
822 "Identifier=" + identifier,
823 "GiveOpennetRef=false",
825 "WithVolatile=false",
830 "Identifier=" + identifier,
831 "ark.pubURI=SSK@3YEf.../ark",
834 "version=Fred,0.7,1.0,1466",
835 "lastGoodVersion=Fred,0.7,1.0,1466",
838 assertThat(nodeData.get(), notNullValue());
842 public void defaultFcpClientCanGetNodeInformationWithOpennetRef()
843 throws InterruptedException, ExecutionException, IOException {
844 Future<NodeData> nodeData = fcpClient.getNode().opennetRef().execute();
846 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
847 String identifier = extractIdentifier(lines);
848 assertThat(lines, matchesFcpMessage(
850 "Identifier=" + identifier,
851 "GiveOpennetRef=true",
853 "WithVolatile=false",
858 "Identifier=" + identifier,
860 "ark.pubURI=SSK@3YEf.../ark",
863 "version=Fred,0.7,1.0,1466",
864 "lastGoodVersion=Fred,0.7,1.0,1466",
867 assertThat(nodeData.get().getVersion().toString(), is("Fred,0.7,1.0,1466"));
871 public void defaultFcpClientCanGetNodeInformationWithPrivateData()
872 throws InterruptedException, ExecutionException, IOException {
873 Future<NodeData> nodeData = fcpClient.getNode().includePrivate().execute();
875 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
876 String identifier = extractIdentifier(lines);
877 assertThat(lines, matchesFcpMessage(
879 "Identifier=" + identifier,
880 "GiveOpennetRef=false",
882 "WithVolatile=false",
887 "Identifier=" + identifier,
889 "ark.pubURI=SSK@3YEf.../ark",
892 "version=Fred,0.7,1.0,1466",
893 "lastGoodVersion=Fred,0.7,1.0,1466",
894 "ark.privURI=SSK@XdHMiRl",
897 assertThat(nodeData.get().getARK().getPrivateURI(), is("SSK@XdHMiRl"));
901 public void defaultFcpClientCanGetNodeInformationWithVolatileData()
902 throws InterruptedException, ExecutionException, IOException {
903 Future<NodeData> nodeData = fcpClient.getNode().includeVolatile().execute();
905 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
906 String identifier = extractIdentifier(lines);
907 assertThat(lines, matchesFcpMessage(
909 "Identifier=" + identifier,
910 "GiveOpennetRef=false",
917 "Identifier=" + identifier,
919 "ark.pubURI=SSK@3YEf.../ark",
922 "version=Fred,0.7,1.0,1466",
923 "lastGoodVersion=Fred,0.7,1.0,1466",
924 "volatile.freeJavaMemory=205706528",
927 assertThat(nodeData.get().getVolatile("freeJavaMemory"), is("205706528"));
931 public void defaultFcpClientCanListSinglePeerByIdentity()
932 throws InterruptedException, ExecutionException, IOException {
933 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id1").execute();
935 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
936 String identifier = extractIdentifier(lines);
937 assertThat(lines, matchesFcpMessage(
939 "Identifier=" + identifier,
940 "NodeIdentifier=id1",
945 "Identifier=" + identifier,
948 "ark.pubURI=SSK@3YEf.../ark",
951 "version=Fred,0.7,1.0,1466",
952 "lastGoodVersion=Fred,0.7,1.0,1466",
955 assertThat(peer.get().get().getIdentity(), is("id1"));
959 public void defaultFcpClientCanListSinglePeerByHostAndPort()
960 throws InterruptedException, ExecutionException, IOException {
961 Future<Optional<Peer>> peer = fcpClient.listPeer().byHostAndPort("host.free.net", 12345).execute();
963 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
964 String identifier = extractIdentifier(lines);
965 assertThat(lines, matchesFcpMessage(
967 "Identifier=" + identifier,
968 "NodeIdentifier=host.free.net:12345",
973 "Identifier=" + identifier,
976 "ark.pubURI=SSK@3YEf.../ark",
979 "version=Fred,0.7,1.0,1466",
980 "lastGoodVersion=Fred,0.7,1.0,1466",
983 assertThat(peer.get().get().getIdentity(), is("id1"));
987 public void defaultFcpClientCanListSinglePeerByName()
988 throws InterruptedException, ExecutionException, IOException {
989 Future<Optional<Peer>> peer = fcpClient.listPeer().byName("FriendNode").execute();
991 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
992 String identifier = extractIdentifier(lines);
993 assertThat(lines, matchesFcpMessage(
995 "Identifier=" + identifier,
996 "NodeIdentifier=FriendNode",
1001 "Identifier=" + identifier,
1004 "ark.pubURI=SSK@3YEf.../ark",
1007 "version=Fred,0.7,1.0,1466",
1008 "lastGoodVersion=Fred,0.7,1.0,1466",
1011 assertThat(peer.get().get().getIdentity(), is("id1"));
1015 public void defaultFcpClientRecognizesUnknownNodeIdentifiers()
1016 throws InterruptedException, ExecutionException, IOException {
1017 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id2").execute();
1019 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1020 String identifier = extractIdentifier(lines);
1021 assertThat(lines, matchesFcpMessage(
1023 "Identifier=" + identifier,
1024 "NodeIdentifier=id2",
1027 fcpServer.writeLine(
1028 "UnknownNodeIdentifier",
1029 "Identifier=" + identifier,
1030 "NodeIdentifier=id2",
1033 assertThat(peer.get().isPresent(), is(false));
1037 public void defaultFcpClientCanAddPeerFromFile() throws InterruptedException, ExecutionException, IOException {
1038 Future<Optional<Peer>> peer = fcpClient.addPeer().fromFile(new File("/tmp/ref.txt")).execute();
1040 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1041 String identifier = extractIdentifier(lines);
1042 assertThat(lines, matchesFcpMessage(
1044 "Identifier=" + identifier,
1045 "File=/tmp/ref.txt",
1048 fcpServer.writeLine(
1050 "Identifier=" + identifier,
1053 "ark.pubURI=SSK@3YEf.../ark",
1056 "version=Fred,0.7,1.0,1466",
1057 "lastGoodVersion=Fred,0.7,1.0,1466",
1060 assertThat(peer.get().get().getIdentity(), is("id1"));
1064 public void defaultFcpClientCanAddPeerFromURL() throws InterruptedException, ExecutionException, IOException {
1065 Future<Optional<Peer>> peer = fcpClient.addPeer().fromURL(new URL("http://node.ref/")).execute();
1067 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1068 String identifier = extractIdentifier(lines);
1069 assertThat(lines, matchesFcpMessage(
1071 "Identifier=" + identifier,
1072 "URL=http://node.ref/",
1075 fcpServer.writeLine(
1077 "Identifier=" + identifier,
1080 "ark.pubURI=SSK@3YEf.../ark",
1083 "version=Fred,0.7,1.0,1466",
1084 "lastGoodVersion=Fred,0.7,1.0,1466",
1087 assertThat(peer.get().get().getIdentity(), is("id1"));
1091 public void defaultFcpClientCanAddPeerFromNodeRef() throws InterruptedException, ExecutionException, IOException {
1092 NodeRef nodeRef = new NodeRef();
1093 nodeRef.setIdentity("id1");
1094 nodeRef.setName("name");
1095 nodeRef.setARK(new ARK("public", "1"));
1096 nodeRef.setDSAGroup(new DSAGroup("base", "prime", "subprime"));
1097 nodeRef.setNegotiationTypes(new int[] { 3, 5 });
1098 nodeRef.setPhysicalUDP("1.2.3.4:5678");
1099 nodeRef.setDSAPublicKey("dsa-public");
1100 nodeRef.setSignature("sig");
1101 Future<Optional<Peer>> peer = fcpClient.addPeer().fromNodeRef(nodeRef).execute();
1103 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1104 String identifier = extractIdentifier(lines);
1105 assertThat(lines, matchesFcpMessage(
1107 "Identifier=" + identifier,
1110 "ark.pubURI=public",
1114 "dsaGroup.q=subprime",
1115 "dsaPubKey.y=dsa-public",
1116 "physical.udp=1.2.3.4:5678",
1117 "auth.negTypes=3;5",
1121 fcpServer.writeLine(
1123 "Identifier=" + identifier,
1126 "ark.pubURI=SSK@3YEf.../ark",
1129 "version=Fred,0.7,1.0,1466",
1130 "lastGoodVersion=Fred,0.7,1.0,1466",
1133 assertThat(peer.get().get().getIdentity(), is("id1"));