flink的KeyedBroadcastProcessFunction测试

背景

我们经常需要对KeyedBroadcastProcessFunction函数进行单元测试,以确保上线之前这个函数的功能是正常的,包括里面的广播状态和键值分区状态

测试KeyedBroadcastProcessFunction类

java 复制代码
    @Test
    public void testHarnessForKeyedBroadcastProcessFunction() throws Exception {
        KeyedBroadcastProcessFunction<String, String, String, String> function = new MyKeyedBroadcastProcessFunction();

        // 键值分区状态
        final ValueStateDescriptor<String> valueStateDescriptor =
                new ValueStateDescriptor<>("item", BasicTypeInfo.STRING_TYPE_INFO);
        // 广播状态
        final MapStateDescriptor<String, String> ruleStateDescriptor = new MapStateDescriptor<>("RulesBroadcastState",
                BasicTypeInfo.STRING_TYPE_INFO, BasicTypeInfo.STRING_TYPE_INFO);

        KeyedBroadcastOperatorTestHarness<String, String, String, String> harness =
                ProcessFunctionTestHarnesses.forKeyedBroadcastProcessFunction(function, x -> x,
                        TypeInformation.of(String.class), ruleStateDescriptor);

        harness.processBroadcastElement("0", 1);
        harness.processBroadcastElement("000", 2);
        harness.processElement("1", 10);

        // 判断键值分区状态(注意这里最好就只是某个key下面,也就是分组key直接设置为x->"固定常数值"即可)
        ValueState<String> valueState = function.getRuntimeContext().getState(valueStateDescriptor);
        Assert.assertEquals(valueState.value(), "1");

        // 判断广播状态
        BroadcastState<String, String> broadcastState = harness.getBroadcastState(ruleStateDescriptor);
        Assert.assertTrue(broadcastState.contains("0"));
        Assert.assertTrue(broadcastState.contains("000"));

        // 判断输出的列表
        Assert.assertEquals(harness.extractOutputValues(), Arrays.asList("0", "000", "1"));
    }

关键代码:

1.获取键值分区状态

java 复制代码
ValueState<String> valueState = function.getRuntimeContext().getState(valueStateDescriptor);

2.获取广播状态:

java 复制代码
BroadcastState<String, String> broadcastState = harness.getBroadcastState(ruleStateDescriptor);

3.工具类

java 复制代码
public class ProcessFunctionTestHarnesses {
    public ProcessFunctionTestHarnesses() {
    }

    public static <IN, OUT> OneInputStreamOperatorTestHarness<IN, OUT> forProcessFunction(ProcessFunction<IN, OUT> function) throws Exception {
        OneInputStreamOperatorTestHarness<IN, OUT> testHarness = new OneInputStreamOperatorTestHarness(new ProcessOperator((ProcessFunction)Preconditions.checkNotNull(function)), 1, 1, 0);
        testHarness.setup();
        testHarness.open();
        return testHarness;
    }

    public static <K, IN, OUT> KeyedOneInputStreamOperatorTestHarness<K, IN, OUT> forKeyedProcessFunction(KeyedProcessFunction<K, IN, OUT> function, KeySelector<IN, K> keySelector, TypeInformation<K> keyType) throws Exception {
        KeyedOneInputStreamOperatorTestHarness<K, IN, OUT> testHarness = new KeyedOneInputStreamOperatorTestHarness(new KeyedProcessOperator((KeyedProcessFunction)Preconditions.checkNotNull(function)), keySelector, keyType, 1, 1, 0);
        testHarness.open();
        return testHarness;
    }

    public static <IN1, IN2, OUT> TwoInputStreamOperatorTestHarness<IN1, IN2, OUT> forCoProcessFunction(CoProcessFunction<IN1, IN2, OUT> function) throws Exception {
        TwoInputStreamOperatorTestHarness<IN1, IN2, OUT> testHarness = new TwoInputStreamOperatorTestHarness(new CoProcessOperator((CoProcessFunction)Preconditions.checkNotNull(function)), 1, 1, 0);
        testHarness.open();
        return testHarness;
    }

    public static <K, IN1, IN2, OUT> KeyedTwoInputStreamOperatorTestHarness<K, IN1, IN2, OUT> forKeyedCoProcessFunction(KeyedCoProcessFunction<K, IN1, IN2, OUT> function, KeySelector<IN1, K> keySelector1, KeySelector<IN2, K> keySelector2, TypeInformation<K> keyType) throws Exception {
        KeyedTwoInputStreamOperatorTestHarness<K, IN1, IN2, OUT> testHarness = new KeyedTwoInputStreamOperatorTestHarness(new KeyedCoProcessOperator((KeyedCoProcessFunction)Preconditions.checkNotNull(function)), keySelector1, keySelector2, keyType, 1, 1, 0);
        testHarness.open();
        return testHarness;
    }

    public static <IN1, IN2, OUT> BroadcastOperatorTestHarness<IN1, IN2, OUT> forBroadcastProcessFunction(BroadcastProcessFunction<IN1, IN2, OUT> function, MapStateDescriptor<?, ?>... descriptors) throws Exception {
        BroadcastOperatorTestHarness<IN1, IN2, OUT> testHarness = new BroadcastOperatorTestHarness(new CoBroadcastWithNonKeyedOperator((BroadcastProcessFunction)Preconditions.checkNotNull(function), Arrays.asList(descriptors)), 1, 1, 0);
        testHarness.open();
        return testHarness;
    }

    public static <K, IN1, IN2, OUT> KeyedBroadcastOperatorTestHarness<K, IN1, IN2, OUT> forKeyedBroadcastProcessFunction(KeyedBroadcastProcessFunction<K, IN1, IN2, OUT> function, KeySelector<IN1, K> keySelector, TypeInformation<K> keyType, MapStateDescriptor<?, ?>... descriptors) throws Exception {
        KeyedBroadcastOperatorTestHarness<K, IN1, IN2, OUT> testHarness = new KeyedBroadcastOperatorTestHarness(new CoBroadcastWithKeyedOperator((KeyedBroadcastProcessFunction)Preconditions.checkNotNull(function), Arrays.asList(descriptors)), keySelector, keyType, 1, 1, 0);
        testHarness.open();
        return testHarness;
    }
}
相关推荐
深邃-2 分钟前
【Web安全】-基础环境安装:虚拟机安装,JDK环境安装(1)
java·开发语言·计算机网络·安全·web安全·网络安全·安全架构
小雅痞3 分钟前
[Java][Leetcode hard] 135. 分发糖果
java·算法·leetcode
jwt7939279378 分钟前
Spring之DataSource配置
java·后端·spring
逻辑驱动的ken17 分钟前
Java高频面试场景题07
java·开发语言·面试·职场和发展·求职招聘·春招
slarymusic22 分钟前
解决报错net.sf.jsqlparser.statement.select.SelectBody
java
callJJ24 分钟前
JVM 内存区域划分详解——从生活比喻到运行时数据区全景图
java·jvm·面试·内存区域划分
小江的记录本27 分钟前
【网络安全】《网络安全与数据安全核心知识体系》(包括数据脱敏、数据加密、隐私合规、等保2.0)
java·网络·后端·python·算法·安全·web安全
北漂Zachary28 分钟前
PHP vs Python vs Java:三大编程语言终极对比
java·python·php
Paxon Zhang30 分钟前
JavaEE初阶学习web开发的第一步**计算机组成原理,操作系统,进程(基础扫盲)**
java·后端·学习·java-ee
慕容卡卡33 分钟前
大模型核心,MCP(模型上下文协议)和Session API
java·开发语言·人工智能·spring boot·spring cloud