flaky-friend 0.3.0 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c996492175a4e470f3ea4c08890a4626c90e4de13e35e33a1d919ef41a5b04b6
4
- data.tar.gz: a7a08059d87983af6e0b163177cee5db2f659201f92267a338355e6b6df71024
3
+ metadata.gz: 3b8649d4ba762628bf9970b0e493e3d2ab06f7662d136b5f2809816fe243185a
4
+ data.tar.gz: b5db3f2cc290f02fb848ecd08ff72935a5727e8aacad548bad6cf41a83ada669
5
5
  SHA512:
6
- metadata.gz: 7282d21702ca0d52b80c74c01dc6bf8fce827f4543bd082a45f57d2080b04d9cbc8b866b10aee1352a74ca1f0279cc3ba73d1baed98911b6843428bb5a184662
7
- data.tar.gz: 5201e17baf1732b2cd21879c391021ba96d0a38a0a9b59970225c6b8f2cba52aaf4b72697e6ac052d9af17cc67bbb28336eb3685dcbb19e2daa0e1ef721e743b
6
+ metadata.gz: daf4b72ca24fcd98aa0d8a5d9ad8c2d40f465349b3f1bf75c536b820c4297bbaa962dde693c1906db0bc427e58136af7978d611a3319490772cef367081ea1d4
7
+ data.tar.gz: c9594cf996ef4461c496066f94e9eda162400ccf266a371e5331c1bbf216f8261422835933ba7c139a327e7de5a8e17bb78af20eb4e049c12f9155e14507e5a4
@@ -24,13 +24,12 @@ module Flaky
24
24
  total_runs = @repo.total_runs_count(branch: branch, since_days: @since_days)
25
25
 
26
26
  puts "Flaky tests on #{branch} (last #{@since_days} days, #{total_runs} CI runs):\n\n"
27
- puts format("%-6s %-50s %s", "Fails", "Location", "Last Failure")
27
+ puts format("%-6s %s", "Fails", "Location")
28
28
  puts "-" * 90
29
29
 
30
30
  rows.each_with_index do |row, i|
31
31
  location = "#{row['spec_file']}:#{row['line_number']}"
32
- truncated = location.length > 48 ? "...#{location[-45..]}" : location
33
- puts format("%-6d %-50s %s", row["failure_count"], truncated, row["last_failure"])
32
+ puts format("%-6d %s (%s)", row["failure_count"], location, row["last_failure"])
34
33
 
35
34
  if i == 0
36
35
  puts "\n \e[33m▶ Next to investigate:\e[0m #{location}"
@@ -18,13 +18,14 @@ module Flaky
18
18
  env = {}
19
19
  env["FLAKY_CI_SIMULATE"] = "1" if @ci_simulate
20
20
 
21
+ seed = resolve_seed
21
22
  passes = 0
22
23
  failures = 0
23
- failed_seeds = []
24
+ failed_seeds = Set.new
24
25
  start_time = Time.now
25
26
 
26
27
  puts "Stress testing: #{@spec_location}"
27
- puts " Iterations: #{@iterations}, Seed: #{@seed || 'random'}, CI simulation: #{@ci_simulate}"
28
+ puts " Iterations: #{@iterations}, Seed: #{seed_description(seed)}, CI simulation: #{@ci_simulate}"
28
29
  puts ""
29
30
 
30
31
  @iterations.times do |i|
@@ -34,7 +35,7 @@ module Flaky
34
35
  break
35
36
  end
36
37
 
37
- run_seed = @seed || rand(100_000)
38
+ run_seed = seed.presence || rand(100_000)
38
39
  cmd = "bundle exec rspec #{@spec_location} --seed #{run_seed} --format progress 2>&1"
39
40
 
40
41
  output = nil
@@ -50,7 +51,7 @@ module Flaky
50
51
  print "\e[32m.\e[0m"
51
52
  else
52
53
  failures += 1
53
- failed_seeds << run_seed
54
+ failed_seeds.add(run_seed)
54
55
  print "\e[31mF\e[0m"
55
56
  end
56
57
  end
@@ -68,14 +69,47 @@ module Flaky
68
69
  end
69
70
 
70
71
  @repo.insert_stress_run(
71
- spec_location: @spec_location, seed: @seed, iterations: @iterations,
72
- passes: passes, failures: failures, ci_simulation: @ci_simulate ? 1 : 0
72
+ spec_location: @spec_location, seed: @seed.is_a?(Integer) ? @seed : nil,
73
+ iterations: @iterations, passes: passes, failures: failures,
74
+ ci_simulation: @ci_simulate ? 1 : 0
73
75
  )
74
76
 
75
77
  exit(failures > 0 ? 1 : 0)
76
78
  ensure
77
79
  @repo.close
78
80
  end
81
+
82
+ private
83
+
84
+ def resolve_seed
85
+ case @seed
86
+ when :random
87
+ nil
88
+ when Integer
89
+ @seed
90
+ when nil
91
+ file, line = parse_location(@spec_location)
92
+ db_seeds = @repo.failing_seeds(file: file, line: line)
93
+ db_seeds.any? ? db_seeds.first : nil
94
+ end
95
+ end
96
+
97
+ def seed_description(seed)
98
+ case @seed
99
+ when :random then "random"
100
+ when Integer then @seed.to_s
101
+ else seed.present? ? seed.to_s : "random (no known failing seeds)"
102
+ end
103
+ end
104
+
105
+ def parse_location(loc)
106
+ if loc.include?(":")
107
+ parts = loc.rpartition(":")
108
+ [parts[0], parts[2].to_i]
109
+ else
110
+ [loc, nil]
111
+ end
112
+ end
79
113
  end
80
114
  end
81
115
  end
@@ -147,6 +147,23 @@ module Flaky
147
147
  connection.execute("SELECT * FROM stress_runs ORDER BY created_at DESC LIMIT ?", limit)
148
148
  end
149
149
 
150
+ # --- Seeds ---
151
+
152
+ def failing_seeds(file:, line: nil)
153
+ conditions = ["spec_file LIKE ?"]
154
+ params = ["%#{file}%"]
155
+
156
+ if line
157
+ conditions << "line_number = ?"
158
+ params << line
159
+ end
160
+
161
+ connection.execute(
162
+ "SELECT seed, COUNT(*) AS n FROM test_failures WHERE #{conditions.join(' AND ')} GROUP BY seed ORDER BY n DESC, MAX(failed_at) DESC",
163
+ params
164
+ ).map { |row| row["seed"] }
165
+ end
166
+
150
167
  # --- Stress ---
151
168
 
152
169
  def insert_stress_run(spec_location:, seed:, iterations:, passes:, failures:, ci_simulation:)
@@ -36,7 +36,7 @@ FLAKY_HELP = <<~HELP
36
36
  SINCE Number of days to look back for rank [default: 30]
37
37
  SPEC Spec file location (path/to/spec.rb or path:line)
38
38
  N Number of stress test iterations [default: 20]
39
- SEED RSpec seed for deterministic ordering
39
+ SEED RSpec seed (omit=use known failing seeds, "random"=random)
40
40
  CI Set to "true" to enable CI simulation (latency + reduced threads)
41
41
  TIMEOUT Stress test timeout in seconds [default: 600]
42
42
 
@@ -78,10 +78,15 @@ namespace :flaky do
78
78
  task stress: :environment do
79
79
  require "flaky/commands/stress"
80
80
  spec = ENV["SPEC"] || abort("Usage: bin/rails flaky:stress SPEC=path/to/spec.rb:42")
81
+ seed = case ENV["SEED"]
82
+ when nil then nil
83
+ when "random" then :random
84
+ else ENV["SEED"].to_i
85
+ end
81
86
  Flaky::Commands::Stress.new(
82
87
  spec_location: spec,
83
88
  iterations: ENV.fetch("N", "20").to_i,
84
- seed: ENV["SEED"]&.to_i,
89
+ seed: seed,
85
90
  ci_simulate: ENV["CI"] == "true",
86
91
  timeout: ENV.fetch("TIMEOUT", "600").to_i
87
92
  ).execute
data/lib/flaky/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Flaky
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flaky-friend
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Flytedesk