package net.tomp2p.holep; import io.netty.channel.ChannelFuture; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import net.tomp2p.futures.BaseFuture; import net.tomp2p.futures.FutureDone; import net.tomp2p.message.Message; import net.tomp2p.message.Message.Type; import net.tomp2p.p2p.Peer; import net.tomp2p.p2p.PeerBuilder; import net.tomp2p.peers.Number160; import net.tomp2p.rpc.RPC.Commands; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @SuppressWarnings("rawtypes") public class TestAbstractHolePuncher { static final int IDLE_UDP_SECONDS = 30; static final int NUMBER_OF_HOLES = 3; // java reflection classes Class noparams[] = {}; Class[] paramCCF = new Class[3]; Class[] paramHPC = new Class[4]; Class[] paramPH = new Class[2]; Peer peer; Peer peer2; Message msg; static final Random RND = new Random(); static final int PORTS = 4000; @Before public void setUp() { // createChannelFutures parameter paramCCF[0] = List.class; paramCCF[1] = FutureDone.class; paramCCF[2] = Integer.TYPE; // HolePuncher constructor parameter paramHPC[0] = Peer.class; paramHPC[1] = Integer.TYPE; paramHPC[2] = Integer.TYPE; paramHPC[3] = Message.class; // prepareHandlers parameter paramPH[0] = Boolean.TYPE; paramPH[1] = FutureDone.class; try { peer = new PeerBuilder(Number160.createHash(RND.nextInt())).ports( PORTS + 1).start(); peer2 = new PeerBuilder(Number160.createHash(RND.nextInt())).ports( PORTS + 1).start(); } catch (IOException e) { e.printStackTrace(); } msg = new Message(); msg.sender(peer.peerAddress()); msg.recipient(peer2.peerAddress()); msg.type(Type.REQUEST_2); msg.command(Commands.DIRECT_DATA.getNr()); } @Test @SuppressWarnings("unchecked") public void testCreateChannelFutures() { AtomicInteger atomic = new AtomicInteger(1); try { Class cls = Class.forName("net.tomp2p.holep.strategy.PortPreservingStrategy"); Constructor constructor = cls.getConstructor(paramHPC); constructor.setAccessible(true); Object obj = constructor.newInstance(peer, NUMBER_OF_HOLES, IDLE_UDP_SECONDS, msg); Method methodCreateChannelFutures = cls.getDeclaredMethod( "createChannelFutures", paramCCF); methodCreateChannelFutures.setAccessible(true); Method methodPrepareHandlers = cls.getDeclaredMethod( "prepareHandlers", paramPH); methodPrepareHandlers.setAccessible(true); FutureDone<Message> fDone1 = new FutureDone<Message>(); try { methodCreateChannelFutures.invoke(obj, null, fDone1, -1); fDone1.awaitUninterruptibly(2000L); if (!fDone1.isSuccess()) { throw new Exception("This must happen"); } // The method call must fail in order to pass the test } catch (Exception e) { atomic.decrementAndGet(); } FutureDone<List<ChannelFuture>> fDone2; try { FutureDone<Message> mainFutureDone = new FutureDone<Message>(); fDone2 = (FutureDone<List<ChannelFuture>>) methodCreateChannelFutures.invoke(obj, methodPrepareHandlers.invoke(obj, true, mainFutureDone), mainFutureDone, NUMBER_OF_HOLES); fDone2.awaitUninterruptibly(); Assert.assertTrue(fDone2.isCompleted()); Assert.assertTrue(fDone2.isSuccess()); Assert.assertEquals(NUMBER_OF_HOLES, fDone2.object().size()); } catch (Exception e) { System.err.println(atomic.incrementAndGet()); } } catch (Exception e) { e.printStackTrace(); } Assert.assertEquals(0, atomic.get()); } @After public void shutdown() { BaseFuture future = null; BaseFuture future2 = null; if (peer != null) { future = peer.shutdown(); } if (peer2 != null) { future2 = peer2.shutdown(); } future.awaitUninterruptibly(); future2.awaitUninterruptibly(); } }