Skip to content

Commit

Permalink
test(state): Adds State Management component specs
Browse files Browse the repository at this point in the history
  • Loading branch information
bougyman committed Oct 23, 2024
1 parent 1e60d07 commit 81118c2
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 18 deletions.
2 changes: 1 addition & 1 deletion coverage/coverage.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"timestamp":1728408645,"command_name":"Unit Tests","files":[{"filename":"/home/bougyman/rubyists/dapr/lib/dapr.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,null,null,1,1,5,null,null,null,1,1,1,1,1,null,null]},"covered_strength":1.4,"covered_lines":10,"lines_of_code":10},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/client.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,1,1,1,null,1,1,null,1,1,1,1,1,null,1,4,null,1,1,null,null,1,9,null,null,1,1,null,null,1,12,null,null,null,1,1,null,1,5,null,null,1,1,1,1,null,1,null,null,1,1,null,null,null,null,null]},"covered_strength":1.7878787878787878,"covered_lines":33,"lines_of_code":33},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/client/configuration.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,null,1,1,1,null,1,null,1,1,null,null,1,null,null,1,null,1,1,null,1,1,1,null,null,null,null,null,null,null,1,1,1,1,null,null,1,1,1,null,null,null,null,null]},"covered_strength":1.0,"covered_lines":21,"lines_of_code":21},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/client/lock.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,null,1,1,1,null,1,null,1,1,null,null,1,null,null,1,null,1,1,null,null,null,null,null,null,1,6,6,null,null,null,null,null,null,1,6,6,null,null,null,1,6,6,5,5,null,null,1,null,null,null,1,4,4,4,null,3,3,null,null,1,null,null,1,18,null,null,null,null,null,1,6,null,null,null,null,null]},"covered_strength":3.085714285714286,"covered_lines":35,"lines_of_code":35},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/version.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,null,1,null,null,null]},"covered_strength":1.0,"covered_lines":3,"lines_of_code":3}],"metrics":{"covered_percent":100.0,"covered_strength":2.0098039215686274,"covered_lines":102,"total_lines":102}}
{"timestamp":1729718516,"command_name":"Unit Tests","files":[{"filename":"/home/bougyman/rubyists/dapr/lib/dapr.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,null,null,1,1,7,null,null,null,1,1,1,1,1,null,null]},"covered_strength":1.6,"covered_lines":10,"lines_of_code":10},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/client.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,1,1,1,null,1,1,null,1,1,1,1,1,1,null,1,4,null,1,1,null,null,1,11,null,null,1,1,null,null,1,14,null,null,null,1,1,null,1,5,null,null,1,1,1,1,null,1,null,null,1,1,null,null,null,null,null]},"covered_strength":1.8823529411764706,"covered_lines":34,"lines_of_code":34},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/client/configuration.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,null,1,1,1,null,1,null,1,1,null,null,1,null,null,1,null,1,1,null,1,1,1,null,null,null,null,null,null,null,1,1,1,1,null,null,1,1,1,null,null,null,null,null]},"covered_strength":1.0,"covered_lines":21,"lines_of_code":21},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/client/lock.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,null,1,1,1,null,1,null,1,1,null,null,1,null,null,1,null,1,1,null,null,null,null,null,null,1,6,6,null,null,null,null,null,null,1,6,6,null,null,null,1,6,6,5,5,null,null,1,null,null,null,1,4,4,4,null,3,3,null,null,1,null,null,1,18,null,null,null,null,null,1,6,null,null,null,null,null]},"covered_strength":3.085714285714286,"covered_lines":35,"lines_of_code":35},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/client/state.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,null,1,1,1,null,null,1,null,1,1,null,1,null,1,1,1,1,1,1,null,null,null,null,null,null,1,1,null,null,null,null,null,null,null,1,1,null,null,null,null,null,1,2,null,null,null,null,null,null,1,1,1,1,null,null,null,null,1,3,1,1,1,null,null,null,null,null]},"covered_strength":1.103448275862069,"covered_lines":29,"lines_of_code":29},{"filename":"/home/bougyman/rubyists/dapr/lib/dapr/version.rb","covered_percent":100.0,"coverage":{"lines":[null,null,1,1,null,1,null,null,null]},"covered_strength":1.0,"covered_lines":3,"lines_of_code":3}],"metrics":{"covered_percent":100.0,"covered_strength":1.8484848484848484,"covered_lines":132,"total_lines":132}}
53 changes: 36 additions & 17 deletions lib/dapr/client/state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,57 @@ class State
include Client
include SemanticLogger::Loggable

attr_reader :store_name, :keys, :metadata
attr_reader :store_name

Runtime = Client::Runtime
GetStateRequest = Runtime::GetStateRequest
GetStateResponse = Runtime::GetStateResponse
SetStateRequest = Runtime::SetStateRequest
SetStateResponse = Runtime::SetStateResponse
DEFAULT_STORE_NAME = 'dapr-statestore'
Empty = Google::Protobuf::Empty
Runtime = Client::Runtime
GetBulkStateResponse = Runtime::GetBulkStateResponse
GetStateRequest = Runtime::GetBulkStateRequest
SaveStateRequest = Runtime::SaveStateRequest
DEFAULT_STORE_NAME = 'statestore'

# @param keys [Array<String>] keys to retrieve from the state store
# @param store_name [String] name of the State Management component, defaults to 'dapr-statestore'
# @param metadata [Hash] metadata to include
#
# @return [GetStateResponse] The response from the Dapr State Management component
def self.get(keys, store_name: DEFAULT_STORE_NAME, metadata: {})
new(store_name, metadata:).get(keys)
# @return [GetBulkStateResponse] The response from the Dapr State Management component
def self.get(*keys, store_name: DEFAULT_STORE_NAME, metadata: {})
new(store_name).get(keys, metadata:)
end

# @param states [Hash] states to set in the state store, key/value pairs
# @param store_name [String] name of the State Management component, defaults to 'dapr-statestore'
# @param metadata [Hash] metadata to include
#
# @return [Empty] The response from the Dapr State Management component
def self.set(states, store_name: DEFAULT_STORE_NAME, metadata: {})
new(store_name).set(states, metadata:)
end

# Initialize the State Management client
#
# @param store_name [String] name of the Dapr Configuration component to use
def initialize(store_name)
@store_name = store_name
end

# @param keys [Array<String>] keys to retrieve from the state store
# @param metadata [Hash] metadata to include
def initialize(store_name, keys: [], metadata: {})
@store_name = store_name
@keys = Array(keys)
@metadata = metadata
#
# @return [Array<BulkStateItem>] Array of items returned by the state store
def get(keys, metadata: {})
logger.debug('Getting state', keys:, store_name:, metadata:)
response = singleton.get_bulk_state GetStateRequest.new(store_name:, keys:, metadata:)
response.items
end

def get
logger.debug('Getting state', keys:, store_name:)
singleton.get_state GetStateRequest.new(store_name:, keys:, metadata:)
# @param states [Hash] states to set (key/values in the state store)
# @param metadata [Hash] metadata to include
def set(states, metadata: {})
states = states.map { |key, value| { key:, value:, metadata: } }
request = SaveStateRequest.new(store_name:, states:)
logger.debug('Setting state', states:, store_name:)
singleton.save_state request
end
end
end
Expand Down
82 changes: 82 additions & 0 deletions test/dapr/client/test_state.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# frozen_string_literal: true

require_relative '../../test_helper'

# Tests for the Dapr State Management component
class TestDaprState < Minitest::Test
require Rubyists::Dapr::LIBROOT / :client / :state
DummyClient = Rubyists::Dapr::Client::DummyClient
Runtime = ::Dapr::Proto::Runtime::V1
Common = ::Dapr::Proto::Common::V1
Empty = Google::Protobuf::Empty

def setup_dummy_client!
DummyClient.define_method(:states) { @states ||= {} }
define_get_bulk_state_method!
define_set_bulk_state_method!
end

def define_get_bulk_state_method!
DummyClient.define_method(:get_bulk_state) do |*args, &_block|
items = args.shift.keys.map.with_index do |key, index|
metadata = { key: "METAKEY-#{index}", value: "METAVALUE-#{index}" }
data = "test-state-data-#{index}"
Runtime::BulkStateItem.new(key:, data:, etag: '1', error: nil, metadata:)
end
Runtime::GetBulkStateResponse.new(items:)
end
end

def define_set_bulk_state_method!
DummyClient.define_method(:save_state) do |*args, &_block|
args.shift.states.map { |s| states[s.key] = s.value }
Empty
end
end

def make_it_testy!
return if testy?

setup_dummy_client!
@testy = true
end

def testy?
@testy
end

context 'State' do # rubocop:disable Metrics/BlockLength
should 'Read existing State item' do
make_it_testy!
messages = semantic_logger_events(Rubyists::Dapr::Client::State) do
states = Rubyists::Dapr::Client::State.get('test_item1', 'test_item2')

assert_equal 2, states.size
assert_equal 'test-state-data-0', states[0].data
assert_equal 'test_item1', states[0].key
assert_equal 'test_item2', states[1].key
assert_equal 'test-state-data-1', states[1].data
end

assert_equal 1, messages.size
assert_semantic_logger_event messages.first, level: :debug, message: 'Getting state'
refute_nil messages.first.payload[:keys]
end

should 'Set a State item' do
make_it_testy!
messages = semantic_logger_events(Rubyists::Dapr::Client::State) do
items = { 'test_item1' => 'test-state-data-writes-0', 'test_item2' => 'test-state-data-writes-1' }
response = Rubyists::Dapr::Client::State.set(items)

assert_equal Empty, response
end

assert_equal 1, messages.size
assert_semantic_logger_event messages.first, level: :debug, message: 'Setting state'
assert_equal [{ key: 'test_item1', value: 'test-state-data-writes-0', metadata: {} },
{ key: 'test_item2', value: 'test-state-data-writes-1', metadata: {} }],
messages.first.payload[:states]
end
end
end

0 comments on commit 81118c2

Please sign in to comment.