Commit 6ee8e88f authored by Luis Mejia's avatar Luis Mejia Committed by Alper Akgun

Add instrumentation class to by-stage-secure metrics

Rename ci_builds class
Move user_sast_jobs metris to ee
Move user_secret_detection_jobs to ee

Changelog: changed
EE: true
parent f9e06ba8
...@@ -9,6 +9,9 @@ product_category: dependency_scanning ...@@ -9,6 +9,9 @@ product_category: dependency_scanning
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: dependency_scanning
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: license_compliance ...@@ -9,6 +9,9 @@ product_category: license_compliance
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: license_management
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,7 +9,7 @@ product_category: container_scanning ...@@ -9,7 +9,7 @@ product_category: container_scanning
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CiBuildDistinctCountMetric instrumentation_class: CountUsersCreatingCiBuildsMetric
options: options:
secure_type: container_scanning secure_type: container_scanning
data_source: database data_source: database
......
...@@ -9,6 +9,9 @@ product_category: dynamic_application_security_testing ...@@ -9,6 +9,9 @@ product_category: dynamic_application_security_testing
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: dast
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: apifuzzer_fuzz
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: apifuzzer_fuzz_dnd
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,9 +9,11 @@ product_category: static_application_security_testing ...@@ -9,9 +9,11 @@ product_category: static_application_security_testing
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: sast
data_source: database data_source: database
distribution: distribution:
- ce
- ee - ee
tier: tier:
- free - free
......
...@@ -9,9 +9,11 @@ product_category: secret_detection ...@@ -9,9 +9,11 @@ product_category: secret_detection
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: secret_detection
data_source: database data_source: database
distribution: distribution:
- ce
- ee - ee
tier: tier:
- free - free
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: 28d time_frame: 28d
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: coverage_fuzzing
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: dependency_scanning ...@@ -9,6 +9,9 @@ product_category: dependency_scanning
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountCiBuildsMetric
options:
secure_type: dependency_scanning
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: dependency_scanning ...@@ -9,6 +9,9 @@ product_category: dependency_scanning
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: dependency_scanning
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: license_compliance ...@@ -9,6 +9,9 @@ product_category: license_compliance
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: license_management
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,7 +9,7 @@ product_category: container_scanning ...@@ -9,7 +9,7 @@ product_category: container_scanning
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CiBuildDistinctCountMetric instrumentation_class: CountUsersCreatingCiBuildsMetric
options: options:
secure_type: container_scanning secure_type: container_scanning
data_source: database data_source: database
......
...@@ -8,6 +8,9 @@ product_category: dynamic_application_security_testing ...@@ -8,6 +8,9 @@ product_category: dynamic_application_security_testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountCiBuildsMetric
options:
secure_type: dast
data_source: database data_source: database
data_category: operational data_category: operational
distribution: distribution:
......
...@@ -8,6 +8,9 @@ product_category: dynamic_application_security_testing ...@@ -8,6 +8,9 @@ product_category: dynamic_application_security_testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: dast
data_source: database data_source: database
data_category: operational data_category: operational
distribution: distribution:
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountCiBuildsMetric
options:
secure_type: apifuzzer_fuzz
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountCiBuildsMetric
options:
secure_type: apifuzzer_fuzz_dnd
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: apifuzzer_fuzz
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: apifuzzer_fuzz_dnd
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: static_application_security_testing ...@@ -9,6 +9,9 @@ product_category: static_application_security_testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountCiBuildsMetric
options:
secure_type: sast
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: secret_detection ...@@ -9,6 +9,9 @@ product_category: secret_detection
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountCiBuildsMetric
options:
secure_type: secret_detection
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,9 +9,11 @@ product_category: static_application_security_testing ...@@ -9,9 +9,11 @@ product_category: static_application_security_testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: sast
data_source: database data_source: database
distribution: distribution:
- ce
- ee - ee
tier: tier:
- free - free
......
...@@ -9,9 +9,11 @@ product_category: secret_detection ...@@ -9,9 +9,11 @@ product_category: secret_detection
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: secret_detection
data_source: database data_source: database
distribution: distribution:
- ce
- ee - ee
tier: tier:
- free - free
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountCiBuildsMetric
options:
secure_type: coverage_fuzzing
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -9,6 +9,9 @@ product_category: fuzz-testing ...@@ -9,6 +9,9 @@ product_category: fuzz-testing
value_type: number value_type: number
status: active status: active
time_frame: all time_frame: all
instrumentation_class: CountUsersCreatingCiBuildsMetric
options:
secure_type: coverage_fuzzing
data_source: database data_source: database
distribution: distribution:
- ee - ee
......
...@@ -19,8 +19,7 @@ module EE ...@@ -19,8 +19,7 @@ module EE
SECURE_PRODUCT_TYPES = { SECURE_PRODUCT_TYPES = {
container_scanning: { container_scanning: {
name: :container_scanning_jobs, name: :container_scanning_jobs
instrumentation_class_migrated: true
}, },
dast: { dast: {
name: :dast_jobs name: :dast_jobs
...@@ -154,7 +153,7 @@ module EE ...@@ -154,7 +153,7 @@ module EE
results = SECURE_PRODUCT_TYPES.each_with_object({}) do |(secure_type, attribs), response| results = SECURE_PRODUCT_TYPES.each_with_object({}) do |(secure_type, attribs), response|
next if secure_type.in?([:license_management, :license_scanning]) next if secure_type.in?([:license_management, :license_scanning])
response[attribs[:name]] = count(::Ci::Build.where(name: secure_type)) # rubocop:disable CodeReuse/ActiveRecord response[attribs[:name]] = add_metric('CountCiBuildsMetric', options: { secure_type: secure_type })
end end
results[:license_management_jobs] = add_metric("LicenseManagementJobsMetric") results[:license_management_jobs] = add_metric("LicenseManagementJobsMetric")
...@@ -383,15 +382,7 @@ module EE ...@@ -383,15 +382,7 @@ module EE
time_frame = metric_time_period(time_period) time_frame = metric_time_period(time_period)
SECURE_PRODUCT_TYPES.each do |secure_type, attribs| SECURE_PRODUCT_TYPES.each do |secure_type, attribs|
results["#{prefix}#{attribs[:name]}".to_sym] = results["#{prefix}#{attribs[:name]}".to_sym] = add_metric('CountUsersCreatingCiBuildsMetric', time_frame: time_frame, options: { secure_type: secure_type })
if attribs[:instrumentation_class_migrated]
add_metric('CiBuildDistinctCountMetric', time_frame: time_frame, options: { secure_type: secure_type })
else
distinct_count(::Ci::Build.where(name: secure_type).where(time_period),
:user_id,
start: minimum_id(::User),
finish: maximum_id(::User))
end
end end
results.merge!(count_secure_pipelines(time_period)) results.merge!(count_secure_pipelines(time_period))
......
# frozen_string_literal: true
module Gitlab
module Usage
module Metrics
module Instrumentations
class CountCiBuildsMetric < DatabaseMetric
relation { ::Ci::Build }
operation :count
def initialize(time_frame:, options: {})
super
raise ArgumentError, "secure_type options attribute is required" unless secure_type.present?
raise ArgumentError, "Attribute: #{secure_type} it not allowed" unless ::EE::Gitlab::UsageData::SECURE_PRODUCT_TYPES.key?(secure_type.to_sym)
end
private
def relation
super.where(name: secure_type) # rubocop: disable CodeReuse/ActiveRecord
end
def secure_type
options[:secure_type]
end
end
end
end
end
end
...@@ -4,12 +4,12 @@ module Gitlab ...@@ -4,12 +4,12 @@ module Gitlab
module Usage module Usage
module Metrics module Metrics
module Instrumentations module Instrumentations
class CiBuildDistinctCountMetric < DatabaseMetric class CountUsersCreatingCiBuildsMetric < DatabaseMetric
operation :distinct_count, column: :user_id
cache_start_and_finish_as :ci_build_distinct_count_user
relation { ::Ci::Build } relation { ::Ci::Build }
operation :distinct_count, column: :user_id
cache_start_and_finish_as :count_users_creating_ci_builds
start { ::User.minimum(:id) } start { ::User.minimum(:id) }
finish { ::User.maximum(:id) } finish { ::User.maximum(:id) }
......
...@@ -131,7 +131,7 @@ RSpec.describe Gitlab::UsageData do ...@@ -131,7 +131,7 @@ RSpec.describe Gitlab::UsageData do
expect(count_data[:epic_issues]).to eq(2) expect(count_data[:epic_issues]).to eq(2)
end end
it 'gathers security products usage data' do it 'gathers security products usage data', :aggregate_failures do
expect(count_data[:container_scanning_jobs]).to eq(1) expect(count_data[:container_scanning_jobs]).to eq(1)
expect(count_data[:dast_jobs]).to eq(1) expect(count_data[:dast_jobs]).to eq(1)
expect(count_data[:dependency_scanning_jobs]).to eq(1) expect(count_data[:dependency_scanning_jobs]).to eq(1)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CiBuildDistinctCountMetric do
before_all do
user = create(:user)
create(:ci_build, name: 'dast')
create(:ci_build, name: 'container_scanning', user: user)
create(:ci_build, name: 'container_scanning', user: user)
end
it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database', options: { secure_type: 'container_scanning' } } do
let(:expected_value) { 1 }
end
it 'raises an exception if secure_type option is not present' do
expect { described_class.new }.to raise_error(ArgumentError)
end
it 'raises an exception if secure_type option is invalid' do
expect { described_class.new(option: { secure_type: 'invalid_type' }) }.to raise_error(ArgumentError)
end
context 'with cache_start_and_finish_as called' do
before do
allow_next_instance_of(Gitlab::Database::BatchCounter) do |batch_counter|
allow(batch_counter).to receive(:transaction_open?).and_return(false)
end
end
it 'caches using the key name passed', :request_store, :use_clean_rails_redis_caching do
expect(Gitlab::Cache).to receive(:fetch_once).with('metric_instrumentation/ci_build_distinct_count_user_minimum_id', any_args).and_call_original
expect(Gitlab::Cache).to receive(:fetch_once).with('metric_instrumentation/ci_build_distinct_count_user_maximum_id', any_args).and_call_original
described_class.new(time_frame: 'all', options: { secure_type: 'container_scanning' }).value
expect(Rails.cache.read('metric_instrumentation/ci_build_distinct_count_user_minimum_id')).to eq(::User.minimum(:id))
expect(Rails.cache.read('metric_instrumentation/ci_build_distinct_count_user_maximum_id')).to eq(::User.maximum(:id))
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiBuildsMetric do
RSpec.shared_examples 'a correct secure type instrumented metric value' do |params|
let(:expected_value) { params[:expected_value] }
before_all do
user = create(:user)
user2 = create(:user)
secure_types = %w[
container_scanning
dast
dependency_scanning
license_management
license_scanning
sast
secret_detection
coverage_fuzzing
apifuzzer_fuzz
apifuzzer_fuzz_dnd
].freeze
secure_types.each do |secure_type|
create(:ci_build, name: secure_type, user: user, created_at: 3.days.ago)
create(:ci_build, name: secure_type, user: user)
create(:ci_build, name: secure_type, user: user2, created_at: 30.days.ago)
end
end
context 'with secure_type container_scanning' do
let(:secure_type) { 'container_scanning' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'container_scanning' } }
end
context 'with secure_type dast' do
let(:secure_type) { 'dast' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'dast' } }
end
context 'with secure_type dependency_scanning' do
let(:secure_type) { 'dependency_scanning' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'dependency_scanning' } }
end
context 'with secure_type license_management' do
let(:secure_type) { 'license_management' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'license_management' } }
end
context 'with secure_type license_scanning' do
let(:secure_type) { 'license_scanning' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'license_scanning' } }
end
context 'with secure_type sast' do
let(:secure_type) { 'sast' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'sast' } }
end
context 'with secure_type secret_detection' do
let(:secure_type) { 'secret_detection' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'secret_detection' } }
end
context 'with secure_type coverage_fuzzing' do
let(:secure_type) { 'coverage_fuzzing' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'coverage_fuzzing' } }
end
context 'with secure_type apifuzzer_fuzz' do
let(:secure_type) { 'apifuzzer_fuzz' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'apifuzzer_fuzz' } }
end
context 'with secure_type apifuzzer_fuzz_dnd' do
let(:secure_type) { 'apifuzzer_fuzz_dnd' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'apifuzzer_fuzz_dnd' } }
end
end
context 'with time_frame all' do
let(:expected_query) { "SELECT COUNT(\"ci_builds\".\"id\") FROM \"ci_builds\" WHERE \"ci_builds\".\"type\" = 'Ci::Build' AND \"ci_builds\".\"name\" = '#{secure_type}'" }
it_behaves_like 'a correct secure type instrumented metric value', { time_frame: 'all', expected_value: 3 }
end
context 'with time_frame 28d' do
let(:start) { 30.days.ago.to_s(:db) }
let(:finish) { 2.days.ago.to_s(:db) }
let(:expected_query) { "SELECT COUNT(\"ci_builds\".\"id\") FROM \"ci_builds\" WHERE \"ci_builds\".\"type\" = 'Ci::Build' AND \"ci_builds\".\"created_at\" BETWEEN '#{start}' AND '#{finish}' AND \"ci_builds\".\"name\" = '#{secure_type}'" }
it_behaves_like 'a correct secure type instrumented metric value', { time_frame: '28d', expected_value: 1 }
end
it 'raises an exception if secure_type option is not present' do
expect { described_class.new }.to raise_error(ArgumentError)
end
it 'raises an exception if secure_type option is invalid' do
expect { described_class.new(option: { secure_type: 'invalid_type' }) }.to raise_error(ArgumentError)
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountUsersCreatingCiBuildsMetric do
RSpec.shared_examples 'a correct secure type instrumented metric value' do |params|
let(:expected_value) { params[:expected_value] }
before_all do
user = create(:user)
user2 = create(:user)
secure_types = %w[
container_scanning
dast
dependency_scanning
license_management
license_scanning
sast
secret_detection
coverage_fuzzing
apifuzzer_fuzz
apifuzzer_fuzz_dnd
].freeze
secure_types.each do |secure_type|
create(:ci_build, name: secure_type, user: user, created_at: 3.days.ago)
create(:ci_build, name: secure_type, user: user)
create(:ci_build, name: secure_type, user: user2, created_at: 30.days.ago)
end
end
context 'with secure_type container_scanning' do
let(:secure_type) { 'container_scanning' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'container_scanning' } }
end
context 'with secure_type dast' do
let(:secure_type) { 'dast' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'dast' } }
end
context 'with secure_type dependency_scanning' do
let(:secure_type) { 'dependency_scanning' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'dependency_scanning' } }
end
context 'with secure_type license_management' do
let(:secure_type) { 'license_management' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'license_management' } }
end
context 'with secure_type license_scanning' do
let(:secure_type) { 'license_scanning' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'license_scanning' } }
end
context 'with secure_type sast' do
let(:secure_type) { 'sast' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'sast' } }
end
context 'with secure_type secret_detection' do
let(:secure_type) { 'secret_detection' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'secret_detection' } }
end
context 'with secure_type coverage_fuzzing' do
let(:secure_type) { 'coverage_fuzzing' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'coverage_fuzzing' } }
end
context 'with secure_type apifuzzer_fuzz' do
let(:secure_type) { 'apifuzzer_fuzz' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'apifuzzer_fuzz' } }
end
context 'with secure_type apifuzzer_fuzz_dnd' do
let(:secure_type) { 'apifuzzer_fuzz_dnd' }
it_behaves_like 'a correct instrumented metric value and query', { time_frame: params[:time_frame], data_source: 'database', options: { secure_type: 'apifuzzer_fuzz_dnd' } }
end
end
context 'with time_frame all' do
let(:expected_query) { "SELECT COUNT(DISTINCT \"ci_builds\".\"user_id\") FROM \"ci_builds\" WHERE \"ci_builds\".\"type\" = 'Ci::Build' AND \"ci_builds\".\"name\" = '#{secure_type}'" }
it_behaves_like 'a correct secure type instrumented metric value', { time_frame: 'all', expected_value: 2 }
end
context 'with time_frame 28d' do
let(:start) { 30.days.ago.to_s(:db) }
let(:finish) { 2.days.ago.to_s(:db) }
let(:expected_query) { "SELECT COUNT(DISTINCT \"ci_builds\".\"user_id\") FROM \"ci_builds\" WHERE \"ci_builds\".\"type\" = 'Ci::Build' AND \"ci_builds\".\"created_at\" BETWEEN '#{start}' AND '#{finish}' AND \"ci_builds\".\"name\" = '#{secure_type}'" }
it_behaves_like 'a correct secure type instrumented metric value', { time_frame: '28d', expected_value: 1 }
end
it 'raises an exception if secure_type option is not present' do
expect { described_class.new }.to raise_error(ArgumentError)
end
it 'raises an exception if secure_type option is invalid' do
expect { described_class.new(option: { secure_type: 'invalid_type' }) }.to raise_error(ArgumentError)
end
context 'with cache_start_and_finish_as called' do
before do
allow_next_instance_of(Gitlab::Database::BatchCounter) do |batch_counter|
allow(batch_counter).to receive(:transaction_open?).and_return(false)
end
end
it 'caches using the key name passed', :request_store, :use_clean_rails_redis_caching do
expect(Gitlab::Cache).to receive(:fetch_once).with('metric_instrumentation/count_users_creating_ci_builds_minimum_id', any_args).and_call_original
expect(Gitlab::Cache).to receive(:fetch_once).with('metric_instrumentation/count_users_creating_ci_builds_maximum_id', any_args).and_call_original
described_class.new(time_frame: 'all', options: { secure_type: 'container_scanning' }).value
expect(Rails.cache.read('metric_instrumentation/count_users_creating_ci_builds_minimum_id')).to eq(::User.minimum(:id))
expect(Rails.cache.read('metric_instrumentation/count_users_creating_ci_builds_maximum_id')).to eq(::User.maximum(:id))
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment