buildkite-test_collector 2.11.0 → 2.13.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: 423b9692a49e1cea2d180d684f9f54c82a6fd84289087efe256cf4a2d1dd5f4b
4
- data.tar.gz: 7ec78a72fb4506ee301b44f2830adfc22c83eb0508cab3ef7d455ec4a1f3049a
3
+ metadata.gz: 3b5079c7b62d8a883afd7c607f452aa0f91b5b73d4b431f1e32137343bfbb5ba
4
+ data.tar.gz: f1fddd40906655afb5d0fc5fc83a5d81e6f44c6548ae85bb32be0ec03b806f38
5
5
  SHA512:
6
- metadata.gz: dcf9a81dd2c1b74f8241c22ea94aff3dc75a9c1190afda0b12d4c2ac06bd79b89694fcee5d43a07a051864d404e140cf665064778dbb5d73b389abbba28af1ec
7
- data.tar.gz: eb43eb66820451723296546c70b3b2fc7b63572aa393ae4ea2380bb8e195e7faa0c6e8b7eff56c04a70223585c55162872a82d647a7a4d74e8cfe7ffa7cad3c6
6
+ metadata.gz: d75687ce79c27f11f56244b1707deb6a54d822c5b2244cb3bea6b25a9454140f4997e9654137f1cffaefa9eadec7e77d9f10cb93bac5b36ac73fd4b760d45701
7
+ data.tar.gz: 55e339451c85f5c95c0a664cd9f34f9f554f06c864e1eab0730d217fb3ae9298de7cd61fd46546156c1081de4a7895c25039f8a9eb776a72c313103596699744
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /vendor/bundle
10
+ Gemfile.lock
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v2.13.0
4
+
5
+ * Remove `./` prefix from minitest collector file paths
6
+
7
+ **Full Changelog**: https://github.com/buildkite/test-collector-ruby/compare/v2.12.0...v2.13.0
8
+
9
+ ## v2.12.0
10
+
11
+ * Prevent OOM with bounded thread pool and memory cleanup
12
+
13
+ **Full Changelog**: https://github.com/buildkite/test-collector-ruby/compare/v2.11.0...v2.12.0
14
+
3
15
  ## v2.11.0
4
16
 
5
17
  * Add `location_prefix` option. Allows a file name prefix to be set which will be prepended to `file_name` and `location` in the test results.
@@ -24,7 +24,10 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
26
26
 
27
+ spec.add_dependency "concurrent-ruby"
28
+
27
29
  spec.add_development_dependency "activesupport", ">= 4.2"
30
+ spec.add_development_dependency "ostruct"
28
31
  spec.add_development_dependency "rspec-core", '~> 3.10'
29
32
  spec.add_development_dependency "rspec-expectations", '~> 3.10'
30
33
 
@@ -49,7 +49,7 @@ module Buildkite::TestCollector::MinitestPlugin
49
49
  end
50
50
 
51
51
  def file_name
52
- @file_name ||= File.join('./', source_location[0].sub(/\A#{project_dir}/, ""))
52
+ @file_name ||= source_location[0].sub(/\A#{project_dir}\//, "")
53
53
  end
54
54
 
55
55
  def line_number
@@ -1,14 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "concurrent-ruby"
4
+
3
5
  module Buildkite::TestCollector
4
6
  class Session
5
- UPLOAD_THREAD_TIMEOUT = 60
6
7
  UPLOAD_SESSION_TIMEOUT = 60
7
8
  UPLOAD_API_MAX_RESULTS = 5000
8
9
 
9
10
  def initialize
10
11
  @send_queue_ids = []
11
- @upload_threads = []
12
+ @upload_futures = []
12
13
  end
13
14
 
14
15
  def add_example_to_send_queue(id)
@@ -24,20 +25,20 @@ module Buildkite::TestCollector
24
25
  return if @send_queue_ids.empty?
25
26
 
26
27
  upload_data(@send_queue_ids)
28
+ @send_queue_ids.clear
27
29
  end
28
30
 
29
31
  def close
30
- # There are two thread joins here, because the inner join will wait up to
31
- # UPLOAD_THREAD_TIMEOUT seconds PER thread that is uploading data, i.e.
32
- # n_threads x UPLOAD_THREAD_TIMEOUT latency if Buildkite happens to be
33
- # down. By wrapping that in an outer thread join with the
34
- # UPLOAD_SESSION_TIMEOUT, we ensure that we only wait a max of
35
- # UPLOAD_SESSION_TIMEOUT seconds before the session exits.
36
- Thread.new do
37
- @upload_threads.each { |t| t.join(UPLOAD_THREAD_TIMEOUT) }
38
- end.join(UPLOAD_SESSION_TIMEOUT)
39
-
40
- @upload_threads.each { |t| t&.kill }
32
+ return if @upload_futures.empty?
33
+
34
+ begin
35
+ Concurrent::Promises.zip(*@upload_futures).value!(UPLOAD_SESSION_TIMEOUT)
36
+ rescue StandardError
37
+ # Timeout or other error - futures will continue running in the thread pool
38
+ # with their own per-upload timeouts, we just stop waiting for them
39
+ ensure
40
+ @upload_futures.clear
41
+ end
41
42
  end
42
43
 
43
44
  private
@@ -45,12 +46,17 @@ module Buildkite::TestCollector
45
46
  def upload_data(ids)
46
47
  data = Buildkite::TestCollector.uploader.traces.values_at(*ids).compact
47
48
 
48
- # we do this in batches of UPLOAD_API_MAX_RESULTS in case the number of
49
- # results exceeds this due to a bug, or user error in configuring the
50
- # batch size
51
- data.each_slice(UPLOAD_API_MAX_RESULTS) do |batch|
52
- new_thread = Buildkite::TestCollector::Uploader.upload(batch)
53
- @upload_threads << new_thread if new_thread
49
+ begin
50
+ # We do this in batches of UPLOAD_API_MAX_RESULTS in case the number of
51
+ # results exceeds this due to a bug, or user error in configuring the
52
+ # batch size
53
+ data.each_slice(UPLOAD_API_MAX_RESULTS) do |batch|
54
+ new_future = Buildkite::TestCollector::Uploader.upload(batch)
55
+ @upload_futures << new_future if new_future
56
+ end
57
+ ensure
58
+ # Free memory by removing uploaded traces from the in-memory cache
59
+ ids.each { |id| Buildkite::TestCollector.uploader.traces.delete(id) }
54
60
  end
55
61
  end
56
62
  end
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "concurrent-ruby"
4
+
3
5
  module Buildkite::TestCollector
4
6
  class Uploader
5
7
  MAX_UPLOAD_ATTEMPTS = 3
8
+ UPLOAD_TIMEOUT = 60
6
9
 
7
- def self.traces
8
- @traces ||= {}
9
- end
10
+ THREAD_POOL_SIZE = 10
11
+ THREAD_POOL = Concurrent::FixedThreadPool.new(THREAD_POOL_SIZE)
10
12
 
11
13
  REQUEST_EXCEPTIONS = [
12
14
  URI::InvalidURIError,
@@ -29,19 +31,23 @@ module Buildkite::TestCollector
29
31
  # TODO: some retries for server-side error would be great.
30
32
  ]
31
33
 
34
+ def self.traces
35
+ @traces ||= {}
36
+ end
37
+
32
38
  def self.tracer
33
39
  Thread.current[:_buildkite_tracer]
34
40
  end
35
41
 
36
42
  def self.upload(data)
37
- return false unless Buildkite::TestCollector.api_token
43
+ return unless Buildkite::TestCollector.api_token
38
44
 
39
45
  http = Buildkite::TestCollector::HTTPClient.new(
40
46
  url: Buildkite::TestCollector.url,
41
47
  api_token: Buildkite::TestCollector.api_token,
42
48
  )
43
49
 
44
- Thread.new do
50
+ upload_future = Concurrent::Promises.future_on(THREAD_POOL) do
45
51
  begin
46
52
  upload_attempts ||= 0
47
53
  http.post_upload(
@@ -58,6 +64,10 @@ module Buildkite::TestCollector
58
64
  $stderr.puts "#{Buildkite::TestCollector::NAME} #{Buildkite::TestCollector::VERSION} experienced an error when sending your data, you may be missing some executions for this run."
59
65
  end
60
66
  end
67
+
68
+ timeout_future = Concurrent::Promises.schedule(UPLOAD_TIMEOUT) { :timeout }
69
+
70
+ Concurrent::Promises.any(upload_future, timeout_future)
61
71
  end
62
72
  end
63
73
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Buildkite
4
4
  module TestCollector
5
- VERSION = "2.11.0"
5
+ VERSION = "2.13.0"
6
6
  NAME = "buildkite-test_collector"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: buildkite-test_collector
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.11.0
4
+ version: 2.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Buildkite
@@ -9,6 +9,20 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: concurrent-ruby
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: activesupport
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -23,6 +37,20 @@ dependencies:
23
37
  - - ">="
24
38
  - !ruby/object:Gem::Version
25
39
  version: '4.2'
40
+ - !ruby/object:Gem::Dependency
41
+ name: ostruct
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
26
54
  - !ruby/object:Gem::Dependency
27
55
  name: rspec-core
28
56
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +108,6 @@ files:
80
108
  - CODE_OF_CONDUCT.md
81
109
  - DESIGN.md
82
110
  - Gemfile
83
- - Gemfile.lock
84
111
  - LICENSE.txt
85
112
  - README.md
86
113
  - Rakefile
data/Gemfile.lock DELETED
@@ -1,96 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- buildkite-test_collector (2.11.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activesupport (8.0.1)
10
- base64
11
- benchmark (>= 0.3)
12
- bigdecimal
13
- concurrent-ruby (~> 1.0, >= 1.3.1)
14
- connection_pool (>= 2.2.5)
15
- drb
16
- i18n (>= 1.6, < 2)
17
- logger (>= 1.4.2)
18
- minitest (>= 5.1)
19
- securerandom (>= 0.3)
20
- tzinfo (~> 2.0, >= 2.0.5)
21
- uri (>= 0.13.1)
22
- base64 (0.2.0)
23
- benchmark (0.4.0)
24
- bigdecimal (3.1.9)
25
- builder (3.3.0)
26
- concurrent-ruby (1.3.5)
27
- connection_pool (2.5.0)
28
- cucumber (9.2.1)
29
- builder (~> 3.2)
30
- cucumber-ci-environment (> 9, < 11)
31
- cucumber-core (> 13, < 14)
32
- cucumber-cucumber-expressions (~> 17.0)
33
- cucumber-gherkin (> 24, < 28)
34
- cucumber-html-formatter (> 20.3, < 22)
35
- cucumber-messages (> 19, < 25)
36
- diff-lcs (~> 1.5)
37
- mini_mime (~> 1.1)
38
- multi_test (~> 1.1)
39
- sys-uname (~> 1.2)
40
- cucumber-ci-environment (10.0.1)
41
- cucumber-core (13.0.3)
42
- cucumber-gherkin (>= 27, < 28)
43
- cucumber-messages (>= 20, < 23)
44
- cucumber-tag-expressions (> 5, < 7)
45
- cucumber-cucumber-expressions (17.1.0)
46
- bigdecimal
47
- cucumber-gherkin (27.0.0)
48
- cucumber-messages (>= 19.1.4, < 23)
49
- cucumber-html-formatter (21.9.0)
50
- cucumber-messages (> 19, < 28)
51
- cucumber-messages (22.0.0)
52
- cucumber-tag-expressions (6.1.2)
53
- diff-lcs (1.6.2)
54
- drb (2.2.1)
55
- ffi (1.17.2)
56
- i18n (1.14.7)
57
- concurrent-ruby (~> 1.0)
58
- logger (1.7.0)
59
- mini_mime (1.1.5)
60
- minitest (5.25.4)
61
- multi_test (1.1.0)
62
- rake (13.2.1)
63
- rspec (3.13.0)
64
- rspec-core (~> 3.13.0)
65
- rspec-expectations (~> 3.13.0)
66
- rspec-mocks (~> 3.13.0)
67
- rspec-core (3.13.2)
68
- rspec-support (~> 3.13.0)
69
- rspec-expectations (3.13.3)
70
- diff-lcs (>= 1.2.0, < 2.0)
71
- rspec-support (~> 3.13.0)
72
- rspec-mocks (3.13.2)
73
- diff-lcs (>= 1.2.0, < 2.0)
74
- rspec-support (~> 3.13.0)
75
- rspec-support (3.13.2)
76
- securerandom (0.4.1)
77
- sys-uname (1.3.1)
78
- ffi (~> 1.1)
79
- tzinfo (2.0.6)
80
- concurrent-ruby (~> 1.0)
81
- uri (1.0.2)
82
-
83
- PLATFORMS
84
- ruby
85
-
86
- DEPENDENCIES
87
- activesupport (>= 4.2)
88
- buildkite-test_collector!
89
- cucumber (~> 9.0)
90
- rake (~> 13.0)
91
- rspec (~> 3.0)
92
- rspec-core (~> 3.10)
93
- rspec-expectations (~> 3.10)
94
-
95
- BUNDLED WITH
96
- 2.3.25