Commit af7bdf18 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-10-23

# Conflicts:
#	app/assets/stylesheets/pages/issues.scss
#	app/models/user.rb
#	db/schema.rb
#	locale/gitlab.pot

[ci skip]
parents 4cdade66 ba3e6500
......@@ -903,7 +903,7 @@ gitlab:assets:compile:
- public/assets/
karma:
<<: *dedicated-no-docs-and-no-qa-pull-cache-job
<<: *dedicated-no-docs-pull-cache-job
<<: *use-pg
dependencies:
- compile-assets
......
......@@ -67,6 +67,11 @@ export const conditions = [
tokenKey: 'milestone',
value: 'none',
},
{
url: 'milestone_title=Any+Milestone',
tokenKey: 'milestone',
value: 'any',
},
{
url: 'milestone_title=%23upcoming',
tokenKey: 'milestone',
......
......@@ -330,6 +330,7 @@ ul.related-merge-requests > li {
text-align: right;
}
}
<<<<<<< HEAD
.issue-token {
display: inline-flex;
......@@ -436,3 +437,5 @@ ul.related-merge-requests > li {
font-size: 0.9em;
}
}
=======
>>>>>>> upstream/master
......@@ -388,8 +388,8 @@ module IssuablesHelper
{
todo_text: "Add todo",
mark_text: "Mark todo as done",
todo_icon: (is_collapsed ? icon('plus-square') : nil),
mark_icon: (is_collapsed ? icon('check-square', class: 'todo-undone') : nil),
todo_icon: (is_collapsed ? sprite_icon('todo-add') : nil),
mark_icon: (is_collapsed ? sprite_icon('todo-done', css_class: 'todo-undone') : nil),
issuable_id: issuable.id,
issuable_type: issuable.class.name.underscore,
url: project_todos_path(@project),
......
......@@ -281,6 +281,12 @@ module Ci
stage unless stage.statuses_count.zero?
end
def ref_exists?
project.repository.ref_exists?(git_ref)
rescue Gitlab::Git::Repository::NoRepository
false
end
##
# TODO We do not completely switch to persisted stages because of
# race conditions with setting statuses gitlab-ce#23257.
......@@ -687,11 +693,11 @@ module Ci
def push_details
strong_memoize(:push_details) do
Gitlab::Git::Push.new(project, before_sha, sha, push_ref)
Gitlab::Git::Push.new(project, before_sha, sha, git_ref)
end
end
def push_ref
def git_ref
if branch?
Gitlab::Git::BRANCH_REF_PREFIX + ref.to_s
elsif tag?
......
......@@ -3,7 +3,7 @@
module Clusters
module Applications
class Runner < ActiveRecord::Base
VERSION = '0.1.34'.freeze
VERSION = '0.1.35'.freeze
self.table_name = 'clusters_applications_runners'
......
......@@ -561,6 +561,8 @@ class Project < ActiveRecord::Base
self[:lfs_enabled] && Gitlab.config.lfs.enabled
end
alias_method :lfs_enabled, :lfs_enabled?
def auto_devops_enabled?
if auto_devops&.enabled.nil?
has_auto_devops_implicitly_enabled?
......
......@@ -229,8 +229,11 @@ class User < ActiveRecord::Base
delegate :path, to: :namespace, allow_nil: true, prefix: true
delegate :notes_filter_for, to: :user_preference
delegate :set_notes_filter, to: :user_preference
<<<<<<< HEAD
accepts_nested_attributes_for :namespace
=======
>>>>>>> upstream/master
state_machine :state, initial: :active do
event :block do
......
......@@ -13,7 +13,11 @@
= pluralize @pipeline.total_size, "job"
- if @pipeline.ref
from
= link_to @pipeline.ref, project_ref_path(@project, @pipeline.ref), class: "ref-name"
- if @pipeline.ref_exists?
= link_to @pipeline.ref, project_ref_path(@project, @pipeline.ref), class: "ref-name"
- else
%span.ref-name
= @pipeline.ref
- if @pipeline.duration
in
= time_interval_in_words(@pipeline.duration)
......
......@@ -36,7 +36,7 @@
%button.btn.btn-link{ type: 'button' }
= sprite_icon('search')
%span
Press Enter or click to search
= _('Press Enter or click to search')
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
%button.btn.btn-link{ type: 'button' }
......@@ -61,7 +61,7 @@
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'none' } }
%button.btn.btn-link{ type: 'button' }
No Assignee
= _('No Assignee')
%li.divider.droplab-item-ignore
- if current_user
= render 'shared/issuable/user_dropdown_item',
......@@ -74,13 +74,16 @@
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'none' } }
%button.btn.btn-link{ type: 'button' }
No Milestone
= _('None')
%li.filter-dropdown-item{ data: { value: 'any' } }
%button.btn.btn-link{ type: 'button' }
= _('Any')
%li.filter-dropdown-item{ data: { value: 'upcoming' } }
%button.btn.btn-link{ type: 'button' }
Upcoming
= _('Upcoming')
%li.filter-dropdown-item{ 'data-value' => 'started' }
%button.btn.btn-link{ type: 'button' }
Started
= _('Started')
%li.divider.droplab-item-ignore
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
......@@ -90,7 +93,7 @@
%ul{ data: { dropdown: true } }
%li.filter-dropdown-item{ data: { value: 'none' } }
%button.btn.btn-link{ type: 'button' }
No Label
= _('No Label')
%li.divider.droplab-item-ignore
%ul.filter-dropdown{ data: { dynamic: true, dropdown: true } }
%li.filter-dropdown-item
......
- is_collapsed = local_assigns.fetch(:is_collapsed, false)
- mark_content = is_collapsed ? icon('check-square', class: 'todo-undone') : _('Mark todo as done')
- todo_content = is_collapsed ? icon('plus-square') : _('Add todo')
- mark_content = is_collapsed ? sprite_icon('todo-done', css_class: 'todo-undone') : _('Mark todo as done')
- todo_content = is_collapsed ? sprite_icon('todo-add') : _('Add todo')
%button.issuable-todo-btn.js-issuable-todo{ type: 'button',
class: (is_collapsed ? 'btn-blank sidebar-collapsed-icon dont-change-state has-tooltip' : 'btn btn-default issuable-header-btn float-right'),
......
......@@ -24,7 +24,7 @@
%td= @runner.active? ? 'Yes' : 'No'
%tr
%td Protected
%td= @runner.active? ? _('Yes') : _('No')
%td= @runner.ref_protected? ? 'Yes' : 'No'
%tr
%td Can run untagged jobs
%td= @runner.run_untagged? ? 'Yes' : 'No'
......
---
title: Update Todo icons in collapsed sidebar for Issues and MRs
merge_request: 22534
author:
type: changed
---
title: Only render link to branch when branch still exists in pipeline page
merge_request:
author:
type: fixed
---
title: Added `Any` option to milestones filter
merge_request: 22351
author: Heinrich Lee Yu
type: added
---
title: Fix rendering of 'Protected' value on Runner details page
merge_request: 22459
author:
type: fixed
---
title: Introduce new kubernetes helpers
merge_request: 22525
author:
type: other
---
title: Allow kubeclient to call RoleBinding methods
merge_request: 22524
author:
type: other
---
title: Resolve LFS not correctly showing enabled
merge_request: 22501
author:
type: fixed
---
title: Fix EOF detection with CI artifacts metadata
merge_request: 22479
author:
type: fixed
---
title: Update used version of Runner Helm Chart to 0.1.35
merge_request: 22541
author:
type: other
......@@ -915,9 +915,6 @@ test:
default:
path: tmp/tests/repositories/
gitaly_address: unix:tmp/tests/gitaly/gitaly.socket
broken:
path: tmp/tests/non-existent-repositories
gitaly_address: unix:tmp/tests/gitaly/gitaly.socket
gitaly:
client_path: tmp/tests/gitaly
......
......@@ -3384,8 +3384,13 @@ ActiveRecord::Schema.define(version: 20181017131623) do
add_foreign_key "u2f_registrations", "users"
add_foreign_key "user_callouts", "users", on_delete: :cascade
add_foreign_key "user_custom_attributes", "users", on_delete: :cascade
<<<<<<< HEAD
add_foreign_key "user_interacted_projects", "projects", on_delete: :cascade
add_foreign_key "user_interacted_projects", "users", on_delete: :cascade
=======
add_foreign_key "user_interacted_projects", "projects", name: "fk_722ceba4f7", on_delete: :cascade
add_foreign_key "user_interacted_projects", "users", name: "fk_0894651f08", on_delete: :cascade
>>>>>>> upstream/master
add_foreign_key "user_preferences", "users", on_delete: :cascade
add_foreign_key "user_statuses", "users", on_delete: :cascade
add_foreign_key "user_synced_attributes_metadata", "users", on_delete: :cascade
......
......@@ -411,6 +411,23 @@ args: {
}
```
### `uid_attribute`
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/43806) in GitLab 10.7.
By default, the `uid` is set as the `name_id` in the SAML response. If you'd like to designate a unique attribute for the `uid`, you can set the `uid_attribute`. In the example below, the value of `uid` attribute in the SAML response is set as the `uid_attribute`.
```yaml
args: {
assertion_consumer_service_url: 'https://gitlab.example.com/users/auth/saml/callback',
idp_cert_fingerprint: '43:51:43:a1:b5:fc:8b:b7:0a:3a:a9:b1:0f:66:73:a8',
idp_sso_target_url: 'https://login.example.com/idp',
issuer: 'https://gitlab.example.com',
name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
uid_attribute: 'uid'
}
```
## Troubleshooting
### 500 error after login
......
......@@ -74,7 +74,8 @@ From the project issue/merge request list pages and the group issue/merge reques
When filtering by milestone, in addition to choosing a specific project milestone or group milestone, you can choose a special milestone filter.
- **No Milestone**: Show issues or merge requests with no assigned milestone.
- **None**: Show issues or merge requests with no assigned milestone.
- **Any**: Show issues or merge requests that have an assigned milestone.
- **Upcoming**: Show issues or merge requests that have been assigned the open milestone that has the next upcoming due date (i.e. nearest due date in the future).
- **Started**: Show issues or merge requests that have an assigned milestone with a start date that is before today.
......
......@@ -59,9 +59,12 @@ module Gitlab
until gz.eof?
begin
path = read_string(gz).force_encoding('UTF-8')
meta = read_string(gz).force_encoding('UTF-8')
path = read_string(gz)&.force_encoding('UTF-8')
meta = read_string(gz)&.force_encoding('UTF-8')
# We might hit an EOF while reading either value, so we should
# abort if we don't get any data.
next unless path && meta
next unless path.valid_encoding? && meta.valid_encoding?
next unless path =~ match_pattern
next if path =~ INVALID_PATH_PATTERN
......
......@@ -937,7 +937,7 @@ database (#{dbname}) using a super user and running:
For MySQL you instead need to run:
GRANT ALL PRIVILEGES ON *.* TO #{user}@'%'
GRANT ALL PRIVILEGES ON #{dbname}.* TO #{user}@'%'
Both queries will grant the user super user permissions, ensuring you don't run
into similar problems in the future (e.g. when new tables are created).
......
......@@ -45,6 +45,13 @@ module Gitlab
:update_cluster_role_binding,
to: :rbac_client
# RBAC methods delegates to the apis/rbac.authorization.k8s.io api
# group client
delegate :create_role_binding,
:get_role_binding,
:update_role_binding,
to: :rbac_client
# Deployments resource is currently on the apis/extensions api group
delegate :get_deployments,
to: :extensions_client
......
# frozen_string_literal: true
module Gitlab
module Kubernetes
class RoleBinding
attr_reader :role_name, :namespace, :service_account_name
def initialize(role_name:, namespace:, service_account_name:)
@role_name = role_name
@namespace = namespace
@service_account_name = service_account_name
end
def generate
::Kubeclient::Resource.new.tap do |resource|
resource.metadata = metadata
resource.roleRef = role_ref
resource.subjects = subjects
end
end
private
def metadata
{ name: "gitlab-#{namespace}", namespace: namespace }
end
def role_ref
{
apiGroup: 'rbac.authorization.k8s.io',
kind: 'Role',
name: role_name
}
end
def subjects
[
{
kind: 'ServiceAccount',
name: service_account_name,
namespace: namespace
}
]
end
end
end
end
......@@ -32,7 +32,10 @@ module Gitlab
end
if Rails.env.test?
storages << { name: 'test_second_storage', path: Rails.root.join('tmp', 'tests', 'second_storage').to_s }
storage_path = Rails.root.join('tmp', 'tests', 'second_storage').to_s
FileUtils.mkdir(storage_path) unless File.exist?(storage_path)
storages << { name: 'test_second_storage', path: storage_path }
end
config = { socket_path: address.sub(/\Aunix:/, ''), storage: storages }
......
......@@ -5254,6 +5254,12 @@ msgstr ""
msgid "No"
msgstr ""
<<<<<<< HEAD
=======
msgid "No Assignee"
msgstr ""
>>>>>>> upstream/master
msgid "No Label"
msgstr ""
......@@ -7233,6 +7239,7 @@ msgstr ""
msgid "Something went wrong while closing the %{issuable}. Please try again later"
msgstr ""
<<<<<<< HEAD
msgid "Something went wrong while fetching %{listType} list"
msgstr ""
......@@ -7242,6 +7249,11 @@ msgstr ""
msgid "Something went wrong while fetching group member contributions"
msgstr ""
=======
msgid "Something went wrong while fetching comments. Please try again."
msgstr ""
>>>>>>> upstream/master
msgid "Something went wrong while fetching the projects."
msgstr ""
......@@ -8376,6 +8388,9 @@ msgstr ""
msgid "Up to date"
msgstr ""
msgid "Upcoming"
msgstr ""
msgid "Update"
msgstr ""
......
......@@ -47,5 +47,15 @@ FactoryBot.define do
trait :ref_protected do
access_level :ref_protected
end
trait :tagged_only do
run_untagged false
tag_list %w(tag1 tag2)
end
trait :locked do
locked true
end
end
end
......@@ -189,13 +189,21 @@ describe 'Dropdown milestone', :js do
end
it 'selects `no milestone`' do
click_static_milestone('No Milestone')
click_static_milestone('None')
expect(page).to have_css(js_dropdown_milestone, visible: false)
expect_tokens([milestone_token('none', false)])
expect_filtered_search_input_empty
end
it 'selects `any milestone`' do
click_static_milestone('Any')
expect(page).to have_css(js_dropdown_milestone, visible: false)
expect_tokens([milestone_token('any', false)])
expect_filtered_search_input_empty
end
it 'selects `upcoming milestone`' do
click_static_milestone('Upcoming')
......
......@@ -68,6 +68,10 @@ describe 'Pipeline', :js do
expect(page).to have_css('#js-tab-pipeline.active')
end
it 'shows link to the pipeline ref' do
expect(page).to have_link(pipeline.ref)
end
it_behaves_like 'showing user status' do
let(:user_with_status) { pipeline.user }
......@@ -236,6 +240,20 @@ describe 'Pipeline', :js do
it { expect(page).not_to have_content('Cancel running') }
end
end
context 'when pipeline ref does not exist in repository anymore' do
let(:pipeline) do
create(:ci_empty_pipeline, project: project,
ref: 'non-existent',
sha: project.commit.id,
user: user)
end
it 'does not render link to the pipeline ref' do
expect(page).not_to have_link(pipeline.ref)
expect(page).to have_content(pipeline.ref)
end
end
end
context 'when user does not have access to read jobs' do
......
......@@ -45,8 +45,10 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
expect(document.querySelector('.js-issuable-todo.sidebar-collapsed-icon')).not.toBeNull();
expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-plus-square'),
).not.toBeNull();
document
.querySelector('.js-issuable-todo.sidebar-collapsed-icon svg use')
.getAttribute('xlink:href'),
).toContain('todo-add');
expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
......@@ -68,8 +70,10 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
).not.toBeNull();
expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-check-square'),
).not.toBeNull();
document
.querySelector('.js-issuable-todo.sidebar-collapsed-icon svg.todo-undone use')
.getAttribute('xlink:href'),
).toContain('todo-done');
done();
});
......
......@@ -26,9 +26,7 @@ describe Gitaly::Server do
end
end
context 'when the storage is not readable' do
let(:server) { described_class.new('broken') }
context 'when the storage is not readable', :broken_storage do
it 'returns false' do
expect(server).not_to be_readable
end
......@@ -42,9 +40,7 @@ describe Gitaly::Server do
end
end
context 'when the storage is not writeable' do
let(:server) { described_class.new('broken') }
context 'when the storage is not writeable', :broken_storage do
it 'returns false' do
expect(server).not_to be_writeable
end
......
......@@ -112,4 +112,34 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
end
end
end
context 'generated metadata' do
let(:tmpfile) { Tempfile.new('test-metadata') }
let(:generator) { CiArtifactMetadataGenerator.new(tmpfile) }
let(:entry_count) { 5 }
before do
tmpfile.binmode
(1..entry_count).each do |index|
generator.add_entry("public/test-#{index}.txt")
end
generator.write
end
after do
File.unlink(tmpfile.path)
end
describe '#find_entries!' do
it 'reads expected number of entries' do
stream = File.open(tmpfile.path)
metadata = described_class.new(stream, 'public', { recursive: true })
expect(metadata.find_entries!.count).to eq entry_count
end
end
end
end
......@@ -335,7 +335,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
restored_project_json
expect(project.lfs_enabled).to be_nil
expect(project.lfs_enabled).to be_falsey
end
end
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Kubernetes::RoleBinding, '#generate' do
let(:role_name) { 'edit' }
let(:namespace) { 'my-namespace' }
let(:service_account_name) { 'my-service-account' }
let(:subjects) do
[
{
kind: 'ServiceAccount',
name: service_account_name,
namespace: namespace
}
]
end
let(:role_ref) do
{
apiGroup: 'rbac.authorization.k8s.io',
kind: 'Role',
name: role_name
}
end
let(:resource) do
::Kubeclient::Resource.new(
metadata: { name: "gitlab-#{namespace}", namespace: namespace },
roleRef: role_ref,
subjects: subjects
)
end
subject do
described_class.new(
role_name: role_name,
namespace: namespace,
service_account_name: service_account_name
).generate
end
it 'should build a Kubeclient Resource' do
is_expected.to eq(resource)
end
end
......@@ -788,6 +788,41 @@ describe Ci::Pipeline, :mailer do
end
end
describe 'ref_exists?' do
context 'when repository exists' do
using RSpec::Parameterized::TableSyntax
let(:project) { create(:project, :repository) }
where(:tag, :ref, :result) do
false | 'master' | true
false | 'non-existent-branch' | false
true | 'v1.1.0' | true
true | 'non-existent-tag' | false
end
with_them do
let(:pipeline) do
create(:ci_empty_pipeline, project: project, tag: tag, ref: ref)
end
it "correctly detects ref" do
expect(pipeline.ref_exists?).to be result
end
end
end
context 'when repository does not exist' do
let(:pipeline) do
create(:ci_empty_pipeline, project: project, ref: 'master')
end
it 'always returns false' do
expect(pipeline.ref_exists?).to eq false
end
end
end
context 'with non-empty project' do
let(:project) { create(:project, :repository) }
......
......@@ -17,7 +17,7 @@ describe Clusters::Applications::Runner do
let(:application) { create(:clusters_applications_runner, :scheduled, version: '0.1.30') }
it 'updates the application version' do
expect(application.reload.version).to eq('0.1.34')
expect(application.reload.version).to eq('0.1.35')
end
end
end
......@@ -45,7 +45,7 @@ describe Clusters::Applications::Runner do
it 'should be initialized with 4 arguments' do
expect(subject.name).to eq('runner')
expect(subject.chart).to eq('runner/gitlab-runner')
expect(subject.version).to eq('0.1.34')
expect(subject.version).to eq('0.1.35')
expect(subject).not_to be_rbac
expect(subject.repository).to eq('https://charts.gitlab.io')
expect(subject.files).to eq(gitlab_runner.files)
......@@ -63,7 +63,7 @@ describe Clusters::Applications::Runner do
let(:gitlab_runner) { create(:clusters_applications_runner, :errored, runner: ci_runner, version: '0.1.13') }
it 'should be initialized with the locked version' do
expect(subject.version).to eq('0.1.34')
expect(subject.version).to eq('0.1.35')
end
end
end
......
# frozen_sting_literal: true
# This generates fake CI metadata .gz for testing
# Based off https://gitlab.com/gitlab-org/gitlab-workhorse/blob/master/internal/zipartifacts/metadata.go
class CiArtifactMetadataGenerator
attr_accessor :entries, :output
ARTIFACT_METADATA = "GitLab Build Artifacts Metadata 0.0.2\n".freeze
def initialize(stream)
@entries = {}
@output = Zlib::GzipWriter.new(stream)
end
def add_entry(filename)
@entries[filename] = { CRC: rand(0xfffffff), Comment: FFaker::Lorem.sentence(10) }
end
def write
write_version
write_errors
write_entries
output.close
end
private
def write_version
write_string(ARTIFACT_METADATA)
end
def write_errors
write_string('{}')
end
def write_entries
entries.each do |filename, metadata|
write_string(filename)
write_string(metadata.to_json + "\n")
end
end
def write_string(data)
bytes = [data.length].pack('L>')
output.write(bytes)
output.write(data)
end
end
......@@ -44,10 +44,11 @@ module KubernetesHelpers
WebMock.stub_request(:get, deployments_url).to_return(response || kube_deployments_response)
end
def stub_kubeclient_get_secret(api_url, namespace: 'default', **options)
def stub_kubeclient_get_secret(api_url, **options)
options[:metadata_name] ||= "default-token-1"
options[:namespace] ||= "default"
WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}/secrets/#{options[:metadata_name]}")
WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{options[:namespace]}/secrets/#{options[:metadata_name]}")
.to_return(kube_response(kube_v1_secret_body(options)))
end
......@@ -76,6 +77,21 @@ module KubernetesHelpers
.to_return(kube_response({}))
end
def stub_kubeclient_create_role_binding(api_url, namespace: 'default')
WebMock.stub_request(:post, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings")
.to_return(kube_response({}))
end
def stub_kubeclient_create_namespace(api_url)
WebMock.stub_request(:post, api_url + "/api/v1/namespaces")
.to_return(kube_response({}))
end
def stub_kubeclient_get_namespace(api_url, namespace: 'default')
WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}")
.to_return(kube_response({}))
end
def kube_v1_secret_body(**options)
{
"kind" => "SecretList",
......@@ -98,7 +114,8 @@ module KubernetesHelpers
{ "name" => "deployments", "namespaced" => true, "kind" => "Deployment" },
{ "name" => "secrets", "namespaced" => true, "kind" => "Secret" },
{ "name" => "serviceaccounts", "namespaced" => true, "kind" => "ServiceAccount" },
{ "name" => "services", "namespaced" => true, "kind" => "Service" }
{ "name" => "services", "namespaced" => true, "kind" => "Service" },
{ "name" => "namespaces", "namespaced" => true, "kind" => "Namespace" }
]
}
end
......
......@@ -70,7 +70,6 @@ module TestEnv
TMP_TEST_PATH = Rails.root.join('tmp', 'tests', '**')
REPOS_STORAGE = 'default'.freeze
BROKEN_STORAGE = 'broken'.freeze
# Test environment
#
......@@ -159,10 +158,6 @@ module TestEnv
version: Gitlab::GitalyClient.expected_server_version,
task: "gitlab:gitaly:install[#{gitaly_dir},#{repos_path}]") do
# Re-create config, to specify the broken storage path
storage_paths = { 'default' => repos_path, 'broken' => broken_path }
Gitlab::SetupHelper.create_gitaly_configuration(gitaly_dir, storage_paths, force: true)
start_gitaly(gitaly_dir)
end
end
......@@ -257,10 +252,6 @@ module TestEnv
@repos_path ||= Gitlab.config.repositories.storages[REPOS_STORAGE].legacy_disk_path
end
def broken_path
@broken_path ||= Gitlab.config.repositories.storages[BROKEN_STORAGE].legacy_disk_path
end
def backup_path
Gitlab.config.backup.path
end
......
RSpec.configure do |config|
config.before(:all, :broken_storage) do
FileUtils.rm_rf Gitlab.config.repositories.storages.broken.legacy_disk_path
end
config.before(:each, :broken_storage) do
allow(Gitlab::GitalyClient).to receive(:call) do
raise GRPC::Unavailable.new('Gitaly broken in this spec')
......
# frozen_string_literal: true
require 'spec_helper'
describe 'shared/runners/show.html.haml' do
include PageLayoutHelper
let(:runner) do
create(:ci_runner, name: 'test runner',
version: '11.4.0',
ip_address: '127.1.2.3',
revision: 'abcd1234',
architecture: 'amd64' )
end
before do
assign(:runner, runner)
end
subject do
render
rendered
end
describe 'Page title' do
before do
expect_any_instance_of(PageLayoutHelper).to receive(:page_title).with("#{runner.description} ##{runner.id}", 'Runners')
end
it 'sets proper page title' do
render
end
end
describe 'Runner id and type' do
context 'when runner is of type instance' do
it { is_expected.to have_content("Runner ##{runner.id} Shared") }
end
context 'when runner is of type group' do
let(:runner) { create(:ci_runner, :group) }
it { is_expected.to have_content("Runner ##{runner.id} Group") }
end
context 'when runner is of type project' do
let(:runner) { create(:ci_runner, :project) }
it { is_expected.to have_content("Runner ##{runner.id} Specific") }
end
end
describe 'Active value' do
context 'when runner is active' do
it { is_expected.to have_content('Active Yes') }
end
context 'when runner is inactive' do
let(:runner) { create(:ci_runner, :inactive) }
it { is_expected.to have_content('Active No') }
end
end
describe 'Protected value' do
context 'when runner is not protected' do
it { is_expected.to have_content('Protected No') }
end
context 'when runner is protected' do
let(:runner) { create(:ci_runner, :ref_protected) }
it { is_expected.to have_content('Protected Yes') }
end
end
describe 'Can run untagged jobs value' do
context 'when runner run untagged job is set' do
it { is_expected.to have_content('Can run untagged jobs Yes') }
end
context 'when runner run untagged job is unset' do
let(:runner) { create(:ci_runner, :tagged_only) }
it { is_expected.to have_content('Can run untagged jobs No') }
end
end
describe 'Locked to this project value' do
context 'when runner locked is not set' do
it { is_expected.to have_content('Locked to this project No') }
context 'when runner is of type group' do
let(:runner) { create(:ci_runner, :group) }
it { is_expected.not_to have_content('Locked to this project') }
end
end
context 'when runner locked is set' do
let(:runner) { create(:ci_runner, :locked) }
it { is_expected.to have_content('Locked to this project Yes') }
context 'when runner is of type group' do
let(:runner) { create(:ci_runner, :group, :locked) }
it { is_expected.not_to have_content('Locked to this project') }
end
end
end
describe 'Tags value' do
context 'when runner does not have tags' do
it { is_expected.to have_content('Tags') }
it { is_expected.not_to have_selector('span.badge.badge-primary')}
end
context 'when runner have tags' do
let(:runner) { create(:ci_runner, tag_list: %w(tag2 tag3 tag1)) }
it { is_expected.to have_content('Tags tag1 tag2 tag3') }
it { is_expected.to have_selector('span.badge.badge-primary')}
end
end
describe 'Metadata values' do
it { is_expected.to have_content("Name #{runner.name}") }
it { is_expected.to have_content("Version #{runner.version}") }
it { is_expected.to have_content("IP Address #{runner.ip_address}") }
it { is_expected.to have_content("Revision #{runner.revision}") }
it { is_expected.to have_content("Platform #{runner.platform}") }
it { is_expected.to have_content("Architecture #{runner.architecture}") }
it { is_expected.to have_content("Description #{runner.description}") }
end
describe 'Maximum job timeout value' do
let(:runner) { create(:ci_runner, maximum_timeout: 5400) }
it { is_expected.to have_content('Maximum job timeout 1h 30m') }
end
describe 'Last contact value' do
context 'when runner have not contacted yet' do
it { is_expected.to have_content('Last contact Never') }
end
context 'when runner have already contacted' do
let(:runner) { create(:ci_runner, contacted_at: DateTime.now - 6.days) }
let(:expected_contacted_at) { I18n.localize(runner.contacted_at, format: "%b %d, %Y") }
it { is_expected.to have_content("Last contact #{expected_contacted_at}") }
end
end
end
......@@ -51,7 +51,7 @@ describe RepositoryCheck::BatchWorker do
it 'does nothing when shard is unhealthy' do
shard_name = 'broken'
create(:project, created_at: 1.week.ago, repository_storage: shard_name)
create(:project, :broken_storage, created_at: 1.week.ago)
expect(subject.perform(shard_name)).to eq(nil)
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