Skip to content
Snippets Groups Projects
Commit 83ab2898 authored by John Jarvis's avatar John Jarvis
Browse files

Merge branch 'master' into 11-10-stable

parents bfec819f a6e9175f
No related branches found
No related tags found
No related merge requests found
Showing
with 904 additions and 148 deletions
Loading
Loading
@@ -128,87 +128,33 @@ describe('noteActions', () => {
});
});
 
describe('with feature flag replyToIndividualNotes enabled', () => {
describe('for showReply = true', () => {
beforeEach(() => {
gon.features = {
replyToIndividualNotes: true,
};
});
afterEach(() => {
gon.features = {};
});
describe('for showReply = true', () => {
beforeEach(() => {
wrapper = shallowMountNoteActions({
...props,
showReply: true,
});
});
it('shows a reply button', () => {
const replyButton = wrapper.find({ ref: 'replyButton' });
expect(replyButton.exists()).toBe(true);
wrapper = shallowMountNoteActions({
...props,
showReply: true,
});
});
 
describe('for showReply = false', () => {
beforeEach(() => {
wrapper = shallowMountNoteActions({
...props,
showReply: false,
});
});
it('does not show a reply button', () => {
const replyButton = wrapper.find({ ref: 'replyButton' });
it('shows a reply button', () => {
const replyButton = wrapper.find({ ref: 'replyButton' });
 
expect(replyButton.exists()).toBe(false);
});
expect(replyButton.exists()).toBe(true);
});
});
 
describe('with feature flag replyToIndividualNotes disabled', () => {
describe('for showReply = false', () => {
beforeEach(() => {
gon.features = {
replyToIndividualNotes: false,
};
});
afterEach(() => {
gon.features = {};
});
describe('for showReply = true', () => {
beforeEach(() => {
wrapper = shallowMountNoteActions({
...props,
showReply: true,
});
});
it('does not show a reply button', () => {
const replyButton = wrapper.find({ ref: 'replyButton' });
expect(replyButton.exists()).toBe(false);
wrapper = shallowMountNoteActions({
...props,
showReply: false,
});
});
 
describe('for showReply = false', () => {
beforeEach(() => {
wrapper = shallowMountNoteActions({
...props,
showReply: false,
});
});
it('does not show a reply button', () => {
const replyButton = wrapper.find({ ref: 'replyButton' });
it('does not show a reply button', () => {
const replyButton = wrapper.find({ ref: 'replyButton' });
 
expect(replyButton.exists()).toBe(false);
});
expect(replyButton.exists()).toBe(false);
});
});
});
import $ from 'jquery';
import GLDropdown from '~/gl_dropdown'; // eslint-disable-line no-unused-vars
import TimezoneDropdown, {
formatUtcOffset,
formatTimezone,
} from '~/pages/projects/pipeline_schedules/shared/components/timezone_dropdown';
describe('Timezone Dropdown', function() {
preloadFixtures('pipeline_schedules/edit.html');
let $inputEl = null;
let $dropdownEl = null;
let $wrapper = null;
const tzListSel = '.dropdown-content ul li a.is-active';
describe('Initialize', () => {
describe('with dropdown already loaded', () => {
beforeEach(() => {
loadFixtures('pipeline_schedules/edit.html');
$wrapper = $('.dropdown');
$inputEl = $('#schedule_cron_timezone');
$dropdownEl = $('.js-timezone-dropdown');
// eslint-disable-next-line no-new
new TimezoneDropdown({
$inputEl,
$dropdownEl,
});
});
it('can take an $inputEl in the constructor', () => {
const tzStr = '[UTC + 5.5] Sri Jayawardenepura';
const tzValue = 'Asia/Colombo';
expect($inputEl.val()).toBe('UTC');
$(`${tzListSel}:contains('${tzStr}')`, $wrapper).trigger('click');
const val = $inputEl.val();
expect(val).toBe(tzValue);
expect(val).not.toBe('UTC');
});
it('will format data array of timezones into a list of offsets', () => {
const data = $dropdownEl.data('data');
const formatted = $wrapper.find(tzListSel).text();
data.forEach(item => {
expect(formatted).toContain(formatTimezone(item));
});
});
it('will default the timezone to UTC', () => {
const tz = $inputEl.val();
expect(tz).toBe('UTC');
});
});
describe('without dropdown loaded', () => {
beforeEach(() => {
loadFixtures('pipeline_schedules/edit.html');
$wrapper = $('.dropdown');
$inputEl = $('#schedule_cron_timezone');
$dropdownEl = $('.js-timezone-dropdown');
});
it('will populate the list of UTC offsets after the dropdown is loaded', () => {
expect($wrapper.find(tzListSel).length).toEqual(0);
// eslint-disable-next-line no-new
new TimezoneDropdown({
$inputEl,
$dropdownEl,
});
expect($wrapper.find(tzListSel).length).toEqual($($dropdownEl).data('data').length);
});
it('will call a provided handler when a new timezone is selected', () => {
const onSelectTimezone = jasmine.createSpy('onSelectTimezoneMock');
// eslint-disable-next-line no-new
new TimezoneDropdown({
$inputEl,
$dropdownEl,
onSelectTimezone,
});
$wrapper
.find(tzListSel)
.first()
.trigger('click');
expect(onSelectTimezone).toHaveBeenCalled();
});
});
});
describe('formatUtcOffset', () => {
it('will convert negative utc offsets in seconds to hours and minutes', () => {
expect(formatUtcOffset(-21600)).toEqual('- 6');
});
it('will convert positive utc offsets in seconds to hours and minutes', () => {
expect(formatUtcOffset(25200)).toEqual('+ 7');
expect(formatUtcOffset(49500)).toEqual('+ 13.75');
});
it('will return 0 when given a string', () => {
expect(formatUtcOffset('BLAH')).toEqual('0');
expect(formatUtcOffset('$%$%')).toEqual('0');
});
it('will return 0 when given an array', () => {
expect(formatUtcOffset(['an', 'array'])).toEqual('0');
});
it('will return 0 when given an object', () => {
expect(formatUtcOffset({ some: '', object: '' })).toEqual('0');
});
it('will return 0 when given null', () => {
expect(formatUtcOffset(null)).toEqual('0');
});
it('will return 0 when given undefined', () => {
expect(formatUtcOffset(undefined)).toEqual('0');
});
it('will return 0 when given empty input', () => {
expect(formatUtcOffset('')).toEqual('0');
});
});
describe('formatTimezone', () => {
it('given name: "Chatham Is.", offset: "49500", will format for display as "[UTC + 13.75] Chatham Is."', () => {
expect(
formatTimezone({
name: 'Chatham Is.',
offset: 49500,
identifier: 'Pacific/Chatham',
}),
).toEqual('[UTC + 13.75] Chatham Is.');
});
it('given name: "Saskatchewan", offset: "-21600", will format for display as "[UTC - 6] Saskatchewan"', () => {
expect(
formatTimezone({
name: 'Saskatchewan',
offset: -21600,
identifier: 'America/Regina',
}),
).toEqual('[UTC - 6] Saskatchewan');
});
it('given name: "Accra", offset: "0", will format for display as "[UTC 0] Accra"', () => {
expect(
formatTimezone({
name: 'Accra',
offset: 0,
identifier: 'Africa/Accra',
}),
).toEqual('[UTC 0] Accra');
});
});
});
Loading
Loading
@@ -116,7 +116,7 @@ describe('SidebarTodo', () => {
const dataAttributes = {
issuableId: '1',
issuableType: 'epic',
originalTitle: 'Mark todo as done',
originalTitle: '',
placement: 'left',
container: 'body',
boundary: 'viewport',
Loading
Loading
@@ -130,6 +130,10 @@ describe('SidebarTodo', () => {
});
});
 
it('check button label computed property', () => {
expect(vm.buttonLabel).toEqual('Mark todo as done');
});
it('renders button label element when `collapsed` prop is `false`', () => {
const buttonLabelEl = vm.$el.querySelector('span.issuable-todo-inner');
 
Loading
Loading
Loading
Loading
@@ -15,6 +15,16 @@ describe('MRWidgetHeader', () => {
gon.relative_url_root = '';
});
 
const expectDownloadDropdownItems = () => {
const downloadEmailPatchesEl = vm.$el.querySelector('.js-download-email-patches');
const downloadPlainDiffEl = vm.$el.querySelector('.js-download-plain-diff');
expect(downloadEmailPatchesEl.textContent.trim()).toEqual('Email patches');
expect(downloadEmailPatchesEl.getAttribute('href')).toEqual('/mr/email-patches');
expect(downloadPlainDiffEl.textContent.trim()).toEqual('Plain diff');
expect(downloadPlainDiffEl.getAttribute('href')).toEqual('/mr/plainDiffPath');
};
describe('computed', () => {
describe('shouldShowCommitsBehindText', () => {
it('return true when there are divergedCommitsCount', () => {
Loading
Loading
@@ -207,21 +217,7 @@ describe('MRWidgetHeader', () => {
});
 
it('renders download dropdown with links', () => {
expect(vm.$el.querySelector('.js-download-email-patches').textContent.trim()).toEqual(
'Email patches',
);
expect(vm.$el.querySelector('.js-download-email-patches').getAttribute('href')).toEqual(
'/mr/email-patches',
);
expect(vm.$el.querySelector('.js-download-plain-diff').textContent.trim()).toEqual(
'Plain diff',
);
expect(vm.$el.querySelector('.js-download-plain-diff').getAttribute('href')).toEqual(
'/mr/plainDiffPath',
);
expectDownloadDropdownItems();
});
});
 
Loading
Loading
@@ -250,10 +246,8 @@ describe('MRWidgetHeader', () => {
expect(button).toEqual(null);
});
 
it('does not render download dropdown with links', () => {
expect(vm.$el.querySelector('.js-download-email-patches')).toEqual(null);
expect(vm.$el.querySelector('.js-download-plain-diff')).toEqual(null);
it('renders download dropdown with links', () => {
expectDownloadDropdownItems();
});
});
 
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe API::Entities::JobRequest::Image do
let(:ports) { [{ number: 80, protocol: 'http', name: 'name' }]}
let(:image) { double(name: 'image_name', entrypoint: ['foo'], ports: ports)}
let(:entity) { described_class.new(image) }
subject { entity.as_json }
it 'returns the image name' do
expect(subject[:name]).to eq 'image_name'
end
it 'returns the entrypoint' do
expect(subject[:entrypoint]).to eq ['foo']
end
it 'returns the ports' do
expect(subject[:ports]).to eq ports
end
context 'when the ports param is nil' do
let(:ports) { nil }
it 'does not return the ports' do
expect(subject[:ports]).to be_nil
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe ::API::Entities::JobRequest::Port do
let(:port) { double(number: 80, protocol: 'http', name: 'name')}
let(:entity) { described_class.new(port) }
subject { entity.as_json }
it 'returns the port number' do
expect(subject[:number]).to eq 80
end
it 'returns if the port protocol' do
expect(subject[:protocol]).to eq 'http'
end
it 'returns the port name' do
expect(subject[:name]).to eq 'name'
end
end
Loading
Loading
@@ -18,11 +18,16 @@ describe Gitlab::Ci::Build::Image do
it 'populates fabricated object with the proper name attribute' do
expect(subject.name).to eq(image_name)
end
it 'does not populate the ports' do
expect(subject.ports).to be_empty
end
end
 
context 'when image is defined as hash' do
let(:entrypoint) { '/bin/sh' }
let(:job) { create(:ci_build, options: { image: { name: image_name, entrypoint: entrypoint } } ) }
let(:job) { create(:ci_build, options: { image: { name: image_name, entrypoint: entrypoint, ports: [80] } } ) }
 
it 'fabricates an object of the proper class' do
is_expected.to be_kind_of(described_class)
Loading
Loading
@@ -32,6 +37,13 @@ describe Gitlab::Ci::Build::Image do
expect(subject.name).to eq(image_name)
expect(subject.entrypoint).to eq(entrypoint)
end
it 'populates the ports' do
port = subject.ports.first
expect(port.number).to eq 80
expect(port.protocol).to eq 'http'
expect(port.name).to eq 'default_port'
end
end
 
context 'when image name is empty' do
Loading
Loading
@@ -67,6 +79,10 @@ describe Gitlab::Ci::Build::Image do
expect(subject.first).to be_kind_of(described_class)
expect(subject.first.name).to eq(service_image_name)
end
it 'does not populate the ports' do
expect(subject.first.ports).to be_empty
end
end
 
context 'when service is defined as hash' do
Loading
Loading
@@ -75,7 +91,7 @@ describe Gitlab::Ci::Build::Image do
let(:service_command) { 'sleep 30' }
let(:job) do
create(:ci_build, options: { services: [{ name: service_image_name, entrypoint: service_entrypoint,
alias: service_alias, command: service_command }] })
alias: service_alias, command: service_command, ports: [80] }] })
end
 
it 'fabricates an non-empty array of objects' do
Loading
Loading
@@ -89,6 +105,11 @@ describe Gitlab::Ci::Build::Image do
expect(subject.first.entrypoint).to eq(service_entrypoint)
expect(subject.first.alias).to eq(service_alias)
expect(subject.first.command).to eq(service_command)
port = subject.first.ports.first
expect(port.number).to eq 80
expect(port.protocol).to eq 'http'
expect(port.name).to eq 'default_port'
end
end
 
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Ci::Build::Port do
subject { described_class.new(port) }
context 'when port is defined as an integer' do
let(:port) { 80 }
it 'populates the object' do
expect(subject.number).to eq 80
expect(subject.protocol).to eq described_class::DEFAULT_PORT_PROTOCOL
expect(subject.name).to eq described_class::DEFAULT_PORT_NAME
end
end
context 'when port is defined as hash' do
let(:port) { { number: 80, protocol: 'https', name: 'port_name' } }
it 'populates the object' do
expect(subject.number).to eq 80
expect(subject.protocol).to eq 'https'
expect(subject.name).to eq 'port_name'
end
end
end
Loading
Loading
@@ -35,6 +35,12 @@ describe Gitlab::Ci::Config::Entry::Image do
expect(entry.entrypoint).to be_nil
end
end
describe '#ports' do
it "returns image's ports" do
expect(entry.ports).to be_nil
end
end
end
 
context 'when configuration is a hash' do
Loading
Loading
@@ -69,6 +75,38 @@ describe Gitlab::Ci::Config::Entry::Image do
expect(entry.entrypoint).to eq %w(/bin/sh run)
end
end
context 'when configuration has ports' do
let(:ports) { [{ number: 80, protocol: 'http', name: 'foobar' }] }
let(:config) { { name: 'ruby:2.2', entrypoint: %w(/bin/sh run), ports: ports } }
let(:entry) { described_class.new(config, { with_image_ports: image_ports }) }
let(:image_ports) { false }
context 'when with_image_ports metadata is not enabled' do
describe '#valid?' do
it 'is not valid' do
expect(entry).not_to be_valid
expect(entry.errors).to include("image config contains disallowed keys: ports")
end
end
end
context 'when with_image_ports metadata is enabled' do
let(:image_ports) { true }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
describe '#ports' do
it "returns image's ports" do
expect(entry.ports).to eq ports
end
end
end
end
end
 
context 'when entry value is not correct' do
Loading
Loading
@@ -76,8 +114,8 @@ describe Gitlab::Ci::Config::Entry::Image do
 
describe '#errors' do
it 'saves errors' do
expect(entry.errors)
.to include 'image config should be a hash or a string'
expect(entry.errors.first)
.to match /config should be a hash or a string/
end
end
 
Loading
Loading
@@ -93,8 +131,8 @@ describe Gitlab::Ci::Config::Entry::Image do
 
describe '#errors' do
it 'saves errors' do
expect(entry.errors)
.to include 'image config contains unknown keys: non_existing'
expect(entry.errors.first)
.to match /config contains unknown keys: non_existing/
end
end
 
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Port do
let(:entry) { described_class.new(config) }
before do
entry.compose!
end
context 'when configuration is a string' do
let(:config) { 80 }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
describe '#value' do
it 'returns valid hash' do
expect(entry.value).to eq(number: 80)
end
end
describe '#number' do
it "returns port number" do
expect(entry.number).to eq 80
end
end
describe '#protocol' do
it "is nil" do
expect(entry.protocol).to be_nil
end
end
describe '#name' do
it "is nil" do
expect(entry.name).to be_nil
end
end
end
context 'when configuration is a hash' do
context 'with the complete hash' do
let(:config) do
{ number: 80,
protocol: 'http',
name: 'foobar' }
end
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
describe '#value' do
it 'returns valid hash' do
expect(entry.value).to eq config
end
end
describe '#number' do
it "returns port number" do
expect(entry.number).to eq 80
end
end
describe '#protocol' do
it "returns port protocol" do
expect(entry.protocol).to eq 'http'
end
end
describe '#name' do
it "returns port name" do
expect(entry.name).to eq 'foobar'
end
end
end
context 'with only the port number' do
let(:config) { { number: 80 } }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
describe '#value' do
it 'returns valid hash' do
expect(entry.value).to eq(number: 80)
end
end
describe '#number' do
it "returns port number" do
expect(entry.number).to eq 80
end
end
describe '#protocol' do
it "is nil" do
expect(entry.protocol).to be_nil
end
end
describe '#name' do
it "is nil" do
expect(entry.name).to be_nil
end
end
end
context 'without the number' do
let(:config) { { protocol: 'http' } }
describe '#valid?' do
it 'is not valid' do
expect(entry).not_to be_valid
end
end
end
end
context 'when configuration is invalid' do
let(:config) { '80' }
describe '#valid?' do
it 'is valid' do
expect(entry).not_to be_valid
end
end
end
context 'when protocol' do
let(:config) { { number: 80, protocol: protocol, name: 'foobar' } }
context 'is http' do
let(:protocol) { 'http' }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
end
context 'is https' do
let(:protocol) { 'https' }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
end
context 'is neither http nor https' do
let(:protocol) { 'foo' }
describe '#valid?' do
it 'is invalid' do
expect(entry.errors).to include("port protocol should be http or https")
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Ports do
let(:entry) { described_class.new(config) }
before do
entry.compose!
end
context 'when configuration is valid' do
let(:config) { [{ number: 80, protocol: 'http', name: 'foobar' }] }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
describe '#value' do
it 'returns valid array' do
expect(entry.value).to eq(config)
end
end
end
context 'when configuration is invalid' do
let(:config) { 'postgresql:9.5' }
describe '#valid?' do
it 'is invalid' do
expect(entry).not_to be_valid
end
end
context 'when any of the ports' do
before do
expect(entry).not_to be_valid
expect(entry.errors.count).to eq 1
end
context 'have the same name' do
let(:config) do
[{ number: 80, protocol: 'http', name: 'foobar' },
{ number: 81, protocol: 'http', name: 'foobar' }]
end
describe '#valid?' do
it 'is invalid' do
expect(entry.errors.first).to match /each port name must be different/
end
end
end
context 'have the same port' do
let(:config) do
[{ number: 80, protocol: 'http', name: 'foobar' },
{ number: 80, protocol: 'http', name: 'foobar1' }]
end
describe '#valid?' do
it 'is invalid' do
expect(entry.errors.first).to match /each port number can only be referenced once/
end
end
end
end
end
end
Loading
Loading
@@ -39,6 +39,12 @@ describe Gitlab::Ci::Config::Entry::Service do
expect(entry.command).to be_nil
end
end
describe '#ports' do
it "returns service's ports" do
expect(entry.ports).to be_nil
end
end
end
 
context 'when configuration is a hash' do
Loading
Loading
@@ -81,6 +87,40 @@ describe Gitlab::Ci::Config::Entry::Service do
expect(entry.entrypoint).to eq %w(/bin/sh run)
end
end
context 'when configuration has ports' do
let(:ports) { [{ number: 80, protocol: 'http', name: 'foobar' }] }
let(:config) do
{ name: 'postgresql:9.5', alias: 'db', command: %w(cmd run), entrypoint: %w(/bin/sh run), ports: ports }
end
let(:entry) { described_class.new(config, { with_image_ports: image_ports }) }
let(:image_ports) { false }
context 'when with_image_ports metadata is not enabled' do
describe '#valid?' do
it 'is not valid' do
expect(entry).not_to be_valid
expect(entry.errors).to include("service config contains disallowed keys: ports")
end
end
end
context 'when with_image_ports metadata is enabled' do
let(:image_ports) { true }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
describe '#ports' do
it "returns image's ports" do
expect(entry.ports).to eq ports
end
end
end
end
end
 
context 'when entry value is not correct' do
Loading
Loading
@@ -88,8 +128,8 @@ describe Gitlab::Ci::Config::Entry::Service do
 
describe '#errors' do
it 'saves errors' do
expect(entry.errors)
.to include 'service config should be a hash or a string'
expect(entry.errors.first)
.to match /config should be a hash or a string/
end
end
 
Loading
Loading
@@ -105,8 +145,8 @@ describe Gitlab::Ci::Config::Entry::Service do
 
describe '#errors' do
it 'saves errors' do
expect(entry.errors)
.to include 'service config contains unknown keys: non_existing'
expect(entry.errors.first)
.to match /config contains unknown keys: non_existing/
end
end
 
Loading
Loading
@@ -116,4 +156,26 @@ describe Gitlab::Ci::Config::Entry::Service do
end
end
end
context 'when service has ports' do
let(:ports) { [{ number: 80, protocol: 'http', name: 'foobar' }] }
let(:config) do
{ name: 'postgresql:9.5', command: %w(cmd run), entrypoint: %w(/bin/sh run), ports: ports }
end
it 'alias field is mandatory' do
expect(entry).not_to be_valid
expect(entry.errors).to include("service alias can't be blank")
end
end
context 'when service does not have ports' do
let(:config) do
{ name: 'postgresql:9.5', alias: 'db', command: %w(cmd run), entrypoint: %w(/bin/sh run) }
end
it 'alias field is optional' do
expect(entry).to be_valid
end
end
end
Loading
Loading
@@ -32,4 +32,91 @@ describe Gitlab::Ci::Config::Entry::Services do
end
end
end
context 'when configuration has ports' do
let(:ports) { [{ number: 80, protocol: 'http', name: 'foobar' }] }
let(:config) { ['postgresql:9.5', { name: 'postgresql:9.1', alias: 'postgres_old', ports: ports }] }
let(:entry) { described_class.new(config, { with_image_ports: image_ports }) }
let(:image_ports) { false }
context 'when with_image_ports metadata is not enabled' do
describe '#valid?' do
it 'is not valid' do
expect(entry).not_to be_valid
expect(entry.errors).to include("service config contains disallowed keys: ports")
end
end
end
context 'when with_image_ports metadata is enabled' do
let(:image_ports) { true }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
describe '#value' do
it 'returns valid array' do
expect(entry.value).to eq([{ name: 'postgresql:9.5' }, { name: 'postgresql:9.1', alias: 'postgres_old', ports: ports }])
end
end
describe 'services alias' do
context 'when they are not unique' do
let(:config) do
['postgresql:9.5',
{ name: 'postgresql:9.1', alias: 'postgres_old', ports: [80] },
{ name: 'ruby', alias: 'postgres_old', ports: [81] }]
end
describe '#valid?' do
it 'is invalid' do
expect(entry).not_to be_valid
expect(entry.errors).to include("services config alias must be unique in services with ports")
end
end
end
context 'when they are unique' do
let(:config) do
['postgresql:9.5',
{ name: 'postgresql:9.1', alias: 'postgres_old', ports: [80] },
{ name: 'ruby', alias: 'ruby', ports: [81] }]
end
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
end
context 'when one of the duplicated alias is in a service without ports' do
let(:config) do
['postgresql:9.5',
{ name: 'postgresql:9.1', alias: 'postgres_old', ports: [80] },
{ name: 'ruby', alias: 'postgres_old' }]
end
it 'is valid' do
expect(entry).to be_valid
end
end
context 'when there are not any ports' do
let(:config) do
['postgresql:9.5',
{ name: 'postgresql:9.1', alias: 'postgres_old' },
{ name: 'ruby', alias: 'postgres_old' }]
end
it 'is valid' do
expect(entry).to be_valid
end
end
end
end
end
end
Loading
Loading
@@ -123,6 +123,63 @@ describe Gitlab::Ci::Config do
)
end
end
context 'when ports have been set' do
context 'in the main image' do
let(:yml) do
<<-EOS
image:
name: ruby:2.2
ports:
- 80
EOS
end
it 'raises an error' do
expect(config.errors).to include("image config contains disallowed keys: ports")
end
end
context 'in the job image' do
let(:yml) do
<<-EOS
image: ruby:2.2
test:
script: rspec
image:
name: ruby:2.2
ports:
- 80
EOS
end
it 'raises an error' do
expect(config.errors).to include("jobs:test:image config contains disallowed keys: ports")
end
end
context 'in the services' do
let(:yml) do
<<-EOS
image: ruby:2.2
test:
script: rspec
image: ruby:2.2
services:
- name: test
alias: test
ports:
- 80
EOS
end
it 'raises an error' do
expect(config.errors).to include("jobs:test:services:service config contains disallowed keys: ports")
end
end
end
end
 
context "when using 'include' directive" do
Loading
Loading
Loading
Loading
@@ -4,6 +4,9 @@ require 'spec_helper'
 
describe "CI YML Templates" do
ABSTRACT_TEMPLATES = %w[Serverless].freeze
# These templates depend on the presence of the `project`
# param to enable processing of `include:` within CI config.
PROJECT_DEPENDENT_TEMPLATES = %w[Auto-DevOps DAST].freeze
 
def self.concrete_templates
Gitlab::Template::GitlabCiYmlTemplate.all.reject do |template|
Loading
Loading
@@ -20,7 +23,10 @@ describe "CI YML Templates" do
describe 'concrete templates with CI/CD jobs' do
concrete_templates.each do |template|
it "#{template.name} template should be valid" do
expect { Gitlab::Ci::YamlProcessor.new(template.content) }
# Trigger processing of included files
project = create(:project, :test_repo) if PROJECT_DEPENDENT_TEMPLATES.include?(template.name)
expect { Gitlab::Ci::YamlProcessor.new(template.content, project: project) }
.not_to raise_error
end
end
Loading
Loading
Loading
Loading
@@ -1233,7 +1233,7 @@ module Gitlab
config = YAML.dump({ services: [10, "test"], rspec: { script: "test" } })
expect do
Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "service config should be a hash or a string")
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "services:service config should be a hash or a string")
end
 
it "returns errors if job services parameter is not an array" do
Loading
Loading
@@ -1247,7 +1247,7 @@ module Gitlab
config = YAML.dump({ rspec: { script: "test", services: [10, "test"] } })
expect do
Gitlab::Ci::YamlProcessor.new(config)
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "service config should be a hash or a string")
end.to raise_error(Gitlab::Ci::YamlProcessor::ValidationError, "jobs:rspec:services:service config should be a hash or a string")
end
 
it "returns error if job configuration is invalid" do
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Graphql::Tracing do
let!(:graphql_duration_seconds) { double('Gitlab::Metrics::NullMetric') }
before do
allow(Gitlab::Metrics)
.to receive(:histogram)
.with(:graphql_duration_seconds, 'GraphQL execution time')
.and_return(graphql_duration_seconds)
end
it 'updates graphql histogram with expected labels' do
query = 'query { users { id } }'
expect_metric('graphql.lex', 'lex')
expect_metric('graphql.parse', 'parse')
expect_metric('graphql.validate', 'validate')
expect_metric('graphql.analyze', 'analyze_multiplex')
expect_metric('graphql.execute', 'execute_query_lazy')
expect_metric('graphql.execute', 'execute_multiplex')
GitlabSchema.execute(query)
end
private
def expect_metric(platform_key, key)
expect(graphql_duration_seconds)
.to receive(:observe)
.with({ platform_key: platform_key, key: key }, be > 0.0)
end
end
Loading
Loading
@@ -9,9 +9,35 @@ describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
let(:query_params) { [environment.id] }
 
it 'queries using specific time' do
expect(client).to receive(:query_range).with(anything, start: 8.hours.ago.to_f, stop: Time.now.to_f)
expect(client).to receive(:query_range)
.with(anything, start: 8.hours.ago.to_f, stop: Time.now.to_f)
expect(query_result).not_to be_nil
end
context 'when start and end time parameters are provided' do
let(:query_params) { [environment.id, start_time, end_time] }
context 'as unix timestamps' do
let(:start_time) { 4.hours.ago.to_f }
let(:end_time) { 2.hours.ago.to_f }
it 'queries using the provided times' do
expect(client).to receive(:query_range)
.with(anything, start: start_time, stop: end_time)
expect(query_result).not_to be_nil
end
end
context 'as Date/Time objects' do
let(:start_time) { 4.hours.ago }
let(:end_time) { 2.hours.ago }
it 'queries using the provided times converted to unix' do
expect(client).to receive(:query_range)
.with(anything, start: start_time.to_f, stop: end_time.to_f)
expect(query_result).not_to be_nil
end
end
end
end
end
Loading
Loading
@@ -6,14 +6,15 @@ describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
include PrometheusHelpers
include ReactiveCachingHelpers
 
class TestClass
include PrometheusAdapter
end
let(:project) { create(:prometheus_project) }
let(:service) { project.prometheus_service }
 
let(:described_class) { TestClass }
let(:described_class) do
Class.new do
include PrometheusAdapter
end
end
let(:environment_query) { Gitlab::Prometheus::Queries::EnvironmentQuery }
 
describe '#query' do
Loading
Loading
@@ -76,6 +77,28 @@ describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
end
end
end
describe 'additional_metrics' do
let(:additional_metrics_environment_query) { Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery }
let(:environment) { build_stubbed(:environment, slug: 'env-slug') }
let(:time_window) { [1552642245.067, 1552642095.831] }
around do |example|
Timecop.freeze { example.run }
end
context 'with valid data' do
subject { service.query(:additional_metrics_environment, environment, *time_window) }
before do
stub_reactive_cache(service, prometheus_data, additional_metrics_environment_query, environment.id, *time_window)
end
it 'returns reactive data' do
expect(subject).to eq(prometheus_data)
end
end
end
end
 
describe '#calculate_reactive_cache' do
Loading
Loading
@@ -120,4 +143,24 @@ describe PrometheusAdapter, :use_clean_rails_memory_store_caching do
end
end
end
describe '#build_query_args' do
subject { service.build_query_args(*args) }
context 'when active record models are included' do
let(:args) { [double(:environment, id: 12)] }
it 'serializes by id' do
is_expected.to eq [12]
end
end
context 'when args are safe for serialization' do
let(:args) { ['stringy arg', 5, 6.0, :symbolic_arg] }
it 'does nothing' do
is_expected.to eq args
end
end
end
end
Loading
Loading
@@ -592,7 +592,9 @@ describe Environment do
 
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'returns the terminals from the deployment service' do
expect(project.deployment_platform)
deployment_platform_target = Gitlab.ee? ? environment : project
expect(deployment_platform_target.deployment_platform)
.to receive(:terminals).with(environment)
.and_return(:fake_terminals)
 
Loading
Loading
@@ -685,7 +687,8 @@ describe Environment do
 
describe '#additional_metrics' do
let(:project) { create(:prometheus_project) }
subject { environment.additional_metrics }
let(:metric_params) { [] }
subject { environment.additional_metrics(*metric_params) }
 
context 'when the environment has additional metrics' do
before do
Loading
Loading
@@ -693,12 +696,26 @@ describe Environment do
end
 
it 'returns the additional metrics from the deployment service' do
expect(environment.prometheus_adapter).to receive(:query)
.with(:additional_metrics_environment, environment)
.and_return(:fake_metrics)
expect(environment.prometheus_adapter)
.to receive(:query)
.with(:additional_metrics_environment, environment)
.and_return(:fake_metrics)
 
is_expected.to eq(:fake_metrics)
end
context 'when time window arguments are provided' do
let(:metric_params) { [1552642245.067, Time.now] }
it 'queries with the expected parameters' do
expect(environment.prometheus_adapter)
.to receive(:query)
.with(:additional_metrics_environment, environment, *metric_params.map(&:to_f))
.and_return(:fake_metrics)
is_expected.to eq(:fake_metrics)
end
end
end
 
context 'when the environment does not have metrics' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment