Class: ReportDiffer

Inherits:
Object
  • Object
show all
Includes:
AnsiHelp
Defined in:
lib/report/report_differ.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from AnsiHelp

#ansi, #bold, #green, #greenbg, #noattrs, #red, #redbg, #white, #yellow

Class Method Details

.compare_files(report_file_a, report_file_b) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
# File 'lib/report/report_differ.rb', line 198

def self.compare_files(report_file_a, report_file_b)  
  differ = ReportDiffer.new
  parser = ReportParser.new
  reports = [report_file_a, report_file_b].map do |filename|
    text=File.read(filename)
    report = parser.parse(File.basename(filename), text)
    report
  end
  diff_data = differ.compare(reports[0], reports[1])
  puts differ.prepare_report(diff_data)
end

Instance Method Details



51
52
53
# File 'lib/report/report_differ.rb', line 51

def banner(title)
  ("="*30) + title + ("=" * 30) + "\n"
end

#compare(report_a, report_b, threshold = 1) ⇒ Object



128
129
130
131
132
# File 'lib/report/report_differ.rb', line 128

def compare(report_a, report_b, threshold=1)
  summary_diff=compare_summaries(report_a, report_b, threshold)
  req_diffs=compare_requests(report_a, report_b, threshold)
  {:threshold => threshold, :summary_diff => summary_diff, :request_diffs => req_diffs, :unmatched_actions => find_unmatched_actions(report_a, report_b)}
end

#compare_attribs(holder_a, holder_b, attribs_for_comparison) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/report/report_differ.rb', line 96

def compare_attribs(holder_a, holder_b, attribs_for_comparison)
  results = {}
  attribs_for_comparison.each do |method_name|
    change = compute_difference(holder_a, holder_b, method_name)
    diff_hash = {}
    diff_hash[:change] = change 
    diff_hash[:from] = holder_a.send(method_name)
    diff_hash[:to] = holder_b.send(method_name)
    results["diff_#{method_name}".to_sym] = diff_hash 
  end
  return results
end

#compare_matched_action(matched_action, threshold) ⇒ Object



109
110
111
112
# File 'lib/report/report_differ.rb', line 109

def compare_matched_action(matched_action, threshold)
  attribs=[:count, :avg_time, :std_dev, :max_time, :min_time]
  return compare_attribs(matched_action.request1, matched_action.request2, attribs)
end

#compare_requests(report_a, report_b, threshold) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/report/report_differ.rb', line 119

def compare_requests(report_a, report_b, threshold)
  diffs = {}
  matched_actions = find_matched_actions(report_a, report_b)
  matched_actions.each do |matched_action|
    diffs[matched_action.key] = compare_matched_action(matched_action, threshold)
  end
  diffs
end

#compare_summaries(report_a, report_b, threshold = 1.3) ⇒ Object



114
115
116
117
# File 'lib/report/report_differ.rb', line 114

def compare_summaries(report_a, report_b, threshold=1.3)
  attribs=[:count, :avg_time, :std_dev, :max_time, :min_time]
  return compare_attribs(report_a.summary, report_b.summary, attribs)
end

#compute_difference(a, b, method_name) ⇒ Object



66
67
68
69
70
# File 'lib/report/report_differ.rb', line 66

def compute_difference(a, b, method_name)
    va= a.send(method_name)
    vb= b.send(method_name)
    return compute_difference_in_values(va,vb)
end

#compute_difference_in_values(va, vb) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/report/report_differ.rb', line 55

def compute_difference_in_values(va, vb)
  return 1 if va==vb
  sign= (vb > va) ? 1 : -1
  return sign * 999999 if (va==0 || vb==0)
  min=[va,vb].min
  max=[va,vb].max
  abs=max/min.to_f
  abs=("%.2f"%abs).to_f
  return sign * abs
end

#find_matched_actions(ra, rb) ⇒ Object



72
73
74
75
76
77
78
79
80
81
# File 'lib/report/report_differ.rb', line 72

def find_matched_actions(ra, rb)
  matched=[]
  ra.requests.each do |req_a|
    req_b = rb.get_request_like(req_a)
    unless req_b.nil?
      matched << MatchedRequests.new(req_a, req_b) 
    end
  end
  matched
end

#find_unmatched_actions(ra, rb) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/report/report_differ.rb', line 83

def find_unmatched_actions(ra, rb)
  unmatched=[]
  [[ra, rb], [rb, ra]].each do|a,b|
    a.requests.each do |req_a|
      req_b = b.get_request_like(req_a)
      if req_b.nil?
        (unmatched << UnmatchedRequest.new(a, req_a)) 
      end
    end
  end
  unmatched
end

#prepare_report(diff_data) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/report/report_differ.rb', line 172

def prepare_report(diff_data)
  dd=diff_data
  threshold = dd[:threshold]
  text =""
  text << "#Threshold=#{threshold}\n"
  w=20
  
  #Headers 
  text << "%-50s %-#{w}s %-#{w}s %-#{w}s %-#{w}s %-#{w}s\n" % ["Request_Times_Summary:", "Count", "Avg", "Std_Dev", "Min", "Max"]
  
  #Summary - all requests - line
  text << prepare_report_line_for_request("ALL_REQUESTS", dd[:summary_diff], threshold)
  text << "\n"
  #Go through all the request diffs and print them, in order of frequency
  req_diffs = dd[:request_diffs]
  req_diffs.sort_by{|k,v| v[:diff_count][:from]}.reverse.each do |req_key, req_diff|
    text << prepare_report_line_for_request(req_key, req_diff, threshold)
  end

  text << "\nUnmatched_Actions: \n\n"
  dd[:unmatched_actions].each do |unmatched_action|
    text << prepare_report_line_for_unmatched_action(unmatched_action)
  end
  text
end

#prepare_report_line_for_request(title, diff_hash, threshold) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/report/report_differ.rb', line 138

def prepare_report_line_for_request(title, diff_hash, threshold)
  text=""
  text << "%-50s" % title
  rd = diff_hash
  w = 20
  cell_texts = []
  %w(count avg_time std_dev min_time max_time).each do |metric|
    metric_key = ("diff_"+metric).to_sym
    diff = rd[metric_key]
    change = diff[:change]
    from = diff[:from]
    to = diff[:to]
    sign = (change == 1 ? " " : (change > 0 ? "+":""))
    change_text="%s%.1f" % [ sign, change ]
    if should_use_ansi()
      change_text = bold(change_text)
      change_text = change > 0 ? redbg(change_text) : ( change.abs > 2 ? greenbg(change_text) : green(change_text) )
    end
    cell_text = ( "%s(%s->%s)" % [ change_text, from, to])
    if change.abs < threshold
      marker = should_use_ansi() ? noattrs(white("~")) : "~"  #when using ansi pad the marker with the same number of ansi control chars as the other columns get
      cell_text = "%-#{w}s" % marker 
    end
    cell_texts << cell_text
  end
  #max_width = cell_texts.map{|ct| ct.length}.max
 ## w=max_width+3
  text << (" %-#{w}s %-#{w}s %-#{w}s %-#{w}s %-#{w}s\n" % cell_texts)
end

#prepare_report_line_for_unmatched_action(ac) ⇒ Object



168
169
170
# File 'lib/report/report_differ.rb', line 168

def prepare_report_line_for_unmatched_action(ac)
  "%-60s only in %s\n" % [ ac.request, ac.report ]
end

#should_use_ansiObject



134
135
136
# File 'lib/report/report_differ.rb', line 134

def should_use_ansi()
 false
end