Repository: netty/netty
File: testsuite/src/main/java/io/netty/testsuite/transport/socket/DatagramConnectedWriteExceptionTest.java (Java)

Code before:
import java.net.PortUnreachableException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class DatagramConnectedWriteExceptionTest extends AbstractClientSocketTest {

    @Override
    protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
        return SocketTestPermutation.INSTANCE.datagramSocket();
    }

    @Test
    @Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
    public void testWriteThrowsPortUnreachableException(TestInfo testInfo) throws Throwable {
        run(testInfo, (Runner<Bootstrap>) this::testWriteExceptionAfterServerStop);
    }

    protected void testWriteExceptionAfterServerStop(Bootstrap clientBootstrap) throws Throwable {
        CountDownLatch serverReceivedLatch = new CountDownLatch(1);
        Bootstrap serverBootstrap = new Bootstrap()
                .group(clientBootstrap.config().group())
                .channel(clientBootstrap.config().channelFactory().newChannel().getClass())
                .option(ChannelOption.SO_BROADCAST, false)
                .handler(new SimpleChannelInboundHandler<DatagramPacket>() {

                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
                        serverReceivedLatch.countDown();
                    }
                });

        Channel serverChannel = serverBootstrap.bind(new InetSocketAddress(NetUtil.LOCALHOST, 0)).sync().channel();
        InetSocketAddress serverAddress = (InetSocketAddress) serverChannel.localAddress();

        clientBootstrap.option(ChannelOption.AUTO_READ, false)
                .handler(new SimpleChannelInboundHandler<DatagramPacket>() {

                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
                        // no-op
                    }

                    @Override
                    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
                        ctx.fireExceptionCaught(cause);

Review comment (suggestion):
You could also just use `clientBootstrap.clone()` and only set the things that differ on the cloned bootstrap. 

Code after:

import java.net.InetSocketAddress;
import java.net.PortUnreachableException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class DatagramConnectedWriteExceptionTest extends AbstractClientSocketTest {

    @Override
    protected List<TestsuitePermutation.BootstrapFactory<Bootstrap>> newFactories() {
        return SocketTestPermutation.INSTANCE.datagramSocket();
    }

    @Test
    @Timeout(value = 10000, unit = TimeUnit.MILLISECONDS)
    @DisabledOnOs(OS.WINDOWS)
    public void testWriteThrowsPortUnreachableException(TestInfo testInfo) throws Throwable {
        run(testInfo, (Runner<Bootstrap>) this::testWriteExceptionAfterServerStop);
    }

    protected void testWriteExceptionAfterServerStop(Bootstrap clientBootstrap) throws Throwable {
        CountDownLatch serverReceivedLatch = new CountDownLatch(1);
        Bootstrap serverBootstrap = clientBootstrap.clone()
                .option(ChannelOption.SO_BROADCAST, false)
                .handler(new SimpleChannelInboundHandler<DatagramPacket>() {

                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
                        serverReceivedLatch.countDown();
                    }
                });

        Channel serverChannel = serverBootstrap.bind(new InetSocketAddress(NetUtil.LOCALHOST, 0)).sync().channel();
        InetSocketAddress serverAddress = (InetSocketAddress) serverChannel.localAddress();

        clientBootstrap.option(ChannelOption.AUTO_READ, false)
                .handler(new SimpleChannelInboundHandler<DatagramPacket>() {

                    @Override
                    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) {
                        // no-op
                    }
                });

        Channel clientChannel = clientBootstrap.connect(serverAddress).sync().channel();