@temporalio/core-bridge 0.17.2 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/Cargo.lock +339 -226
  2. package/Cargo.toml +7 -3
  3. package/common.js +50 -0
  4. package/index.d.ts +7 -0
  5. package/index.js +12 -0
  6. package/package.json +7 -4
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/{index.node → releases/index.node} +0 -0
  10. package/releases/x86_64-apple-darwin/index.node +0 -0
  11. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  12. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  13. package/scripts/build.js +10 -50
  14. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  15. package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
  16. package/sdk-core/.buildkite/pipeline.yml +2 -0
  17. package/sdk-core/Cargo.toml +1 -88
  18. package/sdk-core/README.md +30 -6
  19. package/sdk-core/bridge-ffi/Cargo.toml +24 -0
  20. package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
  21. package/sdk-core/bridge-ffi/build.rs +25 -0
  22. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
  23. package/sdk-core/bridge-ffi/src/lib.rs +829 -0
  24. package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
  25. package/sdk-core/client/Cargo.toml +32 -0
  26. package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
  27. package/sdk-core/client/src/metrics.rs +89 -0
  28. package/sdk-core/client/src/mocks.rs +167 -0
  29. package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
  30. package/sdk-core/core/Cargo.toml +96 -0
  31. package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
  32. package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
  33. package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
  34. package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
  35. package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
  36. package/sdk-core/{src → core/src}/core_tests/queries.rs +45 -52
  37. package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
  38. package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
  39. package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
  40. package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +264 -286
  41. package/sdk-core/core/src/lib.rs +374 -0
  42. package/sdk-core/{src → core/src}/log_export.rs +3 -27
  43. package/sdk-core/core/src/pending_activations.rs +162 -0
  44. package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
  45. package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
  46. package/sdk-core/core/src/protosext/mod.rs +396 -0
  47. package/sdk-core/core/src/replay/mod.rs +210 -0
  48. package/sdk-core/core/src/retry_logic.rs +144 -0
  49. package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
  50. package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
  51. package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
  52. package/sdk-core/{src → core/src}/test_help/mod.rs +34 -73
  53. package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
  55. package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
  56. package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
  57. package/sdk-core/{src → core/src}/worker/mod.rs +305 -195
  58. package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
  59. package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
  60. package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
  61. package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
  62. package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
  63. package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
  64. package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
  65. package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +19 -21
  66. package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
  67. package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
  68. package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
  69. package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
  70. package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
  71. package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
  72. package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
  73. package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
  74. package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
  75. package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
  76. package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
  77. package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
  78. package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
  79. package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +344 -160
  80. package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
  81. package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
  82. package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
  83. package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
  84. package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +297 -81
  85. package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
  86. package/sdk-core/{src → core-api/src}/errors.rs +42 -90
  87. package/sdk-core/core-api/src/lib.rs +158 -0
  88. package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
  89. package/sdk-core/etc/deps.svg +156 -0
  90. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
  92. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
  93. package/sdk-core/histories/fail_wf_task.bin +0 -0
  94. package/sdk-core/histories/timer_workflow_history.bin +0 -0
  95. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
  96. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
  97. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
  98. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
  99. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
  100. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
  101. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
  102. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
  103. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
  104. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  105. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
  106. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
  107. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
  108. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
  109. package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  110. package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
  111. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
  112. package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
  113. package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
  114. package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
  115. package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
  116. package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  117. package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
  118. package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
  119. package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
  120. package/sdk-core/sdk/Cargo.toml +32 -0
  121. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
  122. package/sdk-core/sdk/src/lib.rs +699 -0
  123. package/sdk-core/sdk/src/payload_converter.rs +11 -0
  124. package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
  125. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
  126. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
  127. package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
  128. package/sdk-core/sdk-core-protos/build.rs +28 -6
  129. package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  130. package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
  131. package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
  132. package/sdk-core/sdk-core-protos/src/lib.rs +594 -168
  133. package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  134. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  135. package/sdk-core/test-utils/Cargo.toml +32 -0
  136. package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
  137. package/sdk-core/test-utils/src/histfetch.rs +28 -0
  138. package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
  139. package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
  140. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
  141. package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
  142. package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
  143. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
  144. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
  145. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
  146. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
  147. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
  148. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
  149. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
  150. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
  151. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
  152. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
  153. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
  154. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
  155. package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
  156. package/sdk-core/tests/load_tests.rs +6 -6
  157. package/sdk-core/tests/main.rs +2 -2
  158. package/src/conversions.rs +24 -21
  159. package/src/errors.rs +8 -0
  160. package/src/lib.rs +323 -211
  161. package/sdk-core/protos/local/activity_result.proto +0 -46
  162. package/sdk-core/protos/local/activity_task.proto +0 -66
  163. package/sdk-core/src/core_tests/retry.rs +0 -147
  164. package/sdk-core/src/lib.rs +0 -403
  165. package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
  166. package/sdk-core/src/pending_activations.rs +0 -249
  167. package/sdk-core/src/protosext/mod.rs +0 -160
  168. package/sdk-core/src/prototype_rust_sdk.rs +0 -412
  169. package/sdk-core/src/task_token.rs +0 -20
  170. package/sdk-core/src/test_help/history_info.rs +0 -158
@@ -1,15 +1,15 @@
1
1
  use crate::{
2
2
  errors::PollWfError,
3
3
  job_assert,
4
- pollers::MockServerGatewayApis,
4
+ replay::TestHistoryBuilder,
5
5
  test_help::{
6
6
  build_fake_core, build_mock_pollers, build_multihist_mock_sg, canned_histories,
7
7
  gen_assert_and_fail, gen_assert_and_reply, hist_to_poll_resp, mock_core, poll_and_reply,
8
8
  poll_and_reply_clears_outstanding_evicts, single_hist_mock_sg, FakeWfResponses,
9
- MockPollCfg, MocksHolder, ResponseType, TestHistoryBuilder, NO_MORE_WORK_ERROR_MSG, TEST_Q,
9
+ MockPollCfg, MocksHolder, ResponseType, NO_MORE_WORK_ERROR_MSG, TEST_Q,
10
10
  },
11
11
  workflow::WorkflowCachingPolicy::{self, AfterEveryReply, NonSticky},
12
- Core, CoreSDK, WfActivationCompletion,
12
+ Core, CoreSDK, WorkflowActivationCompletion,
13
13
  };
14
14
  use rstest::{fixture, rstest};
15
15
  use std::{
@@ -17,16 +17,17 @@ use std::{
17
17
  sync::atomic::{AtomicU64, AtomicUsize, Ordering},
18
18
  time::Duration,
19
19
  };
20
+ use temporal_client::mocks::mock_gateway;
20
21
  use temporal_sdk_core_protos::{
21
22
  coresdk::{
22
- activity_result::{self as ar, activity_result, ActivityResult},
23
+ activity_result::{self as ar, activity_resolution, ActivityResolution},
23
24
  workflow_activation::{
24
- wf_activation_job, FireTimer, ResolveActivity, StartWorkflow, UpdateRandomSeed,
25
- WfActivationJob,
25
+ workflow_activation_job, FireTimer, ResolveActivity, StartWorkflow, UpdateRandomSeed,
26
+ WorkflowActivationJob,
26
27
  },
27
28
  workflow_commands::{
28
29
  ActivityCancellationType, CancelTimer, CompleteWorkflowExecution,
29
- FailWorkflowExecution, RequestCancelActivity, ScheduleActivity, StartTimer,
30
+ FailWorkflowExecution, RequestCancelActivity, ScheduleActivity,
30
31
  },
31
32
  },
32
33
  temporal::api::{
@@ -36,7 +37,7 @@ use temporal_sdk_core_protos::{
36
37
  workflowservice::v1::RespondWorkflowTaskCompletedResponse,
37
38
  },
38
39
  };
39
- use test_utils::fanout_tasks;
40
+ use temporal_sdk_core_test_utils::{fanout_tasks, start_timer_cmd};
40
41
 
41
42
  #[fixture(hist_batches = &[])]
42
43
  fn single_timer_setup(hist_batches: &'static [usize]) -> CoreSDK {
@@ -74,15 +75,11 @@ async fn single_timer(#[case] core: CoreSDK, #[case] evict: WorkflowCachingPolic
74
75
  evict,
75
76
  &[
76
77
  gen_assert_and_reply(
77
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
78
- vec![StartTimer {
79
- seq: 1,
80
- ..Default::default()
81
- }
82
- .into()],
78
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
79
+ vec![start_timer_cmd(1, Duration::from_secs(1))],
83
80
  ),
84
81
  gen_assert_and_reply(
85
- &job_assert!(wf_activation_job::Variant::FireTimer(_)),
82
+ &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
86
83
  vec![CompleteWorkflowExecution { result: None }.into()],
87
84
  ),
88
85
  ],
@@ -103,7 +100,7 @@ async fn single_activity_completion(core: CoreSDK) {
103
100
  NonSticky,
104
101
  &[
105
102
  gen_assert_and_reply(
106
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
103
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
107
104
  vec![ScheduleActivity {
108
105
  activity_id: "fake_activity".to_string(),
109
106
  ..Default::default()
@@ -111,7 +108,7 @@ async fn single_activity_completion(core: CoreSDK) {
111
108
  .into()],
112
109
  ),
113
110
  gen_assert_and_reply(
114
- &job_assert!(wf_activation_job::Variant::ResolveActivity(_)),
111
+ &job_assert!(workflow_activation_job::Variant::ResolveActivity(_)),
115
112
  vec![CompleteWorkflowExecution { result: None }.into()],
116
113
  ),
117
114
  ],
@@ -137,18 +134,10 @@ async fn parallel_timer_test_across_wf_bridge(hist_batches: &'static [usize]) {
137
134
  NonSticky,
138
135
  &[
139
136
  gen_assert_and_reply(
140
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
137
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
141
138
  vec![
142
- StartTimer {
143
- seq: timer_1_id,
144
- ..Default::default()
145
- }
146
- .into(),
147
- StartTimer {
148
- seq: timer_2_id,
149
- ..Default::default()
150
- }
151
- .into(),
139
+ start_timer_cmd(timer_1_id, Duration::from_secs(1)),
140
+ start_timer_cmd(timer_2_id, Duration::from_secs(1)),
152
141
  ],
153
142
  ),
154
143
  gen_assert_and_reply(
@@ -156,13 +145,13 @@ async fn parallel_timer_test_across_wf_bridge(hist_batches: &'static [usize]) {
156
145
  assert_matches!(
157
146
  res.jobs.as_slice(),
158
147
  [
159
- WfActivationJob {
160
- variant: Some(wf_activation_job::Variant::FireTimer(
148
+ WorkflowActivationJob {
149
+ variant: Some(workflow_activation_job::Variant::FireTimer(
161
150
  FireTimer { seq: t1_id }
162
151
  )),
163
152
  },
164
- WfActivationJob {
165
- variant: Some(wf_activation_job::Variant::FireTimer(
153
+ WorkflowActivationJob {
154
+ variant: Some(workflow_activation_job::Variant::FireTimer(
166
155
  FireTimer { seq: t2_id }
167
156
  )),
168
157
  }
@@ -197,22 +186,14 @@ async fn timer_cancel(hist_batches: &'static [usize]) {
197
186
  NonSticky,
198
187
  &[
199
188
  gen_assert_and_reply(
200
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
189
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
201
190
  vec![
202
- StartTimer {
203
- seq: cancel_timer_id,
204
- ..Default::default()
205
- }
206
- .into(),
207
- StartTimer {
208
- seq: timer_id,
209
- ..Default::default()
210
- }
211
- .into(),
191
+ start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
192
+ start_timer_cmd(timer_id, Duration::from_secs(1)),
212
193
  ],
213
194
  ),
214
195
  gen_assert_and_reply(
215
- &job_assert!(wf_activation_job::Variant::FireTimer(_)),
196
+ &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
216
197
  vec![
217
198
  CancelTimer {
218
199
  seq: cancel_timer_id,
@@ -242,7 +223,7 @@ async fn scheduled_activity_cancellation_try_cancel(hist_batches: &'static [usiz
242
223
  NonSticky,
243
224
  &[
244
225
  gen_assert_and_reply(
245
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
226
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
246
227
  vec![ScheduleActivity {
247
228
  seq: activity_seq,
248
229
  activity_id: activity_id.to_string(),
@@ -252,12 +233,12 @@ async fn scheduled_activity_cancellation_try_cancel(hist_batches: &'static [usiz
252
233
  .into()],
253
234
  ),
254
235
  gen_assert_and_reply(
255
- &job_assert!(wf_activation_job::Variant::SignalWorkflow(_)),
236
+ &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
256
237
  vec![RequestCancelActivity { seq: activity_seq }.into()],
257
238
  ),
258
239
  // Activity is getting resolved right away as we are in the TryCancel mode.
259
240
  gen_assert_and_reply(
260
- &job_assert!(wf_activation_job::Variant::ResolveActivity(_)),
241
+ &job_assert!(workflow_activation_job::Variant::ResolveActivity(_)),
261
242
  vec![CompleteWorkflowExecution { result: None }.into()],
262
243
  ),
263
244
  ],
@@ -279,7 +260,7 @@ async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
279
260
  NonSticky,
280
261
  &[
281
262
  gen_assert_and_reply(
282
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
263
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
283
264
  vec![ScheduleActivity {
284
265
  seq: activity_seq,
285
266
  activity_id: activity_id.to_string(),
@@ -293,12 +274,12 @@ async fn scheduled_activity_timeout(hist_batches: &'static [usize]) {
293
274
  assert_matches!(
294
275
  res.jobs.as_slice(),
295
276
  [
296
- WfActivationJob {
297
- variant: Some(wf_activation_job::Variant::ResolveActivity(
277
+ WorkflowActivationJob {
278
+ variant: Some(workflow_activation_job::Variant::ResolveActivity(
298
279
  ResolveActivity {
299
280
  seq,
300
- result: Some(ActivityResult {
301
- status: Some(activity_result::Status::Failed(ar::Failure {
281
+ result: Some(ActivityResolution {
282
+ status: Some(activity_resolution::Status::Failed(ar::Failure {
302
283
  failure: Some(failure)
303
284
  })),
304
285
  })
@@ -332,7 +313,7 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
332
313
  NonSticky,
333
314
  &[
334
315
  gen_assert_and_reply(
335
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
316
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
336
317
  vec![ScheduleActivity {
337
318
  seq: activity_seq,
338
319
  activity_id: activity_seq.to_string(),
@@ -343,26 +324,26 @@ async fn started_activity_timeout(hist_batches: &'static [usize]) {
343
324
  // Activity is getting resolved right away as it has been timed out.
344
325
  gen_assert_and_reply(
345
326
  &|res| {
346
- assert_matches!(
347
- res.jobs.as_slice(),
348
- [
349
- WfActivationJob {
350
- variant: Some(wf_activation_job::Variant::ResolveActivity(
351
- ResolveActivity {
352
- seq,
353
- result: Some(ActivityResult {
354
- status: Some(activity_result::Status::Failed(ar::Failure {
355
- failure: Some(failure)
356
- })),
357
- })
358
- }
359
- )),
360
- }
361
- ] => {
362
- assert_eq!(failure.message, "Activity task timed out".to_string());
363
- assert_eq!(*seq, activity_seq);
327
+ assert_matches!(
328
+ res.jobs.as_slice(),
329
+ [
330
+ WorkflowActivationJob {
331
+ variant: Some(workflow_activation_job::Variant::ResolveActivity(
332
+ ResolveActivity {
333
+ seq,
334
+ result: Some(ActivityResolution {
335
+ status: Some(activity_resolution::Status::Failed(ar::Failure {
336
+ failure: Some(failure)
337
+ })),
338
+ })
364
339
  }
365
- );
340
+ )),
341
+ }
342
+ ] => {
343
+ assert_eq!(failure.message, "Activity task timed out".to_string());
344
+ assert_eq!(*seq, activity_seq);
345
+ }
346
+ );
366
347
  },
367
348
  vec![CompleteWorkflowExecution { result: None }.into()],
368
349
  ),
@@ -387,7 +368,7 @@ async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
387
368
  NonSticky,
388
369
  &[
389
370
  gen_assert_and_reply(
390
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
371
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
391
372
  vec![ScheduleActivity {
392
373
  seq: activity_seq,
393
374
  activity_id: activity_id.to_string(),
@@ -396,16 +377,16 @@ async fn cancelled_activity_timeout(hist_batches: &'static [usize]) {
396
377
  .into()],
397
378
  ),
398
379
  gen_assert_and_reply(
399
- &job_assert!(wf_activation_job::Variant::SignalWorkflow(_)),
380
+ &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
400
381
  vec![RequestCancelActivity { seq: activity_seq }.into()],
401
382
  ),
402
383
  // Activity is resolved right away as it has timed out.
403
384
  gen_assert_and_reply(
404
- &job_assert!(wf_activation_job::Variant::ResolveActivity(
385
+ &job_assert!(workflow_activation_job::Variant::ResolveActivity(
405
386
  ResolveActivity {
406
387
  seq: _,
407
- result: Some(ActivityResult {
408
- status: Some(activity_result::Status::Cancelled(..)),
388
+ result: Some(ActivityResolution {
389
+ status: Some(activity_resolution::Status::Cancelled(..)),
409
390
  })
410
391
  }
411
392
  )),
@@ -491,7 +472,7 @@ async fn verify_activity_cancellation(
491
472
  NonSticky,
492
473
  &[
493
474
  gen_assert_and_reply(
494
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
475
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
495
476
  vec![ScheduleActivity {
496
477
  seq: activity_seq,
497
478
  activity_id: activity_seq.to_string(),
@@ -501,16 +482,16 @@ async fn verify_activity_cancellation(
501
482
  .into()],
502
483
  ),
503
484
  gen_assert_and_reply(
504
- &job_assert!(wf_activation_job::Variant::SignalWorkflow(_)),
485
+ &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
505
486
  vec![RequestCancelActivity { seq: activity_seq }.into()],
506
487
  ),
507
488
  // Activity should be resolved right away
508
489
  gen_assert_and_reply(
509
- &job_assert!(wf_activation_job::Variant::ResolveActivity(
490
+ &job_assert!(workflow_activation_job::Variant::ResolveActivity(
510
491
  ResolveActivity {
511
492
  seq: _,
512
- result: Some(ActivityResult {
513
- status: Some(activity_result::Status::Cancelled(..)),
493
+ result: Some(ActivityResolution {
494
+ status: Some(activity_resolution::Status::Cancelled(..)),
514
495
  })
515
496
  }
516
497
  )),
@@ -559,7 +540,7 @@ async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, co
559
540
  NonSticky,
560
541
  &[
561
542
  gen_assert_and_reply(
562
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
543
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
563
544
  vec![ScheduleActivity {
564
545
  seq: activity_id,
565
546
  activity_id: activity_id.to_string(),
@@ -569,21 +550,21 @@ async fn verify_activity_cancellation_wait_for_cancellation(activity_id: u32, co
569
550
  .into()],
570
551
  ),
571
552
  gen_assert_and_reply(
572
- &job_assert!(wf_activation_job::Variant::SignalWorkflow(_)),
553
+ &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
573
554
  vec![RequestCancelActivity { seq: activity_id }.into()],
574
555
  ),
575
556
  // Making sure that activity is not resolved until it's cancelled.
576
557
  gen_assert_and_reply(
577
- &job_assert!(wf_activation_job::Variant::SignalWorkflow(_)),
558
+ &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
578
559
  vec![],
579
560
  ),
580
561
  // Now ActivityTaskCanceled has been processed and activity can be resolved.
581
562
  gen_assert_and_reply(
582
- &job_assert!(wf_activation_job::Variant::ResolveActivity(
563
+ &job_assert!(workflow_activation_job::Variant::ResolveActivity(
583
564
  ResolveActivity {
584
565
  seq: _,
585
- result: Some(ActivityResult {
586
- status: Some(activity_result::Status::Cancelled(..)),
566
+ result: Some(ActivityResolution {
567
+ status: Some(activity_resolution::Status::Cancelled(..)),
587
568
  })
588
569
  }
589
570
  )),
@@ -615,8 +596,8 @@ async fn workflow_update_random_seed_on_workflow_reset() {
615
596
  &|res| {
616
597
  assert_matches!(
617
598
  res.jobs.as_slice(),
618
- [WfActivationJob {
619
- variant: Some(wf_activation_job::Variant::StartWorkflow(
599
+ [WorkflowActivationJob {
600
+ variant: Some(workflow_activation_job::Variant::StartWorkflow(
620
601
  StartWorkflow{randomness_seed, ..}
621
602
  )),
622
603
  }] => {
@@ -624,21 +605,17 @@ async fn workflow_update_random_seed_on_workflow_reset() {
624
605
  }
625
606
  );
626
607
  },
627
- vec![StartTimer {
628
- seq: timer_1_id,
629
- ..Default::default()
630
- }
631
- .into()],
608
+ vec![start_timer_cmd(timer_1_id, Duration::from_secs(1))],
632
609
  ),
633
610
  gen_assert_and_reply(
634
611
  &|res| {
635
612
  assert_matches!(
636
613
  res.jobs.as_slice(),
637
- [WfActivationJob {
638
- variant: Some(wf_activation_job::Variant::FireTimer(_),),
614
+ [WorkflowActivationJob {
615
+ variant: Some(workflow_activation_job::Variant::FireTimer(_),),
639
616
  },
640
- WfActivationJob {
641
- variant: Some(wf_activation_job::Variant::UpdateRandomSeed(
617
+ WorkflowActivationJob {
618
+ variant: Some(workflow_activation_job::Variant::UpdateRandomSeed(
642
619
  UpdateRandomSeed{randomness_seed})),
643
620
  }] => {
644
621
  assert_ne!(randomness_seed_from_start.load(Ordering::SeqCst),
@@ -669,13 +646,9 @@ async fn cancel_timer_before_sent_wf_bridge() {
669
646
  &core,
670
647
  NonSticky,
671
648
  &[gen_assert_and_reply(
672
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
649
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
673
650
  vec![
674
- StartTimer {
675
- seq: cancel_timer_id,
676
- ..Default::default()
677
- }
678
- .into(),
651
+ start_timer_cmd(cancel_timer_id, Duration::from_secs(1)),
679
652
  CancelTimer {
680
653
  seq: cancel_timer_id,
681
654
  }
@@ -718,15 +691,11 @@ async fn complete_activation_with_failure(
718
691
  &[
719
692
  gen_assert_and_reply(
720
693
  &|_| {},
721
- vec![StartTimer {
722
- seq: timer_id,
723
- ..Default::default()
724
- }
725
- .into()],
694
+ vec![start_timer_cmd(timer_id, Duration::from_secs(1))],
726
695
  ),
727
696
  gen_assert_and_fail(&|_| {}),
728
697
  gen_assert_and_reply(
729
- &job_assert!(wf_activation_job::Variant::FireTimer(_)),
698
+ &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
730
699
  vec![CompleteWorkflowExecution { result: None }.into()],
731
700
  ),
732
701
  ],
@@ -749,15 +718,11 @@ async fn simple_timer_fail_wf_execution(hist_batches: &'static [usize]) {
749
718
  NonSticky,
750
719
  &[
751
720
  gen_assert_and_reply(
752
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
753
- vec![StartTimer {
754
- seq: timer_id,
755
- ..Default::default()
756
- }
757
- .into()],
721
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
722
+ vec![start_timer_cmd(timer_id, Duration::from_secs(1))],
758
723
  ),
759
724
  gen_assert_and_reply(
760
- &job_assert!(wf_activation_job::Variant::FireTimer(_)),
725
+ &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
761
726
  vec![FailWorkflowExecution {
762
727
  failure: Some(Failure {
763
728
  message: "I'm ded".to_string(),
@@ -784,14 +749,14 @@ async fn two_signals(hist_batches: &'static [usize]) {
784
749
  NonSticky,
785
750
  &[
786
751
  gen_assert_and_reply(
787
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
752
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
788
753
  // Task is completed with no commands
789
754
  vec![],
790
755
  ),
791
756
  gen_assert_and_reply(
792
757
  &job_assert!(
793
- wf_activation_job::Variant::SignalWorkflow(_),
794
- wf_activation_job::Variant::SignalWorkflow(_)
758
+ workflow_activation_job::Variant::SignalWorkflow(_),
759
+ workflow_activation_job::Variant::SignalWorkflow(_)
795
760
  ),
796
761
  vec![],
797
762
  ),
@@ -837,29 +802,21 @@ async fn workflow_failures_only_reported_once() {
837
802
  &[
838
803
  gen_assert_and_reply(
839
804
  &|_| {},
840
- vec![StartTimer {
841
- seq: timer_1,
842
- ..Default::default()
843
- }
844
- .into()],
805
+ vec![start_timer_cmd(timer_1, Duration::from_secs(1))],
845
806
  ),
846
807
  // Fail a few times in a row (only one of which should be reported)
847
808
  gen_assert_and_fail(&|_| {}),
848
809
  gen_assert_and_fail(&|_| {}),
849
810
  gen_assert_and_fail(&|_| {}),
850
811
  gen_assert_and_reply(
851
- &job_assert!(wf_activation_job::Variant::FireTimer(_)),
852
- vec![StartTimer {
853
- seq: timer_2,
854
- ..Default::default()
855
- }
856
- .into()],
812
+ &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
813
+ vec![start_timer_cmd(timer_2, Duration::from_secs(1))],
857
814
  ),
858
815
  // Again (a new fail should be reported here)
859
816
  gen_assert_and_fail(&|_| {}),
860
817
  gen_assert_and_fail(&|_| {}),
861
818
  gen_assert_and_reply(
862
- &job_assert!(wf_activation_job::Variant::FireTimer(_)),
819
+ &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
863
820
  vec![CompleteWorkflowExecution { result: None }.into()],
864
821
  ),
865
822
  ],
@@ -908,14 +865,10 @@ async fn max_concurrent_wft_respected() {
908
865
  let last_finisher = AtomicUsize::new(0);
909
866
  let (_, mut r1) = tokio::join! {
910
867
  async {
911
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
868
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
912
869
  TEST_Q,
913
870
  r1.run_id,
914
- StartTimer {
915
- seq: 1,
916
- ..Default::default()
917
- }
918
- .into())
871
+ start_timer_cmd(1, Duration::from_secs(1)))
919
872
  ).await.unwrap();
920
873
  last_finisher.store(1, Ordering::SeqCst);
921
874
  },
@@ -930,14 +883,10 @@ async fn max_concurrent_wft_respected() {
930
883
 
931
884
  // Since we never did anything with r2, all subsequent activations should be for wf1
932
885
  for i in 2..=20 {
933
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
886
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
934
887
  TEST_Q,
935
888
  r1.run_id,
936
- StartTimer {
937
- seq: i,
938
- ..Default::default()
939
- }
940
- .into(),
889
+ start_timer_cmd(i, Duration::from_secs(1)),
941
890
  ))
942
891
  .await
943
892
  .unwrap();
@@ -945,7 +894,7 @@ async fn max_concurrent_wft_respected() {
945
894
  assert_eq!(r1.run_id, r1_run_id);
946
895
  }
947
896
  // Finish the tasks so we can shut down
948
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
897
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
949
898
  TEST_Q,
950
899
  r1.run_id,
951
900
  CompleteWorkflowExecution { result: None }.into(),
@@ -957,20 +906,16 @@ async fn max_concurrent_wft_respected() {
957
906
  // We have to properly complete the outstanding task (or the mock will be confused why a task
958
907
  // failure was reported)
959
908
  let _ = core
960
- .complete_workflow_activation(WfActivationCompletion::from_cmd(
909
+ .complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
961
910
  TEST_Q,
962
911
  r2.run_id,
963
- StartTimer {
964
- seq: 1,
965
- ..Default::default()
966
- }
967
- .into(),
912
+ start_timer_cmd(1, Duration::from_secs(1)),
968
913
  ))
969
914
  .await;
970
915
  // Get and complete eviction
971
916
  let r2 = core.poll_workflow_activation(TEST_Q).await.unwrap();
972
917
  let _ = core
973
- .complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, r2.run_id))
918
+ .complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, r2.run_id))
974
919
  .await;
975
920
  core.shutdown().await;
976
921
  }
@@ -988,7 +933,7 @@ async fn activity_not_canceled_on_replay_repro(hist_batches: &'static [usize]) {
988
933
  NonSticky,
989
934
  &[
990
935
  gen_assert_and_reply(
991
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
936
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
992
937
  // Start timer and activity
993
938
  vec![
994
939
  ScheduleActivity {
@@ -998,31 +943,23 @@ async fn activity_not_canceled_on_replay_repro(hist_batches: &'static [usize]) {
998
943
  ..Default::default()
999
944
  }
1000
945
  .into(),
1001
- StartTimer {
1002
- seq: 1,
1003
- ..Default::default()
1004
- }
1005
- .into(),
946
+ start_timer_cmd(1, Duration::from_secs(1)),
1006
947
  ],
1007
948
  ),
1008
949
  gen_assert_and_reply(
1009
- &job_assert!(wf_activation_job::Variant::FireTimer(_)),
950
+ &job_assert!(workflow_activation_job::Variant::FireTimer(_)),
1010
951
  vec![RequestCancelActivity { seq: activity_id }.into()],
1011
952
  ),
1012
953
  gen_assert_and_reply(
1013
- &job_assert!(wf_activation_job::Variant::ResolveActivity(
954
+ &job_assert!(workflow_activation_job::Variant::ResolveActivity(
1014
955
  ResolveActivity {
1015
- result: Some(ActivityResult {
1016
- status: Some(activity_result::Status::Cancelled(..)),
956
+ result: Some(ActivityResolution {
957
+ status: Some(activity_resolution::Status::Cancelled(..)),
1017
958
  }),
1018
959
  ..
1019
960
  }
1020
961
  )),
1021
- vec![StartTimer {
1022
- seq: 2,
1023
- ..Default::default()
1024
- }
1025
- .into()],
962
+ vec![start_timer_cmd(2, Duration::from_secs(1))],
1026
963
  ),
1027
964
  ],
1028
965
  )
@@ -1042,7 +979,7 @@ async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static
1042
979
  NonSticky,
1043
980
  &[
1044
981
  gen_assert_and_reply(
1045
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
982
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
1046
983
  vec![ScheduleActivity {
1047
984
  seq: activity_id,
1048
985
  activity_id: activity_id.to_string(),
@@ -1052,21 +989,17 @@ async fn activity_not_canceled_when_also_completed_repro(hist_batches: &'static
1052
989
  .into()],
1053
990
  ),
1054
991
  gen_assert_and_reply(
1055
- &job_assert!(wf_activation_job::Variant::SignalWorkflow(_)),
992
+ &job_assert!(workflow_activation_job::Variant::SignalWorkflow(_)),
1056
993
  vec![
1057
994
  RequestCancelActivity { seq: activity_id }.into(),
1058
- StartTimer {
1059
- seq: 2,
1060
- ..Default::default()
1061
- }
1062
- .into(),
995
+ start_timer_cmd(2, Duration::from_secs(1)),
1063
996
  ],
1064
997
  ),
1065
998
  gen_assert_and_reply(
1066
- &job_assert!(wf_activation_job::Variant::ResolveActivity(
999
+ &job_assert!(workflow_activation_job::Variant::ResolveActivity(
1067
1000
  ResolveActivity {
1068
- result: Some(ActivityResult {
1069
- status: Some(activity_result::Status::Cancelled(..)),
1001
+ result: Some(ActivityResolution {
1002
+ status: Some(activity_resolution::Status::Cancelled(..)),
1070
1003
  }),
1071
1004
  ..
1072
1005
  }
@@ -1097,13 +1030,11 @@ async fn lots_of_workflows() {
1097
1030
  while let Ok(wft) = core.poll_workflow_activation(TEST_Q).await {
1098
1031
  let job = &wft.jobs[0];
1099
1032
  let reply = match job.variant {
1100
- Some(wf_activation_job::Variant::StartWorkflow(_)) => StartTimer {
1101
- seq: 1,
1102
- ..Default::default()
1033
+ Some(workflow_activation_job::Variant::StartWorkflow(_)) => {
1034
+ start_timer_cmd(1, Duration::from_secs(1))
1103
1035
  }
1104
- .into(),
1105
- Some(wf_activation_job::Variant::RemoveFromCache(_)) => {
1106
- core.complete_workflow_activation(WfActivationCompletion::empty(
1036
+ Some(workflow_activation_job::Variant::RemoveFromCache(_)) => {
1037
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(
1107
1038
  TEST_Q, wft.run_id,
1108
1039
  ))
1109
1040
  .await
@@ -1112,7 +1043,7 @@ async fn lots_of_workflows() {
1112
1043
  }
1113
1044
  _ => CompleteWorkflowExecution { result: None }.into(),
1114
1045
  };
1115
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1046
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1116
1047
  TEST_Q, wft.run_id, reply,
1117
1048
  ))
1118
1049
  .await
@@ -1143,7 +1074,7 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
1143
1074
  NonSticky,
1144
1075
  &[
1145
1076
  gen_assert_and_reply(
1146
- &job_assert!(wf_activation_job::Variant::StartWorkflow(_)),
1077
+ &job_assert!(workflow_activation_job::Variant::StartWorkflow(_)),
1147
1078
  vec![ScheduleActivity {
1148
1079
  seq: activity_id,
1149
1080
  activity_id: activity_id.to_string(),
@@ -1154,11 +1085,11 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
1154
1085
  ),
1155
1086
  gen_assert_and_reply(
1156
1087
  &job_assert!(
1157
- wf_activation_job::Variant::SignalWorkflow(_),
1158
- wf_activation_job::Variant::SignalWorkflow(_),
1159
- wf_activation_job::Variant::ResolveActivity(ResolveActivity {
1160
- result: Some(ActivityResult {
1161
- status: Some(activity_result::Status::Completed(..)),
1088
+ workflow_activation_job::Variant::SignalWorkflow(_),
1089
+ workflow_activation_job::Variant::SignalWorkflow(_),
1090
+ workflow_activation_job::Variant::ResolveActivity(ResolveActivity {
1091
+ result: Some(ActivityResolution {
1092
+ status: Some(activity_resolution::Status::Completed(..)),
1162
1093
  }),
1163
1094
  ..
1164
1095
  })
@@ -1174,7 +1105,7 @@ async fn wft_timeout_repro(hist_batches: &'static [usize]) {
1174
1105
  async fn complete_after_eviction() {
1175
1106
  let wfid = "fake_wf_id";
1176
1107
  let t = canned_histories::single_timer("1");
1177
- let mut mock = MockServerGatewayApis::new();
1108
+ let mut mock = mock_gateway();
1178
1109
  mock.expect_complete_workflow_task().times(0);
1179
1110
  let mock = single_hist_mock_sg(wfid, t, &[2], mock, true);
1180
1111
  let core = mock_core(mock);
@@ -1183,14 +1114,10 @@ async fn complete_after_eviction() {
1183
1114
  // We just got start workflow, immediately evict
1184
1115
  core.request_workflow_eviction(TEST_Q, &activation.run_id);
1185
1116
  // Original task must be completed before we get the eviction
1186
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1117
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1187
1118
  TEST_Q,
1188
1119
  activation.run_id,
1189
- StartTimer {
1190
- seq: 1,
1191
- ..Default::default()
1192
- }
1193
- .into(),
1120
+ start_timer_cmd(1, Duration::from_secs(1)),
1194
1121
  ))
1195
1122
  .await
1196
1123
  .unwrap();
@@ -1198,16 +1125,16 @@ async fn complete_after_eviction() {
1198
1125
  assert_matches!(
1199
1126
  eviction_activation.jobs.as_slice(),
1200
1127
  [
1201
- WfActivationJob {
1202
- variant: Some(wf_activation_job::Variant::FireTimer(_)),
1128
+ WorkflowActivationJob {
1129
+ variant: Some(workflow_activation_job::Variant::FireTimer(_)),
1203
1130
  },
1204
- WfActivationJob {
1205
- variant: Some(wf_activation_job::Variant::RemoveFromCache(_)),
1131
+ WorkflowActivationJob {
1132
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1206
1133
  }
1207
1134
  ]
1208
1135
  );
1209
1136
  // Complete the activation containing the eviction, the way we normally would have
1210
- core.complete_workflow_activation(WfActivationCompletion::from_cmds(
1137
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1211
1138
  TEST_Q,
1212
1139
  eviction_activation.run_id,
1213
1140
  vec![CompleteWorkflowExecution { result: None }.into()],
@@ -1223,7 +1150,7 @@ async fn sends_appropriate_sticky_task_queue_responses() {
1223
1150
  // include the information that tells the server to enqueue the next task on a sticky queue.
1224
1151
  let wfid = "fake_wf_id";
1225
1152
  let t = canned_histories::single_timer("1");
1226
- let mut mock = MockServerGatewayApis::new();
1153
+ let mut mock = mock_gateway();
1227
1154
  mock.expect_complete_workflow_task()
1228
1155
  .withf(|comp| comp.sticky_attributes.is_some())
1229
1156
  .times(1)
@@ -1234,14 +1161,10 @@ async fn sends_appropriate_sticky_task_queue_responses() {
1234
1161
  let core = mock_core(mock);
1235
1162
 
1236
1163
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1237
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1164
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1238
1165
  TEST_Q,
1239
1166
  activation.run_id,
1240
- StartTimer {
1241
- seq: 1,
1242
- ..Default::default()
1243
- }
1244
- .into(),
1167
+ start_timer_cmd(1, Duration::from_secs(1)),
1245
1168
  ))
1246
1169
  .await
1247
1170
  .unwrap();
@@ -1249,37 +1172,33 @@ async fn sends_appropriate_sticky_task_queue_responses() {
1249
1172
  }
1250
1173
 
1251
1174
  #[tokio::test]
1252
- #[should_panic(expected = "called more than 2 times")]
1253
1175
  async fn new_server_work_while_eviction_outstanding_doesnt_overwrite_activation() {
1254
1176
  let wfid = "fake_wf_id";
1255
1177
  let t = canned_histories::single_timer("1");
1256
- let mock = MockServerGatewayApis::new();
1257
- let mock = single_hist_mock_sg(wfid, t, &[1, 2], mock, true);
1178
+ let mock = single_hist_mock_sg(wfid, t, &[1, 2], mock_gateway(), false);
1258
1179
  let core = mock_core(mock);
1259
1180
 
1260
1181
  // Poll for and complete first workflow task
1261
1182
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1262
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1183
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1263
1184
  TEST_Q,
1264
1185
  activation.run_id,
1265
- StartTimer {
1266
- seq: 1,
1267
- ..Default::default()
1268
- }
1269
- .into(),
1186
+ start_timer_cmd(1, Duration::from_secs(1)),
1270
1187
  ))
1271
1188
  .await
1272
1189
  .unwrap();
1273
1190
  let eviction_activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1274
1191
  assert_matches!(
1275
1192
  eviction_activation.jobs.as_slice(),
1276
- [WfActivationJob {
1277
- variant: Some(wf_activation_job::Variant::RemoveFromCache(_)),
1193
+ [WorkflowActivationJob {
1194
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1278
1195
  }]
1279
1196
  );
1280
1197
  // Poll again. We should not overwrite the eviction with the new work from the server to fire
1281
- // the timer. IE: We will panic here because the mock has no more responses.
1282
- core.poll_workflow_activation(TEST_Q).await.unwrap();
1198
+ // the timer, so polling will try again, and run into the mock being out of responses.
1199
+ let act = core.poll_workflow_activation(TEST_Q).await;
1200
+ assert_matches!(act, Err(PollWfError::TonicError(err))
1201
+ if err.message() == NO_MORE_WORK_ERROR_MSG);
1283
1202
  core.shutdown().await;
1284
1203
  }
1285
1204
 
@@ -1318,7 +1237,7 @@ async fn buffered_work_drained_on_shutdown() {
1318
1237
  ))
1319
1238
  .take(50),
1320
1239
  );
1321
- let mut mock = MockServerGatewayApis::new();
1240
+ let mut mock = mock_gateway();
1322
1241
  mock.expect_complete_workflow_task()
1323
1242
  .returning(|_| Ok(RespondWorkflowTaskCompletedResponse::default()));
1324
1243
  let mut mock = MocksHolder::from_gateway_with_responses(mock, tasks, []);
@@ -1332,7 +1251,7 @@ async fn buffered_work_drained_on_shutdown() {
1332
1251
  // Now poll again, which will start spinning, and buffer the next WFT with timer fired in it
1333
1252
  // - it won't stop spinning until the first task is complete
1334
1253
  let t = core.poll_workflow_activation(TEST_Q).await.unwrap();
1335
- core.complete_workflow_activation(WfActivationCompletion::from_cmds(
1254
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1336
1255
  TEST_Q,
1337
1256
  t.run_id,
1338
1257
  vec![CompleteWorkflowExecution { result: None }.into()],
@@ -1341,14 +1260,10 @@ async fn buffered_work_drained_on_shutdown() {
1341
1260
  .unwrap();
1342
1261
  };
1343
1262
  let complete_first = async move {
1344
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1263
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1345
1264
  TEST_Q,
1346
1265
  act1.run_id,
1347
- StartTimer {
1348
- seq: 1,
1349
- ..Default::default()
1350
- }
1351
- .into(),
1266
+ start_timer_cmd(1, Duration::from_secs(1)),
1352
1267
  ))
1353
1268
  .await
1354
1269
  .unwrap();
@@ -1364,7 +1279,7 @@ async fn buffered_work_drained_on_shutdown() {
1364
1279
  async fn buffering_tasks_doesnt_count_toward_outstanding_max() {
1365
1280
  let wfid = "fake_wf_id";
1366
1281
  let t = canned_histories::single_timer("1");
1367
- let mock = MockServerGatewayApis::new();
1282
+ let mock = mock_gateway();
1368
1283
  let mut tasks = VecDeque::new();
1369
1284
  // A way bigger task list than allowed outstanding tasks
1370
1285
  tasks.extend(
@@ -1400,7 +1315,7 @@ async fn fail_wft_then_recover() {
1400
1315
  t,
1401
1316
  // We need to deliver all of history twice because of eviction
1402
1317
  [ResponseType::AllHistory, ResponseType::AllHistory],
1403
- MockServerGatewayApis::new(),
1318
+ mock_gateway(),
1404
1319
  );
1405
1320
  mh.num_expected_fails = Some(1);
1406
1321
  mh.expect_fail_wft_matcher =
@@ -1413,7 +1328,7 @@ async fn fail_wft_then_recover() {
1413
1328
 
1414
1329
  let act = core.poll_workflow_activation(TEST_Q).await.unwrap();
1415
1330
  // Start an activity instead of a timer, triggering nondeterminism error
1416
- core.complete_workflow_activation(WfActivationCompletion::from_cmds(
1331
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1417
1332
  TEST_Q,
1418
1333
  act.run_id.clone(),
1419
1334
  vec![ScheduleActivity {
@@ -1429,35 +1344,34 @@ async fn fail_wft_then_recover() {
1429
1344
  assert_eq!(evict_act.run_id, act.run_id);
1430
1345
  assert_matches!(
1431
1346
  evict_act.jobs.as_slice(),
1432
- [WfActivationJob {
1433
- variant: Some(wf_activation_job::Variant::RemoveFromCache(_)),
1347
+ [WorkflowActivationJob {
1348
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1434
1349
  }]
1435
1350
  );
1436
- core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, evict_act.run_id))
1437
- .await
1438
- .unwrap();
1351
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(
1352
+ TEST_Q,
1353
+ evict_act.run_id,
1354
+ ))
1355
+ .await
1356
+ .unwrap();
1439
1357
 
1440
1358
  // Workflow starting over, this time issue the right command
1441
1359
  let act = core.poll_workflow_activation(TEST_Q).await.unwrap();
1442
- core.complete_workflow_activation(WfActivationCompletion::from_cmds(
1360
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1443
1361
  TEST_Q,
1444
1362
  act.run_id,
1445
- vec![StartTimer {
1446
- seq: 1,
1447
- ..Default::default()
1448
- }
1449
- .into()],
1363
+ vec![start_timer_cmd(1, Duration::from_secs(1))],
1450
1364
  ))
1451
1365
  .await
1452
1366
  .unwrap();
1453
1367
  let act = core.poll_workflow_activation(TEST_Q).await.unwrap();
1454
1368
  assert_matches!(
1455
1369
  act.jobs.as_slice(),
1456
- [WfActivationJob {
1457
- variant: Some(wf_activation_job::Variant::FireTimer(_)),
1370
+ [WorkflowActivationJob {
1371
+ variant: Some(workflow_activation_job::Variant::FireTimer(_)),
1458
1372
  },]
1459
1373
  );
1460
- core.complete_workflow_activation(WfActivationCompletion::from_cmds(
1374
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1461
1375
  TEST_Q,
1462
1376
  act.run_id,
1463
1377
  vec![CompleteWorkflowExecution { result: None }.into()],
@@ -1476,12 +1390,8 @@ async fn poll_response_triggers_wf_error() {
1476
1390
  t.add_full_wf_task();
1477
1391
  t.add_workflow_execution_completed();
1478
1392
 
1479
- let mut mh = MockPollCfg::from_resp_batches(
1480
- "fake_wf_id",
1481
- t,
1482
- [ResponseType::AllHistory],
1483
- MockServerGatewayApis::new(),
1484
- );
1393
+ let mut mh =
1394
+ MockPollCfg::from_resp_batches("fake_wf_id", t, [ResponseType::AllHistory], mock_gateway());
1485
1395
  // Since applying the poll response immediately generates an error core will start polling again
1486
1396
  // Rather than panic on bad expectation we want to return the magic "no more work" error
1487
1397
  mh.enforce_correct_number_of_polls = false;
@@ -1509,7 +1419,7 @@ async fn lang_slower_than_wft_timeouts() {
1509
1419
  hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
1510
1420
  hist_to_poll_resp(&t, wfid.to_owned(), 1.into(), TEST_Q.to_string()),
1511
1421
  ];
1512
- let mut mock = MockServerGatewayApis::new();
1422
+ let mut mock = mock_gateway();
1513
1423
  mock.expect_complete_workflow_task()
1514
1424
  .times(1)
1515
1425
  .returning(|_| Err(tonic::Status::not_found("Workflow task not found.")));
@@ -1528,27 +1438,27 @@ async fn lang_slower_than_wft_timeouts() {
1528
1438
  if err.message() == NO_MORE_WORK_ERROR_MSG);
1529
1439
  // This completion runs into a workflow task not found error, since it's completing a stale
1530
1440
  // task.
1531
- core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, wf_task.run_id))
1441
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, wf_task.run_id))
1532
1442
  .await
1533
1443
  .unwrap();
1534
1444
  // Now we should get an eviction
1535
1445
  let wf_task = core.poll_workflow_activation(TEST_Q).await.unwrap();
1536
1446
  assert_matches!(
1537
1447
  wf_task.jobs.as_slice(),
1538
- [WfActivationJob {
1539
- variant: Some(wf_activation_job::Variant::RemoveFromCache(_)),
1448
+ [WorkflowActivationJob {
1449
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1540
1450
  }]
1541
1451
  );
1542
- core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, wf_task.run_id))
1452
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, wf_task.run_id))
1543
1453
  .await
1544
1454
  .unwrap();
1545
1455
  // The last WFT buffered should be applied now
1546
1456
  let start_again = core.poll_workflow_activation(TEST_Q).await.unwrap();
1547
1457
  assert_matches!(
1548
1458
  start_again.jobs[0].variant,
1549
- Some(wf_activation_job::Variant::StartWorkflow(_))
1459
+ Some(workflow_activation_job::Variant::StartWorkflow(_))
1550
1460
  );
1551
- core.complete_workflow_activation(WfActivationCompletion::from_cmds(
1461
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1552
1462
  TEST_Q,
1553
1463
  start_again.run_id,
1554
1464
  vec![CompleteWorkflowExecution { result: None }.into()],
@@ -1569,13 +1479,13 @@ async fn tries_cancel_of_completed_activity() {
1569
1479
  t.add_activity_task_completed(scheduled_event_id, started_event_id, Default::default());
1570
1480
  t.add_workflow_task_scheduled_and_started();
1571
1481
 
1572
- let mock = MockServerGatewayApis::new();
1482
+ let mock = mock_gateway();
1573
1483
  let mut mock = single_hist_mock_sg("fake_wf_id", t, &[1, 2], mock, true);
1574
1484
  mock.worker_cfg(TEST_Q, |cfg| cfg.max_cached_workflows = 1);
1575
1485
  let core = mock_core(mock);
1576
1486
 
1577
1487
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1578
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1488
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1579
1489
  TEST_Q,
1580
1490
  activation.run_id,
1581
1491
  ScheduleActivity {
@@ -1591,15 +1501,15 @@ async fn tries_cancel_of_completed_activity() {
1591
1501
  assert_matches!(
1592
1502
  activation.jobs.as_slice(),
1593
1503
  [
1594
- WfActivationJob {
1595
- variant: Some(wf_activation_job::Variant::SignalWorkflow(_)),
1504
+ WorkflowActivationJob {
1505
+ variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
1596
1506
  },
1597
- WfActivationJob {
1598
- variant: Some(wf_activation_job::Variant::ResolveActivity(_)),
1507
+ WorkflowActivationJob {
1508
+ variant: Some(workflow_activation_job::Variant::ResolveActivity(_)),
1599
1509
  }
1600
1510
  ]
1601
1511
  );
1602
- core.complete_workflow_activation(WfActivationCompletion::from_cmds(
1512
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1603
1513
  TEST_Q,
1604
1514
  activation.run_id,
1605
1515
  vec![
@@ -1619,7 +1529,7 @@ async fn failing_wft_doesnt_eat_permit_forever() {
1619
1529
  t.add_by_type(EventType::WorkflowExecutionStarted);
1620
1530
  t.add_workflow_task_scheduled_and_started();
1621
1531
 
1622
- let mock = MockServerGatewayApis::new();
1532
+ let mock = mock_gateway();
1623
1533
  let mut mock = single_hist_mock_sg("fake_wf_id", t, [1, 1, 1], mock, true);
1624
1534
  mock.worker_cfg(TEST_Q, |cfg| {
1625
1535
  cfg.max_cached_workflows = 2;
@@ -1634,7 +1544,7 @@ async fn failing_wft_doesnt_eat_permit_forever() {
1634
1544
  for _ in 1..=2 {
1635
1545
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1636
1546
  // Issue a nonsense completion that will trigger a WFT failure
1637
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1547
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1638
1548
  TEST_Q,
1639
1549
  activation.run_id,
1640
1550
  RequestCancelActivity { seq: 1 }.into(),
@@ -1644,14 +1554,17 @@ async fn failing_wft_doesnt_eat_permit_forever() {
1644
1554
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1645
1555
  assert_matches!(
1646
1556
  activation.jobs.as_slice(),
1647
- [WfActivationJob {
1648
- variant: Some(wf_activation_job::Variant::RemoveFromCache(_)),
1557
+ [WorkflowActivationJob {
1558
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1649
1559
  },]
1650
1560
  );
1651
1561
  run_id = activation.run_id.clone();
1652
- core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, activation.run_id))
1653
- .await
1654
- .unwrap();
1562
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(
1563
+ TEST_Q,
1564
+ activation.run_id,
1565
+ ))
1566
+ .await
1567
+ .unwrap();
1655
1568
  assert_eq!(core.outstanding_wfts(TEST_Q), 0);
1656
1569
  assert_eq!(core.available_wft_permits(TEST_Q), 2);
1657
1570
  }
@@ -1665,7 +1578,7 @@ async fn failing_wft_doesnt_eat_permit_forever() {
1665
1578
  .write()
1666
1579
  .remove_by_left(&run_id);
1667
1580
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1668
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1581
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1669
1582
  TEST_Q,
1670
1583
  activation.run_id,
1671
1584
  CompleteWorkflowExecution { result: None }.into(),
@@ -1698,7 +1611,7 @@ async fn cache_miss_doesnt_eat_permit_forever() {
1698
1611
  // Last one to complete successfully
1699
1612
  ResponseType::ToTaskNum(1),
1700
1613
  ],
1701
- MockServerGatewayApis::new(),
1614
+ mock_gateway(),
1702
1615
  );
1703
1616
  mh.num_expected_fails = Some(3);
1704
1617
  mh.expect_fail_wft_matcher =
@@ -1713,20 +1626,26 @@ async fn cache_miss_doesnt_eat_permit_forever() {
1713
1626
  for _ in 1..=3 {
1714
1627
  // Start
1715
1628
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1716
- core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, activation.run_id))
1717
- .await
1718
- .unwrap();
1629
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(
1630
+ TEST_Q,
1631
+ activation.run_id,
1632
+ ))
1633
+ .await
1634
+ .unwrap();
1719
1635
  // Evict
1720
1636
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1721
1637
  assert_matches!(
1722
1638
  activation.jobs.as_slice(),
1723
- [WfActivationJob {
1724
- variant: Some(wf_activation_job::Variant::RemoveFromCache(_)),
1639
+ [WorkflowActivationJob {
1640
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
1725
1641
  },]
1726
1642
  );
1727
- core.complete_workflow_activation(WfActivationCompletion::empty(TEST_Q, activation.run_id))
1728
- .await
1729
- .unwrap();
1643
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(
1644
+ TEST_Q,
1645
+ activation.run_id,
1646
+ ))
1647
+ .await
1648
+ .unwrap();
1730
1649
  assert_eq!(core.outstanding_wfts(TEST_Q), 0);
1731
1650
  assert_eq!(core.available_wft_permits(TEST_Q), 2);
1732
1651
  // When we loop back up, the poll will trigger a cache miss, which we should immediately
@@ -1734,7 +1653,7 @@ async fn cache_miss_doesnt_eat_permit_forever() {
1734
1653
  // history
1735
1654
  }
1736
1655
  let activation = core.poll_workflow_activation(TEST_Q).await.unwrap();
1737
- core.complete_workflow_activation(WfActivationCompletion::from_cmd(
1656
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
1738
1657
  TEST_Q,
1739
1658
  activation.run_id,
1740
1659
  CompleteWorkflowExecution { result: None }.into(),
@@ -1744,3 +1663,62 @@ async fn cache_miss_doesnt_eat_permit_forever() {
1744
1663
 
1745
1664
  core.shutdown().await;
1746
1665
  }
1666
+
1667
+ /// This test verifies that WFTs which come as replies to completing a WFT are properly delivered
1668
+ /// via activation polling.
1669
+ #[tokio::test]
1670
+ async fn tasks_from_completion_are_delivered() {
1671
+ let wfid = "fake_wf_id";
1672
+ let mut t = TestHistoryBuilder::default();
1673
+ t.add_by_type(EventType::WorkflowExecutionStarted);
1674
+ t.add_full_wf_task();
1675
+ t.add_we_signaled("sig", vec![]);
1676
+ t.add_full_wf_task();
1677
+ t.add_workflow_execution_completed();
1678
+
1679
+ let tasks = [hist_to_poll_resp(
1680
+ &t,
1681
+ wfid.to_owned(),
1682
+ 1.into(),
1683
+ TEST_Q.to_string(),
1684
+ )];
1685
+ let mut mock = mock_gateway();
1686
+ mock.expect_complete_workflow_task()
1687
+ .times(1)
1688
+ .returning(move |_| {
1689
+ Ok(RespondWorkflowTaskCompletedResponse {
1690
+ workflow_task: Some(hist_to_poll_resp(
1691
+ &t,
1692
+ wfid.to_owned(),
1693
+ 2.into(),
1694
+ TEST_Q.to_string(),
1695
+ )),
1696
+ })
1697
+ });
1698
+ mock.expect_complete_workflow_task()
1699
+ .times(1)
1700
+ .returning(|_| Ok(Default::default()));
1701
+ let mut mock = MocksHolder::from_gateway_with_responses(mock, tasks, []);
1702
+ mock.worker_cfg(TEST_Q, |wc| wc.max_cached_workflows = 2);
1703
+ let core = mock_core(mock);
1704
+
1705
+ let wf_task = core.poll_workflow_activation(TEST_Q).await.unwrap();
1706
+ core.complete_workflow_activation(WorkflowActivationCompletion::empty(TEST_Q, wf_task.run_id))
1707
+ .await
1708
+ .unwrap();
1709
+ let wf_task = core.poll_workflow_activation(TEST_Q).await.unwrap();
1710
+ assert_matches!(
1711
+ wf_task.jobs.as_slice(),
1712
+ [WorkflowActivationJob {
1713
+ variant: Some(workflow_activation_job::Variant::SignalWorkflow(_)),
1714
+ },]
1715
+ );
1716
+ core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
1717
+ TEST_Q,
1718
+ wf_task.run_id,
1719
+ vec![CompleteWorkflowExecution { result: None }.into()],
1720
+ ))
1721
+ .await
1722
+ .unwrap();
1723
+ core.shutdown().await;
1724
+ }