megatest 0.3.0 → 0.4.0

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: dce0e1b9ec47a98020fabc266db9d93f73961574ed6ef0bf29b4885064114216
4
- data.tar.gz: c4dd6ed24dea6de74effca99474a850af28b77142a0c388dff2f4faf2f4b5338
3
+ metadata.gz: ffc34efd44ab621f7b9008e9f0a611715e8d3d66f6a524a407604166b6bb0612
4
+ data.tar.gz: a4149b89fe5d6fef8d0170f962bceefd860a75ccafe73f4f06a335fc27f3ffd2
5
5
  SHA512:
6
- metadata.gz: 827fa2e37b36c4e8d7fae1317be65d259bac20210276245c119cbf33d506e967514295d4d74cc9fefd499e60aefacfd4a752f17f83feb58a46387af3d516c302
7
- data.tar.gz: 3bfe1897107565dd27ae0eef08857b123eea0f181009669ab3e6c676f7fcbed7266fa3708f7b88589aadd518cb43cfaff8402a9648db5828373759b8219e2f6f
6
+ metadata.gz: a1a160e73481e907da8678544c4a267dfec6cdee353ee46c79222224a6d69f474612bc95e819ecf6a092d2bca8e3e595c59162c366fb94fbb1056206d8af32ef
7
+ data.tar.gz: 3d9482774172c04968f9e85a5006a2ff8b38dc34e92b2b5d2a2a6dd04fa808c3daa1381d97cea2cfb263f19adb6a3d7dfe0b51c54cf7612d588cbead1582c456
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2025-11-12
4
+
5
+ - Allow configuring the test glob via `config.test_globs`.
6
+
3
7
  ## [0.3.0] - 2025-06-20
4
8
 
5
9
  - Added missing MIT license.
data/lib/megatest/cli.rb CHANGED
@@ -92,7 +92,7 @@ module Megatest
92
92
  end
93
93
  end
94
94
 
95
- @config.selectors = Selector.parse(@argv)
95
+ @config.selectors = Selector.new(@config).parse(@argv)
96
96
  Megatest.load_config(@config)
97
97
  Megatest.init(@config)
98
98
  test_cases = Megatest.load_tests(@config)
@@ -125,7 +125,7 @@ module Megatest
125
125
  queue = @config.build_queue
126
126
  raise InvalidArgument, "Distributed queues can't be bisected" if queue.distributed?
127
127
 
128
- @config.selectors = Selector.parse(@argv)
128
+ @config.selectors = Selector.new(@config).parse(@argv)
129
129
  Megatest.load_config(@config)
130
130
  Megatest.init(@config)
131
131
  test_cases = Megatest.load_tests(@config)
@@ -139,7 +139,7 @@ module Megatest
139
139
  attr_accessor :queue_url, :retry_tolerance, :max_retries, :jobs_count, :job_index, :load_paths, :deprecations,
140
140
  :build_id, :heartbeat_frequency, :minitest_compatibility, :ci, :selectors
141
141
  attr_reader :before_fork_callbacks, :global_setup_callbacks, :backtrace, :circuit_breaker, :seed,
142
- :worker_id, :workers_count
142
+ :worker_id, :workers_count, :test_globs
143
143
  attr_writer :differ, :pretty_printer, :program_name, :colors
144
144
 
145
145
  def initialize(env)
@@ -168,12 +168,18 @@ module Megatest
168
168
  @pretty_printer = PrettyPrint.new(self)
169
169
  @minitest_compatibility = false
170
170
  @selectors = nil
171
+ @test_globs = [DEFAULT_TEST_GLOB]
171
172
  CIService.configure(self, env)
172
173
  end
173
174
 
175
+ def test_globs=(patterns)
176
+ @test_globs = normalize_test_glob(patterns)
177
+ end
178
+
174
179
  def initialize_dup(_)
175
180
  super
176
181
  @circuit_breaker = @circuit_breaker.dup
182
+ @test_globs = @test_globs.dup
177
183
  end
178
184
 
179
185
  def program_name
@@ -305,6 +311,16 @@ module Megatest
305
311
  instance_variable_set(name, value)
306
312
  end
307
313
  end
314
+
315
+ private
316
+
317
+ def normalize_test_glob(patterns)
318
+ if patterns
319
+ Array(patterns).compact.map(&:to_s)
320
+ else
321
+ [DEFAULT_TEST_GLOB]
322
+ end
323
+ end
308
324
  end
309
325
 
310
326
  @config = Config.new({})
@@ -232,11 +232,14 @@ module Megatest
232
232
  def populate(test_cases)
233
233
  super
234
234
 
235
- leader_key_set, = @redis.pipelined do |pipeline|
236
- pipeline.call("setnx", key("leader-status"), "setup")
235
+ value = key("leader-setup", worker_id)
236
+ # NB: If we assumed redis 7+ this could be a single command: `SET <key> NX GET EX @ttl <value>`.
237
+ _, _, leader = @redis.multi do |pipeline|
238
+ pipeline.call("setnx", key("leader-status"), value)
237
239
  pipeline.call("expire", key("leader-status"), @ttl)
240
+ pipeline.call("get", key("leader-status"))
238
241
  end
239
- @leader = leader_key_set == 1
242
+ @leader = leader == value
240
243
 
241
244
  if @leader
242
245
  @redis.multi do |transaction|
@@ -113,8 +113,8 @@ module Megatest
113
113
  p99 = sorted_results[(size * 0.99).to_i].duration
114
114
 
115
115
  @out.puts "Finished in #{s(executor.wall_time.to_f)}, average: #{ms(average)}, median: #{ms(median)}, p90: #{ms(p90)}, p99: #{ms(p99)}"
116
- cuttoff = p90 * 10
117
- slowest_tests = sorted_results.last(5).select { |r| r.duration > cuttoff }
116
+ cutoff = p90 * 10
117
+ slowest_tests = sorted_results.last(5).select { |r| r.duration > cutoff }
118
118
  unless slowest_tests.empty?
119
119
  @out.puts "Slowest tests:"
120
120
  slowest_tests.reverse_each do |result|
@@ -3,12 +3,12 @@
3
3
  # :stopdoc:
4
4
 
5
5
  module Megatest
6
- module Selector
6
+ class Selector
7
7
  class List
8
- def initialize(loaders, filters)
8
+ def initialize(config, loaders, filters)
9
9
  @loaders = loaders
10
10
  if loaders.empty?
11
- @loaders = [Loader.new("test")]
11
+ @loaders = [Loader.new(config, "test")]
12
12
  end
13
13
  @filters = filters
14
14
  end
@@ -56,11 +56,11 @@ module Megatest
56
56
  class Loader
57
57
  attr_reader :path
58
58
 
59
- def initialize(path, filter = nil)
59
+ def initialize(config, path, filter = nil)
60
60
  @path = File.expand_path(path)
61
61
  if @directory = File.directory?(@path)
62
62
  @path = File.join(@path, "/")
63
- @paths = Megatest.glob(@path)
63
+ @paths = Megatest.glob(config.test_globs.map { |pattern| File.join(@path, pattern) })
64
64
  else
65
65
  @paths = [@path]
66
66
  end
@@ -244,54 +244,56 @@ module Megatest
244
244
  NameFilter,
245
245
  ].freeze
246
246
 
247
- class << self
248
- def parse(argv)
249
- if argv.empty?
250
- return List.new([], [])
251
- end
247
+ def initialize(config)
248
+ @config = config
249
+ end
252
250
 
253
- argv = argv.dup
254
- loaders = []
255
- filters = []
251
+ def parse(argv)
252
+ if argv.empty?
253
+ return List.new(@config, [], [])
254
+ end
256
255
 
257
- negative = false
256
+ argv = argv.dup
257
+ loaders = []
258
+ filters = []
258
259
 
259
- until argv.empty?
260
- case argument = argv.shift
261
- when "!"
262
- negative = true
263
- else
264
- loader_str, filter_str = argument.split(":", 2)
265
- loader_str = nil if loader_str.empty?
266
-
267
- filter = nil
268
- if filter_str
269
- FILTERS.each do |filter_class|
270
- if filter = filter_class.parse(filter_str)
271
- break
272
- end
260
+ negative = false
261
+
262
+ until argv.empty?
263
+ case argument = argv.shift
264
+ when "!"
265
+ negative = true
266
+ else
267
+ loader_str, filter_str = argument.split(":", 2)
268
+ loader_str = nil if loader_str.empty?
269
+
270
+ filter = nil
271
+ if filter_str
272
+ FILTERS.each do |filter_class|
273
+ if filter = filter_class.parse(filter_str)
274
+ break
273
275
  end
274
276
  end
277
+ end
275
278
 
276
- if loader_str
277
- loader = Loader.new(loader_str, filter)
278
- if negative
279
- loader = NegativeLoader.new(loader)
280
- negative = false
281
- end
282
- loaders << loader
283
- else
284
- if negative
285
- filter = NegativeFilter.new(filter)
286
- negative = false
287
- end
288
- filters << filter
279
+ if loader_str
280
+ loader = Loader.new(@config, loader_str, filter)
281
+ if negative
282
+ loader = NegativeLoader.new(loader)
283
+ negative = false
284
+ end
285
+ loaders << loader
286
+ else
287
+ if negative
288
+ filter = NegativeFilter.new(filter)
289
+ negative = false
289
290
  end
291
+ filters << filter
290
292
  end
291
293
  end
292
-
293
- List.new(loaders, filters)
294
294
  end
295
+
296
+ List.new(@config, loaders, filters)
295
297
  end
296
298
  end
297
299
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Megatest
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
data/lib/megatest.rb CHANGED
@@ -12,6 +12,7 @@ module Megatest
12
12
  ROOT = -File.expand_path("../", __FILE__)
13
13
  PWD = File.join(Dir.pwd, "/")
14
14
  IGNORED_ERRORS = [NoMemoryError, SignalException, SystemExit].freeze
15
+ DEFAULT_TEST_GLOB = "**/{test_*,*_test}.rb"
15
16
 
16
17
  class << self
17
18
  def fork?
@@ -90,12 +91,12 @@ module Megatest
90
91
  end
91
92
 
92
93
  if Dir.method(:glob).parameters.include?(%i(key sort)) # Ruby 2.7+
93
- def glob(path)
94
- Dir.glob(File.join(path, "**/{test_*,*_test}.rb"))
94
+ def glob(pattern)
95
+ Dir.glob(pattern)
95
96
  end
96
97
  else
97
- def glob(path)
98
- paths = Dir.glob(File.join(path, "**/{test_*,*_test}.rb"))
98
+ def glob(pattern)
99
+ paths = Dir.glob(pattern)
99
100
  paths.sort!
100
101
  paths
101
102
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: megatest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-06-20 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Largely API compatible with test-unit / minitest, but with lots of extra
13
13
  modern niceties like a proper CLI, test distribution, etc.
@@ -74,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  requirements: []
77
- rubygems_version: 3.6.2
77
+ rubygems_version: 3.6.9
78
78
  specification_version: 4
79
79
  summary: Modern test-unit style test framework
80
80
  test_files: []