@temporalio/core-bridge 1.8.6 → 1.9.0-rc.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 (196) hide show
  1. package/Cargo.lock +189 -152
  2. package/Cargo.toml +1 -0
  3. package/lib/index.d.ts +17 -44
  4. package/lib/index.js.map +1 -1
  5. package/package.json +3 -4
  6. package/releases/aarch64-apple-darwin/index.node +0 -0
  7. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  8. package/releases/x86_64-apple-darwin/index.node +0 -0
  9. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  10. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  11. package/sdk-core/.github/workflows/heavy.yml +4 -0
  12. package/sdk-core/.github/workflows/per-pr.yml +96 -0
  13. package/sdk-core/ARCHITECTURE.md +1 -1
  14. package/sdk-core/Cargo.toml +6 -0
  15. package/sdk-core/README.md +37 -21
  16. package/sdk-core/client/Cargo.toml +6 -3
  17. package/sdk-core/client/src/lib.rs +272 -138
  18. package/sdk-core/client/src/metrics.rs +68 -57
  19. package/sdk-core/client/src/raw.rs +191 -45
  20. package/sdk-core/client/src/retry.rs +20 -0
  21. package/sdk-core/client/src/worker_registry/mod.rs +264 -0
  22. package/sdk-core/client/src/workflow_handle/mod.rs +2 -1
  23. package/sdk-core/core/Cargo.toml +16 -18
  24. package/sdk-core/core/src/core_tests/child_workflows.rs +7 -7
  25. package/sdk-core/core/src/core_tests/mod.rs +1 -0
  26. package/sdk-core/core/src/core_tests/replay_flag.rs +29 -39
  27. package/sdk-core/core/src/core_tests/updates.rs +73 -0
  28. package/sdk-core/core/src/core_tests/workflow_tasks.rs +52 -1
  29. package/sdk-core/core/src/ephemeral_server/mod.rs +34 -11
  30. package/sdk-core/core/src/internal_flags.rs +7 -1
  31. package/sdk-core/core/src/lib.rs +19 -36
  32. package/sdk-core/core/src/protosext/mod.rs +11 -3
  33. package/sdk-core/core/src/protosext/protocol_messages.rs +102 -0
  34. package/sdk-core/core/src/replay/mod.rs +100 -48
  35. package/sdk-core/core/src/telemetry/log_export.rs +161 -28
  36. package/sdk-core/core/src/telemetry/metrics.rs +869 -248
  37. package/sdk-core/core/src/telemetry/mod.rs +135 -239
  38. package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -31
  39. package/sdk-core/core/src/test_help/mod.rs +63 -4
  40. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +12 -2
  41. package/sdk-core/core/src/worker/activities.rs +276 -10
  42. package/sdk-core/core/src/worker/client/mocks.rs +18 -0
  43. package/sdk-core/core/src/worker/client.rs +16 -3
  44. package/sdk-core/core/src/worker/mod.rs +50 -19
  45. package/sdk-core/core/src/worker/slot_provider.rs +175 -0
  46. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +27 -34
  47. package/sdk-core/core/src/worker/workflow/history_update.rs +4 -1
  48. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +36 -94
  49. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +34 -22
  50. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +50 -34
  51. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +106 -92
  52. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +22 -21
  53. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +386 -499
  54. package/sdk-core/core/src/worker/workflow/machines/mod.rs +12 -2
  55. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +33 -26
  56. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +198 -215
  57. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +66 -62
  58. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +88 -119
  59. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +3 -1
  60. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +411 -0
  61. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +26 -25
  62. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +302 -85
  63. package/sdk-core/core/src/worker/workflow/managed_run.rs +179 -132
  64. package/sdk-core/core/src/worker/workflow/mod.rs +121 -46
  65. package/sdk-core/core/src/worker/workflow/run_cache.rs +8 -12
  66. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +45 -38
  67. package/sdk-core/core-api/Cargo.toml +7 -6
  68. package/sdk-core/core-api/src/lib.rs +4 -12
  69. package/sdk-core/core-api/src/telemetry/metrics.rs +334 -0
  70. package/sdk-core/core-api/src/telemetry.rs +53 -42
  71. package/sdk-core/core-api/src/worker.rs +7 -0
  72. package/sdk-core/{.buildkite/docker → docker}/docker-compose.yaml +1 -1
  73. package/sdk-core/etc/dynamic-config.yaml +11 -1
  74. package/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +1 -1
  75. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +1 -3
  76. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +2 -2
  77. package/sdk-core/sdk/Cargo.toml +1 -1
  78. package/sdk-core/sdk/src/lib.rs +85 -7
  79. package/sdk-core/sdk/src/workflow_context/options.rs +4 -0
  80. package/sdk-core/sdk/src/workflow_context.rs +43 -15
  81. package/sdk-core/sdk/src/workflow_future.rs +334 -204
  82. package/sdk-core/sdk-core-protos/Cargo.toml +2 -2
  83. package/sdk-core/sdk-core-protos/build.rs +14 -14
  84. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +2 -0
  85. package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +99 -0
  86. package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +56 -0
  87. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.gen.yaml +20 -0
  88. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +11 -0
  89. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.yaml +18 -0
  90. package/sdk-core/sdk-core-protos/protos/api_upstream/google/api/annotations.proto +31 -0
  91. package/sdk-core/sdk-core-protos/protos/api_upstream/google/api/http.proto +379 -0
  92. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/any.proto +162 -0
  93. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/descriptor.proto +1212 -0
  94. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/duration.proto +115 -0
  95. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/empty.proto +51 -0
  96. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/timestamp.proto +144 -0
  97. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/wrappers.proto +123 -0
  98. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/batch/v1/message.proto +3 -5
  99. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/command/v1/message.proto +11 -13
  100. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/common/v1/message.proto +2 -4
  101. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
  102. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/reset.proto +1 -1
  103. package/sdk-core/{protos/api_upstream/build/tools.go → sdk-core-protos/protos/api_upstream/temporal/api/export/v1/message.proto} +22 -6
  104. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/filter/v1/message.proto +2 -4
  105. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/history/v1/message.proto +21 -23
  106. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/namespace/v1/message.proto +2 -4
  107. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/operatorservice/v1/request_response.proto +2 -0
  108. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -0
  109. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/replication/v1/message.proto +1 -3
  110. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/schedule/v1/message.proto +36 -20
  111. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +13 -0
  112. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -4
  113. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/update/v1/message.proto +1 -1
  114. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/version/v1/message.proto +2 -3
  115. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/workflow/v1/message.proto +18 -20
  116. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/workflowservice/v1/request_response.proto +84 -32
  117. package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/workflowservice/v1/service.proto +205 -47
  118. package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +57 -0
  119. package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +27 -0
  120. package/sdk-core/sdk-core-protos/src/history_builder.rs +67 -2
  121. package/sdk-core/sdk-core-protos/src/lib.rs +75 -2
  122. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  123. package/sdk-core/test-utils/Cargo.toml +5 -1
  124. package/sdk-core/test-utils/src/canned_histories.rs +3 -57
  125. package/sdk-core/test-utils/src/interceptors.rs +46 -0
  126. package/sdk-core/test-utils/src/lib.rs +106 -38
  127. package/sdk-core/tests/integ_tests/metrics_tests.rs +110 -15
  128. package/sdk-core/tests/integ_tests/queries_tests.rs +174 -3
  129. package/sdk-core/tests/integ_tests/update_tests.rs +908 -0
  130. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +44 -1
  131. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
  132. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  133. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -4
  134. package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +61 -0
  135. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +27 -2
  136. package/sdk-core/tests/integ_tests/workflow_tests.rs +1 -0
  137. package/sdk-core/tests/main.rs +2 -1
  138. package/sdk-core/tests/runner.rs +15 -2
  139. package/src/conversions.rs +75 -89
  140. package/src/helpers.rs +74 -0
  141. package/src/runtime.rs +17 -6
  142. package/src/worker.rs +14 -61
  143. package/ts/index.ts +21 -52
  144. package/sdk-core/.buildkite/docker/Dockerfile +0 -9
  145. package/sdk-core/.buildkite/docker/build.sh +0 -5
  146. package/sdk-core/.buildkite/docker/docker-compose-ci.yaml +0 -27
  147. package/sdk-core/.buildkite/pipeline.yml +0 -57
  148. package/sdk-core/.github/workflows/semgrep.yml +0 -25
  149. package/sdk-core/core/src/worker/workflow/bridge.rs +0 -35
  150. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +0 -215
  151. package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +0 -2
  152. package/sdk-core/protos/api_upstream/Makefile +0 -80
  153. package/sdk-core/protos/api_upstream/api-linter.yaml +0 -40
  154. package/sdk-core/protos/api_upstream/buf.yaml +0 -9
  155. package/sdk-core/protos/api_upstream/build/go.mod +0 -7
  156. package/sdk-core/protos/api_upstream/build/go.sum +0 -5
  157. package/sdk-core/protos/api_upstream/go.mod +0 -6
  158. package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +0 -141
  159. /package/sdk-core/{.buildkite/docker → docker}/docker-compose-telem.yaml +0 -0
  160. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.buildkite/docker-compose.yml +0 -0
  161. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.buildkite/pipeline.yml +0 -0
  162. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/CODEOWNERS +0 -0
  163. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  164. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/workflows/publish-docs.yml +0 -0
  165. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/.github/workflows/trigger-api-go-update.yml +0 -0
  166. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/LICENSE +0 -0
  167. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/README.md +0 -0
  168. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -0
  169. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/command_type.proto +0 -0
  170. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/common.proto +0 -0
  171. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/event_type.proto +0 -0
  172. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/namespace.proto +0 -0
  173. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/query.proto +0 -0
  174. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/schedule.proto +0 -0
  175. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -0
  176. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/update.proto +0 -0
  177. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/enums/v1/workflow.proto +0 -0
  178. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/errordetails/v1/message.proto +0 -0
  179. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/failure/v1/message.proto +0 -0
  180. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/protocol/v1/message.proto +0 -0
  181. /package/sdk-core/{protos → sdk-core-protos/protos}/api_upstream/temporal/api/query/v1/message.proto +0 -0
  182. /package/sdk-core/{protos → sdk-core-protos/protos}/google/rpc/status.proto +0 -0
  183. /package/sdk-core/{protos → sdk-core-protos/protos}/grpc/health/v1/health.proto +0 -0
  184. /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/activity_result/activity_result.proto +0 -0
  185. /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/activity_task/activity_task.proto +0 -0
  186. /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/child_workflow/child_workflow.proto +0 -0
  187. /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/common/common.proto +0 -0
  188. /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/core_interface.proto +0 -0
  189. /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/external_data/external_data.proto +0 -0
  190. /package/sdk-core/{protos → sdk-core-protos/protos}/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +0 -0
  191. /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/Makefile +0 -0
  192. /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/api-linter.yaml +0 -0
  193. /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/buf.yaml +0 -0
  194. /package/sdk-core/{protos/api_upstream → sdk-core-protos/protos/testsrv_upstream}/dependencies/gogoproto/gogo.proto +0 -0
  195. /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +0 -0
  196. /package/sdk-core/{protos → sdk-core-protos/protos}/testsrv_upstream/temporal/api/testservice/v1/service.proto +0 -0
@@ -305,14 +305,17 @@ impl Cancellable for SignalExternalMachine {
305
305
  #[cfg(test)]
306
306
  mod tests {
307
307
  use super::*;
308
- use crate::{replay::TestHistoryBuilder, worker::workflow::ManagedWFFunc};
309
- use std::mem::discriminant;
310
- use temporal_sdk::{
311
- CancellableFuture, SignalWorkflowOptions, WfContext, WorkflowFunction, WorkflowResult,
308
+ use crate::{
309
+ replay::TestHistoryBuilder,
310
+ test_help::{build_fake_sdk, MockPollCfg},
312
311
  };
313
- use temporal_sdk_core_protos::coresdk::workflow_activation::{
314
- workflow_activation_job, WorkflowActivationJob,
312
+ use std::mem::discriminant;
313
+ use temporal_sdk::{CancellableFuture, SignalWorkflowOptions, WfContext, WorkflowResult};
314
+ use temporal_sdk_core_protos::{
315
+ coresdk::workflow_activation::{workflow_activation_job, WorkflowActivationJob},
316
+ DEFAULT_WORKFLOW_TYPE,
315
317
  };
318
+ use temporal_sdk_core_test_utils::interceptors::ActivationAssertionsInterceptor;
316
319
 
317
320
  const SIGNAME: &str = "signame";
318
321
 
@@ -344,37 +347,35 @@ mod tests {
344
347
  t.add_full_wf_task();
345
348
  t.add_workflow_execution_completed();
346
349
 
347
- let wff = WorkflowFunction::new(signal_sender);
348
- let mut wfm = ManagedWFFunc::new(t, wff, vec![]);
349
- wfm.get_next_activation().await.unwrap();
350
- let mut cmds = wfm.get_server_commands().commands;
351
- assert_eq!(cmds.len(), 1);
352
- assert_eq!(
353
- cmds[0].command_type(),
354
- CommandType::SignalExternalWorkflowExecution
355
- );
356
- assert_matches!(
357
- cmds.remove(0).attributes.unwrap(),
358
- command::Attributes::SignalExternalWorkflowExecutionCommandAttributes(attrs) => {
359
- assert_eq!(attrs.signal_name, SIGNAME);
360
- assert_eq!(attrs.input.unwrap().payloads[0],
361
- b"hi!".into());
362
- assert_eq!(*attrs.header.unwrap().fields.get("tupac").unwrap(), b"shakur".into());
363
- }
364
- );
365
- wfm.get_next_activation().await.unwrap();
366
- let cmds = wfm.get_server_commands().commands;
367
- assert_eq!(cmds.len(), 1);
368
- if fails {
369
- assert_eq!(cmds[0].command_type(), CommandType::FailWorkflowExecution);
370
- } else {
371
- assert_eq!(
372
- cmds[0].command_type(),
373
- CommandType::CompleteWorkflowExecution
374
- );
375
- }
350
+ let mut mock_cfg = MockPollCfg::from_hist_builder(t);
351
+ mock_cfg.completion_asserts_from_expectations(|mut asserts| {
352
+ asserts.then(move |wft| {
353
+ assert_matches!(wft.commands.as_slice(),
354
+ [Command { attributes: Some(
355
+ command::Attributes::SignalExternalWorkflowExecutionCommandAttributes(attrs)),..}] => {
356
+ assert_eq!(attrs.signal_name, SIGNAME);
357
+ assert_eq!(attrs.input.as_ref().unwrap().payloads[0], b"hi!".into());
358
+ assert_eq!(*attrs.header.as_ref().unwrap().fields.get("tupac").unwrap(),
359
+ b"shakur".into());
360
+ }
361
+ );
362
+ }).then(move |wft| {
363
+ let cmds = &wft.commands;
364
+ assert_eq!(cmds.len(), 1);
365
+ if fails {
366
+ assert_eq!(cmds[0].command_type(), CommandType::FailWorkflowExecution);
367
+ } else {
368
+ assert_eq!(
369
+ cmds[0].command_type(),
370
+ CommandType::CompleteWorkflowExecution
371
+ );
372
+ }
373
+ });
374
+ });
376
375
 
377
- wfm.shutdown().await.unwrap();
376
+ let mut worker = build_fake_sdk(mock_cfg);
377
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, signal_sender);
378
+ worker.run().await.unwrap();
378
379
  }
379
380
 
380
381
  #[tokio::test]
@@ -384,7 +385,34 @@ mod tests {
384
385
  t.add_full_wf_task();
385
386
  t.add_workflow_execution_completed();
386
387
 
387
- let wff = WorkflowFunction::new(|ctx: WfContext| async move {
388
+ let mut mock_cfg = MockPollCfg::from_hist_builder(t);
389
+ let mut aai = ActivationAssertionsInterceptor::default();
390
+ aai.skip_one().then(move |act| {
391
+ assert_matches!(
392
+ &act.jobs[0],
393
+ WorkflowActivationJob {
394
+ variant: Some(workflow_activation_job::Variant::ResolveSignalExternalWorkflow(
395
+ ResolveSignalExternalWorkflow {
396
+ failure: Some(c),
397
+ ..
398
+ }
399
+ ))
400
+ } => c.message == SIG_CANCEL_MSG
401
+ );
402
+ });
403
+ mock_cfg.completion_asserts_from_expectations(|mut asserts| {
404
+ asserts.then(move |wft| {
405
+ assert_eq!(wft.commands.len(), 1);
406
+ assert_eq!(
407
+ wft.commands[0].command_type(),
408
+ CommandType::CompleteWorkflowExecution
409
+ );
410
+ });
411
+ });
412
+
413
+ let mut worker = build_fake_sdk(mock_cfg);
414
+ worker.set_worker_interceptor(aai);
415
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, |ctx: WfContext| async move {
388
416
  let sig = ctx.signal_workflow(SignalWorkflowOptions::new(
389
417
  "fake_wid",
390
418
  "fake_rid",
@@ -395,31 +423,7 @@ mod tests {
395
423
  let _res = sig.await;
396
424
  Ok(().into())
397
425
  });
398
- let mut wfm = ManagedWFFunc::new(t, wff, vec![]);
399
-
400
- wfm.get_next_activation().await.unwrap();
401
- // No commands b/c we're waiting on the signal which is immediately going to be cancelled
402
- let cmds = wfm.get_server_commands().commands;
403
- assert_eq!(cmds.len(), 0);
404
- let act = wfm.get_next_activation().await.unwrap();
405
- assert_matches!(
406
- &act.jobs[0],
407
- WorkflowActivationJob {
408
- variant: Some(workflow_activation_job::Variant::ResolveSignalExternalWorkflow(
409
- ResolveSignalExternalWorkflow {
410
- failure: Some(c),
411
- ..
412
- }
413
- ))
414
- } => c.message == SIG_CANCEL_MSG
415
- );
416
- let cmds = wfm.get_server_commands().commands;
417
- assert_eq!(cmds.len(), 1);
418
- assert_eq!(
419
- cmds[0].command_type(),
420
- CommandType::CompleteWorkflowExecution
421
- );
422
- wfm.shutdown().await.unwrap();
426
+ worker.run().await.unwrap();
423
427
  }
424
428
 
425
429
  #[test]
@@ -196,7 +196,7 @@ impl StartCommandRecorded {
196
196
  if dat.attrs.seq.to_string() == attrs.timer_id {
197
197
  TransitionResult::ok(vec![TimerMachineCommand::Complete], Fired::default())
198
198
  } else {
199
- TransitionResult::Err(WFMachinesError::Fatal(format!(
199
+ TransitionResult::Err(WFMachinesError::Nondeterminism(format!(
200
200
  "Timer fired event did not have expected timer id {}, it was {}!",
201
201
  dat.attrs.seq, attrs.timer_id
202
202
  )))
@@ -264,154 +264,123 @@ impl Cancellable for TimerMachine {
264
264
  mod test {
265
265
  use super::*;
266
266
  use crate::{
267
- replay::TestHistoryBuilder, test_help::canned_histories, worker::workflow::ManagedWFFunc,
267
+ replay::TestHistoryBuilder,
268
+ test_help::{build_fake_sdk, canned_histories, MockPollCfg},
268
269
  };
269
- use rstest::{fixture, rstest};
270
270
  use std::{mem::discriminant, time::Duration};
271
- use temporal_sdk::{CancellableFuture, WfContext, WorkflowFunction};
272
-
273
- #[fixture]
274
- fn happy_wfm() -> ManagedWFFunc {
275
- /*
276
- We have two versions of this test, one which processes the history in two calls, and one
277
- which replays all of it in one go. Both versions must produce the same two activations.
278
- However, The former will iterate the machines three times and the latter will iterate
279
- them twice.
280
-
281
- There are two workflow tasks, so it seems we should iterate two times, but the reason
282
- for the extra iteration in the incremental version is that we need to "wait" for the
283
- timer to fire. In the all-in-one-go test, the timer is created and resolved in the same
284
- task, hence no extra loop.
285
- */
286
- let func = WorkflowFunction::new(|command_sink: WfContext| async move {
287
- command_sink.timer(Duration::from_secs(5)).await;
288
- Ok(().into())
289
- });
271
+ use temporal_sdk::{CancellableFuture, WfContext, WorkflowResult};
272
+ use temporal_sdk_core_protos::{
273
+ temporal::api::{enums::v1::WorkflowTaskFailedCause, failure::v1::Failure},
274
+ DEFAULT_WORKFLOW_TYPE,
275
+ };
290
276
 
291
- let t = canned_histories::single_timer("1");
292
- assert_eq!(2, t.get_full_history_info().unwrap().wf_task_count());
293
- ManagedWFFunc::new(t, func, vec![])
277
+ async fn happy_timer(ctx: WfContext) -> WorkflowResult<()> {
278
+ ctx.timer(Duration::from_secs(5)).await;
279
+ Ok(().into())
294
280
  }
295
281
 
296
- #[rstest]
297
282
  #[tokio::test]
298
- async fn test_fire_happy_path_inc(mut happy_wfm: ManagedWFFunc) {
299
- happy_wfm.get_next_activation().await.unwrap();
300
- let commands = happy_wfm.get_server_commands().commands;
301
- assert_eq!(commands.len(), 1);
302
- assert_eq!(commands[0].command_type, CommandType::StartTimer as i32);
303
-
304
- happy_wfm.get_next_activation().await.unwrap();
305
- let commands = happy_wfm.get_server_commands().commands;
306
- assert_eq!(commands.len(), 1);
307
- assert_eq!(commands.len(), 1);
308
- assert_eq!(
309
- commands[0].command_type,
310
- CommandType::CompleteWorkflowExecution as i32
311
- );
312
- happy_wfm.shutdown().await.unwrap();
313
- }
283
+ async fn test_fire_happy_path_inc() {
284
+ let t = canned_histories::single_timer("1");
285
+ let mut mock_cfg = MockPollCfg::from_hist_builder(t);
286
+ mock_cfg.completion_asserts_from_expectations(|mut asserts| {
287
+ asserts
288
+ .then(move |wft| {
289
+ assert_eq!(wft.commands.len(), 1);
290
+ assert_eq!(wft.commands[0].command_type(), CommandType::StartTimer);
291
+ })
292
+ .then(move |wft| {
293
+ assert_eq!(wft.commands.len(), 1);
294
+ assert_eq!(
295
+ wft.commands[0].command_type(),
296
+ CommandType::CompleteWorkflowExecution
297
+ );
298
+ });
299
+ });
314
300
 
315
- #[rstest]
316
- #[tokio::test]
317
- async fn test_fire_happy_path_full(mut happy_wfm: ManagedWFFunc) {
318
- happy_wfm.process_all_activations().await.unwrap();
319
- let commands = happy_wfm.get_server_commands().commands;
320
- assert_eq!(commands.len(), 1);
321
- assert_eq!(
322
- commands[0].command_type,
323
- CommandType::CompleteWorkflowExecution as i32
324
- );
325
- happy_wfm.shutdown().await.unwrap();
301
+ let mut worker = build_fake_sdk(mock_cfg);
302
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, happy_timer);
303
+ worker.run().await.unwrap();
326
304
  }
327
305
 
328
306
  #[tokio::test]
329
307
  async fn mismatched_timer_ids_errors() {
330
- let func = WorkflowFunction::new(|command_sink: WfContext| async move {
331
- command_sink.timer(Duration::from_secs(5)).await;
332
- Ok(().into())
333
- });
334
-
335
308
  let t = canned_histories::single_timer("badid");
336
- let mut wfm = ManagedWFFunc::new(t, func, vec![]);
337
- let act = wfm.process_all_activations().await;
338
- assert!(act
339
- .unwrap_err()
340
- .to_string()
341
- .contains("Timer fired event did not have expected timer id 1"));
342
- wfm.shutdown().await.unwrap();
343
- }
344
-
345
- #[fixture]
346
- fn cancellation_setup() -> ManagedWFFunc {
347
- let func = WorkflowFunction::new(|ctx: WfContext| async move {
348
- let cancel_timer_fut = ctx.timer(Duration::from_secs(500));
309
+ let mut mock_cfg = MockPollCfg::from_hist_builder(t);
310
+ mock_cfg.num_expected_fails = 1;
311
+ mock_cfg.expect_fail_wft_matcher = Box::new(move |_, cause, f| {
312
+ matches!(cause, WorkflowTaskFailedCause::NonDeterministicError)
313
+ && matches!(f, Some(Failure { source, .. })
314
+ if source.contains("Timer fired event did not have expected timer id 1"))
315
+ });
316
+ let mut worker = build_fake_sdk(mock_cfg);
317
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, |ctx: WfContext| async move {
349
318
  ctx.timer(Duration::from_secs(5)).await;
350
- // Cancel the first timer after having waited on the second
351
- cancel_timer_fut.cancel(&ctx);
352
- cancel_timer_fut.await;
353
319
  Ok(().into())
354
320
  });
355
-
356
- let t = canned_histories::cancel_timer("2", "1");
357
- ManagedWFFunc::new(t, func, vec![])
321
+ worker.run().await.unwrap();
358
322
  }
359
323
 
360
- #[rstest]
361
- #[tokio::test]
362
- async fn incremental_cancellation(#[from(cancellation_setup)] mut wfm: ManagedWFFunc) {
363
- wfm.get_next_activation().await.unwrap();
364
- let commands = wfm.get_server_commands().commands;
365
- assert_eq!(commands.len(), 2);
366
- assert_eq!(commands[0].command_type, CommandType::StartTimer as i32);
367
- assert_eq!(commands[1].command_type, CommandType::StartTimer as i32);
368
-
369
- wfm.get_next_activation().await.unwrap();
370
- let commands = wfm.get_server_commands().commands;
371
- assert_eq!(commands.len(), 2);
372
- assert_eq!(commands[0].command_type, CommandType::CancelTimer as i32);
373
- assert_eq!(
374
- commands[1].command_type,
375
- CommandType::CompleteWorkflowExecution as i32
376
- );
377
-
378
- assert!(wfm.get_next_activation().await.unwrap().jobs.is_empty());
379
- let commands = wfm.get_server_commands().commands;
380
- // There should be no commands - the wf completed at the same time the timer was cancelled
381
- assert_eq!(commands.len(), 0);
382
- wfm.shutdown().await.unwrap();
324
+ async fn cancel_timer(ctx: WfContext) -> WorkflowResult<()> {
325
+ let cancel_timer_fut = ctx.timer(Duration::from_secs(500));
326
+ ctx.timer(Duration::from_secs(5)).await;
327
+ // Cancel the first timer after having waited on the second
328
+ cancel_timer_fut.cancel(&ctx);
329
+ cancel_timer_fut.await;
330
+ Ok(().into())
383
331
  }
384
332
 
385
- #[rstest]
386
333
  #[tokio::test]
387
- async fn full_cancellation(#[from(cancellation_setup)] mut wfm: ManagedWFFunc) {
388
- wfm.process_all_activations().await.unwrap();
389
- let commands = wfm.get_server_commands().commands;
390
- // There should be no commands - the wf completed at the same time the timer was cancelled
391
- assert_eq!(commands.len(), 0);
392
- wfm.shutdown().await.unwrap();
334
+ async fn incremental_cancellation() {
335
+ let t = canned_histories::cancel_timer("2", "1");
336
+ let mut mock_cfg = MockPollCfg::from_hist_builder(t);
337
+ mock_cfg.completion_asserts_from_expectations(|mut asserts| {
338
+ asserts
339
+ .then(move |wft| {
340
+ assert_eq!(wft.commands.len(), 2);
341
+ assert_eq!(wft.commands[0].command_type(), CommandType::StartTimer);
342
+ assert_eq!(wft.commands[1].command_type(), CommandType::StartTimer);
343
+ })
344
+ .then(move |wft| {
345
+ assert_eq!(wft.commands.len(), 2);
346
+ assert_eq!(wft.commands[0].command_type(), CommandType::CancelTimer);
347
+ assert_eq!(
348
+ wft.commands[1].command_type(),
349
+ CommandType::CompleteWorkflowExecution
350
+ );
351
+ });
352
+ });
353
+
354
+ let mut worker = build_fake_sdk(mock_cfg);
355
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, cancel_timer);
356
+ worker.run().await.unwrap();
393
357
  }
394
358
 
395
359
  #[tokio::test]
396
360
  async fn cancel_before_sent_to_server() {
397
- let func = WorkflowFunction::new(|ctx: WfContext| async move {
361
+ let mut t = TestHistoryBuilder::default();
362
+ t.add_by_type(EventType::WorkflowExecutionStarted);
363
+ t.add_full_wf_task();
364
+ t.add_workflow_execution_completed();
365
+ let mut mock_cfg = MockPollCfg::from_hist_builder(t);
366
+ mock_cfg.completion_asserts_from_expectations(|mut asserts| {
367
+ asserts.then(move |wft| {
368
+ assert_eq!(wft.commands.len(), 1);
369
+ assert_matches!(
370
+ wft.commands[0].command_type(),
371
+ CommandType::CompleteWorkflowExecution
372
+ );
373
+ });
374
+ });
375
+ let mut worker = build_fake_sdk(mock_cfg);
376
+ worker.register_wf(DEFAULT_WORKFLOW_TYPE, |ctx: WfContext| async move {
398
377
  let cancel_timer_fut = ctx.timer(Duration::from_secs(500));
399
378
  // Immediately cancel the timer
400
379
  cancel_timer_fut.cancel(&ctx);
401
380
  cancel_timer_fut.await;
402
381
  Ok(().into())
403
382
  });
404
-
405
- let mut t = TestHistoryBuilder::default();
406
- t.add_by_type(EventType::WorkflowExecutionStarted);
407
- t.add_full_wf_task();
408
- t.add_workflow_execution_completed();
409
- let mut wfm = ManagedWFFunc::new(t, func, vec![]);
410
-
411
- wfm.process_all_activations().await.unwrap();
412
- let commands = wfm.get_server_commands().commands;
413
- assert_eq!(commands.len(), 0);
414
- wfm.shutdown().await.unwrap();
383
+ worker.run().await.unwrap();
415
384
  }
416
385
 
417
386
  #[test]
@@ -78,7 +78,7 @@ mod machine_coverage_report {
78
78
  local_activity_state_machine::LocalActivityMachine,
79
79
  modify_workflow_properties_state_machine::ModifyWorkflowPropertiesMachine,
80
80
  patch_state_machine::PatchMachine, signal_external_state_machine::SignalExternalMachine,
81
- timer_state_machine::TimerMachine,
81
+ timer_state_machine::TimerMachine, update_state_machine::UpdateMachine,
82
82
  upsert_search_attributes_state_machine::UpsertSearchAttributesMachine,
83
83
  workflow_task_state_machine::WorkflowTaskMachine,
84
84
  };
@@ -118,6 +118,7 @@ mod machine_coverage_report {
118
118
  let mut la_mach = LocalActivityMachine::visualizer().to_owned();
119
119
  let mut upsert_search_attr = UpsertSearchAttributesMachine::visualizer().to_owned();
120
120
  let mut modify_wf_props = ModifyWorkflowPropertiesMachine::visualizer().to_owned();
121
+ let mut update = UpdateMachine::visualizer().to_owned();
121
122
 
122
123
  // This isn't at all efficient but doesn't need to be.
123
124
  // Replace transitions in the vizzes with green color if they are covered.
@@ -144,6 +145,7 @@ mod machine_coverage_report {
144
145
  m @ "ModifyWorkflowPropertiesMachine" => {
145
146
  cover_transitions(m, &mut modify_wf_props, coverage)
146
147
  }
148
+ m @ "UpdateMachine" => cover_transitions(m, &mut update, coverage),
147
149
  m => panic!("Unknown machine {m}"),
148
150
  }
149
151
  }