Welcome to mirror list, hosted at ThFree Co, Russian Federation.

rspec_profiling.rb « initializers « config - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 5830a3d5af2e8831b58e9b7dfc5dc254292e53dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# frozen_string_literal: true

return unless Rails.env.test?

module RspecProfilingExt
  module Collectors
    class CSVWithTimestamps < ::RspecProfiling::Collectors::CSV
      TIMESTAMP_FIELDS = %w[created_at updated_at].freeze
      METADATA_FIELDS = %w[feature_category].freeze
      HEADERS = (::RspecProfiling::Collectors::CSV::HEADERS + TIMESTAMP_FIELDS + METADATA_FIELDS).freeze

      def insert(attributes)
        output << HEADERS.map do |field|
          if TIMESTAMP_FIELDS.include?(field)
            Time.now
          else
            attributes.fetch(field.to_sym)
          end
        end
      end

      private

      def output
        @output ||= ::CSV.open(path, "w").tap { |csv| csv << HEADERS }
      end
    end
  end

  module Git
    def branch
      if ENV['CI_COMMIT_REF_NAME']
        "#{defined?(Gitlab::License) ? 'ee' : 'ce'}:#{ENV['CI_COMMIT_REF_NAME']}"
      else
        super&.chomp
      end
    end

    def sha
      super&.chomp
    end
  end

  module Example
    def feature_category
      metadata[:feature_category]
    end
  end

  module Run
    # rubocop:disable Gitlab/ModuleWithInstanceVariables -- patching class which requires setting ivars
    def example_finished(notification)
      # If available, use the spec location where (deeply nested) shared examples are used.
      file, line_number = notification
        .example
        .metadata
        .fetch(:shared_group_inclusion_backtrace)
        .reverse
        .lazy
        .map { |bt| bt.formatted_inclusion_location&.split(':') }
        .first

      unless file && line_number
        file = @current_example.file
        line_number = @current_example.line_number
      end

      collector.insert({
        branch: vcs.branch,
        commit_hash: vcs.sha,
        date: vcs.time,
        file: file,
        line_number: line_number,
        description: @current_example.description,
        status: @current_example.status,
        exception: @current_example.exception,
        time: @current_example.time,
        query_count: @current_example.query_count,
        query_time: @current_example.query_time,
        request_count: @current_example.request_count,
        request_time: @current_example.request_time,
        feature_category: @current_example.feature_category
      })
    rescue StandardError => err
      return if @already_logged_example_finished_error

      warn "rspec_profiling couldn't collect an example: #{err}. Further warnings suppressed."
      @already_logged_example_finished_error = true
    end
    # rubocop:enable Gitlab/ModuleWithInstanceVariables

    alias_method :example_passed, :example_finished
    alias_method :example_failed, :example_finished
  end
end

RspecProfiling.configure do |config|
  if ENV.key?('CI') || ENV.key?('RSPEC_PROFILING')
    RspecProfiling::VCS::Git.prepend(RspecProfilingExt::Git)
    RspecProfiling::Run.prepend(RspecProfilingExt::Run)
    RspecProfiling::Example.prepend(RspecProfilingExt::Example)
    config.collector = RspecProfilingExt::Collectors::CSVWithTimestamps
    config.csv_path = -> do
      prefix = "#{ENV['CI_JOB_NAME']}-".gsub(%r{[ /]}, '-') if ENV['CI_JOB_NAME']
      "#{ENV['RSPEC_PROFILING_FOLDER_PATH']}/#{prefix}#{Time.now.to_i}-#{SecureRandom.hex(8)}-rspec-data.csv"
    end
  end
end