ci-queue 0.12.0 → 0.12.1

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: 78b51045e571e242b8d4b64e49f37abd462be948f007de6a63380ca0f448ce4c
4
- data.tar.gz: bdec2201394129e091516b82e5709a016209aec6a8f41488132ac8400c88150d
3
+ metadata.gz: 9f86ba12b294a5698c6b1fa568d5482f549758e54ea85db004507a498a7477f1
4
+ data.tar.gz: bc54f7c6890c5c1d172a634cafa961a8a5bb76980eed482a7fb0ef8fe1dcaad8
5
5
  SHA512:
6
- metadata.gz: e51188516bdd8b04c29981a4cd7f89ac2f6a8a7979c72210065362d34b86565522e3e26305a2c088656d543c064c802c4886f6ad4801f675b7c73cbec82da38c
7
- data.tar.gz: 14853c01858461192992d2dd330a96dcb66ca6a9c17100c4d73b4d6b364cb7b1c7e8661b14d8136a454f2d0bf0a72a8af375a07dd6eba91a2541784f6964f1fc
6
+ metadata.gz: bbc243b619402d0b4addf5cb85a9ac4bfa91668a9abd5b6d6c3ab48bc47a317271a2efa8bea88f4e3a9e733f3832ba731ba1afb0c21e8e330fda86f87218586b
7
+ data.tar.gz: d7b7f715153b663757f4ee60c3f2bd7236e3b7b9308e1577e8e95b26a4af8b7892965cfabc8ca61847c09c39eb73b5ce3463ccede6e209046f7d5e8e21bf474d
@@ -2,7 +2,8 @@
2
2
  module CI
3
3
  module Queue
4
4
  class Configuration
5
- attr_accessor :timeout, :build_id, :worker_id, :max_requeues, :requeue_tolerance, :namespace, :seed, :failing_test
5
+ attr_accessor :timeout, :build_id, :worker_id, :max_requeues
6
+ attr_accessor :requeue_tolerance, :namespace, :seed, :failing_test, :statsd_endpoint
6
7
 
7
8
  class << self
8
9
  def from_env(env)
@@ -11,6 +12,7 @@ module CI
11
12
  worker_id: env['CIRCLE_NODE_INDEX'] || env['BUILDKITE_PARALLEL_JOB'],
12
13
  seed: env['CIRCLE_SHA1'] || env['BUILDKITE_COMMIT'] || env['TRAVIS_COMMIT'],
13
14
  flaky_tests: load_flaky_tests(env['CI_QUEUE_FLAKY_TESTS']),
15
+ statsd_endpoint: env['CI_QUEUE_STATSD_ADDR'],
14
16
  )
15
17
  end
16
18
 
@@ -24,7 +26,7 @@ module CI
24
26
 
25
27
  def initialize(
26
28
  timeout: 30, build_id: nil, worker_id: nil, max_requeues: 0, requeue_tolerance: 0,
27
- namespace: nil, seed: nil, flaky_tests: []
29
+ namespace: nil, seed: nil, flaky_tests: [], statsd_endpoint: nil
28
30
  )
29
31
  @namespace = namespace
30
32
  @timeout = timeout
@@ -34,6 +36,7 @@ module CI
34
36
  @requeue_tolerance = requeue_tolerance
35
37
  @seed = seed
36
38
  @flaky_tests = flaky_tests
39
+ @statsd_endpoint = statsd_endpoint
37
40
  end
38
41
 
39
42
  def flaky?(test)
@@ -1,6 +1,6 @@
1
1
  module CI
2
2
  module Queue
3
- VERSION = '0.12.0'
3
+ VERSION = '0.12.1'
4
4
  DEV_SCRIPTS_ROOT = ::File.expand_path('../../../../../redis', __FILE__)
5
5
  RELEASE_SCRIPTS_ROOT = ::File.expand_path('../redis', __FILE__)
6
6
  end
@@ -47,8 +47,7 @@ module Minitest
47
47
  self.failures += 1
48
48
  end
49
49
 
50
-
51
- stats = COUNTERS.zip(COUNTERS.map { |c| send(c) })
50
+ stats = COUNTERS.zip(COUNTERS.map { |c| send(c) }).to_h
52
51
  if (test.failure || test.error?) && !test.skipped?
53
52
  build.record_error("#{test.klass}##{test.name}", dump(test), stats: stats)
54
53
  else
@@ -24,7 +24,7 @@ module Minitest
24
24
 
25
25
  xml = Builder::XmlMarkup.new(indent: 2)
26
26
  xml.instruct!
27
- xml.test_suites do
27
+ xml.testsuites do
28
28
  suites.each do |suite, tests|
29
29
  add_tests_to(xml, suite, tests)
30
30
  end
@@ -3,6 +3,7 @@ require 'minitest/queue'
3
3
  require 'ci/queue'
4
4
  require 'digest/md5'
5
5
  require 'minitest/reporters/bisect_reporter'
6
+ require 'minitest/reporters/statsd_reporter'
6
7
 
7
8
  module Minitest
8
9
  module Queue
@@ -43,12 +44,16 @@ module Minitest
43
44
  def run_command
44
45
  set_load_path
45
46
  Minitest.queue = queue
46
- Minitest.queue_reporters = [
47
+ reporters = [
47
48
  LocalRequeueReporter.new,
48
49
  BuildStatusRecorder.new(build: queue.build),
49
50
  JUnitReporter.new,
50
51
  OrderReporter.new(path: 'log/test_order.log'),
51
52
  ]
53
+ if queue_config.statsd_endpoint
54
+ reporters << Minitest::Reporters::StatsdReporter.new(statsd_endpoint: queue_config.statsd_endpoint)
55
+ end
56
+ Minitest.queue_reporters = reporters
52
57
 
53
58
  trap('TERM') { Minitest.queue.shutdown! }
54
59
  trap('INT') { Minitest.queue.shutdown! }
@@ -0,0 +1,60 @@
1
+ # Implements a small and limited StatsD implementation to reduce importing unnecessary dependencies because
2
+ # we don't want to require on the bundle which would slow down a CI Queue run
3
+
4
+ require 'socket'
5
+
6
+ module Minitest
7
+ module Queue
8
+ class Statsd
9
+ attr_reader :addr, :namespace, :default_tags
10
+
11
+ def initialize(addr: nil, default_tags: [], namespace: nil)
12
+ @default_tags = default_tags
13
+ @namespace = namespace
14
+ @addr = addr
15
+
16
+ if addr
17
+ host, port = addr.split(':', 2)
18
+ @socket = UDPSocket.new
19
+ @socket.connect(host, Integer(port))
20
+ end
21
+ rescue SocketError => e
22
+ # No-op, we shouldn't fail CI because of statsd
23
+ end
24
+
25
+ def increment(metric, tags: [], value: 1)
26
+ send_metric(type: 'c', value: value, metric: metric, tags: default_tags + tags)
27
+ end
28
+
29
+ def measure(metric, duration = nil, tags: [], &block)
30
+ if block_given?
31
+ return_value, duration = Minitest::Queue::Statsd.measure_duration(&block)
32
+ elsif duration.nil?
33
+ raise ArgumentError, "You need to pass a block or pass a float as second argument."
34
+ end
35
+ send_metric(type: 'ms', value: duration, metric: metric, tags: default_tags + tags)
36
+ return_value
37
+ end
38
+
39
+ def self.measure_duration
40
+ before = Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond)
41
+ return_value = yield
42
+ after = Process.clock_gettime(Process::CLOCK_REALTIME, :millisecond)
43
+
44
+ [return_value, after - before]
45
+ end
46
+
47
+ private
48
+
49
+ def send_metric(type:, metric:, value:, tags:)
50
+ return unless @socket
51
+ metric_snippet = namespace.nil? ? metric : "#{namespace}.#{metric}"
52
+ tags_snippet = tags.empty? ? '' : "|##{tags.join(',')}"
53
+ payload = "#{metric_snippet}:#{value}|#{type}#{tags_snippet}"
54
+ @socket.send(payload, 0)
55
+ rescue SystemCallError
56
+ # No-op, we shouldn't fail or spam output due to statsd issues
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,45 @@
1
+ require 'minitest/queue'
2
+ require 'minitest/queue/statsd'
3
+ require 'minitest/reporters'
4
+
5
+ module Minitest
6
+ module Reporters
7
+ class StatsdReporter < Minitest::Reporters::BaseReporter
8
+ FAILING_INFRASTRUCTURE_THRESHOLD = 10
9
+
10
+ attr_reader :statsd
11
+
12
+ def initialize(statsd: Minitest::Queue::Statsd, statsd_endpoint: nil, **options)
13
+ super(options)
14
+ @statsd = statsd.new(
15
+ addr: statsd_endpoint,
16
+ namespace: 'minitests.tests',
17
+ default_tags: ["slug:#{ENV['BUILDKITE_PROJECT_SLUG']}"]
18
+ )
19
+ @failures = 0
20
+ end
21
+
22
+ def record(result)
23
+ if result.passed?
24
+ @statsd.increment("passed")
25
+ elsif result.skipped? && !result.requeued?
26
+ @statsd.increment("skipped")
27
+ else
28
+ @statsd.increment('requeued') if result.requeued?
29
+
30
+ if result.failure.is_a?(Minitest::UnexpectedError)
31
+ @statsd.increment("unexpected_errors")
32
+ else
33
+ @statsd.increment("failed")
34
+ end
35
+
36
+ @failures += 1
37
+ end
38
+ end
39
+
40
+ def report
41
+ @statsd.increment("failing_infrastructure_threshold") if @failures >= FAILING_INFRASTRUCTURE_THRESHOLD
42
+ end
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ci-queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-29 00:00:00.000000000 Z
11
+ date: 2018-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ansi
@@ -198,7 +198,9 @@ files:
198
198
  - lib/minitest/queue/local_requeue_reporter.rb
199
199
  - lib/minitest/queue/order_reporter.rb
200
200
  - lib/minitest/queue/runner.rb
201
+ - lib/minitest/queue/statsd.rb
201
202
  - lib/minitest/reporters/bisect_reporter.rb
203
+ - lib/minitest/reporters/statsd_reporter.rb
202
204
  - lib/rspec/queue.rb
203
205
  - lib/rspec/queue/build_status_recorder.rb
204
206
  - railgun.yml