27
28
29
30
31
32
33
34
35
36
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
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/heapscope/baseline.rb', line 27
def compare(baseline_path, current_path_or_report, threshold: 0.5)
baseline = JSON.parse(File.read(baseline_path), symbolize_names: true)
current = current_path_or_report.is_a?(Report) ? current_path_or_report : Report.load(current_path_or_report)
base_retained = baseline[:retained_objects_estimate].to_i
curr_retained = current.diff&.surviving_estimate.to_i
change = if base_retained.zero?
curr_retained.positive? ? 1.0 : 0.0
else
(curr_retained - base_retained).to_f / base_retained
end
base_bytes = baseline[:retained_bytes_estimate].to_i
curr_bytes = current.diff&.heap_bytes_estimate_delta.to_i
bytes_change = base_bytes.zero? ? 0.0 : (curr_bytes - base_bytes).to_f / base_bytes
regression = change > threshold || bytes_change > threshold
findings = []
if regression
findings << Finding.new(
code: "HS008",
severity: :high,
facts: [
"Observed fact: retained objects baseline=#{base_retained} current=#{curr_retained}.",
"Observed fact: retained bytes baseline=#{base_bytes} current=#{curr_bytes}."
],
derived: [
"Derived: object change #{(change * 100).round(1)}%, bytes change #{(bytes_change * 100).round(1)}%."
],
hypothesis: "Current run exceeds baseline retention beyond threshold #{threshold}."
)
end
{
regression: regression,
baseline_retained_objects: base_retained,
current_retained_objects: curr_retained,
object_change_ratio: change,
baseline_retained_bytes: base_bytes,
current_retained_bytes: curr_bytes,
bytes_change_ratio: bytes_change,
findings: findings,
result: regression ? "REGRESSION" : "OK"
}
end
|