/* * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.openflowjava.protocol.impl.core.connection; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalNotification; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; /** * @author madamjak * */ public class ChannelOutboundQueue02Test { private static int counter; private static final int RPC_RESPONSE_EXPIRATION = 1; private static final RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>> REMOVAL_LISTENER = new RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>>() { @Override public void onRemoval( final RemovalNotification<RpcResponseKey, ResponseExpectedRpcListener<?>> notification) { notification.getValue().discard(); } }; @Mock EchoInput echoInput; @Mock BarrierInput barrierInput; @Mock EchoReplyInput echoReplyInput; @Mock ExperimenterInput experimenterInput; private ConnectionAdapterImpl adapter; private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache; /** * Initialize mocks */ @Before public void setUp() { MockitoAnnotations.initMocks(this); } /** * Disconnect adapter after each test */ @After public void tierDown(){ if (adapter != null && adapter.isAlive()) { adapter.disconnect(); } } /** * Test write to closed / opened channel * @throws Exception */ @Test public void test01() throws Exception { final EmbeddedChannel ec = new EmbeddedChannel(new EmbededChannelHandler()); adapter = new ConnectionAdapterImpl(ec, InetSocketAddress.createUnresolved("localhost", 9876), true); cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) .removalListener(REMOVAL_LISTENER).build(); adapter.setResponseCache(cache); final ChannelOutboundQueue cq = (ChannelOutboundQueue) ec.pipeline().last(); counter=0; adapter.barrier(barrierInput); adapter.echo(echoInput); cq.channelInactive(ec.pipeline().lastContext()); ec.runPendingTasks(); Assert.assertEquals("Wrong - ChannelOutboundHandlerAdapter.write was invoked on closed channel",0, counter); cq.channelActive(ec.pipeline().lastContext()); counter=0; adapter.barrier(barrierInput); adapter.experimenter(experimenterInput); ec.runPendingTasks(); Assert.assertEquals("Wrong - ChannelOutboundHandlerAdapter.write has not been invoked on opened channel",2, counter); } /** * Test write to read only / writable channel */ @Test public void test02(){ final ChangeWritableEmbededChannel ec = new ChangeWritableEmbededChannel(new EmbededChannelHandler()); adapter = new ConnectionAdapterImpl(ec, InetSocketAddress.createUnresolved("localhost", 9876), true); cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) .removalListener(REMOVAL_LISTENER).build(); adapter.setResponseCache(cache); ec.setReadOnly(); counter=0; adapter.barrier(barrierInput); adapter.echo(echoInput); ec.runPendingTasks(); Assert.assertEquals("Wrong - write to readonly channel",0, counter); ec.setWritable(); adapter.echoReply(echoReplyInput); adapter.echo(echoInput); ec.runPendingTasks(); Assert.assertEquals("Wrong - write to writtable channel",4, counter); } /** * Channel Handler for testing * @author madamjak * */ private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { @Override public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) throws Exception { if(msg instanceof MessageListenerWrapper){ counter++; } } } /** * Class for testing - channel can change state to read only or writable * @author madamjak * */ private class ChangeWritableEmbededChannel extends EmbeddedChannel { private boolean isWrittable; public ChangeWritableEmbededChannel(final ChannelHandler channelHandler){ super(channelHandler); setReadOnly(); } @Override public boolean isWritable() { return isWrittable; } public void setWritable(){ isWrittable = true; } public void setReadOnly(){ isWrittable = false; } } }