@temporalio/core-bridge 1.13.0 → 1.13.2

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 (181) hide show
  1. package/Cargo.lock +239 -382
  2. package/Cargo.toml +11 -11
  3. package/lib/native.d.ts +10 -3
  4. package/package.json +3 -3
  5. package/releases/aarch64-apple-darwin/index.node +0 -0
  6. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  7. package/releases/x86_64-apple-darwin/index.node +0 -0
  8. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  9. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  10. package/sdk-core/.cargo/config.toml +71 -11
  11. package/sdk-core/.clippy.toml +1 -0
  12. package/sdk-core/.github/workflows/heavy.yml +2 -0
  13. package/sdk-core/.github/workflows/per-pr.yml +50 -18
  14. package/sdk-core/ARCHITECTURE.md +44 -48
  15. package/sdk-core/Cargo.toml +26 -7
  16. package/sdk-core/README.md +4 -0
  17. package/sdk-core/arch_docs/diagrams/TimerMachine_Coverage.puml +14 -0
  18. package/sdk-core/arch_docs/diagrams/initial_event_history.png +0 -0
  19. package/sdk-core/arch_docs/sdks_intro.md +299 -0
  20. package/sdk-core/client/Cargo.toml +8 -7
  21. package/sdk-core/client/src/callback_based.rs +1 -2
  22. package/sdk-core/client/src/lib.rs +485 -299
  23. package/sdk-core/client/src/metrics.rs +32 -8
  24. package/sdk-core/client/src/proxy.rs +124 -5
  25. package/sdk-core/client/src/raw.rs +598 -307
  26. package/sdk-core/client/src/replaceable.rs +253 -0
  27. package/sdk-core/client/src/retry.rs +9 -6
  28. package/sdk-core/client/src/worker_registry/mod.rs +19 -3
  29. package/sdk-core/client/src/workflow_handle/mod.rs +20 -17
  30. package/sdk-core/core/Cargo.toml +100 -31
  31. package/sdk-core/core/src/core_tests/activity_tasks.rs +55 -225
  32. package/sdk-core/core/src/core_tests/mod.rs +2 -8
  33. package/sdk-core/core/src/core_tests/queries.rs +3 -5
  34. package/sdk-core/core/src/core_tests/replay_flag.rs +3 -62
  35. package/sdk-core/core/src/core_tests/updates.rs +4 -5
  36. package/sdk-core/core/src/core_tests/workers.rs +4 -3
  37. package/sdk-core/core/src/core_tests/workflow_cancels.rs +10 -7
  38. package/sdk-core/core/src/core_tests/workflow_tasks.rs +28 -291
  39. package/sdk-core/core/src/ephemeral_server/mod.rs +15 -3
  40. package/sdk-core/core/src/internal_flags.rs +11 -1
  41. package/sdk-core/core/src/lib.rs +50 -36
  42. package/sdk-core/core/src/pollers/mod.rs +5 -5
  43. package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
  44. package/sdk-core/core/src/protosext/mod.rs +13 -5
  45. package/sdk-core/core/src/protosext/protocol_messages.rs +4 -11
  46. package/sdk-core/core/src/retry_logic.rs +256 -108
  47. package/sdk-core/core/src/telemetry/metrics.rs +1 -0
  48. package/sdk-core/core/src/telemetry/mod.rs +8 -2
  49. package/sdk-core/core/src/telemetry/prometheus_meter.rs +2 -2
  50. package/sdk-core/core/src/test_help/integ_helpers.rs +971 -0
  51. package/sdk-core/core/src/test_help/mod.rs +10 -1100
  52. package/sdk-core/core/src/test_help/unit_helpers.rs +218 -0
  53. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +42 -6
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +19 -19
  55. package/sdk-core/core/src/worker/activities.rs +10 -3
  56. package/sdk-core/core/src/worker/client/mocks.rs +3 -3
  57. package/sdk-core/core/src/worker/client.rs +130 -93
  58. package/sdk-core/core/src/worker/heartbeat.rs +12 -13
  59. package/sdk-core/core/src/worker/mod.rs +31 -21
  60. package/sdk-core/core/src/worker/nexus.rs +14 -3
  61. package/sdk-core/core/src/worker/slot_provider.rs +9 -0
  62. package/sdk-core/core/src/worker/tuner.rs +159 -0
  63. package/sdk-core/core/src/worker/workflow/history_update.rs +3 -265
  64. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +1 -54
  65. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -82
  66. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -67
  67. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -192
  68. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -43
  69. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +6 -554
  70. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -71
  71. package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +102 -3
  72. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +10 -539
  73. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -139
  74. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +1 -119
  75. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -63
  76. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +9 -4
  77. package/sdk-core/core/src/worker/workflow/mod.rs +5 -1
  78. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +8 -3
  79. package/sdk-core/core-api/Cargo.toml +4 -4
  80. package/sdk-core/core-api/src/envconfig.rs +153 -54
  81. package/sdk-core/core-api/src/lib.rs +68 -0
  82. package/sdk-core/core-api/src/telemetry/metrics.rs +2 -1
  83. package/sdk-core/core-api/src/telemetry.rs +13 -0
  84. package/sdk-core/core-c-bridge/Cargo.toml +13 -8
  85. package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +184 -22
  86. package/sdk-core/core-c-bridge/src/client.rs +462 -184
  87. package/sdk-core/core-c-bridge/src/envconfig.rs +314 -0
  88. package/sdk-core/core-c-bridge/src/lib.rs +1 -0
  89. package/sdk-core/core-c-bridge/src/random.rs +4 -4
  90. package/sdk-core/core-c-bridge/src/runtime.rs +22 -23
  91. package/sdk-core/core-c-bridge/src/testing.rs +1 -4
  92. package/sdk-core/core-c-bridge/src/tests/context.rs +31 -31
  93. package/sdk-core/core-c-bridge/src/tests/mod.rs +32 -28
  94. package/sdk-core/core-c-bridge/src/tests/utils.rs +7 -7
  95. package/sdk-core/core-c-bridge/src/worker.rs +319 -66
  96. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -1
  97. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +5 -5
  98. package/sdk-core/sdk/Cargo.toml +8 -2
  99. package/sdk-core/sdk/src/activity_context.rs +1 -1
  100. package/sdk-core/sdk/src/app_data.rs +1 -1
  101. package/sdk-core/sdk/src/interceptors.rs +1 -4
  102. package/sdk-core/sdk/src/lib.rs +1 -5
  103. package/sdk-core/sdk/src/workflow_context/options.rs +10 -1
  104. package/sdk-core/sdk/src/workflow_future.rs +1 -1
  105. package/sdk-core/sdk-core-protos/Cargo.toml +6 -6
  106. package/sdk-core/sdk-core-protos/build.rs +10 -23
  107. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/create-release.yml +9 -1
  108. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +254 -5
  109. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +234 -5
  110. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +1 -1
  111. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +6 -0
  112. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -2
  113. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +60 -2
  114. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -6
  115. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  116. package/sdk-core/{test-utils → sdk-core-protos}/src/canned_histories.rs +5 -5
  117. package/sdk-core/sdk-core-protos/src/history_builder.rs +2 -2
  118. package/sdk-core/sdk-core-protos/src/lib.rs +25 -9
  119. package/sdk-core/sdk-core-protos/src/test_utils.rs +89 -0
  120. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -5
  121. package/sdk-core/tests/c_bridge_smoke_test.c +10 -0
  122. package/sdk-core/tests/cloud_tests.rs +10 -8
  123. package/sdk-core/tests/common/http_proxy.rs +134 -0
  124. package/sdk-core/{test-utils/src/lib.rs → tests/common/mod.rs} +214 -281
  125. package/sdk-core/{test-utils/src → tests/common}/workflows.rs +4 -3
  126. package/sdk-core/tests/fuzzy_workflow.rs +1 -1
  127. package/sdk-core/tests/global_metric_tests.rs +8 -7
  128. package/sdk-core/tests/heavy_tests.rs +7 -3
  129. package/sdk-core/tests/integ_tests/client_tests.rs +111 -24
  130. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +14 -9
  131. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +4 -4
  132. package/sdk-core/tests/integ_tests/metrics_tests.rs +114 -14
  133. package/sdk-core/tests/integ_tests/pagination_tests.rs +273 -0
  134. package/sdk-core/tests/integ_tests/polling_tests.rs +311 -93
  135. package/sdk-core/tests/integ_tests/queries_tests.rs +4 -4
  136. package/sdk-core/tests/integ_tests/update_tests.rs +13 -7
  137. package/sdk-core/tests/integ_tests/visibility_tests.rs +26 -9
  138. package/sdk-core/tests/integ_tests/worker_tests.rs +668 -13
  139. package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +40 -24
  140. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +244 -11
  141. package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
  142. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +78 -2
  143. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +61 -2
  144. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +465 -7
  145. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +41 -2
  146. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +315 -3
  147. package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +1 -1
  148. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1990 -14
  149. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +65 -2
  150. package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +123 -23
  151. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +525 -3
  152. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +65 -16
  153. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +32 -23
  154. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +126 -5
  155. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +1 -2
  156. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +124 -8
  157. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +62 -2
  158. package/sdk-core/tests/integ_tests/workflow_tests.rs +67 -8
  159. package/sdk-core/tests/main.rs +26 -17
  160. package/sdk-core/tests/manual_tests.rs +5 -1
  161. package/sdk-core/tests/runner.rs +22 -40
  162. package/sdk-core/tests/shared_tests/mod.rs +1 -1
  163. package/sdk-core/tests/shared_tests/priority.rs +1 -1
  164. package/sdk-core/{core/benches/workflow_replay.rs → tests/workflow_replay_bench.rs} +10 -5
  165. package/src/client.rs +97 -20
  166. package/src/helpers/callbacks.rs +4 -4
  167. package/src/helpers/errors.rs +7 -1
  168. package/src/helpers/handles.rs +1 -0
  169. package/src/helpers/try_from_js.rs +4 -3
  170. package/src/lib.rs +3 -2
  171. package/src/metrics.rs +3 -0
  172. package/src/runtime.rs +5 -2
  173. package/src/worker.rs +9 -12
  174. package/ts/native.ts +13 -3
  175. package/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
  176. package/sdk-core/core/src/core_tests/child_workflows.rs +0 -281
  177. package/sdk-core/core/src/core_tests/determinism.rs +0 -318
  178. package/sdk-core/core/src/core_tests/local_activities.rs +0 -1442
  179. package/sdk-core/test-utils/Cargo.toml +0 -38
  180. package/sdk-core/test-utils/src/histfetch.rs +0 -28
  181. package/sdk-core/test-utils/src/interceptors.rs +0 -46
@@ -1,31 +1,29 @@
1
- //! This crate contains testing functionality that can be useful when building SDKs against Core,
2
- //! or even when testing workflows written in SDKs that use Core.
1
+ //! Common integration testing utilities
2
+ //! These utilities are specific to integration tests and depend on the full temporal-client stack.
3
3
 
4
- #[macro_use]
5
- extern crate tracing;
4
+ pub(crate) mod http_proxy;
5
+ pub(crate) mod workflows;
6
6
 
7
- pub mod canned_histories;
8
- pub mod interceptors;
9
- pub mod workflows;
10
-
11
- pub use temporal_sdk_core::replay::HistoryForReplay;
12
-
13
- use crate::stream::{Stream, TryStreamExt};
14
7
  use anyhow::{Context, Error, bail};
15
- use assert_matches::assert_matches;
16
- use futures_util::{StreamExt, future, stream, stream::FuturesUnordered};
8
+ use futures_util::{
9
+ Future, StreamExt, future, stream,
10
+ stream::{Stream, TryStreamExt},
11
+ };
17
12
  use parking_lot::Mutex;
18
13
  use prost::Message;
19
14
  use rand::Rng;
20
15
  use std::{
21
16
  cell::Cell,
17
+ collections::VecDeque,
22
18
  convert::TryFrom,
23
19
  env,
24
- future::Future,
25
20
  net::SocketAddr,
26
21
  path::PathBuf,
27
22
  str::FromStr,
28
- sync::Arc,
23
+ sync::{
24
+ Arc,
25
+ atomic::{AtomicBool, Ordering},
26
+ },
29
27
  time::{Duration, Instant},
30
28
  };
31
29
  use temporal_client::{
@@ -40,17 +38,14 @@ use temporal_sdk::{
40
38
  WorkerInterceptor,
41
39
  },
42
40
  };
43
- #[cfg(feature = "ephemeral-server")]
44
- use temporal_sdk_core::ephemeral_server::{EphemeralExe, EphemeralExeVersion};
45
41
  use temporal_sdk_core::{
46
42
  ClientOptions, ClientOptionsBuilder, CoreRuntime, WorkerConfigBuilder, init_replay_worker,
47
43
  init_worker,
48
- replay::ReplayWorkerInput,
44
+ replay::{HistoryForReplay, ReplayWorkerInput},
49
45
  telemetry::{build_otlp_metric_exporter, start_prometheus_metric_exporter},
50
46
  };
51
47
  use temporal_sdk_core_api::{
52
48
  Worker as CoreWorker,
53
- errors::PollError,
54
49
  telemetry::{
55
50
  Logger, OtelCollectorOptionsBuilder, PrometheusExporterOptions,
56
51
  PrometheusExporterOptionsBuilder, TelemetryOptions, TelemetryOptionsBuilder,
@@ -59,14 +54,8 @@ use temporal_sdk_core_api::{
59
54
  worker::WorkerVersioningStrategy,
60
55
  };
61
56
  use temporal_sdk_core_protos::{
62
- DEFAULT_ACTIVITY_TYPE,
63
57
  coresdk::{
64
- FromPayloadsExt,
65
- workflow_activation::{WorkflowActivation, WorkflowActivationJob, workflow_activation_job},
66
- workflow_commands::{
67
- ActivityCancellationType, CompleteWorkflowExecution, QueryResult, QuerySuccess,
68
- ScheduleActivity, ScheduleLocalActivity, StartTimer, workflow_command,
69
- },
58
+ FromPayloadsExt, workflow_activation::WorkflowActivation,
70
59
  workflow_completion::WorkflowActivationCompletion,
71
60
  },
72
61
  temporal::api::{
@@ -76,47 +65,40 @@ use temporal_sdk_core_protos::{
76
65
  },
77
66
  };
78
67
  use tokio::{sync::OnceCell, task::AbortHandle};
68
+ use tonic::IntoRequest;
69
+ use tracing::{debug, warn};
79
70
  use url::Url;
80
71
 
81
- pub const NAMESPACE: &str = "default";
82
- pub const TEST_Q: &str = "q";
72
+ pub(crate) use temporal_sdk_core::test_help::NAMESPACE;
83
73
  /// The env var used to specify where the integ tests should point
84
- pub const INTEG_SERVER_TARGET_ENV_VAR: &str = "TEMPORAL_SERVICE_ADDRESS";
85
- pub const INTEG_NAMESPACE_ENV_VAR: &str = "TEMPORAL_NAMESPACE";
86
- pub const INTEG_USE_TLS_ENV_VAR: &str = "TEMPORAL_USE_TLS";
87
- pub const INTEG_API_KEY: &str = "TEMPORAL_API_KEY_PATH";
88
- /// This env var is set (to any value) if temporal CLI dev server is in use
89
- pub const INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR: &str = "INTEG_TEMPORAL_DEV_SERVER_ON";
90
- /// This env var is set (to any value) if the test server is in use
91
- pub const INTEG_TEST_SERVER_USED_ENV_VAR: &str = "INTEG_TEST_SERVER_ON";
92
- pub static SEARCH_ATTR_TXT: &str = "CustomTextField";
93
- pub static SEARCH_ATTR_INT: &str = "CustomIntField";
74
+ pub(crate) const INTEG_SERVER_TARGET_ENV_VAR: &str = "TEMPORAL_SERVICE_ADDRESS";
75
+ pub(crate) const INTEG_NAMESPACE_ENV_VAR: &str = "TEMPORAL_NAMESPACE";
76
+ pub(crate) const INTEG_USE_TLS_ENV_VAR: &str = "TEMPORAL_USE_TLS";
77
+ pub(crate) const INTEG_API_KEY: &str = "TEMPORAL_API_KEY_PATH";
78
+ pub(crate) static SEARCH_ATTR_TXT: &str = "CustomTextField";
79
+ pub(crate) static SEARCH_ATTR_INT: &str = "CustomIntField";
94
80
  /// If set, turn export traces and metrics to the OTel collector at the given URL
95
- pub const OTEL_URL_ENV_VAR: &str = "TEMPORAL_INTEG_OTEL_URL";
81
+ pub(crate) const OTEL_URL_ENV_VAR: &str = "TEMPORAL_INTEG_OTEL_URL";
96
82
  /// If set, enable direct scraping of prom metrics on the specified port
97
- pub const PROM_ENABLE_ENV_VAR: &str = "TEMPORAL_INTEG_PROM_PORT";
83
+ pub(crate) const PROM_ENABLE_ENV_VAR: &str = "TEMPORAL_INTEG_PROM_PORT";
98
84
  /// This should match the prometheus port exposed in docker-compose-ci.yaml
99
- pub const PROMETHEUS_QUERY_API: &str = "http://localhost:9090/api/v1/query";
100
-
101
- #[macro_export]
102
- macro_rules! prost_dur {
103
- ($dur_call:ident $args:tt) => {
104
- std::time::Duration::$dur_call$args
105
- .try_into()
106
- .expect("test duration fits")
107
- };
108
- }
85
+ pub(crate) const PROMETHEUS_QUERY_API: &str = "http://localhost:9090/api/v1/query";
86
+ /// If set, integ tests will use this specific version of CLI for starting dev server
87
+ pub(crate) const CLI_VERSION_OVERRIDE_ENV_VAR: &str = "CLI_VERSION_OVERRIDE";
88
+ pub(crate) const INTEG_CLIENT_IDENTITY: &str = "integ_tester";
89
+ pub(crate) const INTEG_CLIENT_NAME: &str = "temporal-core";
90
+ pub(crate) const INTEG_CLIENT_VERSION: &str = "0.1.0";
109
91
 
110
92
  /// Create a worker instance which will use the provided test name to base the task queue and wf id
111
93
  /// upon. Returns the instance.
112
- pub async fn init_core_and_create_wf(test_name: &str) -> CoreWfStarter {
94
+ pub(crate) async fn init_core_and_create_wf(test_name: &str) -> CoreWfStarter {
113
95
  let mut starter = CoreWfStarter::new(test_name);
114
96
  let _ = starter.get_worker().await;
115
97
  starter.start_wf().await;
116
98
  starter
117
99
  }
118
100
 
119
- pub fn integ_worker_config(tq: &str) -> WorkerConfigBuilder {
101
+ pub(crate) fn integ_worker_config(tq: &str) -> WorkerConfigBuilder {
120
102
  let mut b = WorkerConfigBuilder::default();
121
103
  b.namespace(NAMESPACE)
122
104
  .task_queue(tq)
@@ -130,14 +112,14 @@ pub fn integ_worker_config(tq: &str) -> WorkerConfigBuilder {
130
112
  }
131
113
 
132
114
  /// Create a worker replay instance preloaded with provided histories. Returns the worker impl.
133
- pub fn init_core_replay_preloaded<I>(test_name: &str, histories: I) -> Arc<dyn CoreWorker>
115
+ pub(crate) fn init_core_replay_preloaded<I>(test_name: &str, histories: I) -> Arc<dyn CoreWorker>
134
116
  where
135
117
  I: IntoIterator<Item = HistoryForReplay> + 'static,
136
118
  <I as IntoIterator>::IntoIter: Send,
137
119
  {
138
120
  init_core_replay_stream(test_name, stream::iter(histories))
139
121
  }
140
- pub fn init_core_replay_stream<I>(test_name: &str, histories: I) -> Arc<dyn CoreWorker>
122
+ pub(crate) fn init_core_replay_stream<I>(test_name: &str, histories: I) -> Arc<dyn CoreWorker>
141
123
  where
142
124
  I: Stream<Item = HistoryForReplay> + Send + 'static,
143
125
  {
@@ -149,14 +131,14 @@ where
149
131
  .expect("Replay worker must init properly");
150
132
  Arc::new(worker)
151
133
  }
152
- pub fn replay_sdk_worker<I>(histories: I) -> Worker
134
+ pub(crate) fn replay_sdk_worker<I>(histories: I) -> Worker
153
135
  where
154
136
  I: IntoIterator<Item = HistoryForReplay> + 'static,
155
137
  <I as IntoIterator>::IntoIter: Send,
156
138
  {
157
139
  replay_sdk_worker_stream(stream::iter(histories))
158
140
  }
159
- pub fn replay_sdk_worker_stream<I>(histories: I) -> Worker
141
+ pub(crate) fn replay_sdk_worker_stream<I>(histories: I) -> Worker
160
142
  where
161
143
  I: Stream<Item = HistoryForReplay> + Send + 'static,
162
144
  {
@@ -167,7 +149,9 @@ where
167
149
  }
168
150
 
169
151
  /// Load history from a file containing the protobuf serialization of it
170
- pub async fn history_from_proto_binary(path_from_root: &str) -> Result<History, anyhow::Error> {
152
+ pub(crate) async fn history_from_proto_binary(
153
+ path_from_root: &str,
154
+ ) -> Result<History, anyhow::Error> {
171
155
  let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
172
156
  path.push("..");
173
157
  path.push(path_from_root);
@@ -180,7 +164,7 @@ thread_local! {
180
164
  pub static DONT_AUTO_INIT_INTEG_TELEM: Cell<bool> = const { Cell::new(false) };
181
165
  }
182
166
  static INTEG_TESTS_RT: std::sync::OnceLock<CoreRuntime> = std::sync::OnceLock::new();
183
- pub fn init_integ_telem() -> Option<&'static CoreRuntime> {
167
+ pub(crate) fn init_integ_telem() -> Option<&'static CoreRuntime> {
184
168
  if DONT_AUTO_INIT_INTEG_TELEM.get() {
185
169
  return None;
186
170
  }
@@ -195,7 +179,7 @@ pub fn init_integ_telem() -> Option<&'static CoreRuntime> {
195
179
  }))
196
180
  }
197
181
 
198
- pub async fn get_cloud_client() -> RetryClient<Client> {
182
+ pub(crate) async fn get_cloud_client() -> RetryClient<Client> {
199
183
  let cloud_addr = env::var("TEMPORAL_CLOUD_ADDRESS").unwrap();
200
184
  let cloud_key = env::var("TEMPORAL_CLIENT_KEY").unwrap();
201
185
 
@@ -227,7 +211,7 @@ pub async fn get_cloud_client() -> RetryClient<Client> {
227
211
  }
228
212
 
229
213
  /// Implements a builder pattern to help integ tests initialize core and create workflows
230
- pub struct CoreWfStarter {
214
+ pub(crate) struct CoreWfStarter {
231
215
  /// Used for both the task queue and workflow id
232
216
  task_queue_name: String,
233
217
  pub worker_config: WorkerConfigBuilder,
@@ -244,25 +228,20 @@ struct InitializedWorker {
244
228
  }
245
229
 
246
230
  impl CoreWfStarter {
247
- pub fn new(test_name: &str) -> Self {
231
+ pub(crate) fn new(test_name: &str) -> Self {
248
232
  init_integ_telem();
249
233
  Self::_new(test_name, None, None)
250
234
  }
251
235
 
252
- pub fn new_with_runtime(test_name: &str, runtime: CoreRuntime) -> Self {
236
+ pub(crate) fn new_with_runtime(test_name: &str, runtime: CoreRuntime) -> Self {
253
237
  Self::_new(test_name, Some(runtime), None)
254
238
  }
255
239
 
256
- pub fn new_with_client(test_name: &str, client: RetryClient<Client>) -> Self {
257
- init_integ_telem();
258
- Self::_new(test_name, None, Some(client))
259
- }
260
-
261
240
  /// Targets cloud if the required env vars are present. Otherwise, local server (but only if
262
241
  /// the minimum version requirement is met). Returns None if the local server is not new enough.
263
242
  ///
264
243
  /// An empty string means to skip the version check.
265
- pub async fn new_cloud_or_local(test_name: &str, version_req: &str) -> Option<Self> {
244
+ pub(crate) async fn new_cloud_or_local(test_name: &str, version_req: &str) -> Option<Self> {
266
245
  init_integ_telem();
267
246
  let mut check_mlsv = false;
268
247
  let client = if env::var("TEMPORAL_CLOUD_ADDRESS").is_ok() {
@@ -278,8 +257,7 @@ impl CoreWfStarter {
278
257
  .get_client()
279
258
  .inner()
280
259
  .workflow_svc()
281
- .clone()
282
- .get_cluster_info(GetClusterInfoRequest::default())
260
+ .get_cluster_info(GetClusterInfoRequest::default().into_request())
283
261
  .await;
284
262
  let srv_ver = semver::Version::parse(
285
263
  &clustinfo
@@ -327,7 +305,7 @@ impl CoreWfStarter {
327
305
 
328
306
  /// Create a new starter with no initialized worker or runtime override. Useful for starting a
329
307
  /// new worker on the same queue.
330
- pub fn clone_no_worker(&self) -> Self {
308
+ pub(crate) fn clone_no_worker(&self) -> Self {
331
309
  Self {
332
310
  task_queue_name: self.task_queue_name.clone(),
333
311
  worker_config: self.worker_config.clone(),
@@ -339,7 +317,7 @@ impl CoreWfStarter {
339
317
  }
340
318
  }
341
319
 
342
- pub async fn worker(&mut self) -> TestWorker {
320
+ pub(crate) async fn worker(&mut self) -> TestWorker {
343
321
  let w = self.get_worker().await;
344
322
  let tq = w.get_config().task_queue.clone();
345
323
  let mut w = TestWorker::new(w, tq);
@@ -348,25 +326,25 @@ impl CoreWfStarter {
348
326
  w
349
327
  }
350
328
 
351
- pub async fn shutdown(&mut self) {
329
+ pub(crate) async fn shutdown(&mut self) {
352
330
  self.get_worker().await.shutdown().await;
353
331
  }
354
332
 
355
- pub async fn get_worker(&mut self) -> Arc<dyn CoreWorker> {
333
+ pub(crate) async fn get_worker(&mut self) -> Arc<dyn CoreWorker> {
356
334
  self.get_or_init().await.worker.clone()
357
335
  }
358
336
 
359
- pub async fn get_client(&mut self) -> Arc<RetryClient<Client>> {
337
+ pub(crate) async fn get_client(&mut self) -> Arc<RetryClient<Client>> {
360
338
  self.get_or_init().await.client.clone()
361
339
  }
362
340
 
363
341
  /// Start the workflow defined by the builder and return run id
364
- pub async fn start_wf(&mut self) -> String {
342
+ pub(crate) async fn start_wf(&mut self) -> String {
365
343
  self.start_wf_with_id(self.get_wf_id().to_owned()).await
366
344
  }
367
345
 
368
346
  /// Starts the workflow using the worker
369
- pub async fn start_with_worker(
347
+ pub(crate) async fn start_with_worker(
370
348
  &self,
371
349
  wf_name: impl Into<String>,
372
350
  worker: &mut TestWorker,
@@ -387,7 +365,7 @@ impl CoreWfStarter {
387
365
  .get_untyped_workflow_handle(&self.task_queue_name, run_id)
388
366
  }
389
367
 
390
- pub async fn eager_start_with_worker(
368
+ pub(crate) async fn eager_start_with_worker(
391
369
  &self,
392
370
  wf_name: impl Into<String>,
393
371
  worker: &mut TestWorker,
@@ -404,7 +382,7 @@ impl CoreWfStarter {
404
382
  .unwrap()
405
383
  }
406
384
 
407
- pub async fn start_wf_with_id(&self, workflow_id: String) -> String {
385
+ pub(crate) async fn start_wf_with_id(&self, workflow_id: String) -> String {
408
386
  let iw = self.initted_worker.get().expect(
409
387
  "Worker must be initted before starting a workflow.\
410
388
  Tests must call `get_worker` first.",
@@ -423,17 +401,17 @@ impl CoreWfStarter {
423
401
  .run_id
424
402
  }
425
403
 
426
- pub fn get_task_queue(&self) -> &str {
404
+ pub(crate) fn get_task_queue(&self) -> &str {
427
405
  &self.task_queue_name
428
406
  }
429
407
 
430
- pub fn get_wf_id(&self) -> &str {
408
+ pub(crate) fn get_wf_id(&self) -> &str {
431
409
  &self.task_queue_name
432
410
  }
433
411
 
434
412
  /// Fetch the history of the default workflow for this starter. IE: The one that would
435
413
  /// be started by [CoreWfStarter::start_wf].
436
- pub async fn get_history(&self) -> History {
414
+ pub(crate) async fn get_history(&self) -> History {
437
415
  self.initted_worker
438
416
  .get()
439
417
  .expect("Starter must be initialized")
@@ -445,7 +423,7 @@ impl CoreWfStarter {
445
423
  .unwrap()
446
424
  }
447
425
 
448
- pub async fn wait_for_default_wf_finish(
426
+ pub(crate) async fn wait_for_default_wf_finish(
449
427
  &self,
450
428
  ) -> Result<WorkflowExecutionResult<Vec<Payload>>, Error> {
451
429
  self.initted_worker
@@ -493,7 +471,7 @@ impl CoreWfStarter {
493
471
  }
494
472
 
495
473
  /// Provides conveniences for running integ tests with the SDK (against real server or mocks)
496
- pub struct TestWorker {
474
+ pub(crate) struct TestWorker {
497
475
  inner: Worker,
498
476
  pub core_worker: Arc<dyn CoreWorker>,
499
477
  client: Option<Arc<RetryClient<Client>>>,
@@ -504,7 +482,7 @@ pub struct TestWorker {
504
482
  }
505
483
  impl TestWorker {
506
484
  /// Create a new test worker
507
- pub fn new(core_worker: Arc<dyn CoreWorker>, task_queue: impl Into<String>) -> Self {
485
+ pub(crate) fn new(core_worker: Arc<dyn CoreWorker>, task_queue: impl Into<String>) -> Self {
508
486
  let inner = Worker::new_from_core(core_worker.clone(), task_queue);
509
487
  Self {
510
488
  inner,
@@ -515,12 +493,12 @@ impl TestWorker {
515
493
  }
516
494
  }
517
495
 
518
- pub fn inner_mut(&mut self) -> &mut Worker {
496
+ pub(crate) fn inner_mut(&mut self) -> &mut Worker {
519
497
  &mut self.inner
520
498
  }
521
499
 
522
500
  // TODO: Maybe trait-ify?
523
- pub fn register_wf<F: Into<WorkflowFunction>>(
501
+ pub(crate) fn register_wf<F: Into<WorkflowFunction>>(
524
502
  &mut self,
525
503
  workflow_type: impl Into<String>,
526
504
  wf_function: F,
@@ -528,7 +506,7 @@ impl TestWorker {
528
506
  self.inner.register_wf(workflow_type, wf_function)
529
507
  }
530
508
 
531
- pub fn register_activity<A, R, O>(
509
+ pub(crate) fn register_activity<A, R, O>(
532
510
  &mut self,
533
511
  activity_type: impl Into<String>,
534
512
  act_function: impl IntoActivityFunc<A, R, O>,
@@ -538,7 +516,7 @@ impl TestWorker {
538
516
 
539
517
  /// Create a handle that can be used to submit workflows. Useful when workflows need to be
540
518
  /// started concurrently with running the worker.
541
- pub fn get_submitter_handle(&self) -> TestWorkerSubmitterHandle {
519
+ pub(crate) fn get_submitter_handle(&self) -> TestWorkerSubmitterHandle {
542
520
  TestWorkerSubmitterHandle {
543
521
  client: self.client.clone().expect("client must be set"),
544
522
  tq: self.inner.task_queue().to_string(),
@@ -552,7 +530,7 @@ impl TestWorker {
552
530
  /// Increments the expected Workflow run count.
553
531
  ///
554
532
  /// Returns the run id of the started workflow (if no client has initialized returns a fake id)
555
- pub async fn submit_wf(
533
+ pub(crate) async fn submit_wf(
556
534
  &self,
557
535
  workflow_id: impl Into<String>,
558
536
  workflow_type: impl Into<String>,
@@ -575,7 +553,7 @@ impl TestWorker {
575
553
  /// Similar to `submit_wf` but checking that the server returns the first
576
554
  /// workflow task in the client response.
577
555
  /// Note that this does not guarantee that the worker will execute this task eagerly.
578
- pub async fn eager_submit_wf(
556
+ pub(crate) async fn eager_submit_wf(
579
557
  &self,
580
558
  workflow_id: impl Into<String>,
581
559
  workflow_type: impl Into<String>,
@@ -605,27 +583,30 @@ impl TestWorker {
605
583
  Ok(res)
606
584
  }
607
585
 
608
- pub fn expect_workflow_completion(&self, wf_id: impl Into<String>, run_id: Option<String>) {
586
+ pub(crate) fn expect_workflow_completion(
587
+ &self,
588
+ wf_id: impl Into<String>,
589
+ run_id: Option<String>,
590
+ ) {
609
591
  self.started_workflows.lock().push(WorkflowExecutionInfo {
610
592
  namespace: self
611
593
  .client
612
594
  .as_ref()
613
595
  .map(|c| c.namespace())
614
- .unwrap_or(NAMESPACE)
615
- .to_owned(),
596
+ .unwrap_or(NAMESPACE.to_owned()),
616
597
  workflow_id: wf_id.into(),
617
598
  run_id,
618
599
  });
619
600
  }
620
601
 
621
602
  /// Runs until all expected workflows have completed and then shuts down the worker
622
- pub async fn run_until_done(&mut self) -> Result<(), anyhow::Error> {
603
+ pub(crate) async fn run_until_done(&mut self) -> Result<(), anyhow::Error> {
623
604
  self.run_until_done_intercepted(Option::<TestWorkerCompletionIceptor>::None)
624
605
  .await
625
606
  }
626
607
 
627
608
  /// See [Self::run_until_done], but allows configuration of some low-level interception.
628
- pub async fn run_until_done_intercepted(
609
+ pub(crate) async fn run_until_done_intercepted(
629
610
  &mut self,
630
611
  next_interceptor: Option<impl WorkerInterceptor + 'static>,
631
612
  ) -> Result<(), anyhow::Error> {
@@ -650,7 +631,7 @@ impl TestWorker {
650
631
  }
651
632
  }
652
633
 
653
- pub struct TestWorkerSubmitterHandle {
634
+ pub(crate) struct TestWorkerSubmitterHandle {
654
635
  client: Arc<RetryClient<Client>>,
655
636
  tq: String,
656
637
  started_workflows: Arc<Mutex<Vec<WorkflowExecutionInfo>>>,
@@ -662,7 +643,7 @@ impl TestWorkerSubmitterHandle {
662
643
  /// Increments the expected Workflow run count.
663
644
  ///
664
645
  /// Returns the run id of the started workflow
665
- pub async fn submit_wf(
646
+ pub(crate) async fn submit_wf(
666
647
  &self,
667
648
  workflow_id: impl Into<String>,
668
649
  workflow_type: impl Into<String>,
@@ -690,20 +671,18 @@ impl TestWorkerSubmitterHandle {
690
671
  }
691
672
  }
692
673
 
693
- pub type BoxDynActivationHook = Box<dyn Fn(&WorkflowActivationCompletion)>;
694
-
695
- pub enum TestWorkerShutdownCond {
674
+ pub(crate) enum TestWorkerShutdownCond {
696
675
  GetResults(Vec<WorkflowExecutionInfo>, Arc<RetryClient<Client>>),
697
676
  NoAutoShutdown,
698
677
  }
699
678
  /// Implements calling the shutdown handle when the expected number of test workflows has completed
700
- pub struct TestWorkerCompletionIceptor {
679
+ pub(crate) struct TestWorkerCompletionIceptor {
701
680
  condition: TestWorkerShutdownCond,
702
681
  shutdown_handle: Arc<dyn Fn()>,
703
682
  next: Option<Box<dyn WorkerInterceptor>>,
704
683
  }
705
684
  impl TestWorkerCompletionIceptor {
706
- pub fn new(condition: TestWorkerShutdownCond, shutdown_handle: Arc<dyn Fn()>) -> Self {
685
+ pub(crate) fn new(condition: TestWorkerShutdownCond, shutdown_handle: Arc<dyn Fn()>) -> Self {
707
686
  Self {
708
687
  condition,
709
688
  shutdown_handle,
@@ -761,15 +740,15 @@ impl WorkerInterceptor for TestWorkerCompletionIceptor {
761
740
  }
762
741
 
763
742
  /// Returns the client options used to connect to the server used for integration tests.
764
- pub fn get_integ_server_options() -> ClientOptions {
743
+ pub(crate) fn get_integ_server_options() -> ClientOptions {
765
744
  let temporal_server_address = env::var(INTEG_SERVER_TARGET_ENV_VAR)
766
745
  .unwrap_or_else(|_| "http://localhost:7233".to_owned());
767
746
  let url = Url::try_from(&*temporal_server_address).unwrap();
768
747
  let mut cb = ClientOptionsBuilder::default();
769
- cb.identity("integ_tester".to_string())
748
+ cb.identity(INTEG_CLIENT_IDENTITY.to_string())
770
749
  .target_url(url)
771
- .client_name("temporal-core".to_string())
772
- .client_version("0.1.0".to_string());
750
+ .client_name(INTEG_CLIENT_NAME.to_string())
751
+ .client_version(INTEG_CLIENT_VERSION.to_string());
773
752
  if let Ok(key_file) = env::var(INTEG_API_KEY) {
774
753
  let content = std::fs::read_to_string(key_file).unwrap();
775
754
  cb.api_key(Some(content));
@@ -780,7 +759,7 @@ pub fn get_integ_server_options() -> ClientOptions {
780
759
  cb.build().unwrap()
781
760
  }
782
761
 
783
- pub fn get_integ_tls_config() -> Option<TlsConfig> {
762
+ pub(crate) fn get_integ_tls_config() -> Option<TlsConfig> {
784
763
  if env::var(INTEG_USE_TLS_ENV_VAR).is_ok() {
785
764
  let root = std::fs::read("../.cloud_certs/ca.pem").unwrap();
786
765
  let client_cert = std::fs::read("../.cloud_certs/client.pem").unwrap();
@@ -798,7 +777,7 @@ pub fn get_integ_tls_config() -> Option<TlsConfig> {
798
777
  }
799
778
  }
800
779
 
801
- pub fn get_integ_telem_options() -> TelemetryOptions {
780
+ pub(crate) fn get_integ_telem_options() -> TelemetryOptions {
802
781
  let mut ob = TelemetryOptionsBuilder::default();
803
782
  let filter_string =
804
783
  env::var("RUST_LOG").unwrap_or_else(|_| "INFO,temporal_sdk_core=INFO".to_string());
@@ -832,154 +811,8 @@ pub fn get_integ_telem_options() -> TelemetryOptions {
832
811
  .unwrap()
833
812
  }
834
813
 
835
- #[cfg(feature = "ephemeral-server")]
836
- pub fn default_cached_download() -> EphemeralExe {
837
- EphemeralExe::CachedDownload {
838
- version: EphemeralExeVersion::SDKDefault {
839
- sdk_name: "sdk-rust".to_string(),
840
- sdk_version: "0.1.0".to_string(),
841
- },
842
- dest_dir: None,
843
- // 15 days
844
- ttl: Some(Duration::from_secs(60 * 60 * 24 * 15)),
845
- }
846
- }
847
-
848
- pub fn schedule_activity_cmd(
849
- seq: u32,
850
- task_q: &str,
851
- activity_id: &str,
852
- cancellation_type: ActivityCancellationType,
853
- activity_timeout: Duration,
854
- heartbeat_timeout: Duration,
855
- ) -> workflow_command::Variant {
856
- ScheduleActivity {
857
- seq,
858
- activity_id: activity_id.to_string(),
859
- activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
860
- task_queue: task_q.to_owned(),
861
- schedule_to_start_timeout: Some(activity_timeout.try_into().expect("duration fits")),
862
- start_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
863
- schedule_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
864
- heartbeat_timeout: Some(heartbeat_timeout.try_into().expect("duration fits")),
865
- cancellation_type: cancellation_type as i32,
866
- ..Default::default()
867
- }
868
- .into()
869
- }
870
-
871
- pub fn schedule_local_activity_cmd(
872
- seq: u32,
873
- activity_id: &str,
874
- cancellation_type: ActivityCancellationType,
875
- activity_timeout: Duration,
876
- ) -> workflow_command::Variant {
877
- ScheduleLocalActivity {
878
- seq,
879
- activity_id: activity_id.to_string(),
880
- activity_type: DEFAULT_ACTIVITY_TYPE.to_string(),
881
- schedule_to_start_timeout: Some(activity_timeout.try_into().expect("duration fits")),
882
- start_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
883
- schedule_to_close_timeout: Some(activity_timeout.try_into().expect("duration fits")),
884
- cancellation_type: cancellation_type as i32,
885
- ..Default::default()
886
- }
887
- .into()
888
- }
889
-
890
- pub fn start_timer_cmd(seq: u32, duration: Duration) -> workflow_command::Variant {
891
- StartTimer {
892
- seq,
893
- start_to_fire_timeout: Some(duration.try_into().expect("duration fits")),
894
- }
895
- .into()
896
- }
897
-
898
- pub fn query_ok(id: impl Into<String>, response: impl Into<Payload>) -> workflow_command::Variant {
899
- QueryResult {
900
- query_id: id.into(),
901
- variant: Some(
902
- QuerySuccess {
903
- response: Some(response.into()),
904
- }
905
- .into(),
906
- ),
907
- }
908
- .into()
909
- }
910
-
911
- /// Given a desired number of concurrent executions and a provided function that produces a future,
912
- /// run that many instances of the future concurrently.
913
- ///
914
- /// Annoyingly, because of a sorta-bug in the way async blocks work, the async block produced by
915
- /// the closure must be `async move` if it uses the provided iteration number. On the plus side,
916
- /// since you're usually just accessing core in the closure, if core is a reference everything just
917
- /// works. See <https://github.com/rust-lang/rust/issues/81653>
918
- pub async fn fanout_tasks<FutureMaker, Fut>(num: usize, fm: FutureMaker)
919
- where
920
- FutureMaker: Fn(usize) -> Fut,
921
- Fut: Future,
922
- {
923
- let mut tasks = FuturesUnordered::new();
924
- for i in 0..num {
925
- tasks.push(fm(i));
926
- }
927
-
928
- while tasks.next().await.is_some() {}
929
- }
930
-
931
- #[async_trait::async_trait]
932
- pub trait WorkerTestHelpers {
933
- async fn complete_execution(&self, run_id: &str);
934
- async fn complete_timer(&self, run_id: &str, seq: u32, duration: Duration);
935
- async fn handle_eviction(&self);
936
- }
937
-
938
- #[async_trait::async_trait]
939
- impl<T> WorkerTestHelpers for T
940
- where
941
- T: CoreWorker + ?Sized,
942
- {
943
- async fn complete_execution(&self, run_id: &str) {
944
- self.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
945
- run_id.to_string(),
946
- vec![CompleteWorkflowExecution { result: None }.into()],
947
- ))
948
- .await
949
- .unwrap();
950
- }
951
-
952
- async fn complete_timer(&self, run_id: &str, seq: u32, duration: Duration) {
953
- self.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
954
- run_id.to_string(),
955
- vec![
956
- StartTimer {
957
- seq,
958
- start_to_fire_timeout: Some(duration.try_into().expect("duration fits")),
959
- }
960
- .into(),
961
- ],
962
- ))
963
- .await
964
- .unwrap();
965
- }
966
-
967
- async fn handle_eviction(&self) {
968
- let task = self.poll_workflow_activation().await.unwrap();
969
- assert_matches!(
970
- task.jobs.as_slice(),
971
- [WorkflowActivationJob {
972
- variant: Some(workflow_activation_job::Variant::RemoveFromCache(_)),
973
- }]
974
- );
975
- self.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
976
- .await
977
- .unwrap();
978
- }
979
- }
980
-
981
814
  #[async_trait::async_trait(?Send)]
982
- pub trait WorkflowHandleExt {
815
+ pub(crate) trait WorkflowHandleExt {
983
816
  async fn fetch_history_and_replay(
984
817
  &self,
985
818
  worker: &mut Worker,
@@ -1016,27 +849,7 @@ where
1016
849
  }
1017
850
  }
1018
851
 
1019
- /// Initiate shutdown, drain the pollers, and wait for shutdown to complete.
1020
- pub async fn drain_pollers_and_shutdown(worker: &Arc<dyn CoreWorker>) {
1021
- worker.initiate_shutdown();
1022
- tokio::join!(
1023
- async {
1024
- assert!(matches!(
1025
- worker.poll_activity_task().await.unwrap_err(),
1026
- PollError::ShutDown
1027
- ));
1028
- },
1029
- async {
1030
- assert!(matches!(
1031
- worker.poll_workflow_activation().await.unwrap_err(),
1032
- PollError::ShutDown,
1033
- ));
1034
- }
1035
- );
1036
- worker.shutdown().await;
1037
- }
1038
-
1039
- pub fn rand_6_chars() -> String {
852
+ pub(crate) fn rand_6_chars() -> String {
1040
853
  rand::rng()
1041
854
  .sample_iter(&rand::distr::Alphanumeric)
1042
855
  .take(6)
@@ -1044,9 +857,9 @@ pub fn rand_6_chars() -> String {
1044
857
  .collect()
1045
858
  }
1046
859
 
1047
- pub static ANY_PORT: &str = "127.0.0.1:0";
860
+ pub(crate) static ANY_PORT: &str = "127.0.0.1:0";
1048
861
 
1049
- pub fn prom_metrics(
862
+ pub(crate) fn prom_metrics(
1050
863
  options_override: Option<PrometheusExporterOptions>,
1051
864
  ) -> (TelemetryOptions, SocketAddr, AbortOnDrop) {
1052
865
  let prom_exp_opts = options_override.unwrap_or_else(|| {
@@ -1067,7 +880,7 @@ pub fn prom_metrics(
1067
880
  )
1068
881
  }
1069
882
 
1070
- pub struct AbortOnDrop {
883
+ pub(crate) struct AbortOnDrop {
1071
884
  ah: AbortHandle,
1072
885
  }
1073
886
 
@@ -1077,7 +890,7 @@ impl Drop for AbortOnDrop {
1077
890
  }
1078
891
  }
1079
892
 
1080
- pub async fn eventually<F, Fut, T, E>(func: F, timeout: Duration) -> Result<T, anyhow::Error>
893
+ pub(crate) async fn eventually<F, Fut, T, E>(func: F, timeout: Duration) -> Result<T, anyhow::Error>
1081
894
  where
1082
895
  F: Fn() -> Fut,
1083
896
  Fut: Future<Output = Result<T, E>>,
@@ -1093,3 +906,123 @@ where
1093
906
  tokio::time::sleep(Duration::from_millis(50)).await;
1094
907
  }
1095
908
  }
909
+
910
+ use temporal_sdk_core::{
911
+ WorkerConfig,
912
+ test_help::{MockPollCfg, build_mock_pollers, mock_worker},
913
+ };
914
+
915
+ pub(crate) fn build_fake_sdk(mock_cfg: MockPollCfg) -> temporal_sdk::Worker {
916
+ let mut mock = build_mock_pollers(mock_cfg);
917
+ mock.worker_cfg(|c| {
918
+ c.max_cached_workflows = 1;
919
+ c.ignore_evicts_on_shutdown = false;
920
+ });
921
+ let core = mock_worker(mock);
922
+ let mut worker = temporal_sdk::Worker::new_from_core(Arc::new(core), "replay_q".to_string());
923
+ worker.set_worker_interceptor(FailOnNondeterminismInterceptor {});
924
+ worker
925
+ }
926
+
927
+ pub(crate) fn mock_sdk(poll_cfg: MockPollCfg) -> TestWorker {
928
+ mock_sdk_cfg(poll_cfg, |_| {})
929
+ }
930
+
931
+ pub(crate) fn mock_sdk_cfg(
932
+ mut poll_cfg: MockPollCfg,
933
+ mutator: impl FnOnce(&mut WorkerConfig),
934
+ ) -> TestWorker {
935
+ poll_cfg.using_rust_sdk = true;
936
+ let mut mock = build_mock_pollers(poll_cfg);
937
+ mock.worker_cfg(mutator);
938
+ let core = mock_worker(mock);
939
+ TestWorker::new(
940
+ Arc::new(core),
941
+ temporal_sdk_core::test_help::TEST_Q.to_string(),
942
+ )
943
+ }
944
+
945
+ #[derive(Default)]
946
+ pub(crate) struct ActivationAssertionsInterceptor {
947
+ #[allow(clippy::type_complexity)]
948
+ assertions: Mutex<VecDeque<Box<dyn FnOnce(&WorkflowActivation)>>>,
949
+ used: AtomicBool,
950
+ }
951
+
952
+ impl ActivationAssertionsInterceptor {
953
+ pub(crate) fn skip_one(&mut self) -> &mut Self {
954
+ self.assertions.lock().push_back(Box::new(|_| {}));
955
+ self
956
+ }
957
+
958
+ pub(crate) fn then(&mut self, assert: impl FnOnce(&WorkflowActivation) + 'static) -> &mut Self {
959
+ self.assertions.lock().push_back(Box::new(assert));
960
+ self
961
+ }
962
+ }
963
+
964
+ #[async_trait::async_trait(?Send)]
965
+ impl WorkerInterceptor for ActivationAssertionsInterceptor {
966
+ async fn on_workflow_activation(&self, act: &WorkflowActivation) -> Result<(), anyhow::Error> {
967
+ self.used.store(true, Ordering::Relaxed);
968
+ if let Some(fun) = self.assertions.lock().pop_front() {
969
+ fun(act);
970
+ }
971
+ Ok(())
972
+ }
973
+ }
974
+
975
+ #[cfg(test)]
976
+ impl Drop for ActivationAssertionsInterceptor {
977
+ fn drop(&mut self) {
978
+ if !self.used.load(Ordering::Relaxed) {
979
+ panic!("Activation assertions interceptor was never used!")
980
+ }
981
+ }
982
+ }
983
+
984
+ #[cfg(feature = "ephemeral-server")]
985
+ use temporal_sdk_core::ephemeral_server::{
986
+ EphemeralExe, EphemeralExeVersion, TemporalDevServerConfigBuilder, default_cached_download,
987
+ };
988
+
989
+ #[cfg(feature = "ephemeral-server")]
990
+ pub(crate) fn integ_dev_server_config(
991
+ mut extra_args: Vec<String>,
992
+ ) -> TemporalDevServerConfigBuilder {
993
+ let cli_version = if let Ok(ver_override) = env::var(CLI_VERSION_OVERRIDE_ENV_VAR) {
994
+ EphemeralExe::CachedDownload {
995
+ version: EphemeralExeVersion::Fixed(ver_override.to_owned()),
996
+ dest_dir: None,
997
+ ttl: None,
998
+ }
999
+ } else {
1000
+ default_cached_download()
1001
+ };
1002
+ extra_args.extend(
1003
+ [
1004
+ // TODO: Delete when temporalCLI enables it by default.
1005
+ "--dynamic-config-value".to_string(),
1006
+ "system.enableEagerWorkflowStart=true".to_string(),
1007
+ "--dynamic-config-value".to_string(),
1008
+ "system.enableNexus=true".to_string(),
1009
+ "--dynamic-config-value".to_owned(),
1010
+ "frontend.workerVersioningWorkflowAPIs=true".to_owned(),
1011
+ "--dynamic-config-value".to_owned(),
1012
+ "frontend.workerVersioningDataAPIs=true".to_owned(),
1013
+ "--dynamic-config-value".to_owned(),
1014
+ "system.enableDeploymentVersions=true".to_owned(),
1015
+ "--dynamic-config-value".to_owned(),
1016
+ "component.nexusoperations.recordCancelRequestCompletionEvents=true".to_owned(),
1017
+ "--search-attribute".to_string(),
1018
+ format!("{SEARCH_ATTR_TXT}=Text"),
1019
+ "--search-attribute".to_string(),
1020
+ format!("{SEARCH_ATTR_INT}=Int"),
1021
+ ]
1022
+ .map(Into::into),
1023
+ );
1024
+
1025
+ let mut config = TemporalDevServerConfigBuilder::default();
1026
+ config.exe(cli_version).extra_args(extra_args);
1027
+ config
1028
+ }