Class: Overseer::TestingControl::Rails::SinkStore

Inherits:
Object
  • Object
show all
Defined in:
lib/overseer/testing_control/rails/stores.rb

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ SinkStore

Returns a new instance of SinkStore.



51
52
53
54
55
# File 'lib/overseer/testing_control/rails/stores.rb', line 51

def initialize(configuration)
  @configuration = configuration
  @records = []
  @mutex = Mutex.new
end

Instance Method Details

#capture(capability:, version:, effect_kind:, summary:, payload:, context:, outcome: nil, metadata: nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/overseer/testing_control/rails/stores.rb', line 57

def capture(capability:, version:, effect_kind:, summary:, payload:, context:, outcome: nil, metadata: nil)
  definition = @configuration.sink!(capability, version)
  ProtocolV3.identifier!(context.run_id, label: 'capture run ID')
  ProtocolV3.identifier!(context.correlation_id, label: 'capture correlation ID')
  ProtocolV3.identifier!(context.step_id, label: 'capture step ID') if context.step_id
  validate_capture!(definition, effect_kind:, outcome:, summary:, payload:, metadata:)
  record = {
    'id' => "effect-#{SecureRandom.hex(12)}",
    'capability' => { 'id' => capability, 'version' => version },
    'effectKind' => effect_kind,
    **(outcome ? { 'outcome' => outcome } : {}),
    'correlationId' => context.correlation_id,
    **(context.step_id ? { 'stepId' => context.step_id } : {}),
    'capturedAt' => ProtocolV3.timestamp,
    'summary' => summary,
    **( ? { 'metadata' => ProtocolV3.stringify() } : {}),
    'payload' => ProtocolV3.stringify(payload)
  }
  validate_record_size!(record)
  @mutex.synchronize do
    raise StoreLimitExceeded, 'Fake-sink storage reached its bounded limit' if
      @records.length >= @configuration.max_sink_records

    @records << { run_id: context.run_id, record: deep_copy(record) }
  end
  deep_copy(record)
rescue ProtocolV3::ValidationError => e
  raise CaptureError, e.message
end

#clear ⇒ Object



117
118
119
# File 'lib/overseer/testing_control/rails/stores.rb', line 117

def clear
  @mutex.synchronize { @records.clear }
end

#query(capability:, version:, run_id:, input:, filter:, cursor:, limit:) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/overseer/testing_control/rails/stores.rb', line 87

def query(capability:, version:, run_id:, input:, filter:, cursor:, limit:)
  definition = @configuration.sink!(capability, version)
  ProtocolV3.identifier!(run_id, label: 'sink query run ID')
  ProtocolV3.validate_value!(definition.query_input_schema, input, label: 'sink query input')
  if !input.empty? && !definition.query_matcher
    raise ProtocolV3::ValidationError, 'non-empty sink input requires a product query matcher'
  end

  offset = cursor ? Integer(cursor, 10) : 0
  raise ProtocolV3::ValidationError, 'sink cursor is outside the bounded result' if offset.negative?

  matched = @mutex.synchronize do
    selected = @records.filter_map do |entry|
      next unless entry.fetch(:run_id) == run_id

      record = entry.fetch(:record)
      next unless matches_filter?(record, capability, version, filter)
      next unless matches_input?(definition, record, input)

      record
    end
    selected.map { |record| deep_copy(record) }
  end
  records = matched.slice(offset, limit) || []
  next_offset = offset + records.length
  [records, next_offset < matched.length ? next_offset.to_s : nil]
rescue ArgumentError
  raise ProtocolV3::ValidationError, 'sink cursor is invalid'
end