/* * The MIT License * * Copyright 2014 sorrge. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.nyan.dch.communication; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import static org.junit.Assert.*; import org.junit.Test; import org.nyan.dch.crypto.SHA256Hash; import org.nyan.dch.node.IRemoteNode; import org.nyan.dch.node.IRemoteResponseListener; import org.nyan.dch.posts.Board; import org.nyan.dch.posts.Post; import org.nyan.dch.posts.PostData; import org.nyan.dch.posts.Thread; import org.nyan.dch.posts.StorageTest; /** * * @author sorrge */ public class MessagesTest { static class TestListener implements IRemoteResponseListener { RemoteNodeMessages.MessageTypes type; PostData post; ArrayList<SHA256Hash> hashes = new ArrayList<>(); String board; SHA256Hash thread; @Override public void PostReceived(IRemoteNode node, PostData post) { type = RemoteNodeMessages.MessageTypes.PushPost; this.post = post; } @Override public void OnlineStatusChanged(IRemoteNode node, boolean isOnline, boolean iAmInitiator) { } @Override public void UpdateThreadsAndSendOthers(IRemoteNode node, String board, Collection<SHA256Hash> myThreads) { type = RemoteNodeMessages.MessageTypes.UpdateThreadsAndGetOthers; this.board = board; hashes.addAll(myThreads); } @Override public void SendOtherPostsInThread(IRemoteNode node, String board, SHA256Hash threadId, Collection<SHA256Hash> myPosts) { type = RemoteNodeMessages.MessageTypes.GetOtherPostsInThread; this.board = board; this.thread = threadId; hashes.addAll(myPosts); } @Override public void SendPosts(IRemoteNode node, Collection<SHA256Hash> postsNeeded) { type = RemoteNodeMessages.MessageTypes.PullPosts; hashes.addAll(postsNeeded); } } class TestConnections implements IConnections { @Override public boolean AddAddress(IAddress address) { return false; } @Override public void Connected(IRemoteHost host, boolean iAmTheInitiator) { } @Override public void Disconnected(IRemoteHost host) { } @Override public void ConnectionFailed(IAddress host) { } @Override public INetworkTransport GetTransport() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void AddressSupplied(IRemoteHost host, IAddress address, long cookie, boolean wandAcceptanceConfirmation) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } } class Loopback implements IRemoteHost { byte[] sentData; IRemoteHostListener node; @Override public void SendData(byte[] data) { sentData = data; assert(sentData.length <= RemoteNodeMessages.MaxMessageSize); try { node.ReceiveData(data); } catch (ProtocolException ex) { fail(); } } @Override public void SetReceiveListener(IRemoteHostListener node) { this.node = node; } @Override public IAddress GetAddress() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void Disconnect() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void SetAddress(IAddress address, long cookie) { } @Override public long GetCookie() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } } /** * Test of EncodePushPost method, of class Messages. * @throws java.lang.Exception */ @Test public void testEncodePushPost() throws Exception { Random rand = new Random(12); ArrayList<Post> posts = StorageTest.GenerateStream(10000, rand, 100, "b", "e", "d"); Loopback h = new Loopback(); RemoteNodeMessages n = new RemoteNodeMessages(h, new TestConnections()); h.SetReceiveListener(n); TestListener l = new TestListener(); n.SetResponseListener(l, true); for(Post p : posts) { n.PushPost(p.GetData()); assert(l.type == RemoteNodeMessages.MessageTypes.PushPost); assert(new Post(l.post).equals(p)); } } /** * Test of EncodePullPosts method, of class Messages. */ @Test public void testEncodePullPosts() throws Exception { Random rand = new Random(12); int numHashes = 100000; ArrayList<SHA256Hash> hashes = GenerateHashes(numHashes, rand); Loopback h = new Loopback(); RemoteNodeMessages n = new RemoteNodeMessages(h, new TestConnections()); h.SetReceiveListener(n); TestListener l = new TestListener(); n.SetResponseListener(l, true); n.PullPosts(hashes); assert(l.type == RemoteNodeMessages.MessageTypes.PullPosts); assert(l.hashes.equals(hashes)); } private ArrayList<SHA256Hash> GenerateHashes(int numHashes, Random rand) { ArrayList<SHA256Hash> hashes = new ArrayList<>(numHashes); for(int i = 0; i < numHashes; ++i) { byte[] hash = new byte[SHA256Hash.BytesLength]; rand.nextBytes(hash); hashes.add(new SHA256Hash(hash)); } return hashes; } /** * Test of EncodeUpdateThreadsAndGetOthers method, of class Messages. */ @Test public void testEncodeUpdateThreadsAndGetOthers() throws Exception { Random rand = new Random(12); ArrayList<SHA256Hash> hashes = GenerateHashes(Board.MaxThreads, rand); Loopback h = new Loopback(); RemoteNodeMessages n = new RemoteNodeMessages(h, new TestConnections()); h.SetReceiveListener(n); TestListener l = new TestListener(); n.SetResponseListener(l, true); n.UpdateThreadsAndGetOthers("b", hashes); assert(l.type == RemoteNodeMessages.MessageTypes.UpdateThreadsAndGetOthers); assert(l.board.equals("b")); assert(l.hashes.equals(hashes)); } /** * Test of EncodeGetOtherPostsInThread method, of class Messages. */ @Test public void testEncodeGetOtherPostsInThread() throws Exception { Random rand = new Random(12); int numPosts = Thread.MaxPosts * 5; ArrayList<SHA256Hash> hashes = GenerateHashes(numPosts, rand); SHA256Hash thread = hashes.get(numPosts - 1); hashes.remove(numPosts - 1); Loopback h = new Loopback(); RemoteNodeMessages n = new RemoteNodeMessages(h, new TestConnections()); h.SetReceiveListener(n); TestListener l = new TestListener(); n.SetResponseListener(l, true); n.GetOtherPostsInThread("b", thread, hashes); assert(l.type == RemoteNodeMessages.MessageTypes.GetOtherPostsInThread); assert(l.board.equals("b")); assert(l.thread.equals(thread)); assert(l.hashes.equals(hashes)); } }