Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion temporalio/ext/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ impl EphemeralServer {
.ip(options.member::<String>(id!("ip"))?)
.port(options.member::<Option<u16>>(id!("port"))?)
.db_filename(options.member::<Option<String>>(id!("database_filename"))?)
.ui(options.member(id!("namespace"))?)
.ui(options.member(id!("ui"))?)
.ui_port(options.member::<Option<u16>>(id!("ui_port"))?)
.log((
options.member::<String>(id!("log_format"))?,
options.member::<String>(id!("log_level"))?,
Expand Down
1 change: 1 addition & 0 deletions temporalio/lib/temporalio/internal/bridge/testing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class EphemeralServer
:port, # Optional
:database_filename, # Optional
:ui,
:ui_port, # Optional, should be nil if ui is false
:log_format,
:log_level,
:extra_args,
Expand Down
13 changes: 13 additions & 0 deletions temporalio/lib/temporalio/search_attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ def length
@raw_hash.length
end

# Check equality.
#
# @param other [SearchAttributes] To compare.
# @return [Boolean] Whether equal.
def ==(other)
other.is_a?(SearchAttributes) && @raw_hash == other._raw_hash
end

alias size length

# Return a new search attributes collection with updates applied.
Expand Down Expand Up @@ -280,6 +288,11 @@ def update!(*updates)
end
end

# @!visibility private
def _raw_hash
@raw_hash
end

# @!visibility private
def _to_proto
Api::Common::V1::SearchAttributes.new(indexed_fields: _to_proto_hash)
Expand Down
17 changes: 16 additions & 1 deletion temporalio/lib/temporalio/testing/workflow_environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
require 'temporalio/internal/bridge/testing'
require 'temporalio/internal/proto_utils'
require 'temporalio/runtime'
require 'temporalio/search_attributes'
require 'temporalio/version'

module Temporalio
Expand All @@ -34,8 +35,10 @@ class WorkflowEnvironment
# @param default_workflow_query_reject_condition [WorkflowQueryRejectCondition, nil] Default rejection condition
# for the client.
# @param ip [String] IP to bind to.
# @param port [Integer, nil] Port to bind on, or +nil+ for random.
# @param port [Integer, nil] Port to bind on, or `nil` for random.
# @param ui [Boolean] If +true+, also starts the UI.
# @param ui_port [Integer, nil] Port to bind on if `ui` is true, or `nil` for random.
# @param search_attributes [Array<SearchAttributes::Key>] Search attributes to make available on start.
# @param runtime [Runtime] Runtime for the server and client.
# @param dev_server_existing_path [String, nil] Existing CLI path to use instead of downloading and caching to
# tmp.
Expand All @@ -62,6 +65,8 @@ def self.start_local(
ip: '127.0.0.1',
port: nil,
ui: false, # rubocop:disable Naming/MethodParameterName
ui_port: nil,
search_attributes: [],
runtime: Runtime.default,
dev_server_existing_path: nil,
dev_server_database_filename: nil,
Expand All @@ -72,6 +77,15 @@ def self.start_local(
dev_server_extra_args: [],
&
)
# Add search attribute args
unless search_attributes.empty?
dev_server_extra_args += search_attributes.flat_map do |key|
raise 'Search attribute must be Key' unless key.is_a?(SearchAttributes::Key)

['--search-attribute', "#{key.name}=#{SearchAttributes::IndexedValueType::PROTO_NAMES[key.type]}"]
end
end

server_options = Internal::Bridge::Testing::EphemeralServer::StartDevServerOptions.new(
existing_path: dev_server_existing_path,
sdk_name: 'sdk-ruby',
Expand All @@ -83,6 +97,7 @@ def self.start_local(
port:,
database_filename: dev_server_database_filename,
ui:,
ui_port: ui ? ui_port : nil,
log_format: dev_server_log_format,
log_level: dev_server_log_level,
extra_args: dev_server_extra_args
Expand Down
2 changes: 2 additions & 0 deletions temporalio/sig/temporalio/internal/bridge/testing.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Temporalio
attr_accessor port: Integer?
attr_accessor database_filename: String?
attr_accessor ui: bool
attr_accessor ui_port: Integer?
attr_accessor log_format: String
attr_accessor log_level: String
attr_accessor extra_args: Array[String]
Expand All @@ -29,6 +30,7 @@ module Temporalio
port: Integer?,
database_filename: String?,
ui: bool,
ui_port: Integer?,
log_format: String,
log_level: String,
extra_args: Array[String]
Expand Down
2 changes: 2 additions & 0 deletions temporalio/sig/temporalio/search_attributes.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ module Temporalio

def update!: (*Update updates) -> void

def _raw_hash: -> Hash[Key, Object]

def _to_proto: -> untyped

def _to_proto_hash: -> Hash[String, untyped]
Expand Down
4 changes: 4 additions & 0 deletions temporalio/sig/temporalio/testing/workflow_environment.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ module Temporalio
?ip: String,
?port: Integer?,
?ui: bool,
?ui_port: Integer?,
?search_attributes: Array[SearchAttributes::Key],
?runtime: Runtime,
?dev_server_existing_path: String?,
?dev_server_database_filename: String?,
Expand All @@ -30,6 +32,8 @@ module Temporalio
?ip: String,
?port: Integer?,
?ui: bool,
?ui_port: Integer?,
?search_attributes: Array[SearchAttributes::Key],
?runtime: Runtime,
?dev_server_existing_path: String?,
?dev_server_database_filename: String?,
Expand Down
58 changes: 58 additions & 0 deletions temporalio/test/testing/workflow_environment_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,63 @@ def test_time_skipping_heartbeat_timeout
end
end
end

def test_start_local_search_attributes
pre = 'ruby-temporal-test-'
attr_boolean = Temporalio::SearchAttributes::Key.new(
"#{pre}boolean", Temporalio::SearchAttributes::IndexedValueType::BOOLEAN
)
attr_float = Temporalio::SearchAttributes::Key.new(
"#{pre}float", Temporalio::SearchAttributes::IndexedValueType::FLOAT
)
attr_integer = Temporalio::SearchAttributes::Key.new(
"#{pre}integer", Temporalio::SearchAttributes::IndexedValueType::INTEGER
)
attr_keyword = Temporalio::SearchAttributes::Key.new(
"#{pre}keyword", Temporalio::SearchAttributes::IndexedValueType::KEYWORD
)
attr_keyword_list = Temporalio::SearchAttributes::Key.new(
"#{pre}keyword-list", Temporalio::SearchAttributes::IndexedValueType::KEYWORD_LIST
)
attr_text = Temporalio::SearchAttributes::Key.new(
"#{pre}text", Temporalio::SearchAttributes::IndexedValueType::TEXT
)
attr_time = Temporalio::SearchAttributes::Key.new(
"#{pre}time", Temporalio::SearchAttributes::IndexedValueType::TIME
)
attrs = Temporalio::SearchAttributes.new(
{
attr_boolean => true,
attr_float => 1.23,
attr_integer => 456,
attr_keyword => 'some keyword',
attr_keyword_list => ['some keyword list 1', 'some keyword list 2'],
attr_text => 'some text',
attr_time => Time.at(Time.now.to_i)
}
)

# Confirm when used in env without SAs it fails
Temporalio::Testing::WorkflowEnvironment.start_local do |env|
err = assert_raises(Temporalio::Error::RPCError) do
env.client.start_workflow(
:some_workflow,
id: "wf-#{SecureRandom.uuid}", task_queue: "tq-#{SecureRandom.uuid}",
search_attributes: attrs
)
end
assert_includes err.message, 'no mapping defined'
end

# Confirm when used in env with SAs it succeeds
Temporalio::Testing::WorkflowEnvironment.start_local(search_attributes: attrs.to_h.keys) do |env|
handle = env.client.start_workflow(
:some_workflow,
id: "wf-#{SecureRandom.uuid}", task_queue: "tq-#{SecureRandom.uuid}",
search_attributes: attrs
)
assert_equal attrs, handle.describe.search_attributes
end
end
end
end
Loading