rspecq 0.4.0 → 0.5.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 +4 -4
- data/CHANGELOG.md +10 -2
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/bin/rspecq +16 -4
- data/lib/rspecq/formatters/failure_recorder.rb +11 -3
- data/lib/rspecq/formatters/job_timing_recorder.rb +3 -0
- data/lib/rspecq/formatters/worker_heartbeat_recorder.rb +0 -1
- data/lib/rspecq/queue.rb +5 -4
- data/lib/rspecq/reporter.rb +8 -7
- data/lib/rspecq/version.rb +1 -1
- data/lib/rspecq/worker.rb +20 -13
- metadata +20 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2abc0b960b2d28528c0d8a4f9fff7dc0708fd582c7377af021b6c01777350124
         | 
| 4 | 
            +
              data.tar.gz: 23d432f09a68ace0932d3c82a112fd0e7058357fa4029c94401a75b84240d5b7
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9c499c1ded556a66e9547e71ebfc3f4cdefd6ec984269986b7ae2e1078a86e157ed9805d57afd615f7e9044869124b8f2359095c65febf2d39b3065191e450b7
         | 
| 7 | 
            +
              data.tar.gz: 050a8b4eb4983234cbd2d42a24590c9d0914833231c16692f273020c297757c8afca453f09f9ff72a6ec10564809c81356f3ab23c9220644fbcba89f7f0a90a3
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,8 +1,16 @@ | |
| 1 1 | 
             
            # Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            ## master (unreleased)
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            Breaking changes are prefixed with a "[BREAKING]" label.
         | 
| 4 6 |  | 
| 5 | 
            -
            ##  | 
| 7 | 
            +
            ## 0.5.0 (2021-02-05)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            ### Added
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            - New cli parameter `queue_wait_timeout`.
         | 
| 12 | 
            +
              It configured the time a queue can wait to be ready. The env equivalent
         | 
| 13 | 
            +
              is `RSPECQ_QUEUE_WAIT_TIMEOUT`. [#51](https://github.com/skroutz/rspecq/pull/51)
         | 
| 6 14 |  | 
| 7 15 | 
             
            ## 0.4.0 (2020-10-07)
         | 
| 8 16 |  | 
| @@ -27,7 +35,7 @@ Breaking changes are prefixed with a "[BREAKING]" label. | |
| 27 35 | 
             
            ## 0.2.2 (2020-09-10)
         | 
| 28 36 |  | 
| 29 37 | 
             
            ### Fixed
         | 
| 30 | 
            -
            - Worker would fail if application code was writing to stderr | 
| 38 | 
            +
            - Worker would fail if application code was writing to stderr
         | 
| 31 39 | 
             
             [[#35](https://github.com/skroutz/rspecq/pull/35)]
         | 
| 32 40 |  | 
| 33 41 | 
             
            ## 0.2.1 (2020-09-09)
         | 
    
        data/README.md
    CHANGED
    
    | @@ -26,7 +26,6 @@ and [ci-queue](https://github.com/Shopify/ci-queue). | |
| 26 26 | 
             
            - Handles intermittent worker failures (e.g. network hiccups, faulty hardware etc.)
         | 
| 27 27 | 
             
              by detecting non-responsive workers and requeing their jobs. See [*Worker failures*](#worker-failures)
         | 
| 28 28 | 
             
            - Sentry integration for monitoring build-level events. See [*Sentry integration*](#sentry-integration).
         | 
| 29 | 
            -
            - [PLANNED] StatsD integration for various build-level metrics and insights.
         | 
| 30 29 | 
             
              See [#2](https://github.com/skroutz/rspecq/issues/2).
         | 
| 31 30 | 
             
            - Automatic termination of builds after a certain amount of failures. See [*Fail-fast*](#fail-fast).
         | 
| 32 31 |  | 
| @@ -74,6 +73,7 @@ OPTIONS: | |
| 74 73 | 
             
                                                 Exits with a non-zero status code if there were any failures.
         | 
| 75 74 | 
             
                    --report-timeout N           Fail if build is not finished after N seconds. Only applicable if --report is enabled (default: 3600).
         | 
| 76 75 | 
             
                    --max-requeues N             Retry failed examples up to N times before considering them legit failures (default: 3).
         | 
| 76 | 
            +
                    --queue-wait-timeout N       Time to wait for a queue to be ready before considering it failed (default: 30).
         | 
| 77 77 | 
             
                    --fail-fast N                Abort build with a non-zero status code after N failed examples.
         | 
| 78 78 | 
             
                -h, --help                       Show this message.
         | 
| 79 79 | 
             
                -v, --version                    Print the version and exit.
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/bin/rspecq
    CHANGED
    
    | @@ -2,9 +2,10 @@ | |
| 2 2 | 
             
            require "optparse"
         | 
| 3 3 | 
             
            require "rspecq"
         | 
| 4 4 |  | 
| 5 | 
            -
            DEFAULT_REDIS_HOST = "127.0.0.1"
         | 
| 5 | 
            +
            DEFAULT_REDIS_HOST = "127.0.0.1".freeze
         | 
| 6 6 | 
             
            DEFAULT_REPORT_TIMEOUT = 3600 # 1 hour
         | 
| 7 7 | 
             
            DEFAULT_MAX_REQUEUES = 3
         | 
| 8 | 
            +
            DEFAULT_QUEUE_WAIT_TIMEOUT = 30
         | 
| 8 9 | 
             
            DEFAULT_FAIL_FAST = 0
         | 
| 9 10 |  | 
| 10 11 | 
             
            def env_set?(var)
         | 
| @@ -66,7 +67,7 @@ OptionParser.new do |o| | |
| 66 67 |  | 
| 67 68 | 
             
              o.on("--report", "Enable reporter mode: do not pull tests off the queue; " \
         | 
| 68 69 | 
             
                               "instead print build progress and exit when it's "        \
         | 
| 69 | 
            -
                               "finished.\n#{o.summary_indent*9} "                       \
         | 
| 70 | 
            +
                               "finished.\n#{o.summary_indent * 9} "                       \
         | 
| 70 71 | 
             
                               "Exits with a non-zero status code if there were any "    \
         | 
| 71 72 | 
             
                               "failures.") do |v|
         | 
| 72 73 | 
             
                opts[:report] = v
         | 
| @@ -84,8 +85,14 @@ OptionParser.new do |o| | |
| 84 85 | 
             
                opts[:max_requeues] = v
         | 
| 85 86 | 
             
              end
         | 
| 86 87 |  | 
| 88 | 
            +
              o.on("--queue-wait-timeout N", Integer, "Time to wait for a queue to be "   \
         | 
| 89 | 
            +
                   "ready before considering it failed "                                  \
         | 
| 90 | 
            +
                   "(default: #{DEFAULT_QUEUE_WAIT_TIMEOUT}).") do |v|
         | 
| 91 | 
            +
                opts[:queue_wait_timeout] = v
         | 
| 92 | 
            +
              end
         | 
| 93 | 
            +
             | 
| 87 94 | 
             
              o.on("--fail-fast N", Integer, "Abort build with a non-zero status code " \
         | 
| 88 | 
            -
                   "after N failed examples." | 
| 95 | 
            +
                   "after N failed examples.") do |v|
         | 
| 89 96 | 
             
                opts[:fail_fast] = v
         | 
| 90 97 | 
             
              end
         | 
| 91 98 |  | 
| @@ -104,15 +111,18 @@ opts[:build] ||= ENV["RSPECQ_BUILD"] | |
| 104 111 | 
             
            opts[:worker] ||= ENV["RSPECQ_WORKER"]
         | 
| 105 112 | 
             
            opts[:redis_host] ||= ENV["RSPECQ_REDIS"] || DEFAULT_REDIS_HOST
         | 
| 106 113 | 
             
            opts[:timings] ||= env_set?("RSPECQ_UPDATE_TIMINGS")
         | 
| 107 | 
            -
            opts[:file_split_threshold] ||= Integer(ENV["RSPECQ_FILE_SPLIT_THRESHOLD"] ||  | 
| 114 | 
            +
            opts[:file_split_threshold] ||= Integer(ENV["RSPECQ_FILE_SPLIT_THRESHOLD"] || 9_999_999)
         | 
| 108 115 | 
             
            opts[:report] ||= env_set?("RSPECQ_REPORT")
         | 
| 109 116 | 
             
            opts[:report_timeout] ||= Integer(ENV["RSPECQ_REPORT_TIMEOUT"] || DEFAULT_REPORT_TIMEOUT)
         | 
| 110 117 | 
             
            opts[:max_requeues] ||= Integer(ENV["RSPECQ_MAX_REQUEUES"] || DEFAULT_MAX_REQUEUES)
         | 
| 118 | 
            +
            opts[:queue_wait_timeout] ||= Integer(ENV["RSPECQ_QUEUE_WAIT_TIMEOUT"] || DEFAULT_QUEUE_WAIT_TIMEOUT)
         | 
| 111 119 | 
             
            opts[:redis_url] ||= ENV["RSPECQ_REDIS_URL"]
         | 
| 112 120 | 
             
            opts[:fail_fast] ||= Integer(ENV["RSPECQ_FAIL_FAST"] || DEFAULT_FAIL_FAST)
         | 
| 113 121 |  | 
| 122 | 
            +
            # rubocop:disable Style/RaiseArgs, Layout/EmptyLineAfterGuardClause
         | 
| 114 123 | 
             
            raise OptionParser::MissingArgument.new(:build) if opts[:build].nil?
         | 
| 115 124 | 
             
            raise OptionParser::MissingArgument.new(:worker) if !opts[:report] && opts[:worker].nil?
         | 
| 125 | 
            +
            # rubocop:enable Style/RaiseArgs, Layout/EmptyLineAfterGuardClause
         | 
| 116 126 |  | 
| 117 127 | 
             
            redis_opts = {}
         | 
| 118 128 |  | 
| @@ -127,6 +137,7 @@ if opts[:report] | |
| 127 137 | 
             
                build_id: opts[:build],
         | 
| 128 138 | 
             
                timeout: opts[:report_timeout],
         | 
| 129 139 | 
             
                redis_opts: redis_opts,
         | 
| 140 | 
            +
                queue_wait_timeout: opts[:queue_wait_timeout]
         | 
| 130 141 | 
             
              )
         | 
| 131 142 |  | 
| 132 143 | 
             
              reporter.report
         | 
| @@ -141,6 +152,7 @@ else | |
| 141 152 | 
             
              worker.populate_timings = opts[:timings]
         | 
| 142 153 | 
             
              worker.file_split_threshold = opts[:file_split_threshold]
         | 
| 143 154 | 
             
              worker.max_requeues = opts[:max_requeues]
         | 
| 155 | 
            +
              worker.queue_wait_timeout = opts[:queue_wait_timeout]
         | 
| 144 156 | 
             
              worker.fail_fast = opts[:fail_fast]
         | 
| 145 157 | 
             
              worker.work
         | 
| 146 158 | 
             
            end
         | 
| @@ -1,5 +1,10 @@ | |
| 1 1 | 
             
            module RSpecQ
         | 
| 2 2 | 
             
              module Formatters
         | 
| 3 | 
            +
                # Persists failed examples information (i.e. message and backtrace), so
         | 
| 4 | 
            +
                # that they can be reported to the end user by the Reporter.
         | 
| 5 | 
            +
                #
         | 
| 6 | 
            +
                # Also persists non-example error information (e.g. a syntax error that
         | 
| 7 | 
            +
                # in a spec file).
         | 
| 3 8 | 
             
                class FailureRecorder
         | 
| 4 9 | 
             
                  def initialize(queue, job, max_requeues)
         | 
| 5 10 | 
             
                    @queue = queue
         | 
| @@ -33,16 +38,19 @@ module RSpecQ | |
| 33 38 | 
             
                    end
         | 
| 34 39 |  | 
| 35 40 | 
             
                    presenter = RSpec::Core::Formatters::ExceptionPresenter.new(
         | 
| 36 | 
            -
                      example.exception, example | 
| 41 | 
            +
                      example.exception, example
         | 
| 42 | 
            +
                    )
         | 
| 37 43 |  | 
| 38 44 | 
             
                    msg = presenter.fully_formatted(nil, @colorizer)
         | 
| 39 45 | 
             
                    msg << "\n"
         | 
| 40 46 | 
             
                    msg << @colorizer.wrap(
         | 
| 41 47 | 
             
                      "bin/rspec #{example.location_rerun_argument}",
         | 
| 42 | 
            -
                      RSpec.configuration.failure_color | 
| 48 | 
            +
                      RSpec.configuration.failure_color
         | 
| 49 | 
            +
                    )
         | 
| 43 50 |  | 
| 44 51 | 
             
                    msg << @colorizer.wrap(
         | 
| 45 | 
            -
                      " # #{example.full_description}", RSpec.configuration.detail_color | 
| 52 | 
            +
                      " # #{example.full_description}", RSpec.configuration.detail_color
         | 
| 53 | 
            +
                    )
         | 
| 46 54 |  | 
| 47 55 | 
             
                    @queue.record_example_failure(notification.example.id, msg)
         | 
| 48 56 | 
             
                  end
         | 
| @@ -1,5 +1,8 @@ | |
| 1 1 | 
             
            module RSpecQ
         | 
| 2 2 | 
             
              module Formatters
         | 
| 3 | 
            +
                # Persists each job's timing (in seconds). Those timings are used when
         | 
| 4 | 
            +
                # determining the ordering in which jobs are scheduled (slower jobs will
         | 
| 5 | 
            +
                # be enqueued first).
         | 
| 3 6 | 
             
                class JobTimingRecorder
         | 
| 4 7 | 
             
                  def initialize(queue, job)
         | 
| 5 8 | 
             
                    @queue = queue
         | 
    
        data/lib/rspecq/queue.rb
    CHANGED
    
    | @@ -79,7 +79,7 @@ module RSpecQ | |
| 79 79 | 
             
                # NOTE: jobs will be processed from head to tail (lpop)
         | 
| 80 80 | 
             
                def publish(jobs, fail_fast = 0)
         | 
| 81 81 | 
             
                  @redis.multi do
         | 
| 82 | 
            -
                    @redis.hset(key_queue_config,  | 
| 82 | 
            +
                    @redis.hset(key_queue_config, "fail_fast", fail_fast)
         | 
| 83 83 | 
             
                    @redis.rpush(key_queue_unprocessed, jobs)
         | 
| 84 84 | 
             
                    @redis.set(key_queue_status, STATUS_READY)
         | 
| 85 85 | 
             
                  end.first
         | 
| @@ -131,7 +131,7 @@ module RSpecQ | |
| 131 131 | 
             
                  @redis.eval(
         | 
| 132 132 | 
             
                    REQUEUE_JOB,
         | 
| 133 133 | 
             
                    keys: [key_queue_unprocessed, key_requeues],
         | 
| 134 | 
            -
                    argv: [job, max_requeues] | 
| 134 | 
            +
                    argv: [job, max_requeues]
         | 
| 135 135 | 
             
                  )
         | 
| 136 136 | 
             
                end
         | 
| 137 137 |  | 
| @@ -210,9 +210,10 @@ module RSpecQ | |
| 210 210 | 
             
                  @redis.get(key_queue_status) == STATUS_READY
         | 
| 211 211 | 
             
                end
         | 
| 212 212 |  | 
| 213 | 
            -
                def wait_until_published(timeout=30)
         | 
| 213 | 
            +
                def wait_until_published(timeout = 30)
         | 
| 214 214 | 
             
                  (timeout * 10).times do
         | 
| 215 215 | 
             
                    return if published?
         | 
| 216 | 
            +
             | 
| 216 217 | 
             
                    sleep 0.1
         | 
| 217 218 | 
             
                  end
         | 
| 218 219 |  | 
| @@ -250,7 +251,7 @@ module RSpecQ | |
| 250 251 | 
             
                def fail_fast
         | 
| 251 252 | 
             
                  return nil unless published?
         | 
| 252 253 |  | 
| 253 | 
            -
                  @fail_fast ||= Integer(@redis.hget(key_queue_config,  | 
| 254 | 
            +
                  @fail_fast ||= Integer(@redis.hget(key_queue_config, "fail_fast"))
         | 
| 254 255 | 
             
                end
         | 
| 255 256 |  | 
| 256 257 | 
             
                # Returns true if the number of failed tests, has surpassed the threshold
         | 
    
        data/lib/rspecq/reporter.rb
    CHANGED
    
    | @@ -9,18 +9,19 @@ module RSpecQ | |
| 9 9 | 
             
              #
         | 
| 10 10 | 
             
              # Reporters are readers of the queue.
         | 
| 11 11 | 
             
              class Reporter
         | 
| 12 | 
            -
                def initialize(build_id:, timeout:, redis_opts:)
         | 
| 12 | 
            +
                def initialize(build_id:, timeout:, redis_opts:, queue_wait_timeout: 30)
         | 
| 13 13 | 
             
                  @build_id = build_id
         | 
| 14 14 | 
             
                  @timeout = timeout
         | 
| 15 15 | 
             
                  @queue = Queue.new(build_id, "reporter", redis_opts)
         | 
| 16 | 
            +
                  @queue_wait_timeout = queue_wait_timeout
         | 
| 16 17 |  | 
| 17 18 | 
             
                  # We want feedback to be immediattely printed to CI users, so
         | 
| 18 19 | 
             
                  # we disable buffering.
         | 
| 19 | 
            -
                   | 
| 20 | 
            +
                  $stdout.sync = true
         | 
| 20 21 | 
             
                end
         | 
| 21 22 |  | 
| 22 23 | 
             
                def report
         | 
| 23 | 
            -
                  @queue.wait_until_published
         | 
| 24 | 
            +
                  @queue.wait_until_published(@queue_wait_timeout)
         | 
| 24 25 |  | 
| 25 26 | 
             
                  finished = false
         | 
| 26 27 |  | 
| @@ -28,7 +29,7 @@ module RSpecQ | |
| 28 29 | 
             
                  failure_heading_printed = false
         | 
| 29 30 |  | 
| 30 31 | 
             
                  tests_duration = measure_duration do
         | 
| 31 | 
            -
                    @timeout.times do | 
| 32 | 
            +
                    @timeout.times do
         | 
| 32 33 | 
             
                      @queue.example_failures.each do |job, rspec_output|
         | 
| 33 34 | 
             
                        next if reported_failures[job]
         | 
| 34 35 |  | 
| @@ -124,13 +125,13 @@ module RSpecQ | |
| 124 125 | 
             
                  return if jobs.empty?
         | 
| 125 126 |  | 
| 126 127 | 
             
                  jobs.each do |job|
         | 
| 127 | 
            -
                    filename = job.sub(/\[.+\]/,  | 
| 128 | 
            +
                    filename = job.sub(/\[.+\]/, "")
         | 
| 128 129 |  | 
| 129 130 | 
             
                    extra = {
         | 
| 130 131 | 
             
                      build: @build_id,
         | 
| 131 132 | 
             
                      build_timeout: @timeout,
         | 
| 132 133 | 
             
                      queue: @queue.inspect,
         | 
| 133 | 
            -
                      object:  | 
| 134 | 
            +
                      object: inspect,
         | 
| 134 135 | 
             
                      pid: Process.pid,
         | 
| 135 136 | 
             
                      job_path: job,
         | 
| 136 137 | 
             
                      build_duration: build_duration
         | 
| @@ -143,7 +144,7 @@ module RSpecQ | |
| 143 144 |  | 
| 144 145 | 
             
                    Raven.capture_message(
         | 
| 145 146 | 
             
                      "Flaky test in #{filename}",
         | 
| 146 | 
            -
                      level:  | 
| 147 | 
            +
                      level: "warning",
         | 
| 147 148 | 
             
                      extra: extra,
         | 
| 148 149 | 
             
                      tags: tags
         | 
| 149 150 | 
             
                    )
         | 
    
        data/lib/rspecq/version.rb
    CHANGED
    
    
    
        data/lib/rspecq/worker.rb
    CHANGED
    
    | @@ -46,6 +46,11 @@ module RSpecQ | |
| 46 46 | 
             
                # Defaults to 0
         | 
| 47 47 | 
             
                attr_accessor :fail_fast
         | 
| 48 48 |  | 
| 49 | 
            +
                # Time to wait for a queue to be published.
         | 
| 50 | 
            +
                #
         | 
| 51 | 
            +
                # Defaults to 30
         | 
| 52 | 
            +
                attr_accessor :queue_wait_timeout
         | 
| 53 | 
            +
             | 
| 49 54 | 
             
                attr_reader :queue
         | 
| 50 55 |  | 
| 51 56 | 
             
                def initialize(build_id:, worker_id:, redis_opts:)
         | 
| @@ -55,9 +60,10 @@ module RSpecQ | |
| 55 60 | 
             
                  @fail_fast = 0
         | 
| 56 61 | 
             
                  @files_or_dirs_to_run = "spec"
         | 
| 57 62 | 
             
                  @populate_timings = false
         | 
| 58 | 
            -
                  @file_split_threshold =  | 
| 63 | 
            +
                  @file_split_threshold = 999_999
         | 
| 59 64 | 
             
                  @heartbeat_updated_at = nil
         | 
| 60 65 | 
             
                  @max_requeues = 3
         | 
| 66 | 
            +
                  @queue_wait_timeout = 30
         | 
| 61 67 |  | 
| 62 68 | 
             
                  RSpec::Core::Formatters.register(Formatters::JobTimingRecorder, :dump_summary)
         | 
| 63 69 | 
             
                  RSpec::Core::Formatters.register(Formatters::ExampleCountRecorder, :dump_summary)
         | 
| @@ -69,7 +75,7 @@ module RSpecQ | |
| 69 75 | 
             
                  puts "Working for build #{@build_id} (worker=#{@worker_id})"
         | 
| 70 76 |  | 
| 71 77 | 
             
                  try_publish_queue!(queue)
         | 
| 72 | 
            -
                  queue.wait_until_published
         | 
| 78 | 
            +
                  queue.wait_until_published(queue_wait_timeout)
         | 
| 73 79 |  | 
| 74 80 | 
             
                  loop do
         | 
| 75 81 | 
             
                    # we have to bootstrap this so that it can be used in the first call
         | 
| @@ -98,7 +104,7 @@ module RSpecQ | |
| 98 104 | 
             
                    # reconfigure rspec
         | 
| 99 105 | 
             
                    RSpec.configuration.detail_color = :magenta
         | 
| 100 106 | 
             
                    RSpec.configuration.seed = srand && srand % 0xFFFF
         | 
| 101 | 
            -
                    RSpec.configuration.backtrace_formatter.filter_gem( | 
| 107 | 
            +
                    RSpec.configuration.backtrace_formatter.filter_gem("rspecq")
         | 
| 102 108 | 
             
                    RSpec.configuration.add_formatter(Formatters::FailureRecorder.new(queue, job, max_requeues))
         | 
| 103 109 | 
             
                    RSpec.configuration.add_formatter(Formatters::ExampleCountRecorder.new(queue))
         | 
| 104 110 | 
             
                    RSpec.configuration.add_formatter(Formatters::WorkerHeartbeatRecorder.new(self))
         | 
| @@ -155,7 +161,7 @@ module RSpecQ | |
| 155 161 | 
             
                    jobs.concat(files_to_run)
         | 
| 156 162 | 
             
                  end
         | 
| 157 163 |  | 
| 158 | 
            -
                  default_timing = timings.values[timings.values.size/2]
         | 
| 164 | 
            +
                  default_timing = timings.values[timings.values.size / 2]
         | 
| 159 165 |  | 
| 160 166 | 
             
                  # assign timings (based on previous runs) to all jobs
         | 
| 161 167 | 
             
                  jobs = jobs.each_with_object({}) do |j, h|
         | 
| @@ -180,7 +186,8 @@ module RSpecQ | |
| 180 186 | 
             
                  # see https://github.com/rspec/rspec-core/pull/2723
         | 
| 181 187 | 
             
                  if Gem::Version.new(RSpec::Core::Version::STRING) <= Gem::Version.new("3.9.1")
         | 
| 182 188 | 
             
                    RSpec.world.instance_variable_set(
         | 
| 183 | 
            -
                      :@example_group_counts_by_spec_file, Hash.new(0) | 
| 189 | 
            +
                      :@example_group_counts_by_spec_file, Hash.new(0)
         | 
| 190 | 
            +
                    )
         | 
| 184 191 | 
             
                  end
         | 
| 185 192 |  | 
| 186 193 | 
             
                  # RSpec.clear_examples does not reset those, which causes issues when
         | 
| @@ -204,17 +211,17 @@ module RSpecQ | |
| 204 211 |  | 
| 205 212 | 
             
                  if !cmd_result.success?
         | 
| 206 213 | 
             
                    rspec_output = begin
         | 
| 207 | 
            -
             | 
| 208 | 
            -
             | 
| 209 | 
            -
             | 
| 210 | 
            -
             | 
| 214 | 
            +
                      JSON.parse(out)
         | 
| 215 | 
            +
                    rescue JSON::ParserError
         | 
| 216 | 
            +
                      out
         | 
| 217 | 
            +
                    end
         | 
| 211 218 |  | 
| 212 219 | 
             
                    log_event(
         | 
| 213 220 | 
             
                      "Failed to split slow files, falling back to regular scheduling.\n #{err}",
         | 
| 214 221 | 
             
                      "error",
         | 
| 215 222 | 
             
                      rspec_stdout: rspec_output,
         | 
| 216 223 | 
             
                      rspec_stderr: err,
         | 
| 217 | 
            -
                      cmd_result: cmd_result.inspect | 
| 224 | 
            +
                      cmd_result: cmd_result.inspect
         | 
| 218 225 | 
             
                    )
         | 
| 219 226 |  | 
| 220 227 | 
             
                    pp rspec_output
         | 
| @@ -236,7 +243,7 @@ module RSpecQ | |
| 236 243 |  | 
| 237 244 | 
             
                # Prints msg to standard output and emits an event to Sentry, if the
         | 
| 238 245 | 
             
                # SENTRY_DSN environment variable is set.
         | 
| 239 | 
            -
                def log_event(msg, level, additional={})
         | 
| 246 | 
            +
                def log_event(msg, level, additional = {})
         | 
| 240 247 | 
             
                  puts msg
         | 
| 241 248 |  | 
| 242 249 | 
             
                  Raven.capture_message(msg, level: level, extra: {
         | 
| @@ -247,8 +254,8 @@ module RSpecQ | |
| 247 254 | 
             
                    populate_timings: populate_timings,
         | 
| 248 255 | 
             
                    file_split_threshold: file_split_threshold,
         | 
| 249 256 | 
             
                    heartbeat_updated_at: @heartbeat_updated_at,
         | 
| 250 | 
            -
                    object:  | 
| 251 | 
            -
                    pid: Process.pid | 
| 257 | 
            +
                    object: inspect,
         | 
| 258 | 
            +
                    pid: Process.pid
         | 
| 252 259 | 
             
                  }.merge(additional))
         | 
| 253 260 | 
             
                end
         | 
| 254 261 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rspecq
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.5.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Agis Anastasopoulos
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-02-05 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rspec-core
         | 
| @@ -53,7 +53,7 @@ dependencies: | |
| 53 53 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 54 | 
             
                    version: '0'
         | 
| 55 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            -
              name:  | 
| 56 | 
            +
              name: minitest
         | 
| 57 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 59 | 
             
                - - ">="
         | 
| @@ -81,7 +81,7 @@ dependencies: | |
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: '0'
         | 
| 83 83 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            -
              name:  | 
| 84 | 
            +
              name: rake
         | 
| 85 85 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
                requirements:
         | 
| 87 87 | 
             
                - - ">="
         | 
| @@ -108,6 +108,20 @@ dependencies: | |
| 108 108 | 
             
                - - ">="
         | 
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 110 | 
             
                    version: '0'
         | 
| 111 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            +
              name: rubocop
         | 
| 113 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - "~>"
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: 0.93.0
         | 
| 118 | 
            +
              type: :development
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            +
                requirements:
         | 
| 122 | 
            +
                - - "~>"
         | 
| 123 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            +
                    version: 0.93.0
         | 
| 111 125 | 
             
            description: 
         | 
| 112 126 | 
             
            email: agis.anast@gmail.com
         | 
| 113 127 | 
             
            executables:
         | 
| @@ -149,7 +163,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 149 163 | 
             
                - !ruby/object:Gem::Version
         | 
| 150 164 | 
             
                  version: '0'
         | 
| 151 165 | 
             
            requirements: []
         | 
| 152 | 
            -
             | 
| 166 | 
            +
            rubyforge_project: 
         | 
| 167 | 
            +
            rubygems_version: 2.7.6.2
         | 
| 153 168 | 
             
            signing_key: 
         | 
| 154 169 | 
             
            specification_version: 4
         | 
| 155 170 | 
             
            summary: Optimally distribute and run RSpec suites among parallel workers; for faster
         |