Module: Elasticsearch::Tests::CodeRunner

Includes:
Printer
Included in:
Test
Defined in:
lib/elasticsearch/tests/code_runner.rb

Overview

The module in charge of actually running actions and matching expected results with actual response results.

Constant Summary collapse

COMPARATORS =
{
  'lt' => '<',
  'lte' => '<=',
  'gt' => '>',
  'gte' => '>='
}.freeze

Instance Method Summary collapse

Methods included from Printer

display_errors, display_summary, #print_error, #print_failure, #print_match_failure, #print_success

Instance Method Details

#compare(action) ⇒ Object

Used for comparing gte (greater or equal than), gt (greater than), lte (less or equal than) and lt (less than) action - { ‘gte’ => { ‘key’ => value } }



161
162
163
164
165
166
167
168
169
# File 'lib/elasticsearch/tests/code_runner.rb', line 161

def compare(action)
  operator, value = action.first
  result = search_in_response(value.keys.first)
  if result&.send(COMPARATORS[operator], value[value.keys.first])
    print_success
  else
    print_failure(action, @response)
  end
end

#do_action(action) ⇒ Object

The main functionality in the test runner, run actions with the client from YAML ‘do` specifications. These are function calls to the Elasticsearch clients.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/elasticsearch/tests/code_runner.rb', line 37

def do_action(action)
  @response = nil
  catchable = action.delete('catch')
  client = @client
  if action['headers']
    client.transport.options[:transport_options][:headers].merge(
      { headers: action.delete('headers') }
    )
  end

  action = action.first if action.is_a?(Array)
  method, params = action.is_a?(String) ? [action, {}] : action.first

  # Get the namespace client if the method is namespaced
  if method.include?('.')
    arrayed_method = method.split('.')
    client = @client.send(arrayed_method.first)
    method = arrayed_method.last
  end
  @response = client.send(method.to_sym, process_params(params))
  puts "Action: #{action}\nResponse: #{@response}\n\n" if ENV['DEBUG']
  @response
rescue StandardError => e
  raise e unless expected_exception?(catchable, e)
end

#do_length(action) ⇒ Object



119
120
121
122
123
124
125
126
127
# File 'lib/elasticsearch/tests/code_runner.rb', line 119

def do_length(action)
  k, v = action['length'].first
  result = search_in_response(k).count
  if result && result == v
    print_success
  else
    print_failure(action, @response)
  end
end

#do_match(action) ⇒ Object

Code for matching expectations and response



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/elasticsearch/tests/code_runner.rb', line 97

def do_match(action)
  k, v = action['match'].first
  v = instance_variable_get(v.gsub('$', '@')) if v.is_a?(String) && v.include?('$')
  result = search_in_response(k)

  if !result.nil? && (
       result == v ||
       (result.respond_to?(:include?) && result.include?(v)) ||
       match_regexp(v, result)
     )
    print_success
  else
    print_match_failure(action)
  end
end

#expected_exception?(error_type, e) ⇒ Boolean

Returns:

  • (Boolean)


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/elasticsearch/tests/code_runner.rb', line 63

def expected_exception?(error_type, e)
  return false if error_type.nil?

  case error_type
  when 'request_timeout'
    e.is_a?(Elastic::Transport::Transport::Errors::RequestTimeout)
  when 'missing', /resource_not_found_exception/
    e.is_a?(Elastic::Transport::Transport::Errors::NotFound)
  when 'conflict'
    e.is_a?(Elastic::Transport::Transport::Errors::Conflict)
  when 'request'
    e.is_a?(Elastic::Transport::Transport::Errors::InternalServerError)
  when 'bad_request'
    e.is_a?(Elastic::Transport::Transport::Errors::BadRequest)
  when 'param'
    actual_error.is_a?(ArgumentError)
  when 'unauthorized'
    e.is_a?(Elastic::Transport::Transport::Errors::Unauthorized)
  when 'forbidden'
    e.is_a?(Elastic::Transport::Transport::Errors::Forbidden)
  when /error parsing field/, /illegal_argument_exception/
    e.message =~ /\[400\]/ ||
      e.is_a?(Elastic::Transport::Transport::Errors::BadRequest)
  when /NullPointerException/
    e.message =~ /\[400\]/
  when /status_exception/
    e.message =~ /\[409\]/
  else
    e.message =~ /#{error_type}/
  end
end

#is_false(action) ⇒ Object



147
148
149
150
151
152
153
154
# File 'lib/elasticsearch/tests/code_runner.rb', line 147

def is_false(action)
  response_value = search_in_response(action['is_false']) unless [true, false].include? @response
  if @response == false || response_value.nil? || [false, 'false'].include?(response_value)
    print_success
  else
    print_failure(action, @response)
  end
end

#is_true(action) ⇒ Object

The specified key exists and has a true value (ie not 0, false, undefined, null) action - { ‘is_true’ => field } or { ‘is_true’ => ” }



133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/elasticsearch/tests/code_runner.rb', line 133

def is_true(action)
  if @response.respond_to?(:body) && !@response&.nil? && ['', []].include?(action['is_true'])
    print_success
    return
  end

  response_value = search_in_response(action['is_true']) unless [true, false].include?(@response)
  if @response == true || !response_value.nil?
    print_success
  else
    print_failure(action, @response)
  end
end

#match_regexp(expected, result) ⇒ Object



113
114
115
116
117
# File 'lib/elasticsearch/tests/code_runner.rb', line 113

def match_regexp(expected, result)
  expected.is_a?(String) &&
    expected.match?(/^\//) &&
    result.match?(Regexp.new(expected.gsub('/', '').strip))
end

#set_variable(action) ⇒ Object

When the yaml test has a set instruction, set an instance variable with that value coming from the response.



173
174
175
176
# File 'lib/elasticsearch/tests/code_runner.rb', line 173

def set_variable(action)
  k, v = action['set'].first
  instance_variable_set("@#{v}", search_in_response(k))
end