@@ -81,8 +81,8 @@ void shouldOkWhenAiFlowWithNormalRunnableParallel() {
8181 assertThat (answer1 .toString ()).isEqualTo ("answer question1 from context with my history" );
8282 }
8383
84- @ Test
85- @ DisplayName ("测试 ExampleSelector" )
84+ @ RepeatedTest ( 1000 )
85+ @ DisplayName ("测试 ExampleSelector - 重复运行以复现 NPE " )
8686 void shouldOkWhenAiFlowWithExampleSelector () {
8787 Example [] examples = {new DefaultExample ("2+2" , "4" ), new DefaultExample ("2+3" , "5" )};
8888 Conversation <String , Prompt > converse = AiFlows .<String >create ()
@@ -98,62 +98,6 @@ void shouldOkWhenAiFlowWithExampleSelector() {
9898 assertThat (converse .offer ("1+2" ).await ().text ()).isEqualTo ("2+2=4\n 2+3=5\n 1+2=" );
9999 }
100100
101- @ RepeatedTest (500 )
102- @ DisplayName ("【复现测试】强制触发 runnableParallel 的竞态条件 NPE" )
103- void shouldReproduceNPEInRunnableParallel () {
104- // 慢分支:模拟 fewShot() 的延迟,增大竞态窗口
105- modelengine .fel .engine .operators .patterns .SyncTipper <String > slowBranch = arg -> {
106- try {
107- Thread .sleep (200 ); // 200ms 延迟
108- } catch (InterruptedException e ) {
109- Thread .currentThread ().interrupt ();
110- }
111- return Tip .from ("slow" , "slow-value" );
112- };
113-
114- // 快分支:模拟 question() 的快速返回
115- modelengine .fel .engine .operators .patterns .SyncTipper <String > fastBranch = arg -> {
116- return Tip .from ("fast" , "fast-value" );
117- };
118-
119- // 执行并发聚合
120- Conversation <String , Prompt > converse = AiFlows .<String >create ()
121- .runnableParallel (fastBranch , slowBranch )
122- .prompt (Prompts .human ("{{fast}} {{slow}}" ))
123- .close ()
124- .converse ();
125-
126- // 在修复前:这里应该偶发抛出 NullPointerException
127- // 在修复后:这里应该稳定通过
128- String result = converse .offer ("test" ).await ().text ();
129-
130- assertThat (result ).contains ("fast-value" , "slow-value" );
131- }
132-
133- @ RepeatedTest (500 )
134- @ DisplayName ("【复现测试】使用原测试配置重复运行" )
135- void shouldReproduceOriginalTestFailure () {
136- // 使用原始失败测试的完全相同配置
137- Example [] examples = {new DefaultExample ("2+2" , "4" ), new DefaultExample ("2+3" , "5" )};
138-
139- Conversation <String , Prompt > converse = AiFlows .<String >create ()
140- .runnableParallel (
141- question (),
142- fewShot (ExampleSelector .builder ()
143- .template ("{{q}}={{a}}" , "q" , "a" )
144- .delimiter ("\n " )
145- .example (examples )
146- .build ()))
147- .prompt (Prompts .human ("{{examples}}\n {{question}}=" ))
148- .close ()
149- .converse ();
150-
151- // 在修复前:偶发 NPE
152- // 在修复后:稳定通过
153- assertThat (converse .offer ("1+2" ).await ().text ())
154- .isEqualTo ("2+2=4\n 2+3=5\n 1+2=" );
155- }
156-
157101 @ Test
158102 @ DisplayName ("测试 Retriever" )
159103 void shouldOkWhenAiFlowWithRetriever () {
0 commit comments