flink对状态ttl进行单元测试

背景

在处理键值分区状态时,使用ttl设置过期时间是我们经常使用的,但是任何代码的修改都需要首先进行单元测试,本文就使用单元测试来验证一下状态ttl的设置是否正确

测试状态ttl超时的单元测试

首先看一下处理函数:

java 复制代码
// 处理函数
public class MyStateProcessFunction extends KeyedProcessFunction<String, String, String> {
 
    // 键值分区状态
    ValueState<String> previousInput;
 
    @Override
    public void open(Configuration parameters) throws Exception {
        ValueStateDescriptor stateDescriptor = new ValueStateDescriptor<String>("previousInput", Types.STRING);
        // 状态ttl超时时间设置
        StateTtlConfig ttlConfig =
                StateTtlConfig.newBuilder(Time.minutes(1)).setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
                        .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
                        // check 10 keys for every state access
                        .cleanupIncrementally(10, false).build();
        stateDescriptor.enableTimeToLive(ttlConfig);
        previousInput = getRuntimeContext().getState(stateDescriptor);
    }
 
    @Override
    public void processElement(String in, Context context, Collector<String> collector) throws Exception {
        context.timerService().registerProcessingTimeTimer(100);
        String out = (Objects.nonNull(previousInput.value()) ? previousInput.value() : "") + in;
        collector.collect(out);
        if (!in.contains("NotUpdate")) {// 为了模仿有访问状态,但是不更新状态,正常情况下业务逻辑是访问其他key组的其它state,而一直没有访问的key的状态会在超时时间到之后被清理掉
            previousInput.update(in);
        }
    }
 
    @Override
    public void onTimer(long timestamp, OnTimerContext ctx, Collector<String> out) throws Exception {
        if (Objects.nonNull(previousInput.value())) {
            out.collect(String.format("timer trigger %s", previousInput.value()));
        } else {
            out.collect(String.format("timer trigger state clear", previousInput.value()));
        }
    }
 
}

单元测试代码:

java 复制代码
/**
 * 测试状态处理函数,包含状态的ttl配置,以及ontimer方法
 **/
@Test
public void testKeyedStateProcessFunction() throws Exception {
    MyStateProcessFunction myStateProcessFunction = new MyStateProcessFunction();
    OneInputStreamOperatorTestHarness<String, String> testHarness =
            ProcessFunctionTestHarnesses.forKeyedProcessFunction(myStateProcessFunction, x -> "1", Types.STRING);
    testHarness.open();
    testHarness.processElement("hello", 10);
    // 注册了一个定时器,定时器100后过期
    Assert.assertEquals(1, testHarness.numProcessingTimeTimers());
    // 测试输出
    Assert.assertEquals(Lists.newArrayList("hello"), testHarness.extractOutputValues());
    ValueState<String> previousInput = myStateProcessFunction.getRuntimeContext()
            .getState(new ValueStateDescriptor<>("previousInput", Types.STRING));
    // 查看下状态应该已经被设置
    Assert.assertEquals("hello", previousInput.value());
 
    testHarness.processElement("world", 10);
    // 再次测试输出
    Assert.assertEquals(Lists.newArrayList("hello", "helloworld"), testHarness.extractOutputValues());
    // 再次查看下状态应该已经被设置
    Assert.assertEquals("world", previousInput.value());
 
    // 设置时间为1分钟,让状态超时
    testHarness.setStateTtlProcessingTime(Time.minutes(1).toMilliseconds());
    // 触发下状态访问,这样flink就会清理,正常生产中不需要这一步,访问状态本来就一直在进行中,只是可能是其他key分组的状态
    testHarness.processElement("NotUpdate1", System.currentTimeMillis());
    // 查看下状态应该已经被清理
    Assert.assertNull(previousInput.value());
 
    // 设置让定时器过期,顺带确认下状态已经被清理
    testHarness.setProcessingTime(100);
 
    // 测试输出(包含两个输入+一个定时器的输出)
    Assert.assertEquals(Lists.newArrayList("hello", "helloworld", "NotUpdate1", "timer trigger state clear"),
            testHarness.extractOutputValues());
    testHarness.close();
}

测试代码中已经包含了详细的注解,我们实现自己的ttl单元测试时可以参考下

相关推荐
Hello.Reader17 小时前
Flink 自适应批执行(Adaptive Batch Execution)让 Batch 作业“边跑边优化”
大数据·flink·batch
Warren9820 小时前
Pytest Fixture 作用域详解:Function、Class、Module、Session 怎么选
面试·职场和发展·单元测试·pytest·pip·模块测试·jira
愤怒的苹果ext1 天前
flink-sql-connector-elasticsearch8兼容Flink SQL同步到Elasticsearch8.18.8
sql·flink·es8
CTO Plus技术服务中2 天前
Flink运维与开发教程
大数据·运维·flink
Hello.Reader2 天前
Flink CLI 从提交作业到 Savepoint/Checkpoint、再到 YARN/K8S 与 PyFlink
大数据·flink·kubernetes
Hello.Reader2 天前
Flink 弹性伸缩(Elastic Scaling)Adaptive Scheduler、Reactive Mode 与外部资源声明
服务器·网络·flink
一晌小贪欢2 天前
Python 测试利器:使用 pytest 高效编写和管理单元测试
python·单元测试·pytest·python3·python测试
汽车仪器仪表相关领域3 天前
MTX-A 模拟废气温度(EGT)计 核心特性与车载实操指南
网络·人工智能·功能测试·单元测试·汽车·可用性测试
zhangxl-jc3 天前
StreamPark2.1.7 添加Flink Home 报错 base64 character 2d 解决方法
大数据·flink
卓码软件测评3 天前
第三方软件课题验收测试【使用Docker容器部署LoadRunner负载生成器以实现弹性压测 】
测试工具·docker·容器·性能优化·单元测试·测试用例