Class: Inferno::CLI::Session::SessionCompare

Inherits:
SessionResults show all
Defined in:
lib/inferno/apps/cli/session/session_compare.rb

Defined Under Namespace

Classes: ComparedTestResult

Constant Summary collapse

COMMAND_OPTIONS =
{
  expected_results_session: {
    aliases: ['-s'],
    type: :string,
    desc: 'Session ID on the same server. The results of this indicated ' \
          'session will be used as the expected results. When the compared ' \
          "session's results do not match, comparison details will not be " \
          'written to file (use the `-f` option).'
  },
  expected_results_file: {
    aliases: ['-f'],
    type: :string,
    desc: 'Path to a file that contains the expected results. When the session ' \
          'results do not match the expected results in the file, generated ' \
          'comparison files will be placed in the same directory.'
  },
  compare_messages: {
    aliases: ['-m'],
    type: :boolean,
    default: false,
    desc: 'Compare messages when comparing results.'
  },
  compare_result_message: {
    aliases: ['-r'],
    type: :boolean,
    default: false,
    desc: 'Compare result_message when comparing results.'
  },
  normalized_strings: {
    aliases: ['-n'],
    type: :array,
    desc: 'Literal strings or regexes to normalize away before comparing ' \
          '(URL-encoded form of literal strings will also be normalized).'
  }
}.freeze

Instance Attribute Summary

Attributes inherited from SessionResults

#options, #session_id

Instance Method Summary collapse

Methods inherited from SessionResults

#initialize, #results_for_session, #session_results

Methods included from Errors

#handle_web_api_error, #not_found_error_message, #parse_error_response, #test_run_not_found_message, #text_error_message

Methods included from Connection

#base_url, #check_session_exists, #connection, #delete, #get, #handle_connection_error, #post

Constructor Details

This class inherits a constructor from Inferno::CLI::Session::SessionResults

Instance Method Details

#build_short_id_map(runnable, map = {}) ⇒ Object



155
156
157
158
159
160
161
162
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 155

def build_short_id_map(runnable, map = {})
  return map unless runnable.is_a?(Hash)

  map[runnable['id']] = runnable['short_id'] if runnable['id'].present?
  runnable['test_groups']&.each { |group| build_short_id_map(group, map) }
  runnable['tests']&.each { |test| build_short_id_map(test, map) }
  map
end

#compared_resultsObject



143
144
145
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 143

def compared_results
  @compared_results = match_result_ids(expected_results, session_results)
end

#compared_results_as_csvObject



96
97
98
99
100
101
102
103
104
105
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 96

def compared_results_as_csv
  CSV.generate do |csv|
    csv << comparison_csv_header_row
    compared_results.each do |result|
      next unless result.different_result?

      csv << result.comparison_csv_row
    end
  end
end

#comparison_csv_header_rowObject



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 111

def comparison_csv_header_row
  normalized_suffix = normalizing? ? ' (normalized)' : ''
  header_row = ['id', 'short_id', 'type', 'different?', 'expected result', 'actual result']
  if options[:compare_result_message]
    header_row << 'result_message different?'
    header_row << "expected result_message#{normalized_suffix}"
    header_row << "actual result_message#{normalized_suffix}"
  end
  if options[:compare_messages]
    header_row << 'messages different?'
    header_row << "expected messages#{normalized_suffix}"
    header_row << "actual messages#{normalized_suffix}"
  end

  header_row
end

#display_compared_resultsObject



88
89
90
91
92
93
94
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 88

def display_compared_results
  output = {
    matched: results_match?,
    results: compared_results.map(&:to_h)
  }
  puts JSON.pretty_generate(output)
end

#expected_resultsObject



132
133
134
135
136
137
138
139
140
141
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 132

def expected_results
  @expected_results ||= if options[:expected_results_session].present?
                          results_for_session(options[:expected_results_session])
                        elsif options[:expected_results_file].present?
                          JSON.parse(File.read(options[:expected_results_file]))
                        else
                          puts({ errors: 'No expected results provided.' }.to_json)
                          exit(3)
                        end
end

#match_result_ids(expected, actual) ⇒ Object



164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 164

def match_result_ids(expected, actual)
  expected_hash = results_hash_by_id(expected)
  actual_hash = results_hash_by_id(actual)

  compared_results = expected_hash.map do |id, result|
    ComparedTestResult.new(id, result, actual_hash[id], options, short_id_map)
  end
  actual_hash.keys.reject { |id| expected_hash.key?(id) }.each do |id|
    compared_results << ComparedTestResult.new(id, nil, actual_hash[id], options, short_id_map)
  end

  compared_results
end

#normalizing?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 107

def normalizing?
  options[:normalized_strings].present?
end

#output_directoryObject

Output directory is the dirname of the expected results file (-f). Returns nil when -f is not provided (e.g. session-to-session comparison), in which case no output files are written on mismatch.



66
67
68
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 66

def output_directory
  options[:expected_results_file].present? && File.dirname(options[:expected_results_file])
end

#output_file_prefixObject



70
71
72
73
74
75
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 70

def output_file_prefix
  return '' unless options[:expected_results_file].present?

  basename = File.basename(options[:expected_results_file])
  basename.end_with?('expected.json') ? basename.sub(/expected\.json$/, '') : ''
end

#results_hash_by_id(results) ⇒ Object



178
179
180
181
182
183
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 178

def results_hash_by_id(results)
  results.each_with_object({}) do |result, hash|
    key = result['test_id'] || result['test_group_id'] || result['test_suite_id']
    hash[key] = result
  end
end

#results_match?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 128

def results_match?
  compared_results.all?(&:same_result?)
end

#results_timestampObject



59
60
61
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 59

def results_timestamp
  @results_timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
end

#runObject



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 45

def run
  display_compared_results
  if output_directory.present? && !results_match?
    save_actual_results_to_file
    save_comparison_csv_to_file
  end

  if results_match?
    exit(0)
  else
    exit(3)
  end
end

#save_actual_results_to_fileObject



77
78
79
80
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 77

def save_actual_results_to_file
  actual_results_file_name = "#{output_file_prefix}actual_results_#{results_timestamp}.json"
  File.write(File.join(output_directory, actual_results_file_name), session_results.to_json)
end

#save_comparison_csv_to_fileObject



82
83
84
85
86
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 82

def save_comparison_csv_to_file
  compared_csv_file_name = "#{output_file_prefix}compared_results_#{results_timestamp}.csv"
  File.write(File.join(output_directory, compared_csv_file_name),
             compared_results_as_csv)
end

#session_detailsObject



147
148
149
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 147

def session_details
  @session_details ||= SessionDetails.new(session_id, options).details_for_session
end

#short_id_mapObject



151
152
153
# File 'lib/inferno/apps/cli/session/session_compare.rb', line 151

def short_id_map
  @short_id_map ||= build_short_id_map(session_details['test_suite'])
end