Skip to content

Commit 232437a

Browse files
committed
tests for seq and parallel agenic exec
Signed-off-by: Dmitrii Tikhomirov <[email protected]>
1 parent 1241aa2 commit 232437a

File tree

2 files changed

+171
-0
lines changed

2 files changed

+171
-0
lines changed

fluent/agentic/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@
6060
<scope>test</scope>
6161
<version>1.2.0-SNAPSHOT</version>
6262
</dependency>
63+
<dependency>
64+
<groupId>io.serverlessworkflow</groupId>
65+
<artifactId>serverlessworkflow-experimental-lambda</artifactId>
66+
<version>${project.version}</version>
67+
<scope>test</scope>
68+
</dependency>
6369
</dependencies>
6470

6571
</project>
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Copyright 2020-Present The Serverless Workflow Specification Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.serverlessworkflow.fluent.agentic;
18+
19+
import static io.serverlessworkflow.fluent.agentic.Agents.*;
20+
import static org.junit.jupiter.api.Assertions.assertEquals;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
22+
import static org.mockito.ArgumentMatchers.eq;
23+
import static org.mockito.Mockito.mock;
24+
import static org.mockito.Mockito.when;
25+
26+
import io.serverlessworkflow.api.types.Workflow;
27+
import io.serverlessworkflow.impl.WorkflowApplication;
28+
import java.util.HashMap;
29+
import java.util.List;
30+
import java.util.Map;
31+
import java.util.Set;
32+
import java.util.concurrent.ExecutionException;
33+
import java.util.function.Function;
34+
import java.util.stream.Collectors;
35+
import org.junit.jupiter.api.Test;
36+
37+
class WorkflowTests {
38+
39+
@Test
40+
public void testSequence() throws ExecutionException, InterruptedException {
41+
final StorySeedAgent storySeedAgent = mock(StorySeedAgent.class);
42+
final PlotAgent plotAgent = mock(PlotAgent.class);
43+
final SceneAgent sceneAgent = mock(SceneAgent.class);
44+
45+
when(storySeedAgent.invoke(eq("A Great Story"))).thenReturn("storySeedAgent");
46+
when(storySeedAgent.outputName()).thenReturn("premise");
47+
48+
when(plotAgent.invoke(eq("storySeedAgent"))).thenReturn("plotAgent");
49+
when(plotAgent.outputName()).thenReturn("plot");
50+
51+
when(sceneAgent.invoke(eq("plotAgent"))).thenReturn("plotAgent");
52+
when(sceneAgent.outputName()).thenReturn("story");
53+
54+
Workflow workflow =
55+
AgentWorkflowBuilder.workflow("storyFlow")
56+
.tasks(d -> d.sequence("story", storySeedAgent, plotAgent, sceneAgent))
57+
.build();
58+
59+
Map<String, String> topic = new HashMap<>();
60+
topic.put("title", "A Great Story");
61+
62+
try (WorkflowApplication app = WorkflowApplication.builder().build()) {
63+
String result =
64+
app.workflowDefinition(workflow).instance(topic).start().get().asText().orElseThrow();
65+
66+
assertEquals("plotAgent", result);
67+
}
68+
}
69+
70+
@Test
71+
public void testParallel() throws ExecutionException, InterruptedException {
72+
73+
final SettingAgent setting = mock(SettingAgent.class);
74+
final HeroAgent hero = mock(HeroAgent.class);
75+
final ConflictAgent conflict = mock(ConflictAgent.class);
76+
77+
when(setting.invoke(eq("sci-fi"))).thenReturn("Fake conflict response");
78+
when(setting.outputName()).thenReturn("setting");
79+
80+
when(hero.invoke(eq("sci-fi"))).thenReturn("Fake hero response");
81+
when(hero.outputName()).thenReturn("hero");
82+
83+
when(conflict.invoke(eq("sci-fi"))).thenReturn("Fake setting response");
84+
when(conflict.outputName()).thenReturn("conflict");
85+
86+
Workflow workflow =
87+
AgentWorkflowBuilder.workflow("parallelFlow")
88+
.tasks(d -> d.parallel("story", setting, hero, conflict))
89+
.build();
90+
91+
Map<String, String> topic = new HashMap<>();
92+
topic.put("style", "sci-fi");
93+
94+
try (WorkflowApplication app = WorkflowApplication.builder().build()) {
95+
Map<String, Object> result =
96+
app.workflowDefinition(workflow).instance(topic).start().get().asMap().orElseThrow();
97+
98+
assertEquals(3, result.size());
99+
assertTrue(result.containsKey("branch-0-story"));
100+
assertTrue(result.containsKey("branch-1-story"));
101+
assertTrue(result.containsKey("branch-2-story"));
102+
103+
Set<String> values =
104+
result.values().stream().map(Object::toString).collect(Collectors.toSet());
105+
106+
assertTrue(values.contains("Fake conflict response"));
107+
assertTrue(values.contains("Fake hero response"));
108+
assertTrue(values.contains("Fake setting response"));
109+
}
110+
}
111+
112+
@Test
113+
// TODO: callFn must be replace with a .output() method once it's available
114+
public void testSeqAndThenParallel() throws ExecutionException, InterruptedException {
115+
final FactAgent factAgent = mock(FactAgent.class);
116+
final CultureAgent cultureAgent = mock(CultureAgent.class);
117+
final TechnologyAgent technologyAgent = mock(TechnologyAgent.class);
118+
119+
List<String> cultureTraits =
120+
List.of("Alien Culture Trait 1", "Alien Culture Trait 2", "Alien Culture Trait 3");
121+
122+
List<String> technologyTraits =
123+
List.of("Alien Technology Trait 1", "Alien Technology Trait 2", "Alien Technology Trait 3");
124+
125+
when(factAgent.invoke(eq("alien"))).thenReturn("Some Fact about aliens");
126+
when(factAgent.outputName()).thenReturn("fact");
127+
128+
when(cultureAgent.invoke(eq("Some Fact about aliens"))).thenReturn(cultureTraits);
129+
when(cultureAgent.outputName()).thenReturn("culture");
130+
131+
when(technologyAgent.invoke(eq("Some Fact about aliens"))).thenReturn(technologyTraits);
132+
when(technologyAgent.outputName()).thenReturn("technology");
133+
Workflow workflow =
134+
AgentWorkflowBuilder.workflow("alienCultureFlow")
135+
.tasks(
136+
d ->
137+
d.sequence("fact", factAgent)
138+
.callFn(
139+
f ->
140+
f.function(
141+
(Function<String, Map<String, String>>)
142+
fact -> {
143+
Map<String, String> result = new HashMap<>();
144+
result.put("fact", fact);
145+
return result;
146+
}))
147+
.parallel("cultureAndTechnology", cultureAgent, technologyAgent))
148+
.build();
149+
150+
Map<String, String> topic = new HashMap<>();
151+
topic.put("fact", "alien");
152+
153+
try (WorkflowApplication app = WorkflowApplication.builder().build()) {
154+
Map<String, Object> result =
155+
app.workflowDefinition(workflow).instance(topic).start().get().asMap().orElseThrow();
156+
157+
assertEquals(2, result.size());
158+
assertTrue(result.containsKey("branch-0-cultureAndTechnology"));
159+
assertTrue(result.containsKey("branch-1-cultureAndTechnology"));
160+
161+
assertEquals(cultureTraits, result.get("branch-0-cultureAndTechnology"));
162+
assertEquals(technologyTraits, result.get("branch-1-cultureAndTechnology"));
163+
}
164+
}
165+
}

0 commit comments

Comments
 (0)