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.PeerNote;
33 import net.pterodactylus.fcp.Priority;
34 import net.pterodactylus.fcp.fake.FakeTcpServer;
35 import net.pterodactylus.fcp.quelaton.ClientGetCommand.Data;
37 import com.google.common.io.ByteStreams;
38 import com.google.common.io.Files;
39 import org.hamcrest.Description;
40 import org.hamcrest.Matcher;
41 import org.hamcrest.TypeSafeDiagnosingMatcher;
42 import org.junit.After;
43 import org.junit.Assert;
44 import org.junit.Test;
47 * Unit test for {@link DefaultFcpClient}.
49 * @author <a href="bombe@freenetproject.org">David ‘Bombe’ Roden</a>
51 public class DefaultFcpClientTest {
53 private static final String INSERT_URI =
54 "SSK@RVCHbJdkkyTCeNN9AYukEg76eyqmiosSaNKgE3U9zUw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQECAAE/";
55 private static final String REQUEST_URI =
56 "SSK@wtbgd2loNcJCXvtQVOftl2tuWBomDQHfqS6ytpPRhfw,7SHH53gletBVb9JD7nBsyClbLQsBubDPEIcwg908r7Y,AQACAAE/";
58 private static int threadCounter = 0;
59 private final FakeTcpServer fcpServer;
60 private final DefaultFcpClient fcpClient;
62 public DefaultFcpClientTest() throws IOException {
63 ExecutorService threadPool =
64 Executors.newCachedThreadPool(r -> new Thread(r, "Test-Thread-" + threadCounter++));
65 fcpServer = new FakeTcpServer(threadPool);
66 fcpClient = new DefaultFcpClient(threadPool, "localhost", fcpServer.getPort(), () -> "Test");
70 public void tearDown() throws IOException {
74 @Test(expected = ExecutionException.class)
75 public void defaultFcpClientThrowsExceptionIfItCanNotConnect()
76 throws IOException, ExecutionException, InterruptedException {
77 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
78 fcpServer.connect().get();
79 fcpServer.collectUntil(is("EndMessage"));
81 "CloseConnectionDuplicateClientName",
87 @Test(expected = ExecutionException.class)
88 public void defaultFcpClientThrowsExceptionIfConnectionIsClosed()
89 throws IOException, ExecutionException, InterruptedException {
90 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
91 fcpServer.connect().get();
92 fcpServer.collectUntil(is("EndMessage"));
98 public void defaultFcpClientCanGenerateKeypair() throws ExecutionException, InterruptedException, IOException {
99 Future<FcpKeyPair> keyPairFuture = fcpClient.generateKeypair().execute();
101 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
102 String identifier = extractIdentifier(lines);
103 fcpServer.writeLine("SSKKeypair",
104 "InsertURI=" + INSERT_URI + "",
105 "RequestURI=" + REQUEST_URI + "",
106 "Identifier=" + identifier,
108 FcpKeyPair keyPair = keyPairFuture.get();
109 assertThat(keyPair.getPublicKey(), is(REQUEST_URI));
110 assertThat(keyPair.getPrivateKey(), is(INSERT_URI));
113 private void connectNode() throws InterruptedException, ExecutionException, IOException {
114 fcpServer.connect().get();
115 fcpServer.collectUntil(is("EndMessage"));
116 fcpServer.writeLine("NodeHello",
117 "CompressionCodecs=4 - GZIP(0), BZIP2(1), LZMA(2), LZMA_NEW(3)",
118 "Revision=build01466",
120 "Version=Fred,0.7,1.0,1466",
122 "ConnectionIdentifier=14318898267048452a81b36e7f13a3f0",
126 "NodeLanguage=ENGLISH",
133 public void clientGetCanDownloadData() throws InterruptedException, ExecutionException, IOException {
134 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
136 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
137 assertThat(lines, matchesFcpMessage("ClientGet", "ReturnType=direct", "URI=KSK@foo.txt"));
138 String identifier = extractIdentifier(lines);
141 "Identifier=" + identifier,
143 "StartupTime=1435610539000",
144 "CompletionTime=1435610540000",
145 "Metadata.ContentType=text/plain;charset=utf-8",
149 Optional<Data> data = dataFuture.get();
150 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
151 assertThat(data.get().size(), is(6L));
152 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
153 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
156 private String extractIdentifier(List<String> lines) {
157 return lines.stream()
158 .filter(s -> s.startsWith("Identifier="))
159 .map(s -> s.substring(s.indexOf('=') + 1))
165 public void clientGetDownloadsDataForCorrectIdentifier()
166 throws InterruptedException, ExecutionException, IOException {
167 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
169 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
170 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
171 String identifier = extractIdentifier(lines);
174 "Identifier=not-test",
176 "StartupTime=1435610539000",
177 "CompletionTime=1435610540000",
178 "Metadata.ContentType=text/plain;charset=latin-9",
184 "Identifier=" + identifier,
186 "StartupTime=1435610539000",
187 "CompletionTime=1435610540000",
188 "Metadata.ContentType=text/plain;charset=utf-8",
192 Optional<Data> data = dataFuture.get();
193 assertThat(data.get().getMimeType(), is("text/plain;charset=utf-8"));
194 assertThat(data.get().size(), is(6L));
195 assertThat(ByteStreams.toByteArray(data.get().getInputStream()),
196 is("Hello\n".getBytes(StandardCharsets.UTF_8)));
200 public void clientGetRecognizesGetFailed() throws InterruptedException, ExecutionException, IOException {
201 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
203 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
204 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
205 String identifier = extractIdentifier(lines);
208 "Identifier=" + identifier,
212 Optional<Data> data = dataFuture.get();
213 assertThat(data.isPresent(), is(false));
217 public void clientGetRecognizesGetFailedForCorrectIdentifier()
218 throws InterruptedException, ExecutionException, IOException {
219 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
221 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
222 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
223 String identifier = extractIdentifier(lines);
226 "Identifier=not-test",
232 "Identifier=" + identifier,
236 Optional<Data> data = dataFuture.get();
237 assertThat(data.isPresent(), is(false));
240 @Test(expected = ExecutionException.class)
241 public void clientGetRecognizesConnectionClosed() throws InterruptedException, ExecutionException, IOException {
242 Future<Optional<Data>> dataFuture = fcpClient.clientGet().uri("KSK@foo.txt").execute();
244 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
245 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt"));
251 public void defaultFcpClientReusesConnection() throws InterruptedException, ExecutionException, IOException {
252 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
254 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
255 String identifier = extractIdentifier(lines);
258 "InsertURI=" + INSERT_URI + "",
259 "RequestURI=" + REQUEST_URI + "",
260 "Identifier=" + identifier,
264 keyPair = fcpClient.generateKeypair().execute();
265 lines = fcpServer.collectUntil(is("EndMessage"));
266 identifier = extractIdentifier(lines);
269 "InsertURI=" + INSERT_URI + "",
270 "RequestURI=" + REQUEST_URI + "",
271 "Identifier=" + identifier,
278 public void defaultFcpClientCanReconnectAfterConnectionHasBeenClosed()
279 throws InterruptedException, ExecutionException, IOException {
280 Future<FcpKeyPair> keyPair = fcpClient.generateKeypair().execute();
282 fcpServer.collectUntil(is("EndMessage"));
287 } catch (ExecutionException e) {
289 keyPair = fcpClient.generateKeypair().execute();
291 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
292 String identifier = extractIdentifier(lines);
295 "InsertURI=" + INSERT_URI + "",
296 "RequestURI=" + REQUEST_URI + "",
297 "Identifier=" + identifier,
304 public void clientGetWithIgnoreDataStoreSettingSendsCorrectCommands()
305 throws InterruptedException, ExecutionException, IOException {
306 fcpClient.clientGet().ignoreDataStore().uri("KSK@foo.txt").execute();
308 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
309 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "IgnoreDS=true"));
313 public void clientGetWithDataStoreOnlySettingSendsCorrectCommands()
314 throws InterruptedException, ExecutionException, IOException {
315 fcpClient.clientGet().dataStoreOnly().uri("KSK@foo.txt").execute();
317 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
318 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "DSonly=true"));
322 public void clientGetWithMaxSizeSettingSendsCorrectCommands()
323 throws InterruptedException, ExecutionException, IOException {
324 fcpClient.clientGet().maxSize(1048576).uri("KSK@foo.txt").execute();
326 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
327 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "MaxSize=1048576"));
331 public void clientGetWithPrioritySettingSendsCorrectCommands()
332 throws InterruptedException, ExecutionException, IOException {
333 fcpClient.clientGet().priority(Priority.interactive).uri("KSK@foo.txt").execute();
335 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
336 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "PriorityClass=1"));
340 public void clientGetWithRealTimeSettingSendsCorrectCommands()
341 throws InterruptedException, ExecutionException, IOException {
342 fcpClient.clientGet().realTime().uri("KSK@foo.txt").execute();
344 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
345 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "RealTimeFlag=true"));
349 public void clientGetWithGlobalSettingSendsCorrectCommands()
350 throws InterruptedException, ExecutionException, IOException {
351 fcpClient.clientGet().global().uri("KSK@foo.txt").execute();
353 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
354 assertThat(lines, matchesFcpMessage("ClientGet", "URI=KSK@foo.txt", "Global=true"));
357 private Matcher<List<String>> matchesFcpMessage(String name, String... requiredLines) {
358 return new TypeSafeDiagnosingMatcher<List<String>>() {
360 protected boolean matchesSafely(List<String> item, Description mismatchDescription) {
361 if (!item.get(0).equals(name)) {
362 mismatchDescription.appendText("FCP message is named ").appendValue(item.get(0));
365 for (String requiredLine : requiredLines) {
366 if (item.indexOf(requiredLine) < 1) {
367 mismatchDescription.appendText("FCP message does not contain ").appendValue(requiredLine);
375 public void describeTo(Description description) {
376 description.appendText("FCP message named ").appendValue(name);
377 description.appendValueList(", containing the lines ", ", ", "", requiredLines);
383 public void clientPutWithDirectDataSendsCorrectCommand()
384 throws IOException, ExecutionException, InterruptedException {
385 fcpClient.clientPut()
386 .from(new ByteArrayInputStream("Hello\n".getBytes()))
391 List<String> lines = fcpServer.collectUntil(is("Hello"));
392 assertThat(lines, matchesFcpMessage("ClientPut", "UploadFrom=direct", "DataLength=6", "URI=KSK@foo.txt"));
396 public void clientPutWithDirectDataSucceedsOnCorrectIdentifier()
397 throws InterruptedException, ExecutionException, IOException {
398 Future<Optional<Key>> key = fcpClient.clientPut()
399 .from(new ByteArrayInputStream("Hello\n".getBytes()))
404 List<String> lines = fcpServer.collectUntil(is("Hello"));
405 String identifier = extractIdentifier(lines);
408 "Identifier=not-the-right-one",
414 "Identifier=" + identifier,
417 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
421 public void clientPutWithDirectDataFailsOnCorrectIdentifier()
422 throws InterruptedException, ExecutionException, IOException {
423 Future<Optional<Key>> key = fcpClient.clientPut()
424 .from(new ByteArrayInputStream("Hello\n".getBytes()))
429 List<String> lines = fcpServer.collectUntil(is("Hello"));
430 String identifier = extractIdentifier(lines);
433 "Identifier=not-the-right-one",
439 "Identifier=" + identifier,
442 assertThat(key.get().isPresent(), is(false));
446 public void clientPutWithRenamedDirectDataSendsCorrectCommand()
447 throws InterruptedException, ExecutionException, IOException {
448 fcpClient.clientPut()
449 .named("otherName.txt")
450 .from(new ByteArrayInputStream("Hello\n".getBytes()))
455 List<String> lines = fcpServer.collectUntil(is("Hello"));
456 assertThat(lines, matchesFcpMessage("ClientPut", "TargetFilename=otherName.txt", "UploadFrom=direct",
457 "DataLength=6", "URI=KSK@foo.txt"));
461 public void clientPutWithRedirectSendsCorrectCommand()
462 throws IOException, ExecutionException, InterruptedException {
463 fcpClient.clientPut().redirectTo("KSK@bar.txt").uri("KSK@foo.txt").execute();
465 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
467 matchesFcpMessage("ClientPut", "UploadFrom=redirect", "URI=KSK@foo.txt", "TargetURI=KSK@bar.txt"));
471 public void clientPutWithFileSendsCorrectCommand() throws InterruptedException, ExecutionException, IOException {
472 fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
474 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
476 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt", "Filename=/tmp/data.txt"));
480 public void clientPutWithFileCanCompleteTestDdaSequence()
481 throws IOException, ExecutionException, InterruptedException {
482 File tempFile = createTempFile();
483 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
485 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
486 String identifier = extractIdentifier(lines);
489 "Identifier=" + identifier,
493 lines = fcpServer.collectUntil(is("EndMessage"));
494 assertThat(lines, matchesFcpMessage(
496 "Directory=" + tempFile.getParent(),
497 "WantReadDirectory=true",
498 "WantWriteDirectory=false",
503 "Directory=" + tempFile.getParent(),
504 "ReadFilename=" + tempFile,
507 lines = fcpServer.collectUntil(is("EndMessage"));
508 assertThat(lines, matchesFcpMessage(
510 "Directory=" + tempFile.getParent(),
511 "ReadContent=test-content",
516 "Directory=" + tempFile.getParent(),
517 "ReadDirectoryAllowed=true",
520 lines = fcpServer.collectUntil(is("EndMessage"));
522 matchesFcpMessage("ClientPut", "UploadFrom=disk", "URI=KSK@foo.txt",
523 "Filename=" + new File(tempFile.getParent(), "test.dat")));
526 private File createTempFile() throws IOException {
527 File tempFile = File.createTempFile("test-dda-", ".dat");
528 tempFile.deleteOnExit();
529 Files.write("test-content", tempFile, StandardCharsets.UTF_8);
534 public void clientPutDoesNotReactToProtocolErrorForDifferentIdentifier()
535 throws InterruptedException, ExecutionException, IOException {
536 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
538 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
539 String identifier = extractIdentifier(lines);
542 "Identifier=not-the-right-one",
548 "Identifier=" + identifier,
552 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
556 public void clientPutAbortsOnProtocolErrorOtherThan25()
557 throws InterruptedException, ExecutionException, IOException {
558 Future<Optional<Key>> key = fcpClient.clientPut().from(new File("/tmp/data.txt")).uri("KSK@foo.txt").execute();
560 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
561 String identifier = extractIdentifier(lines);
564 "Identifier=" + identifier,
568 assertThat(key.get().isPresent(), is(false));
572 public void clientPutDoesNotReplyToWrongTestDdaReply() throws IOException, ExecutionException,
573 InterruptedException {
574 File tempFile = createTempFile();
575 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
577 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
578 String identifier = extractIdentifier(lines);
581 "Identifier=" + identifier,
585 lines = fcpServer.collectUntil(is("EndMessage"));
586 assertThat(lines, matchesFcpMessage(
588 "Directory=" + tempFile.getParent(),
589 "WantReadDirectory=true",
590 "WantWriteDirectory=false",
595 "Directory=/some-other-directory",
596 "ReadFilename=" + tempFile,
601 "Directory=" + tempFile.getParent(),
602 "ReadFilename=" + tempFile,
605 lines = fcpServer.collectUntil(is("EndMessage"));
606 assertThat(lines, matchesFcpMessage(
608 "Directory=" + tempFile.getParent(),
609 "ReadContent=test-content",
615 public void clientPutSendsResponseEvenIfFileCanNotBeRead()
616 throws IOException, ExecutionException, InterruptedException {
617 File tempFile = createTempFile();
618 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
620 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
621 String identifier = extractIdentifier(lines);
624 "Identifier=" + identifier,
628 lines = fcpServer.collectUntil(is("EndMessage"));
629 assertThat(lines, matchesFcpMessage(
631 "Directory=" + tempFile.getParent(),
632 "WantReadDirectory=true",
633 "WantWriteDirectory=false",
638 "Directory=" + tempFile.getParent(),
639 "ReadFilename=" + tempFile + ".foo",
642 lines = fcpServer.collectUntil(is("EndMessage"));
643 assertThat(lines, matchesFcpMessage(
645 "Directory=" + tempFile.getParent(),
646 "ReadContent=failed-to-read",
652 public void clientPutDoesNotResendOriginalClientPutOnTestDDACompleteWithWrongDirectory()
653 throws IOException, ExecutionException, InterruptedException {
654 File tempFile = createTempFile();
655 fcpClient.clientPut().from(new File(tempFile.getParent(), "test.dat")).uri("KSK@foo.txt").execute();
657 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
658 String identifier = extractIdentifier(lines);
661 "Directory=/some-other-directory",
666 "Identifier=" + identifier,
670 lines = fcpServer.collectUntil(is("EndMessage"));
671 assertThat(lines, matchesFcpMessage(
673 "Directory=" + tempFile.getParent(),
674 "WantReadDirectory=true",
675 "WantWriteDirectory=false",
681 public void clientPutSendsNotificationsForGeneratedKeys()
682 throws InterruptedException, ExecutionException, IOException {
683 List<String> generatedKeys = new CopyOnWriteArrayList<>();
684 Future<Optional<Key>> key = fcpClient.clientPut()
685 .onKeyGenerated(generatedKeys::add)
686 .from(new ByteArrayInputStream("Hello\n".getBytes()))
691 List<String> lines = fcpServer.collectUntil(is("Hello"));
692 String identifier = extractIdentifier(lines);
695 "Identifier=" + identifier,
702 "Identifier=" + identifier,
705 assertThat(key.get().get().getKey(), is("KSK@foo.txt"));
706 assertThat(generatedKeys, contains("KSK@foo.txt"));
710 public void clientCanListPeers() throws IOException, ExecutionException, InterruptedException {
711 Future<Collection<Peer>> peers = fcpClient.listPeers().execute();
713 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
714 assertThat(lines, matchesFcpMessage(
716 "WithVolatile=false",
717 "WithMetadata=false",
720 String identifier = extractIdentifier(lines);
723 "Identifier=" + identifier,
729 "Identifier=" + identifier,
735 "Identifier=" + identifier,
738 assertThat(peers.get(), hasSize(2));
739 assertThat(peers.get().stream().map(Peer::getIdentity).collect(Collectors.toList()),
740 containsInAnyOrder("id1", "id2"));
744 public void clientCanListPeersWithMetadata() throws IOException, ExecutionException, InterruptedException {
745 Future<Collection<Peer>> peers = fcpClient.listPeers().includeMetadata().execute();
747 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
748 assertThat(lines, matchesFcpMessage(
750 "WithVolatile=false",
754 String identifier = extractIdentifier(lines);
757 "Identifier=" + identifier,
764 "Identifier=" + identifier,
771 "Identifier=" + identifier,
774 assertThat(peers.get(), hasSize(2));
775 assertThat(peers.get().stream().map(peer -> peer.getMetadata("foo")).collect(Collectors.toList()),
776 containsInAnyOrder("bar1", "bar2"));
780 public void clientCanListPeersWithVolatiles() throws IOException, ExecutionException, InterruptedException {
781 Future<Collection<Peer>> peers = fcpClient.listPeers().includeVolatile().execute();
783 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
784 assertThat(lines, matchesFcpMessage(
787 "WithMetadata=false",
790 String identifier = extractIdentifier(lines);
793 "Identifier=" + identifier,
800 "Identifier=" + identifier,
807 "Identifier=" + identifier,
810 assertThat(peers.get(), hasSize(2));
811 assertThat(peers.get().stream().map(peer -> peer.getVolatile("foo")).collect(Collectors.toList()),
812 containsInAnyOrder("bar1", "bar2"));
816 public void defaultFcpClientCanGetNodeInformation() throws InterruptedException, ExecutionException, IOException {
817 Future<NodeData> nodeData = fcpClient.getNode().execute();
819 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
820 String identifier = extractIdentifier(lines);
821 assertThat(lines, matchesFcpMessage(
823 "Identifier=" + identifier,
824 "GiveOpennetRef=false",
826 "WithVolatile=false",
831 "Identifier=" + identifier,
832 "ark.pubURI=SSK@3YEf.../ark",
835 "version=Fred,0.7,1.0,1466",
836 "lastGoodVersion=Fred,0.7,1.0,1466",
839 assertThat(nodeData.get(), notNullValue());
843 public void defaultFcpClientCanGetNodeInformationWithOpennetRef()
844 throws InterruptedException, ExecutionException, IOException {
845 Future<NodeData> nodeData = fcpClient.getNode().opennetRef().execute();
847 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
848 String identifier = extractIdentifier(lines);
849 assertThat(lines, matchesFcpMessage(
851 "Identifier=" + identifier,
852 "GiveOpennetRef=true",
854 "WithVolatile=false",
859 "Identifier=" + identifier,
861 "ark.pubURI=SSK@3YEf.../ark",
864 "version=Fred,0.7,1.0,1466",
865 "lastGoodVersion=Fred,0.7,1.0,1466",
868 assertThat(nodeData.get().getVersion().toString(), is("Fred,0.7,1.0,1466"));
872 public void defaultFcpClientCanGetNodeInformationWithPrivateData()
873 throws InterruptedException, ExecutionException, IOException {
874 Future<NodeData> nodeData = fcpClient.getNode().includePrivate().execute();
876 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
877 String identifier = extractIdentifier(lines);
878 assertThat(lines, matchesFcpMessage(
880 "Identifier=" + identifier,
881 "GiveOpennetRef=false",
883 "WithVolatile=false",
888 "Identifier=" + identifier,
890 "ark.pubURI=SSK@3YEf.../ark",
893 "version=Fred,0.7,1.0,1466",
894 "lastGoodVersion=Fred,0.7,1.0,1466",
895 "ark.privURI=SSK@XdHMiRl",
898 assertThat(nodeData.get().getARK().getPrivateURI(), is("SSK@XdHMiRl"));
902 public void defaultFcpClientCanGetNodeInformationWithVolatileData()
903 throws InterruptedException, ExecutionException, IOException {
904 Future<NodeData> nodeData = fcpClient.getNode().includeVolatile().execute();
906 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
907 String identifier = extractIdentifier(lines);
908 assertThat(lines, matchesFcpMessage(
910 "Identifier=" + identifier,
911 "GiveOpennetRef=false",
918 "Identifier=" + identifier,
920 "ark.pubURI=SSK@3YEf.../ark",
923 "version=Fred,0.7,1.0,1466",
924 "lastGoodVersion=Fred,0.7,1.0,1466",
925 "volatile.freeJavaMemory=205706528",
928 assertThat(nodeData.get().getVolatile("freeJavaMemory"), is("205706528"));
932 public void defaultFcpClientCanListSinglePeerByIdentity()
933 throws InterruptedException, ExecutionException, IOException {
934 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id1").execute();
936 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
937 String identifier = extractIdentifier(lines);
938 assertThat(lines, matchesFcpMessage(
940 "Identifier=" + identifier,
941 "NodeIdentifier=id1",
946 "Identifier=" + identifier,
949 "ark.pubURI=SSK@3YEf.../ark",
952 "version=Fred,0.7,1.0,1466",
953 "lastGoodVersion=Fred,0.7,1.0,1466",
956 assertThat(peer.get().get().getIdentity(), is("id1"));
960 public void defaultFcpClientCanListSinglePeerByHostAndPort()
961 throws InterruptedException, ExecutionException, IOException {
962 Future<Optional<Peer>> peer = fcpClient.listPeer().byHostAndPort("host.free.net", 12345).execute();
964 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
965 String identifier = extractIdentifier(lines);
966 assertThat(lines, matchesFcpMessage(
968 "Identifier=" + identifier,
969 "NodeIdentifier=host.free.net:12345",
974 "Identifier=" + identifier,
977 "ark.pubURI=SSK@3YEf.../ark",
980 "version=Fred,0.7,1.0,1466",
981 "lastGoodVersion=Fred,0.7,1.0,1466",
984 assertThat(peer.get().get().getIdentity(), is("id1"));
988 public void defaultFcpClientCanListSinglePeerByName()
989 throws InterruptedException, ExecutionException, IOException {
990 Future<Optional<Peer>> peer = fcpClient.listPeer().byName("FriendNode").execute();
992 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
993 String identifier = extractIdentifier(lines);
994 assertThat(lines, matchesFcpMessage(
996 "Identifier=" + identifier,
997 "NodeIdentifier=FriendNode",
1000 fcpServer.writeLine(
1002 "Identifier=" + identifier,
1005 "ark.pubURI=SSK@3YEf.../ark",
1008 "version=Fred,0.7,1.0,1466",
1009 "lastGoodVersion=Fred,0.7,1.0,1466",
1012 assertThat(peer.get().get().getIdentity(), is("id1"));
1016 public void defaultFcpClientRecognizesUnknownNodeIdentifiers()
1017 throws InterruptedException, ExecutionException, IOException {
1018 Future<Optional<Peer>> peer = fcpClient.listPeer().byIdentity("id2").execute();
1020 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1021 String identifier = extractIdentifier(lines);
1022 assertThat(lines, matchesFcpMessage(
1024 "Identifier=" + identifier,
1025 "NodeIdentifier=id2",
1028 fcpServer.writeLine(
1029 "UnknownNodeIdentifier",
1030 "Identifier=" + identifier,
1031 "NodeIdentifier=id2",
1034 assertThat(peer.get().isPresent(), is(false));
1038 public void defaultFcpClientCanAddPeerFromFile() throws InterruptedException, ExecutionException, IOException {
1039 Future<Optional<Peer>> peer = fcpClient.addPeer().fromFile(new File("/tmp/ref.txt")).execute();
1041 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1042 String identifier = extractIdentifier(lines);
1043 assertThat(lines, matchesFcpMessage(
1045 "Identifier=" + identifier,
1046 "File=/tmp/ref.txt",
1049 fcpServer.writeLine(
1051 "Identifier=" + identifier,
1054 "ark.pubURI=SSK@3YEf.../ark",
1057 "version=Fred,0.7,1.0,1466",
1058 "lastGoodVersion=Fred,0.7,1.0,1466",
1061 assertThat(peer.get().get().getIdentity(), is("id1"));
1065 public void defaultFcpClientCanAddPeerFromURL() throws InterruptedException, ExecutionException, IOException {
1066 Future<Optional<Peer>> peer = fcpClient.addPeer().fromURL(new URL("http://node.ref/")).execute();
1068 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1069 String identifier = extractIdentifier(lines);
1070 assertThat(lines, matchesFcpMessage(
1072 "Identifier=" + identifier,
1073 "URL=http://node.ref/",
1076 fcpServer.writeLine(
1078 "Identifier=" + identifier,
1081 "ark.pubURI=SSK@3YEf.../ark",
1084 "version=Fred,0.7,1.0,1466",
1085 "lastGoodVersion=Fred,0.7,1.0,1466",
1088 assertThat(peer.get().get().getIdentity(), is("id1"));
1092 public void defaultFcpClientCanAddPeerFromNodeRef() throws InterruptedException, ExecutionException, IOException {
1093 NodeRef nodeRef = new NodeRef();
1094 nodeRef.setIdentity("id1");
1095 nodeRef.setName("name");
1096 nodeRef.setARK(new ARK("public", "1"));
1097 nodeRef.setDSAGroup(new DSAGroup("base", "prime", "subprime"));
1098 nodeRef.setNegotiationTypes(new int[] { 3, 5 });
1099 nodeRef.setPhysicalUDP("1.2.3.4:5678");
1100 nodeRef.setDSAPublicKey("dsa-public");
1101 nodeRef.setSignature("sig");
1102 Future<Optional<Peer>> peer = fcpClient.addPeer().fromNodeRef(nodeRef).execute();
1104 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1105 String identifier = extractIdentifier(lines);
1106 assertThat(lines, matchesFcpMessage(
1108 "Identifier=" + identifier,
1111 "ark.pubURI=public",
1115 "dsaGroup.q=subprime",
1116 "dsaPubKey.y=dsa-public",
1117 "physical.udp=1.2.3.4:5678",
1118 "auth.negTypes=3;5",
1122 fcpServer.writeLine(
1124 "Identifier=" + identifier,
1127 "ark.pubURI=SSK@3YEf.../ark",
1130 "version=Fred,0.7,1.0,1466",
1131 "lastGoodVersion=Fred,0.7,1.0,1466",
1134 assertThat(peer.get().get().getIdentity(), is("id1"));
1138 public void listPeerNotesCanGetPeerNotesByNodeName() throws InterruptedException, ExecutionException, IOException {
1139 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute();
1141 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1142 String identifier = extractIdentifier(lines);
1143 assertThat(lines, matchesFcpMessage(
1145 "NodeIdentifier=Friend1",
1148 fcpServer.writeLine(
1150 "Identifier=" + identifier,
1151 "NodeIdentifier=Friend1",
1152 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1156 fcpServer.writeLine(
1158 "Identifier=" + identifier,
1161 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1162 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1166 public void listPeerNotesReturnsEmptyOptionalWhenNodeIdenfierUnknown()
1167 throws InterruptedException, ExecutionException,
1169 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byName("Friend1").execute();
1171 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1172 String identifier = extractIdentifier(lines);
1173 assertThat(lines, matchesFcpMessage(
1175 "NodeIdentifier=Friend1",
1178 fcpServer.writeLine(
1179 "UnknownNodeIdentifier",
1180 "Identifier=" + identifier,
1181 "NodeIdentifier=Friend1",
1184 assertThat(peerNote.get().isPresent(), is(false));
1188 public void listPeerNotesCanGetPeerNotesByNodeIdentifier()
1189 throws InterruptedException, ExecutionException, IOException {
1190 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byIdentity("id1").execute();
1192 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1193 String identifier = extractIdentifier(lines);
1194 assertThat(lines, matchesFcpMessage(
1196 "NodeIdentifier=id1",
1199 fcpServer.writeLine(
1201 "Identifier=" + identifier,
1202 "NodeIdentifier=id1",
1203 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1207 fcpServer.writeLine(
1209 "Identifier=" + identifier,
1212 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1213 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1217 public void listPeerNotesCanGetPeerNotesByHostNameAndPortNumber()
1218 throws InterruptedException, ExecutionException, IOException {
1219 Future<Optional<PeerNote>> peerNote = fcpClient.listPeerNotes().byHostAndPort("1.2.3.4", 5678).execute();
1221 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1222 String identifier = extractIdentifier(lines);
1223 assertThat(lines, matchesFcpMessage(
1225 "NodeIdentifier=1.2.3.4:5678",
1228 fcpServer.writeLine(
1230 "Identifier=" + identifier,
1231 "NodeIdentifier=id1",
1232 "NoteText=RXhhbXBsZSBUZXh0Lg==",
1236 fcpServer.writeLine(
1238 "Identifier=" + identifier,
1241 assertThat(peerNote.get().get().getNoteText(), is("RXhhbXBsZSBUZXh0Lg=="));
1242 assertThat(peerNote.get().get().getPeerNoteType(), is(1));
1246 public void defaultFcpClientCanEnablePeerByName() throws InterruptedException, ExecutionException, IOException {
1247 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byName("Friend1").execute();
1249 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1250 String identifier = extractIdentifier(lines);
1251 assertThat(lines, matchesFcpMessage(
1253 "Identifier=" + identifier,
1254 "NodeIdentifier=Friend1",
1258 fcpServer.writeLine(
1260 "Identifier=" + identifier,
1261 "NodeIdentifier=Friend1",
1265 assertThat(peer.get().get().getIdentity(), is("id1"));
1269 public void defaultFcpClientCanDisablePeerByName() throws InterruptedException, ExecutionException, IOException {
1270 Future<Optional<Peer>> peer = fcpClient.modifyPeer().disable().byName("Friend1").execute();
1272 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1273 String identifier = extractIdentifier(lines);
1274 assertThat(lines, matchesFcpMessage(
1276 "Identifier=" + identifier,
1277 "NodeIdentifier=Friend1",
1281 fcpServer.writeLine(
1283 "Identifier=" + identifier,
1284 "NodeIdentifier=Friend1",
1288 assertThat(peer.get().get().getIdentity(), is("id1"));
1292 public void defaultFcpClientCanEnablePeerByIdentity() throws InterruptedException, ExecutionException, IOException {
1293 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byIdentity("id1").execute();
1295 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1296 String identifier = extractIdentifier(lines);
1297 assertThat(lines, matchesFcpMessage(
1299 "Identifier=" + identifier,
1300 "NodeIdentifier=id1",
1304 fcpServer.writeLine(
1306 "Identifier=" + identifier,
1307 "NodeIdentifier=Friend1",
1311 assertThat(peer.get().get().getIdentity(), is("id1"));
1315 public void defaultFcpClientCanEnablePeerByHostAndPort()
1316 throws InterruptedException, ExecutionException, IOException {
1317 Future<Optional<Peer>> peer = fcpClient.modifyPeer().enable().byHostAndPort("1.2.3.4", 5678).execute();
1319 List<String> lines = fcpServer.collectUntil(is("EndMessage"));
1320 String identifier = extractIdentifier(lines);
1321 assertThat(lines, matchesFcpMessage(
1323 "Identifier=" + identifier,
1324 "NodeIdentifier=1.2.3.4:5678",
1328 fcpServer.writeLine(
1330 "Identifier=" + identifier,
1331 "NodeIdentifier=Friend1",
1335 assertThat(peer.get().get().getIdentity(), is("id1"));