temporalio 0.0.2 → 0.1.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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -23
  3. data/bridge/Cargo.lock +168 -59
  4. data/bridge/Cargo.toml +4 -2
  5. data/bridge/sdk-core/README.md +19 -6
  6. data/bridge/sdk-core/client/src/lib.rs +215 -39
  7. data/bridge/sdk-core/client/src/metrics.rs +17 -8
  8. data/bridge/sdk-core/client/src/raw.rs +4 -4
  9. data/bridge/sdk-core/client/src/retry.rs +32 -20
  10. data/bridge/sdk-core/core/Cargo.toml +22 -9
  11. data/bridge/sdk-core/core/src/abstractions.rs +203 -14
  12. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +76 -41
  13. data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
  14. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +204 -83
  15. data/bridge/sdk-core/core/src/core_tests/queries.rs +3 -4
  16. data/bridge/sdk-core/core/src/core_tests/workers.rs +1 -3
  17. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +397 -54
  18. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
  19. data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
  20. data/bridge/sdk-core/core/src/lib.rs +16 -9
  21. data/bridge/sdk-core/core/src/telemetry/log_export.rs +1 -1
  22. data/bridge/sdk-core/core/src/telemetry/metrics.rs +69 -35
  23. data/bridge/sdk-core/core/src/telemetry/mod.rs +29 -13
  24. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +17 -12
  25. data/bridge/sdk-core/core/src/test_help/mod.rs +62 -12
  26. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
  27. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  28. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +352 -122
  29. data/bridge/sdk-core/core/src/worker/activities.rs +233 -157
  30. data/bridge/sdk-core/core/src/worker/client/mocks.rs +22 -2
  31. data/bridge/sdk-core/core/src/worker/client.rs +18 -2
  32. data/bridge/sdk-core/core/src/worker/mod.rs +165 -58
  33. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  34. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  35. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +856 -277
  36. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +100 -43
  37. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +7 -7
  38. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +5 -4
  39. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +87 -27
  40. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +5 -4
  41. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +5 -4
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +5 -4
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +137 -62
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +25 -17
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +7 -6
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +103 -152
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +7 -7
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -9
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -7
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +5 -16
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +201 -121
  53. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +11 -14
  54. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +30 -15
  55. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1026 -376
  56. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +460 -384
  57. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  58. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  59. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  60. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +448 -718
  63. data/bridge/sdk-core/core-api/Cargo.toml +2 -1
  64. data/bridge/sdk-core/core-api/src/errors.rs +1 -34
  65. data/bridge/sdk-core/core-api/src/lib.rs +6 -2
  66. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -6
  67. data/bridge/sdk-core/core-api/src/worker.rs +14 -1
  68. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
  69. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
  70. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  71. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
  72. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
  73. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
  74. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
  75. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
  76. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
  77. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
  78. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
  79. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
  80. data/bridge/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
  81. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  82. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
  83. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
  84. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
  85. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
  86. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
  87. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
  88. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  89. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  90. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
  91. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +7 -0
  92. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +1 -0
  93. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
  94. data/bridge/sdk-core/sdk/Cargo.toml +3 -2
  95. data/bridge/sdk-core/sdk/src/lib.rs +87 -20
  96. data/bridge/sdk-core/sdk/src/workflow_future.rs +9 -8
  97. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  98. data/bridge/sdk-core/sdk-core-protos/build.rs +36 -1
  99. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +100 -87
  100. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +5 -1
  101. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +175 -57
  102. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  103. data/bridge/sdk-core/test-utils/Cargo.toml +3 -1
  104. data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
  105. data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
  106. data/bridge/sdk-core/test-utils/src/lib.rs +82 -23
  107. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  108. data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
  109. data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
  110. data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  111. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  112. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
  113. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
  114. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
  115. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  116. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  117. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
  118. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  119. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  120. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
  121. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  122. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  123. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +72 -191
  124. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -0
  125. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
  126. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
  127. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  128. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  129. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  130. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  131. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
  132. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +10 -11
  133. data/bridge/sdk-core/tests/main.rs +3 -13
  134. data/bridge/sdk-core/tests/runner.rs +75 -36
  135. data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
  136. data/bridge/src/connection.rs +41 -25
  137. data/bridge/src/lib.rs +269 -14
  138. data/bridge/src/runtime.rs +1 -1
  139. data/bridge/src/test_server.rs +153 -0
  140. data/bridge/src/worker.rs +89 -16
  141. data/lib/gen/temporal/api/command/v1/message_pb.rb +4 -18
  142. data/lib/gen/temporal/api/common/v1/message_pb.rb +4 -0
  143. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +1 -3
  144. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -3
  145. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +2 -0
  146. data/lib/gen/temporal/api/enums/v1/update_pb.rb +6 -4
  147. data/lib/gen/temporal/api/history/v1/message_pb.rb +27 -19
  148. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -0
  149. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +3 -0
  150. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
  151. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
  152. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
  153. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
  154. data/lib/gen/temporal/api/update/v1/message_pb.rb +72 -0
  155. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +26 -16
  156. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
  157. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
  158. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
  159. data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
  160. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
  161. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
  162. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +27 -21
  163. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +28 -24
  164. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
  165. data/lib/temporalio/activity/context.rb +13 -8
  166. data/lib/temporalio/activity/info.rb +1 -1
  167. data/lib/temporalio/bridge/connect_options.rb +15 -0
  168. data/lib/temporalio/bridge/retry_config.rb +24 -0
  169. data/lib/temporalio/bridge/tls_options.rb +19 -0
  170. data/lib/temporalio/client/implementation.rb +8 -8
  171. data/lib/temporalio/connection/retry_config.rb +44 -0
  172. data/lib/temporalio/connection/service.rb +20 -0
  173. data/lib/temporalio/connection/test_service.rb +92 -0
  174. data/lib/temporalio/connection/tls_options.rb +51 -0
  175. data/lib/temporalio/connection/workflow_service.rb +731 -0
  176. data/lib/temporalio/connection.rb +55 -720
  177. data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
  178. data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
  179. data/lib/temporalio/interceptor/chain.rb +5 -5
  180. data/lib/temporalio/interceptor/client.rb +8 -4
  181. data/lib/temporalio/interceptor.rb +22 -0
  182. data/lib/temporalio/retry_policy.rb +13 -3
  183. data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
  184. data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
  185. data/lib/temporalio/testing/workflow_environment.rb +112 -0
  186. data/lib/temporalio/testing.rb +175 -0
  187. data/lib/temporalio/version.rb +1 -1
  188. data/lib/temporalio/worker/activity_runner.rb +26 -4
  189. data/lib/temporalio/worker/activity_worker.rb +44 -18
  190. data/lib/temporalio/worker/sync_worker.rb +47 -11
  191. data/lib/temporalio/worker.rb +27 -21
  192. data/lib/temporalio/workflow/async.rb +46 -0
  193. data/lib/temporalio/workflow/future.rb +138 -0
  194. data/lib/temporalio/workflow/info.rb +76 -0
  195. data/temporalio.gemspec +4 -3
  196. metadata +67 -17
  197. data/bridge/sdk-core/Cargo.lock +0 -2606
  198. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
  199. data/lib/bridge.so +0 -0
  200. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +0 -25
  201. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +0 -49
  202. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
@@ -1,12 +1,13 @@
1
1
  use std::time::Duration;
2
- use temporal_client::WorkflowOptions;
2
+
3
3
  use temporal_sdk::{WfContext, WorkflowResult};
4
4
  use temporal_sdk_core_protos::coresdk::{
5
5
  workflow_commands::{CancelTimer, CompleteWorkflowExecution, StartTimer},
6
6
  workflow_completion::WorkflowActivationCompletion,
7
7
  };
8
8
  use temporal_sdk_core_test_utils::{
9
- init_core_and_create_wf, start_timer_cmd, CoreWfStarter, WorkerTestHelpers,
9
+ drain_pollers_and_shutdown, init_core_and_create_wf, start_timer_cmd, CoreWfStarter,
10
+ WorkerTestHelpers,
10
11
  };
11
12
 
12
13
  pub async fn timer_wf(command_sink: WfContext) -> WorkflowResult<()> {
@@ -18,18 +19,11 @@ pub async fn timer_wf(command_sink: WfContext) -> WorkflowResult<()> {
18
19
  async fn timer_workflow_workflow_driver() {
19
20
  let wf_name = "timer_wf_new";
20
21
  let mut starter = CoreWfStarter::new(wf_name);
22
+ starter.no_remote_activities();
21
23
  let mut worker = starter.worker().await;
22
24
  worker.register_wf(wf_name.to_owned(), timer_wf);
23
25
 
24
- worker
25
- .submit_wf(
26
- wf_name.to_owned(),
27
- wf_name.to_owned(),
28
- vec![],
29
- WorkflowOptions::default(),
30
- )
31
- .await
32
- .unwrap();
26
+ starter.start_with_worker(wf_name, &mut worker).await;
33
27
  worker.run_until_done().await.unwrap();
34
28
  }
35
29
 
@@ -37,6 +31,7 @@ async fn timer_workflow_workflow_driver() {
37
31
  async fn timer_workflow_manual() {
38
32
  let mut starter = init_core_and_create_wf("timer_workflow").await;
39
33
  let core = starter.get_worker().await;
34
+ starter.no_remote_activities();
40
35
  let task = core.poll_workflow_activation().await.unwrap();
41
36
  core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
42
37
  task.run_id,
@@ -50,13 +45,14 @@ async fn timer_workflow_manual() {
50
45
  .unwrap();
51
46
  let task = core.poll_workflow_activation().await.unwrap();
52
47
  core.complete_execution(&task.run_id).await;
53
- core.shutdown().await;
48
+ drain_pollers_and_shutdown(&core).await;
54
49
  }
55
50
 
56
51
  #[tokio::test]
57
52
  async fn timer_cancel_workflow() {
58
53
  let mut starter = init_core_and_create_wf("timer_cancel_workflow").await;
59
54
  let core = starter.get_worker().await;
55
+ starter.no_remote_activities();
60
56
  let task = core.poll_workflow_activation().await.unwrap();
61
57
  core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
62
58
  task.run_id,
@@ -115,17 +111,10 @@ async fn parallel_timer_wf(command_sink: WfContext) -> WorkflowResult<()> {
115
111
  async fn parallel_timers() {
116
112
  let wf_name = "parallel_timers";
117
113
  let mut starter = CoreWfStarter::new(wf_name);
114
+ starter.no_remote_activities();
118
115
  let mut worker = starter.worker().await;
119
116
  worker.register_wf(wf_name.to_owned(), parallel_timer_wf);
120
117
 
121
- worker
122
- .submit_wf(
123
- wf_name.to_owned(),
124
- wf_name.to_owned(),
125
- vec![],
126
- WorkflowOptions::default(),
127
- )
128
- .await
129
- .unwrap();
118
+ starter.start_with_worker(wf_name, &mut worker).await;
130
119
  worker.run_until_done().await.unwrap();
131
120
  }
@@ -1,9 +1,9 @@
1
- use log::warn;
2
1
  use std::{collections::HashMap, env};
3
2
  use temporal_client::{WorkflowClientTrait, WorkflowOptions};
4
3
  use temporal_sdk::{WfContext, WorkflowResult};
5
4
  use temporal_sdk_core_protos::coresdk::{AsJsonPayloadExt, FromJsonPayloadExt};
6
- use temporal_sdk_core_test_utils::{CoreWfStarter, INTEG_TEMPORALITE_USED_ENV_VAR};
5
+ use temporal_sdk_core_test_utils::{CoreWfStarter, INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR};
6
+ use tracing::warn;
7
7
  use uuid::Uuid;
8
8
 
9
9
  // These are initialized on the server as part of the autosetup container which we
@@ -24,9 +24,11 @@ async fn sends_upsert() {
24
24
  let wf_name = "sends_upsert_search_attrs";
25
25
  let wf_id = Uuid::new_v4();
26
26
  let mut starter = CoreWfStarter::new(wf_name);
27
+ starter.no_remote_activities();
27
28
  let mut worker = starter.worker().await;
28
- if env::var(INTEG_TEMPORALITE_USED_ENV_VAR).is_ok() {
29
- warn!("skipping sends_upsert -- does not work on temporalite");
29
+ // TODO: this should be supported in server 1.20, remove this condition when CLI is upgraded.
30
+ if env::var(INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR).is_ok() {
31
+ warn!("skipping sends_upsert -- does not work on temporal dev server");
30
32
  return;
31
33
  }
32
34
 
@@ -42,8 +42,8 @@ use temporal_sdk_core_protos::{
42
42
  temporal::api::{failure::v1::Failure, history::v1::history_event},
43
43
  };
44
44
  use temporal_sdk_core_test_utils::{
45
- history_from_proto_binary, init_core_and_create_wf, init_core_replay_preloaded,
46
- schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
45
+ drain_pollers_and_shutdown, history_from_proto_binary, init_core_and_create_wf,
46
+ init_core_replay_preloaded, schedule_activity_cmd, CoreWfStarter, WorkerTestHelpers,
47
47
  };
48
48
  use tokio::time::sleep;
49
49
  use uuid::Uuid;
@@ -58,8 +58,7 @@ async fn parallel_workflows_same_queue() {
58
58
  let num_workflows = 25usize;
59
59
 
60
60
  let run_ids: Vec<_> = future::join_all(
61
- (0..num_workflows)
62
- .map(|i| starter.start_wf_with_id(format!("wf-id-{}", i), WorkflowOptions::default())),
61
+ (0..num_workflows).map(|i| starter.start_wf_with_id(format!("wf-id-{i}"))),
63
62
  )
64
63
  .await;
65
64
 
@@ -104,7 +103,7 @@ async fn parallel_workflows_same_queue() {
104
103
  for handle in handles {
105
104
  handle.await.unwrap()
106
105
  }
107
- core.shutdown().await;
106
+ drain_pollers_and_shutdown(&core).await;
108
107
  }
109
108
 
110
109
  static RUN_CT: AtomicUsize = AtomicUsize::new(0);
@@ -118,7 +117,7 @@ pub async fn cache_evictions_wf(command_sink: WfContext) -> WorkflowResult<()> {
118
117
  async fn workflow_lru_cache_evictions() {
119
118
  let wf_type = "workflow_lru_cache_evictions";
120
119
  let mut starter = CoreWfStarter::new(wf_type);
121
- starter.max_cached_workflows(1);
120
+ starter.no_remote_activities().max_cached_workflows(1);
122
121
  let mut worker = starter.worker().await;
123
122
  worker.register_wf(wf_type.to_string(), cache_evictions_wf);
124
123
 
@@ -163,7 +162,7 @@ async fn shutdown_aborts_actively_blocked_poll() {
163
162
  let tcore = core.clone();
164
163
  let handle = tokio::spawn(async move {
165
164
  std::thread::sleep(Duration::from_millis(100));
166
- tcore.shutdown().await;
165
+ drain_pollers_and_shutdown(&tcore).await;
167
166
  });
168
167
  assert_matches!(
169
168
  core.poll_workflow_activation().await.unwrap_err(),
@@ -435,8 +434,8 @@ async fn wft_timeout_doesnt_create_unsolvable_autocomplete() {
435
434
  wf_starter
436
435
  // Test needs eviction on and a short timeout
437
436
  .max_cached_workflows(0)
438
- .max_wft(1)
439
- .wft_timeout(Duration::from_secs(1));
437
+ .max_wft(1);
438
+ wf_starter.workflow_options.task_timeout = Some(Duration::from_secs(1));
440
439
  let core = wf_starter.get_worker().await;
441
440
  let client = wf_starter.get_client().await;
442
441
  let task_q = wf_starter.get_task_queue();
@@ -460,7 +459,7 @@ async fn wft_timeout_doesnt_create_unsolvable_autocomplete() {
460
459
  .unwrap();
461
460
  wf_task
462
461
  };
463
- wf_starter.start_wf().await;
462
+ wf_starter.start_wf_with_id(wf_id.to_string()).await;
464
463
 
465
464
  // Poll and schedule the activity
466
465
  let wf_task = poll_sched_act().await;
@@ -572,7 +571,7 @@ async fn slow_completes_with_small_cache() {
572
571
  for i in 0..20 {
573
572
  worker
574
573
  .submit_wf(
575
- format!("{}_{}", wf_name, i),
574
+ format!("{wf_name}_{i}"),
576
575
  wf_name.to_owned(),
577
576
  vec![],
578
577
  WorkflowOptions::default(),
@@ -1,22 +1,12 @@
1
1
  //! Integration tests
2
- //!
3
- //! Note that integ tests which want to use the server (nearly all of them) *need* to use the
4
- //! `#[rstest]` macro and accept the TODO fixture to support auto setup & teardown of ephemeral
5
- //! local servers.
6
2
 
7
3
  #[macro_use]
8
4
  extern crate rstest;
5
+ #[macro_use]
6
+ extern crate temporal_sdk_core_test_utils;
9
7
 
10
8
  #[cfg(test)]
11
9
  mod integ_tests {
12
- #[macro_export]
13
- macro_rules! prost_dur {
14
- ($dur_call:ident $args:tt) => {
15
- std::time::Duration::$dur_call$args
16
- .try_into()
17
- .expect("test duration fits")
18
- };
19
- }
20
10
  mod client_tests;
21
11
  mod ephemeral_server_tests;
22
12
  mod heartbeat_tests;
@@ -46,7 +36,7 @@ mod integ_tests {
46
36
  let opts = get_integ_server_options();
47
37
  let runtime = CoreRuntime::new_assume_tokio(get_integ_telem_options()).unwrap();
48
38
  let mut retrying_client = opts
49
- .connect_no_namespace(runtime.metric_meter(), None)
39
+ .connect_no_namespace(runtime.metric_meter().as_deref(), None)
50
40
  .await
51
41
  .unwrap();
52
42
 
@@ -1,62 +1,101 @@
1
1
  use anyhow::{anyhow, bail};
2
+ use clap::Parser;
2
3
  use std::{
3
4
  env,
4
- env::args,
5
5
  path::{Path, PathBuf},
6
6
  process::Stdio,
7
7
  };
8
- use temporal_sdk_core::ephemeral_server::{TemporaliteConfigBuilder, TestServerConfigBuilder};
8
+ use temporal_sdk_core::ephemeral_server::{
9
+ TemporalDevServerConfigBuilder, TestServerConfigBuilder,
10
+ };
9
11
  use temporal_sdk_core_test_utils::{
10
- default_cached_download, INTEG_SERVER_TARGET_ENV_VAR, INTEG_TEMPORALITE_USED_ENV_VAR,
12
+ default_cached_download, INTEG_SERVER_TARGET_ENV_VAR, INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR,
11
13
  INTEG_TEST_SERVER_USED_ENV_VAR,
12
14
  };
13
15
  use tokio::{self, process::Command};
14
16
 
17
+ #[derive(clap::Parser)]
18
+ #[command(author, version, about, long_about = None)]
19
+ struct Cli {
20
+ /// Test harness to run. Anything defined as a `[[test]]` in core's `Cargo.toml` is valid.
21
+ #[arg(short, long, default_value = "integ_tests")]
22
+ test_name: String,
23
+
24
+ /// What kind of server to auto-launch, if any
25
+ #[arg(short, long, value_enum, default_value = "temporal-cli")]
26
+ server_kind: ServerKind,
27
+
28
+ /// Arguments to pass through to the `cargo test` command. Ex: `--release`
29
+ #[arg(short, long, allow_hyphen_values(true))]
30
+ cargo_test_args: Vec<String>,
31
+
32
+ /// The rest of the arguments will be passed through to the test harness
33
+ harness_args: Vec<String>,
34
+ }
35
+
36
+ #[derive(Copy, Clone, PartialEq, Eq, clap::ValueEnum)]
37
+ enum ServerKind {
38
+ /// Use Temporal-cli
39
+ TemporalCLI,
40
+ /// Use the Java test server
41
+ TestServer,
42
+ /// Do not automatically start any server
43
+ External,
44
+ }
45
+
15
46
  #[tokio::main]
16
47
  async fn main() -> Result<(), anyhow::Error> {
48
+ let Cli {
49
+ test_name,
50
+ server_kind,
51
+ cargo_test_args,
52
+ harness_args,
53
+ } = Cli::parse();
17
54
  let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
18
- let server_type = env::var("INTEG_SERVER_TYPE")
19
- .unwrap_or_else(|_| "temporalite".to_string())
20
- .to_lowercase();
21
55
  // Try building first, so that we error early on build failures & don't start server
56
+ let test_args_preamble = ["test", "--test", &test_name]
57
+ .into_iter()
58
+ .map(ToString::to_string)
59
+ .chain(cargo_test_args)
60
+ .collect::<Vec<_>>();
22
61
  let status = Command::new(&cargo)
23
- .args(["test", "--test", "integ_tests", "--no-run"])
62
+ .args([test_args_preamble.as_slice(), &["--no-run".to_string()]].concat())
24
63
  .status()
25
64
  .await?;
26
65
  if !status.success() {
27
66
  bail!("Building integration tests failed!");
28
67
  }
29
68
 
30
- // Move to clap if we start doing any more complicated input
31
- let (server, envs) = if server_type == "test-server" {
32
- let config = TestServerConfigBuilder::default()
33
- .exe(default_cached_download())
34
- .build()?;
35
- println!("Using java test server");
36
- (
37
- Some(config.start_server_with_output(Stdio::null()).await?),
38
- vec![(INTEG_TEST_SERVER_USED_ENV_VAR, "true")],
39
- )
40
- } else if server_type == "temporalite" {
41
- let config = TemporaliteConfigBuilder::default()
42
- .exe(default_cached_download())
43
- .build()?;
44
- println!("Using temporalite");
45
- (
46
- Some(config.start_server_with_output(Stdio::null()).await?),
47
- vec![(INTEG_TEMPORALITE_USED_ENV_VAR, "true")],
48
- )
49
- } else {
50
- println!("Not starting up a server. One should be running already.");
51
- (None, vec![])
69
+ let (server, envs) = match server_kind {
70
+ ServerKind::TemporalCLI => {
71
+ let config = TemporalDevServerConfigBuilder::default()
72
+ .exe(default_cached_download())
73
+ .build()?;
74
+ println!("Using temporal CLI");
75
+ (
76
+ Some(config.start_server_with_output(Stdio::null()).await?),
77
+ vec![(INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR, "true")],
78
+ )
79
+ }
80
+ ServerKind::TestServer => {
81
+ let config = TestServerConfigBuilder::default()
82
+ .exe(default_cached_download())
83
+ .build()?;
84
+ println!("Using java test server");
85
+ (
86
+ Some(config.start_server_with_output(Stdio::null()).await?),
87
+ vec![(INTEG_TEST_SERVER_USED_ENV_VAR, "true")],
88
+ )
89
+ }
90
+ ServerKind::External => {
91
+ println!("Not starting up a server. One should be running already.");
92
+ (None, vec![])
93
+ }
52
94
  };
53
95
 
54
- // Run the integ tests, passing through arguments
55
- let mut args = args();
56
- // Shift off binary name
57
- args.next();
58
96
  let mut cmd = Command::new(&cargo);
59
97
  if let Some(srv) = server.as_ref() {
98
+ println!("Running on {}", srv.target);
60
99
  cmd.env(
61
100
  INTEG_SERVER_TARGET_ENV_VAR,
62
101
  format!("http://{}", &srv.target),
@@ -66,10 +105,10 @@ async fn main() -> Result<(), anyhow::Error> {
66
105
  .envs(envs)
67
106
  .current_dir(project_root())
68
107
  .args(
69
- ["test", "--test", "integ_tests"]
108
+ test_args_preamble
70
109
  .into_iter()
71
- .map(ToString::to_string)
72
- .chain(args),
110
+ .chain(["--".to_string()])
111
+ .chain(harness_args),
73
112
  )
74
113
  .status()
75
114
  .await?;
@@ -0,0 +1,32 @@
1
+ use anyhow::Context;
2
+ use clap::Parser;
3
+ use futures_util::StreamExt;
4
+ use std::path::PathBuf;
5
+ use temporal_sdk_core::replay_wf_state_inputs;
6
+ use temporal_sdk_core_test_utils::{init_integ_telem, wf_input_saver::read_from_file};
7
+
8
+ #[derive(clap::Parser)]
9
+ #[command(author, version, about, long_about = None)]
10
+ struct Cli {
11
+ /// Path to file containing the saved wf input data
12
+ replay_data: PathBuf,
13
+ }
14
+
15
+ #[tokio::main]
16
+ async fn main() -> Result<(), anyhow::Error> {
17
+ init_integ_telem();
18
+ let Cli { replay_data } = Cli::parse();
19
+ let replay_dat = read_from_file(replay_data)
20
+ .await
21
+ .context("while reading replay data file")?;
22
+
23
+ replay_wf_state_inputs(
24
+ replay_dat.config,
25
+ replay_dat
26
+ .inputs
27
+ .map(|r| r.expect("Reading bytes from file works").to_vec()),
28
+ )
29
+ .await;
30
+
31
+ Ok(())
32
+ }
@@ -1,18 +1,18 @@
1
+ use parking_lot::RwLock;
1
2
  use std::collections::HashMap;
2
3
  use std::convert::TryFrom;
3
4
  use std::str::FromStr;
4
5
  use std::sync::Arc;
5
6
  use std::time::Duration;
6
7
  use temporal_client::{
7
- ClientInitError, ClientOptionsBuilder, ClientOptionsBuilderError, WorkflowService, RetryClient,
8
- ConfiguredClient, TemporalServiceClientWithMetrics
8
+ ClientInitError, ClientOptionsBuilderError, ConfiguredClient, RetryClient,
9
+ TemporalServiceClientWithMetrics, TestService, WorkflowService, ClientOptions,
9
10
  };
10
11
  use thiserror::Error;
11
- use tokio::{select};
12
- use tokio::runtime::{Runtime};
12
+ use tokio::runtime::Runtime;
13
+ use tokio::select;
13
14
  use tokio_util::sync::CancellationToken;
14
- use tonic::metadata::{MetadataKey,MetadataValue};
15
- use url::Url;
15
+ use tonic::metadata::{MetadataKey, MetadataValue};
16
16
 
17
17
  pub type Client = RetryClient<ConfiguredClient<TemporalServiceClientWithMetrics>>;
18
18
 
@@ -27,8 +27,8 @@ pub enum ConnectionError {
27
27
  #[error(transparent)]
28
28
  InvalidConnectionOptions(#[from] ClientOptionsBuilderError),
29
29
 
30
- #[error("`{0}` RPC call is not supported by the API")]
31
- InvalidRpc(String),
30
+ #[error("`{0}`/`{1}` RPC call is not supported by the API")]
31
+ InvalidRpc(String, String),
32
32
 
33
33
  #[error(transparent)]
34
34
  InvalidRpcMetadataKey(#[from] tonic::metadata::errors::InvalidMetadataKey),
@@ -36,6 +36,9 @@ pub enum ConnectionError {
36
36
  #[error(transparent)]
37
37
  InvalidRpcMetadataValue(#[from] tonic::metadata::errors::InvalidMetadataValue),
38
38
 
39
+ #[error("`{0}` Service is not supported by the API")]
40
+ InvalidService(String),
41
+
39
42
  #[error(transparent)]
40
43
  UnableToConnect(#[from] ClientInitError),
41
44
 
@@ -79,7 +82,15 @@ macro_rules! rpc_call {
79
82
  };
80
83
  }
81
84
 
82
- async fn make_rpc_call(mut client: Client, params: RpcParams) -> RpcResult {
85
+ async fn make_rpc_call(client: Client, params: RpcParams) -> RpcResult {
86
+ match params.service.as_str() {
87
+ "workflow_service" => make_workflow_service_rpc(client, params).await,
88
+ "test_service" => make_test_service_rpc(client, params).await,
89
+ _ => Err(ConnectionError::InvalidService(params.service.to_string()))
90
+ }
91
+ }
92
+
93
+ async fn make_workflow_service_rpc(mut client: Client, params: RpcParams) -> RpcResult {
83
94
  match params.rpc.as_str() {
84
95
  "register_namespace" => rpc_call!(client, register_namespace, params),
85
96
  "describe_namespace" => rpc_call!(client, describe_namespace, params),
@@ -88,7 +99,7 @@ async fn make_rpc_call(mut client: Client, params: RpcParams) -> RpcResult {
88
99
  "deprecate_namespace" => rpc_call!(client, deprecate_namespace, params),
89
100
  "start_workflow_execution" => rpc_call!(client, start_workflow_execution, params),
90
101
  "get_workflow_execution_history" => rpc_call!(client, get_workflow_execution_history, params),
91
- // "get_workflow_execution_history_reverse" => rpc_call!(client, get_workflow_execution_history_reverse, params),
102
+ "get_workflow_execution_history_reverse" => rpc_call!(client, get_workflow_execution_history_reverse, params),
92
103
  "poll_workflow_task_queue" => rpc_call!(client, poll_workflow_task_queue, params),
93
104
  "respond_workflow_task_completed" => rpc_call!(client, respond_workflow_task_completed, params),
94
105
  "respond_workflow_task_failed" => rpc_call!(client, respond_workflow_task_failed, params),
@@ -131,12 +142,24 @@ async fn make_rpc_call(mut client: Client, params: RpcParams) -> RpcResult {
131
142
  "list_schedules" => rpc_call!(client, list_schedules, params),
132
143
  "update_worker_build_id_ordering" => rpc_call!(client, update_worker_build_id_ordering, params),
133
144
  "get_worker_build_id_ordering" => rpc_call!(client, get_worker_build_id_ordering, params),
134
- "update_workflow" => rpc_call!(client, update_workflow, params),
145
+ "update_workflow_execution" => rpc_call!(client, update_workflow_execution, params),
135
146
  "start_batch_operation" => rpc_call!(client, start_batch_operation, params),
136
147
  "stop_batch_operation" => rpc_call!(client, stop_batch_operation, params),
137
148
  "describe_batch_operation" => rpc_call!(client, describe_batch_operation, params),
138
149
  "list_batch_operations" => rpc_call!(client, list_batch_operations, params),
139
- _ => Err(ConnectionError::InvalidRpc(params.rpc.to_string()))
150
+ _ => Err(ConnectionError::InvalidRpc(params.service.to_string(), params.rpc.to_string()))
151
+ }
152
+ }
153
+
154
+ async fn make_test_service_rpc(mut client: Client, params: RpcParams) -> RpcResult {
155
+ match params.rpc.as_str() {
156
+ "lock_time_skipping" => rpc_call!(client, lock_time_skipping, params),
157
+ "unlock_time_skipping" => rpc_call!(client, unlock_time_skipping, params),
158
+ "sleep" => rpc_call!(client, sleep, params),
159
+ "sleep_until" => rpc_call!(client, sleep_until, params),
160
+ "unlock_time_skipping_with_sleep" => rpc_call!(client, unlock_time_skipping_with_sleep, params),
161
+ "get_current_time" => rpc_call!(client, get_current_time, params),
162
+ _ => Err(ConnectionError::InvalidRpc(params.service.to_string(), params.rpc.to_string()))
140
163
  }
141
164
  }
142
165
 
@@ -148,27 +171,20 @@ pub struct Connection {
148
171
 
149
172
  pub struct RpcParams {
150
173
  pub rpc: String,
174
+ pub service: String,
151
175
  pub request: Vec<u8>,
152
176
  pub metadata: HashMap<String, String>,
153
177
  pub timeout_millis: Option<u64>
154
178
  }
155
179
 
156
- async fn create_client(host: String) -> Result<Client, ConnectionError> {
157
- let url = Url::try_from(&*host)?;
158
- let options = ClientOptionsBuilder::default()
159
- .identity("testtest".to_string())
160
- .target_url(url)
161
- .client_name("ruby-sdk".to_string())
162
- .client_version("0.0.1".to_string())
163
- .build()?;
164
-
165
- Ok(options.connect_no_namespace(None, None).await?)
180
+ async fn create_client(options: ClientOptions, headers: Option<HashMap<String, String>>) -> Result<Client, ConnectionError> {
181
+ let headers = headers.map(|h| Arc::new(RwLock::new(h)));
182
+ Ok(options.connect_no_namespace(None, headers).await?)
166
183
  }
167
184
 
168
185
  impl Connection {
169
- // TODO: Change the interface to accept a full configuration
170
- pub fn connect(runtime: Arc<Runtime>, host: String) -> Result<Self, ConnectionError> {
171
- let client = runtime.block_on(create_client(host))?;
186
+ pub fn connect(runtime: Arc<Runtime>, options: ClientOptions, headers: Option<HashMap<String, String>>) -> Result<Self, ConnectionError> {
187
+ let client = runtime.block_on(create_client(options, headers))?;
172
188
 
173
189
  Ok(Connection { client, runtime })
174
190
  }