V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zjp
V2EX  ›  Java

如何编写 Netty 的集成测试?

  •  
  •   zjp ·
    zunpiau · 2018-12-06 22:20:56 +08:00 · 2234 次点击
    这是一个创建于 2205 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Netty 里 UniqueIpFilter 的代码

    public class UniqueIpFilter extends AbstractRemoteAddressFilter<InetSocketAddress> {
    
        private final Set<InetAddress> connected = new ConcurrentSet<InetAddress>();
    
        @Override
        protected boolean accept(ChannelHandlerContext ctx, InetSocketAddress remoteAddress) throws Exception {
            final InetAddress remoteIp = remoteAddress.getAddress();
            if (connected.contains(remoteIp)) {
                return false;
            } else {
                connected.add(remoteIp);
                ctx.channel().closeFuture().addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        connected.remove(remoteIp);
                    }
                });
                return true;
            }
        }
    }
    

    逻辑很简单,就是每次连接建立时判断 set 里是否已经有新连接的远程地址。但多线程下同一个 IP 的两个请求在执行connected.contains(remoteIp)时可能出现同时为false的情况。似乎是个典型的 Test and Set 问题...

    但我现在问题是不知道怎么写测试,搞了大半天了,官方也没有对这个类的测试...不管从客户端还是服务端入手,都找不到合适的时间点验证存在两个相同 IP 的连接

    7 条回复    2018-12-07 14:25:36 +08:00
    zjp
        1
    zjp  
    OP
       2018-12-06 22:49:09 +08:00
    mm163
        2
    mm163  
       2018-12-06 23:04:09 +08:00
    ConcurrentSet 虽然时线程安全的,但是
    if (connected.contains(remoteIp)) {
    return false;
    } else {
    connected.add(remoteIp);
    这几行没有原子化,有可能造成同一个 IP 的两个请求同时 false。
    BBCCBB
        3
    BBCCBB  
       2018-12-06 23:07:16 +08:00   ❤️ 1
    netty 一般是用 EmbeddedChannel 做测试, 你这个不知道用哪个
    zjp
        4
    zjp  
    OP
       2018-12-06 23:25:37 +08:00
    @BBCCBB EmbeddedChannel 只表征一条通道,这里需要一个服务器下的两个连接

    @mm163 是的,但是测试代码 我就只会不断同时建立两个连接,过一段时间看两个是不是都没有被 UniqueIpFilter 掐掉连接...这样测试可能永远结束不了......
    q263397478
        5
    q263397478  
       2018-12-07 10:37:45 +08:00
    不是,accept 处理是单线程的啊,不用担心线程安全问题
    zjp
        6
    zjp  
    OP
       2018-12-07 13:22:56 +08:00
    @BBCCBB 重新看了下 EmbeddedChannel,确实可以用


    @q263397478 UniqueIpFilter 是在 Channel 中共享的
    BBCCBB
        7
    BBCCBB  
       2018-12-07 14:25:36 +08:00
    我猜开多线程用多个 EmbeddedChannel 就可以, 只是这个 uniqueIpFilter 得用同一个
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5250 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:42 · PVG 11:42 · LAX 19:42 · JFK 22:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.