ci-queue 0.12.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
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