Skip to content

Commit

Permalink
Search attributes and UI port on dev server (#220)
Browse files Browse the repository at this point in the history
Fixes #205
Fixes #206
  • Loading branch information
cretz authored Feb 12, 2025
1 parent 319fe2e commit 66d68ea
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 2 deletions.
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

0 comments on commit 66d68ea

Please sign in to comment.