Commit 224830d8 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 0f6cbe50 ec87f32f
...@@ -15,7 +15,7 @@ module Security ...@@ -15,7 +15,7 @@ module Security
attr_reader :pipeline attr_reader :pipeline
def self.allowed_job_types def self.allowed_job_types
# Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_management, :coverage_fuzzing] # Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_scanning, :coverage_fuzzing]
raise NotImplementedError, 'allowed_job_types must be overwritten to return an array of job types' raise NotImplementedError, 'allowed_job_types must be overwritten to return an array of job types'
end end
......
...@@ -40,7 +40,9 @@ module AuthorizedProjectUpdate ...@@ -40,7 +40,9 @@ module AuthorizedProjectUpdate
private private
def use_primary_database def use_primary_database
# no-op in CE, overriden in EE if ::Gitlab::Database::LoadBalancing.enable?
::Gitlab::Database::LoadBalancing::Session.current.use_primary!
end
end end
def project_authorizations_needs_refresh?(user) def project_authorizations_needs_refresh?(user)
...@@ -54,5 +56,3 @@ module AuthorizedProjectUpdate ...@@ -54,5 +56,3 @@ module AuthorizedProjectUpdate
end end
end end
end end
AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker.prepend_mod_with('AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker')
# frozen_string_literal: true
class RemoveSegmentSelectionsTable < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def up
drop_table :analytics_devops_adoption_segment_selections
end
def down
create_table :analytics_devops_adoption_segment_selections do |t|
t.references :segment, index: { name: 'index_on_segment_selections_segment_id' }, null: false, foreign_key: { to_table: :analytics_devops_adoption_segments, on_delete: :cascade }
t.bigint :group_id
t.bigint :project_id
t.index [:group_id, :segment_id], unique: true, name: 'index_on_segment_selections_group_id_segment_id'
t.index [:project_id, :segment_id], unique: true, name: 'index_on_segment_selections_project_id_segment_id'
t.timestamps_with_timezone
end
add_concurrent_foreign_key(:analytics_devops_adoption_segment_selections, :projects, column: :project_id, on_delete: :cascade)
add_concurrent_foreign_key(:analytics_devops_adoption_segment_selections, :namespaces, column: :group_id, on_delete: :cascade)
add_check_constraint :analytics_devops_adoption_segment_selections, '(project_id != NULL AND group_id IS NULL) OR (group_id != NULL AND project_id IS NULL)', 'segment_selection_project_id_or_group_id_required'
end
end
ee76ee2e2515c06b09fca23a77bdfb9532fa5d80fc3d5aba44a80d123b74cfa9
\ No newline at end of file
...@@ -9110,25 +9110,6 @@ CREATE SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq ...@@ -9110,25 +9110,6 @@ CREATE SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq
ALTER SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq OWNED BY analytics_cycle_analytics_project_value_streams.id; ALTER SEQUENCE analytics_cycle_analytics_project_value_streams_id_seq OWNED BY analytics_cycle_analytics_project_value_streams.id;
CREATE TABLE analytics_devops_adoption_segment_selections (
id bigint NOT NULL,
segment_id bigint NOT NULL,
group_id bigint,
project_id bigint,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
CONSTRAINT segment_selection_project_id_or_group_id_required CHECK ((((project_id <> NULL::bigint) AND (group_id IS NULL)) OR ((group_id <> NULL::bigint) AND (project_id IS NULL))))
);
CREATE SEQUENCE analytics_devops_adoption_segment_selections_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE analytics_devops_adoption_segment_selections_id_seq OWNED BY analytics_devops_adoption_segment_selections.id;
CREATE TABLE analytics_devops_adoption_segments ( CREATE TABLE analytics_devops_adoption_segments (
id bigint NOT NULL, id bigint NOT NULL,
last_recorded_at timestamp with time zone, last_recorded_at timestamp with time zone,
...@@ -19520,8 +19501,6 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages ALTER COLUMN id SET DE ...@@ -19520,8 +19501,6 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages ALTER COLUMN id SET DE
ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams ALTER COLUMN id SET DEFAULT nextval('analytics_cycle_analytics_project_value_streams_id_seq'::regclass); ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams ALTER COLUMN id SET DEFAULT nextval('analytics_cycle_analytics_project_value_streams_id_seq'::regclass);
ALTER TABLE ONLY analytics_devops_adoption_segment_selections ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_segment_selections_id_seq'::regclass);
ALTER TABLE ONLY analytics_devops_adoption_segments ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_segments_id_seq'::regclass); ALTER TABLE ONLY analytics_devops_adoption_segments ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_segments_id_seq'::regclass);
ALTER TABLE ONLY analytics_devops_adoption_snapshots ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_snapshots_id_seq'::regclass); ALTER TABLE ONLY analytics_devops_adoption_snapshots ALTER COLUMN id SET DEFAULT nextval('analytics_devops_adoption_snapshots_id_seq'::regclass);
...@@ -20611,9 +20590,6 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages ...@@ -20611,9 +20590,6 @@ ALTER TABLE ONLY analytics_cycle_analytics_project_stages
ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams ALTER TABLE ONLY analytics_cycle_analytics_project_value_streams
ADD CONSTRAINT analytics_cycle_analytics_project_value_streams_pkey PRIMARY KEY (id); ADD CONSTRAINT analytics_cycle_analytics_project_value_streams_pkey PRIMARY KEY (id);
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT analytics_devops_adoption_segment_selections_pkey PRIMARY KEY (id);
ALTER TABLE ONLY analytics_devops_adoption_segments ALTER TABLE ONLY analytics_devops_adoption_segments
ADD CONSTRAINT analytics_devops_adoption_segments_pkey PRIMARY KEY (id); ADD CONSTRAINT analytics_devops_adoption_segments_pkey PRIMARY KEY (id);
...@@ -23899,12 +23875,6 @@ CREATE INDEX index_on_projects_lower_path ON projects USING btree (lower((path): ...@@ -23899,12 +23875,6 @@ CREATE INDEX index_on_projects_lower_path ON projects USING btree (lower((path):
CREATE INDEX index_on_routes_lower_path ON routes USING btree (lower((path)::text)); CREATE INDEX index_on_routes_lower_path ON routes USING btree (lower((path)::text));
CREATE UNIQUE INDEX index_on_segment_selections_group_id_segment_id ON analytics_devops_adoption_segment_selections USING btree (group_id, segment_id);
CREATE UNIQUE INDEX index_on_segment_selections_project_id_segment_id ON analytics_devops_adoption_segment_selections USING btree (project_id, segment_id);
CREATE INDEX index_on_segment_selections_segment_id ON analytics_devops_adoption_segment_selections USING btree (segment_id);
CREATE INDEX index_on_snapshots_segment_id_end_time ON analytics_devops_adoption_snapshots USING btree (segment_id, end_time); CREATE INDEX index_on_snapshots_segment_id_end_time ON analytics_devops_adoption_snapshots USING btree (segment_id, end_time);
CREATE INDEX index_on_snapshots_segment_id_recorded_at ON analytics_devops_adoption_snapshots USING btree (segment_id, recorded_at); CREATE INDEX index_on_snapshots_segment_id_recorded_at ON analytics_devops_adoption_snapshots USING btree (segment_id, recorded_at);
...@@ -25957,9 +25927,6 @@ ALTER TABLE ONLY project_group_links ...@@ -25957,9 +25927,6 @@ ALTER TABLE ONLY project_group_links
ALTER TABLE ONLY epics ALTER TABLE ONLY epics
ADD CONSTRAINT fk_dccd3f98fc FOREIGN KEY (assignee_id) REFERENCES users(id) ON DELETE SET NULL; ADD CONSTRAINT fk_dccd3f98fc FOREIGN KEY (assignee_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT fk_ded7fe0344 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY issues ALTER TABLE ONLY issues
ADD CONSTRAINT fk_df75a7c8b8 FOREIGN KEY (promoted_to_epic_id) REFERENCES epics(id) ON DELETE SET NULL; ADD CONSTRAINT fk_df75a7c8b8 FOREIGN KEY (promoted_to_epic_id) REFERENCES epics(id) ON DELETE SET NULL;
...@@ -26029,9 +25996,6 @@ ALTER TABLE ONLY vulnerability_external_issue_links ...@@ -26029,9 +25996,6 @@ ALTER TABLE ONLY vulnerability_external_issue_links
ALTER TABLE ONLY epics ALTER TABLE ONLY epics
ADD CONSTRAINT fk_f081aa4489 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; ADD CONSTRAINT fk_f081aa4489 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT fk_f1472b95f3 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY boards ALTER TABLE ONLY boards
ADD CONSTRAINT fk_f15266b5f9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; ADD CONSTRAINT fk_f15266b5f9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
...@@ -26122,9 +26086,6 @@ ALTER TABLE ONLY ip_restrictions ...@@ -26122,9 +26086,6 @@ ALTER TABLE ONLY ip_restrictions
ALTER TABLE ONLY terraform_state_versions ALTER TABLE ONLY terraform_state_versions
ADD CONSTRAINT fk_rails_04f176e239 FOREIGN KEY (terraform_state_id) REFERENCES terraform_states(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_04f176e239 FOREIGN KEY (terraform_state_id) REFERENCES terraform_states(id) ON DELETE CASCADE;
ALTER TABLE ONLY analytics_devops_adoption_segment_selections
ADD CONSTRAINT fk_rails_053f00a9da FOREIGN KEY (segment_id) REFERENCES analytics_devops_adoption_segments(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_build_report_results ALTER TABLE ONLY ci_build_report_results
ADD CONSTRAINT fk_rails_056d298d48 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_056d298d48 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
...@@ -131,6 +131,9 @@ list. ...@@ -131,6 +131,9 @@ list.
```shell ```shell
sudo gitlab-ctl reconfigure sudo gitlab-ctl reconfigure
# Needed when enabling or disabling for the first time but not for password changes.
# See https://gitlab.com/gitlab-org/gitlab-foss/-/issues/23560#note_61966788
sudo gitlab-ctl restart sudo gitlab-ctl restart
``` ```
......
...@@ -21,7 +21,7 @@ The following are the requirements for providing your own Redis instance: ...@@ -21,7 +21,7 @@ The following are the requirements for providing your own Redis instance:
[requirements page](../../install/requirements.md). [requirements page](../../install/requirements.md).
- Standalone Redis or Redis high availability with Sentinel are supported. Redis - Standalone Redis or Redis high availability with Sentinel are supported. Redis
Cluster is not supported. Cluster is not supported.
- Managed Redis from cloud providers such as AWS ElastiCache will work. If these - Managed Redis from cloud providers such as AWS ElastiCache works fine. If these
services support high availability, be sure it is **not** the Redis Cluster type. services support high availability, be sure it is **not** the Redis Cluster type.
Note the Redis node's IP address or hostname, port, and password (if required). Note the Redis node's IP address or hostname, port, and password (if required).
...@@ -53,7 +53,7 @@ Note the Redis node's IP address or hostname, port, and password (if required). ...@@ -53,7 +53,7 @@ Note the Redis node's IP address or hostname, port, and password (if required).
This is the documentation for configuring a scalable Redis setup when This is the documentation for configuring a scalable Redis setup when
you have installed Redis all by yourself and not using the bundled one that you have installed Redis all by yourself and not using the bundled one that
comes with the Omnibus packages, although using the Omnibus GitLab packages is comes with the Omnibus packages, although using the Omnibus GitLab packages is
highly recommend as we optimize them specifically for GitLab, and we will take highly recommend as we optimize them specifically for GitLab, and we take
care of upgrading Redis to the latest supported version. care of upgrading Redis to the latest supported version.
Note also that you may elect to override all references to Note also that you may elect to override all references to
...@@ -76,7 +76,7 @@ requirements: ...@@ -76,7 +76,7 @@ requirements:
(e.g., one from an internal network). (e.g., one from an internal network).
- Since Redis 3.2, you must define a password to receive external connections - Since Redis 3.2, you must define a password to receive external connections
(`requirepass`). (`requirepass`).
- If you are using Redis with Sentinel, you will also need to define the same - If you are using Redis with Sentinel, you also need to define the same
password for the replica password definition (`masterauth`) in the same instance. password for the replica password definition (`masterauth`) in the same instance.
In addition, read the prerequisites as described in the In addition, read the prerequisites as described in the
...@@ -176,7 +176,7 @@ primary with IP `10.0.0.1` (some settings might overlap with the primary): ...@@ -176,7 +176,7 @@ primary with IP `10.0.0.1` (some settings might overlap with the primary):
sentinel monitor gitlab-redis 10.0.0.1 6379 2 sentinel monitor gitlab-redis 10.0.0.1 6379 2
## Define with `sentinel down-after-milliseconds` the time in `ms` ## Define with `sentinel down-after-milliseconds` the time in `ms`
## that an unresponsive server will be considered down. ## that an unresponsive server is considered down.
sentinel down-after-milliseconds gitlab-redis 10000 sentinel down-after-milliseconds gitlab-redis 10000
## Define a value for `sentinel failover_timeout` in `ms`. This has multiple ## Define a value for `sentinel failover_timeout` in `ms`. This has multiple
...@@ -197,7 +197,7 @@ primary with IP `10.0.0.1` (some settings might overlap with the primary): ...@@ -197,7 +197,7 @@ primary with IP `10.0.0.1` (some settings might overlap with the primary):
## ##
## * The maximum time a failover in progress waits for all the replicas to be ## * The maximum time a failover in progress waits for all the replicas to be
## reconfigured as replicas of the new primary. However even after this time ## reconfigured as replicas of the new primary. However even after this time
## the replicas will be reconfigured by the Sentinels anyway, but not with ## the replicas are reconfigured by the Sentinels anyway, but not with
## the exact parallel-syncs progression as specified. ## the exact parallel-syncs progression as specified.
sentinel failover_timeout 30000 sentinel failover_timeout 30000
``` ```
...@@ -249,7 +249,7 @@ In a real world usage, you would also set up firewall rules to prevent ...@@ -249,7 +249,7 @@ In a real world usage, you would also set up firewall rules to prevent
unauthorized access from other machines, and block traffic from the unauthorized access from other machines, and block traffic from the
outside ([Internet](https://gitlab.com/gitlab-org/gitlab-foss/uploads/c4cc8cd353604bd80315f9384035ff9e/The_Internet_IT_Crowd.png)). outside ([Internet](https://gitlab.com/gitlab-org/gitlab-foss/uploads/c4cc8cd353604bd80315f9384035ff9e/The_Internet_IT_Crowd.png)).
For this example, **Sentinel 1** will be configured in the same machine as the For this example, **Sentinel 1** is configured in the same machine as the
**Redis Primary**, **Sentinel 2** and **Sentinel 3** in the same machines as the **Redis Primary**, **Sentinel 2** and **Sentinel 3** in the same machines as the
**Replica 1** and **Replica 2** respectively. **Replica 1** and **Replica 2** respectively.
...@@ -261,11 +261,11 @@ Here is a list and description of each **machine** and the assigned **IP**: ...@@ -261,11 +261,11 @@ Here is a list and description of each **machine** and the assigned **IP**:
- `10.0.0.4`: GitLab application - `10.0.0.4`: GitLab application
Please note that after the initial configuration, if a failover is initiated Please note that after the initial configuration, if a failover is initiated
by the Sentinel nodes, the Redis nodes will be reconfigured and the **Primary** by the Sentinel nodes, the Redis nodes are reconfigured and the **Primary**
will change permanently (including in `redis.conf`) from one node to the other, changes permanently (including in `redis.conf`) from one node to the other,
until a new failover is initiated again. until a new failover is initiated again.
The same thing will happen with `sentinel.conf` that will be overridden after the The same thing happens with `sentinel.conf` that is overridden after the
initial execution, after any new sentinel node starts watching the **Primary**, initial execution, after any new sentinel node starts watching the **Primary**,
or a failover promotes a different **Primary** node. or a failover promotes a different **Primary** node.
......
...@@ -6,6 +6,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -6,6 +6,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Create an A/B test with `Experimentation Module` # Create an A/B test with `Experimentation Module`
NOTE:
We recommend using [GLEX](gitlab_experiment.md) for new experiments.
## Implement the experiment ## Implement the experiment
1. Add the experiment to the `Gitlab::Experimentation::EXPERIMENTS` hash in 1. Add the experiment to the `Gitlab::Experimentation::EXPERIMENTS` hash in
......
...@@ -46,16 +46,10 @@ One is built into GitLab directly and has been around for a while (this is calle ...@@ -46,16 +46,10 @@ One is built into GitLab directly and has been around for a while (this is calle
to as `Gitlab::Experiment` -- GLEX for short. to as `Gitlab::Experiment` -- GLEX for short.
Both approaches use [experiment](../feature_flags/index.md#experiment-type) Both approaches use [experiment](../feature_flags/index.md#experiment-type)
feature flags, and there is currently no strong suggestion to use one over the other. feature flags. We recommend using GLEX rather than `Experimentation Module` for new experiments.
| Feature | `Experimentation Module` | GLEX |
| -------------------- |------------------------- | ---- |
| Record user grouping | Yes | No |
| Uses feature flags | Yes | Yes |
| Multivariate (A/B/n) | No | Yes |
- [Implementing an A/B experiment using `Experimentation Module`](experimentation.md)
- [Implementing an A/B/n experiment using GLEX](gitlab_experiment.md) - [Implementing an A/B/n experiment using GLEX](gitlab_experiment.md)
- [Implementing an A/B experiment using `Experimentation Module`](experimentation.md)
Historical Context: `Experimentation Module` was built iteratively with the needs that Historical Context: `Experimentation Module` was built iteratively with the needs that
appeared while implementing Growth sub-department experiments, while GLEX was built appeared while implementing Growth sub-department experiments, while GLEX was built
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
module Types module Types
module Vulnerability module Vulnerability
# rubocop: disable Graphql/AuthorizeTypes
class IssueLinkType < BaseObject class IssueLinkType < BaseObject
graphql_name 'VulnerabilityIssueLink' graphql_name 'VulnerabilityIssueLink'
description 'Represents an issue link of a vulnerability' description 'Represents an issue link of a vulnerability'
authorize :read_issue_link
field :id, GraphQL::ID_TYPE, null: false, field :id, GraphQL::ID_TYPE, null: false,
description: 'GraphQL ID of the vulnerability.' description: 'GraphQL ID of the vulnerability.'
...@@ -16,6 +17,5 @@ module Types ...@@ -16,6 +17,5 @@ module Types
field :issue, ::Types::IssueType, null: false, field :issue, ::Types::IssueType, null: false,
description: 'The issue attached to issue link.' description: 'The issue attached to issue link.'
end end
# rubocop: enable Graphql/AuthorizeTypes
end end
end end
...@@ -3,5 +3,9 @@ ...@@ -3,5 +3,9 @@
module Vulnerabilities module Vulnerabilities
class IssueLinkPolicy < BasePolicy class IssueLinkPolicy < BasePolicy
delegate { @subject.vulnerability&.project } delegate { @subject.vulnerability&.project }
condition(:issue_readable?) { Ability.allowed?(@user, :read_issue, @subject.issue) }
rule { ~issue_readable? }.prevent :read_issue_link
end end
end end
...@@ -9,7 +9,7 @@ module Security ...@@ -9,7 +9,7 @@ module Security
end end
def execute def execute
sync_license_management_rules sync_license_scanning_rules
sync_vulnerability_rules sync_vulnerability_rules
success success
rescue StandardError => error rescue StandardError => error
...@@ -27,7 +27,7 @@ module Security ...@@ -27,7 +27,7 @@ module Security
attr_reader :pipeline attr_reader :pipeline
def sync_license_management_rules def sync_license_scanning_rules
project = pipeline.project project = pipeline.project
report = pipeline.license_scanning_report report = pipeline.license_scanning_report
return if report.empty? && !pipeline.complete? return if report.empty? && !pipeline.complete?
......
# frozen_string_literal: true
module EE
module AuthorizedProjectUpdate
module UserRefreshOverUserRangeWorker # rubocop:disable Scalability/IdempotentWorker
extend ::Gitlab::Utils::Override
private
override :use_primary_database
def use_primary_database
if ::Gitlab::Database::LoadBalancing.enable?
::Gitlab::Database::LoadBalancing::Session.current.use_primary!
end
end
end
end
end
...@@ -52,7 +52,6 @@ RSpec.describe GitlabSchema.types['Project'] do ...@@ -52,7 +52,6 @@ RSpec.describe GitlabSchema.types['Project'] do
create(:ci_build, :success, :sast, pipeline: pipeline) create(:ci_build, :success, :sast, pipeline: pipeline)
create(:ci_build, :success, :dast, pipeline: pipeline) create(:ci_build, :success, :dast, pipeline: pipeline)
create(:ci_build, :success, :license_scanning, pipeline: pipeline) create(:ci_build, :success, :license_scanning, pipeline: pipeline)
create(:ci_build, :success, :license_management, pipeline: pipeline)
create(:ci_build, :pending, :secret_detection, pipeline: pipeline) create(:ci_build, :pending, :secret_detection, pipeline: pipeline)
end end
......
...@@ -8,4 +8,5 @@ RSpec.describe GitlabSchema.types['VulnerabilityIssueLink'] do ...@@ -8,4 +8,5 @@ RSpec.describe GitlabSchema.types['VulnerabilityIssueLink'] do
subject { described_class } subject { described_class }
it { is_expected.to have_graphql_fields(expected_fields) } it { is_expected.to have_graphql_fields(expected_fields) }
it { is_expected.to require_graphql_authorizations(:read_issue_link) }
end end
...@@ -3,16 +3,16 @@ ...@@ -3,16 +3,16 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Vulnerabilities::IssueLinkPolicy do RSpec.describe Vulnerabilities::IssueLinkPolicy do
let(:vulnerability_issue_link) { build(:vulnerabilities_issue_link, vulnerability: vulnerability, issue: issue) }
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: user.namespace) } let_it_be(:project) { create(:project, namespace: user.namespace) }
let_it_be(:vulnerability) { create(:vulnerability, project: project) }
let(:vulnerability) { create(:vulnerability, project: project) } let_it_be(:issue) { create(:issue, project: project) }
let(:issue) { create(:issue, project: project) }
let(:vulnerability_issue_link) { build(:vulnerabilities_issue_link, vulnerability: vulnerability, issue: issue) }
subject { described_class.new(user, vulnerability_issue_link) } subject { described_class.new(user, vulnerability_issue_link) }
context 'with a user authorized to admin vulnerability-issue links' do describe ':admin_vulnerability_issue_link' do
before do before do
stub_licensed_features(security_dashboard: true) stub_licensed_features(security_dashboard: true)
...@@ -20,8 +20,8 @@ RSpec.describe Vulnerabilities::IssueLinkPolicy do ...@@ -20,8 +20,8 @@ RSpec.describe Vulnerabilities::IssueLinkPolicy do
end end
context 'with missing vulnerability' do context 'with missing vulnerability' do
let(:vulnerability) { nil } let_it_be(:vulnerability) { nil }
let(:issue) { create(:issue) } let_it_be(:issue) { create(:issue) }
it { is_expected.to be_disallowed(:admin_vulnerability_issue_link) } it { is_expected.to be_disallowed(:admin_vulnerability_issue_link) }
end end
...@@ -31,9 +31,27 @@ RSpec.describe Vulnerabilities::IssueLinkPolicy do ...@@ -31,9 +31,27 @@ RSpec.describe Vulnerabilities::IssueLinkPolicy do
end end
context "when issue and link don't belong to the same project" do context "when issue and link don't belong to the same project" do
let(:issue) { create(:issue) } let_it_be(:issue) { create(:issue) }
it { is_expected.to be_allowed(:admin_vulnerability_issue_link) } it { is_expected.to be_allowed(:admin_vulnerability_issue_link) }
end end
end end
describe ':read_issue_link' do
before do
allow(Ability).to receive(:allowed?).with(user, :read_issue, issue).and_return(allowed?)
end
context 'when the associated issue can not be read by the user' do
let(:allowed?) { false }
it { is_expected.to be_disallowed(:read_issue_link) }
end
context 'when the associated issue can be read by the user' do
let(:allowed?) { true }
it { is_expected.to be_allowed(:read_issue_link) }
end
end
end end
...@@ -8,11 +8,14 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do ...@@ -8,11 +8,14 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do
let_it_be(:project) { create(:project) } let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user, security_dashboard_projects: [project]) } let_it_be(:user) { create(:user, security_dashboard_projects: [project]) }
let_it_be(:vulnerability) { create(:vulnerability, project: project) } let_it_be(:vulnerability) { create(:vulnerability, project: project) }
let_it_be(:related_issue) { create(:vulnerabilities_issue_link, :related, vulnerability: vulnerability) } let_it_be(:created_issue) { create(:issue, project: project) }
let_it_be(:created_issue) { create(:vulnerabilities_issue_link, :created, vulnerability: vulnerability) } let_it_be(:related_issue) { create(:issue, project: project) }
let_it_be(:related_issue_link) { create(:vulnerabilities_issue_link, :related, vulnerability: vulnerability, issue: related_issue) }
let_it_be(:created_issue_link) { create(:vulnerabilities_issue_link, :created, vulnerability: vulnerability, issue: created_issue) }
before do before do
project.add_developer(user) project.add_developer(user)
stub_licensed_features(security_dashboard: true) stub_licensed_features(security_dashboard: true)
end end
...@@ -46,13 +49,13 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do ...@@ -46,13 +49,13 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do
it 'returns a list of VulnerabilityIssueLink with `CREATED` linkType' do it 'returns a list of VulnerabilityIssueLink with `CREATED` linkType' do
query_issue_links('CREATED') query_issue_links('CREATED')
expect_issue_links_response(created_issue) expect_issue_links_response(created_issue_link)
end end
it 'returns a list of VulnerabilityIssueLink with `RELATED` linkType' do it 'returns a list of VulnerabilityIssueLink with `RELATED` linkType' do
query_issue_links('RELATED') query_issue_links('RELATED')
expect_issue_links_response(related_issue) expect_issue_links_response(related_issue_link)
end end
end end
...@@ -60,7 +63,7 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do ...@@ -60,7 +63,7 @@ RSpec.describe 'Query.vulnerabilities.issueLinks' do
it 'returns a list of all VulnerabilityIssueLink' do it 'returns a list of all VulnerabilityIssueLink' do
query_issue_links query_issue_links
expect_issue_links_response(related_issue, created_issue) expect_issue_links_response(related_issue_link, created_issue_link)
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
let_it_be(:project) { create(:project) }
let(:user) { project.namespace.owner }
let(:start_user_id) { user.id }
let(:end_user_id) { start_user_id }
let(:execute_worker) { subject.perform(start_user_id, end_user_id) }
describe '#perform' do
context 'when the feature flag `periodic_project_authorization_update_via_replica` is disabled' do
before do
stub_feature_flags(periodic_project_authorization_update_via_replica: false)
end
context 'when load balancing is enabled' do
before do
allow(Gitlab::Database::LoadBalancing).to receive(:enable?).and_return(true)
end
it 'reads from the primary database' do
expect(Gitlab::Database::LoadBalancing::Session.current)
.to receive(:use_primary!)
execute_worker
end
end
end
end
end
...@@ -77,7 +77,7 @@ module Gitlab ...@@ -77,7 +77,7 @@ module Gitlab
end end
def set_section_duration(duration) def set_section_duration(duration)
@section_duration = Time.at(duration.to_i).strftime('%M:%S') @section_duration = Time.at(duration.to_i).utc.strftime('%M:%S')
end end
def flush_current_segment! def flush_current_segment!
......
...@@ -28,19 +28,19 @@ RSpec.describe Security::SecurityJobsFinder do ...@@ -28,19 +28,19 @@ RSpec.describe Security::SecurityJobsFinder do
end end
end end
context 'with combination of security jobs and license management jobs' do context 'with combination of security jobs and license scanning jobs' do
let!(:sast_build) { create(:ci_build, :sast, pipeline: pipeline) } let!(:sast_build) { create(:ci_build, :sast, pipeline: pipeline) }
let!(:container_scanning_build) { create(:ci_build, :container_scanning, pipeline: pipeline) } let!(:container_scanning_build) { create(:ci_build, :container_scanning, pipeline: pipeline) }
let!(:dast_build) { create(:ci_build, :dast, pipeline: pipeline) } let!(:dast_build) { create(:ci_build, :dast, pipeline: pipeline) }
let!(:secret_detection_build) { create(:ci_build, :secret_detection, pipeline: pipeline) } let!(:secret_detection_build) { create(:ci_build, :secret_detection, pipeline: pipeline) }
let!(:license_management_build) { create(:ci_build, :license_management, pipeline: pipeline) } let!(:license_scanning_build) { create(:ci_build, :license_scanning, pipeline: pipeline) }
it 'returns only the security jobs' do it 'returns only the security jobs' do
is_expected.to include(sast_build) is_expected.to include(sast_build)
is_expected.to include(container_scanning_build) is_expected.to include(container_scanning_build)
is_expected.to include(dast_build) is_expected.to include(dast_build)
is_expected.to include(secret_detection_build) is_expected.to include(secret_detection_build)
is_expected.not_to include(license_management_build) is_expected.not_to include(license_scanning_build)
end end
end end
end end
......
...@@ -66,14 +66,16 @@ RSpec.describe Mutations::Ci::Runner::Update do ...@@ -66,14 +66,16 @@ RSpec.describe Mutations::Ci::Runner::Update do
context 'with valid arguments' do context 'with valid arguments' do
it 'updates runner with correct values' do it 'updates runner with correct values' do
expected_attributes = mutation_params.except(:id) expected_attributes = mutation_params.except(:id, :tag_list)
subject subject
expect(subject[:errors]).to be_empty expect(subject[:errors]).to be_empty
expect(subject[:runner]).to be_an_instance_of(Ci::Runner) expect(subject[:runner]).to be_an_instance_of(Ci::Runner)
expect(subject[:runner]).to have_attributes(expected_attributes) expect(subject[:runner]).to have_attributes(expected_attributes)
expect(subject[:runner].tag_list).to contain_exactly(*mutation_params[:tag_list])
expect(runner.reload).to have_attributes(expected_attributes) expect(runner.reload).to have_attributes(expected_attributes)
expect(runner.tag_list).to contain_exactly(*mutation_params[:tag_list])
end end
end end
......
...@@ -76,10 +76,30 @@ RSpec.describe Gitlab::Ci::Ansi2json::Line do ...@@ -76,10 +76,30 @@ RSpec.describe Gitlab::Ci::Ansi2json::Line do
end end
describe '#set_section_duration' do describe '#set_section_duration' do
it 'sets and formats the section_duration' do shared_examples 'set_section_duration' do
subject.set_section_duration(75) it 'sets and formats the section_duration' do
subject.set_section_duration(75)
expect(subject.section_duration).to eq('01:15') expect(subject.section_duration).to eq('01:15')
end
end
context 'with default timezone' do
it_behaves_like 'set_section_duration'
end
context 'with a timezone carrying minutes offset' do
before do
# The actual call by does use Time.at(...).utc that the following
# rubocop rule (Rails/TimeZone) suggests, but for this specific
# test's purposes we needed to mock at the Time.at call point.
# rubocop:disable Rails/TimeZone
allow(Time).to receive(:at).with(75).and_return(Time.at(75, in: '+05:30'))
# rubocop:enable Rails/TimeZone
end
it_behaves_like 'set_section_duration'
end end
end end
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
let(:project) { create(:project) } let_it_be(:project) { create(:project) }
let(:user) { project.namespace.owner } let(:user) { project.namespace.owner }
let(:start_user_id) { user.id } let(:start_user_id) { user.id }
let(:end_user_id) { start_user_id } let(:end_user_id) { start_user_id }
...@@ -64,6 +65,18 @@ RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do ...@@ -64,6 +65,18 @@ RSpec.describe AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker do
execute_worker execute_worker
end end
context 'when load balancing is enabled' do
before do
allow(Gitlab::Database::LoadBalancing).to receive(:enable?).and_return(true)
end
it 'reads from the primary database' do
expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary!)
execute_worker
end
end
end end
end 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