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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-11-04 12:06:21 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-11-04 12:06:21 +0300
commit2b7a5214342baa2575b35868316ea9413d2afe1f (patch)
treef80a862f7fa382620b8f8a695d07b6d1734fc5f5 /spec
parent15a2d004be2f79160752d77f701c0f08e7f96973 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb94
-rw-r--r--spec/frontend/api_spec.js20
-rw-r--r--spec/frontend/clusters/clusters_bundle_spec.js7
-rw-r--r--spec/frontend/fixtures/static/environments_logs.html3
-rw-r--r--spec/frontend/monitoring/embed/embed_spec.js4
-rw-r--r--spec/frontend/monitoring/embed/mock_data.js4
-rw-r--r--spec/graphql/mutations/merge_requests/set_milestone_spec.rb53
-rw-r--r--spec/javascripts/monitoring/charts/time_series_spec.js2
-rw-r--r--spec/javascripts/monitoring/components/dashboard_spec.js28
-rw-r--r--spec/javascripts/monitoring/store/actions_spec.js4
-rw-r--r--spec/javascripts/monitoring/store/mutations_spec.js34
-rw-r--r--spec/lib/gitlab/prometheus/internal_spec.rb108
-rw-r--r--spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb66
-rw-r--r--spec/support/helpers/kubernetes_helpers.rb218
14 files changed, 514 insertions, 131 deletions
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index eccc8e1d5de..73fb0fad646 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -13,6 +13,10 @@ describe Projects::Serverless::FunctionsController do
let(:environment) { create(:environment, project: project) }
let!(:deployment) { create(:deployment, :success, environment: environment, cluster: cluster) }
let(:knative_services_finder) { environment.knative_services_finder }
+ let(:function_description) { 'A serverless function' }
+ let(:knative_stub_options) do
+ { namespace: namespace.namespace, name: cluster.project.name, description: function_description }
+ end
let(:namespace) do
create(:cluster_kubernetes_namespace,
@@ -114,40 +118,33 @@ describe Projects::Serverless::FunctionsController do
expect(response).to have_gitlab_http_status(200)
expect(json_response).to include(
- "name" => project.name,
- "url" => "http://#{project.name}.#{namespace.namespace}.example.com",
- "podcount" => 1
+ 'name' => project.name,
+ 'url' => "http://#{project.name}.#{namespace.namespace}.example.com",
+ 'description' => function_description,
+ 'podcount' => 1
)
end
end
- context 'on Knative 0.5' do
+ context 'on Knative 0.5.0' do
+ before do
+ prepare_knative_stubs(knative_05_service(knative_stub_options))
+ end
+
+ include_examples 'GET #show with valid data'
+ end
+
+ context 'on Knative 0.6.0' do
before do
- stub_kubeclient_service_pods
- stub_reactive_cache(knative_services_finder,
- {
- services: kube_knative_services_body(
- legacy_knative: true,
- namespace: namespace.namespace,
- name: cluster.project.name
- )["items"],
- pods: kube_knative_pods_body(cluster.project.name, namespace.namespace)["items"]
- },
- *knative_services_finder.cache_args)
+ prepare_knative_stubs(knative_06_service(knative_stub_options))
end
include_examples 'GET #show with valid data'
end
- context 'on Knative 0.6 or 0.7' do
+ context 'on Knative 0.7.0' do
before do
- stub_kubeclient_service_pods
- stub_reactive_cache(knative_services_finder,
- {
- services: kube_knative_services_body(namespace: namespace.namespace, name: cluster.project.name)["items"],
- pods: kube_knative_pods_body(cluster.project.name, namespace.namespace)["items"]
- },
- *knative_services_finder.cache_args)
+ prepare_knative_stubs(knative_07_service(knative_stub_options))
end
include_examples 'GET #show with valid data'
@@ -172,11 +169,12 @@ describe Projects::Serverless::FunctionsController do
expect(response).to have_gitlab_http_status(200)
expect(json_response).to match({
- "knative_installed" => "checking",
- "functions" => [
+ 'knative_installed' => 'checking',
+ 'functions' => [
a_hash_including(
- "name" => project.name,
- "url" => "http://#{project.name}.#{namespace.namespace}.example.com"
+ 'name' => project.name,
+ 'url' => "http://#{project.name}.#{namespace.namespace}.example.com",
+ 'description' => function_description
)
]
})
@@ -189,36 +187,38 @@ describe Projects::Serverless::FunctionsController do
end
end
- context 'on Knative 0.5' do
+ context 'on Knative 0.5.0' do
before do
- stub_kubeclient_service_pods
- stub_reactive_cache(knative_services_finder,
- {
- services: kube_knative_services_body(
- legacy_knative: true,
- namespace: namespace.namespace,
- name: cluster.project.name
- )["items"],
- pods: kube_knative_pods_body(cluster.project.name, namespace.namespace)["items"]
- },
- *knative_services_finder.cache_args)
+ prepare_knative_stubs(knative_05_service(knative_stub_options))
end
include_examples 'GET #index with data'
end
- context 'on Knative 0.6 or 0.7' do
+ context 'on Knative 0.6.0' do
before do
- stub_kubeclient_service_pods
- stub_reactive_cache(knative_services_finder,
- {
- services: kube_knative_services_body(namespace: namespace.namespace, name: cluster.project.name)["items"],
- pods: kube_knative_pods_body(cluster.project.name, namespace.namespace)["items"]
- },
- *knative_services_finder.cache_args)
+ prepare_knative_stubs(knative_06_service(knative_stub_options))
end
include_examples 'GET #index with data'
end
+
+ context 'on Knative 0.7.0' do
+ before do
+ prepare_knative_stubs(knative_07_service(knative_stub_options))
+ end
+
+ include_examples 'GET #index with data'
+ end
+ end
+
+ def prepare_knative_stubs(knative_service)
+ stub_kubeclient_service_pods
+ stub_reactive_cache(knative_services_finder,
+ {
+ services: [knative_service],
+ pods: kube_knative_pods_body(cluster.project.name, namespace.namespace)["items"]
+ },
+ *knative_services_finder.cache_args)
end
end
diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js
index 62ba0d36982..cef50bf553c 100644
--- a/spec/frontend/api_spec.js
+++ b/spec/frontend/api_spec.js
@@ -467,6 +467,26 @@ describe('Api', () => {
});
});
+ describe('user projects', () => {
+ it('fetches all projects that belong to a particular user', done => {
+ const query = 'dummy query';
+ const options = { unused: 'option' };
+ const userId = '123456';
+ const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users/${userId}/projects`;
+ mock.onGet(expectedUrl).reply(200, [
+ {
+ name: 'test',
+ },
+ ]);
+
+ Api.userProjects(userId, query, options, response => {
+ expect(response.length).toBe(1);
+ expect(response[0].name).toBe('test');
+ done();
+ });
+ });
+ });
+
describe('commitPipelines', () => {
it('fetches pipelines for a given commit', done => {
const projectId = 'example/foobar';
diff --git a/spec/frontend/clusters/clusters_bundle_spec.js b/spec/frontend/clusters/clusters_bundle_spec.js
index 517d8781600..317d3f3012b 100644
--- a/spec/frontend/clusters/clusters_bundle_spec.js
+++ b/spec/frontend/clusters/clusters_bundle_spec.js
@@ -10,8 +10,10 @@ import axios from '~/lib/utils/axios_utils';
import { loadHTMLFixture } from 'helpers/fixtures';
import { setTestTimeout } from 'helpers/timeout';
import $ from 'jquery';
+import initProjectSelectDropdown from '~/project_select';
jest.mock('~/lib/utils/poll');
+jest.mock('~/project_select');
const { INSTALLING, INSTALLABLE, INSTALLED, UNINSTALLING } = APPLICATION_STATUS;
@@ -44,6 +46,7 @@ describe('Clusters', () => {
afterEach(() => {
cluster.destroy();
mock.restore();
+ jest.clearAllMocks();
});
describe('class constructor', () => {
@@ -55,6 +58,10 @@ describe('Clusters', () => {
it('should call initPolling on construct', () => {
expect(cluster.initPolling).toHaveBeenCalled();
});
+
+ it('should call initProjectSelectDropdown on construct', () => {
+ expect(initProjectSelectDropdown).toHaveBeenCalled();
+ });
});
describe('toggle', () => {
diff --git a/spec/frontend/fixtures/static/environments_logs.html b/spec/frontend/fixtures/static/environments_logs.html
index 4e242b77d1f..88bb0a3ed41 100644
--- a/spec/frontend/fixtures/static/environments_logs.html
+++ b/spec/frontend/fixtures/static/environments_logs.html
@@ -2,7 +2,8 @@
class="js-kubernetes-logs"
data-current-environment-name="production"
data-environments-path="/root/my-project/environments.json"
- data-logs-endpoint="/root/my-project/environments/1/logs.json"
+ data-project-full-path="root/my-project"
+ data-environment-id=1
>
<div class="build-page-pod-logs">
<div class="build-trace-container prepend-top-default">
diff --git a/spec/frontend/monitoring/embed/embed_spec.js b/spec/frontend/monitoring/embed/embed_spec.js
index 5de1a7c4c3b..3e22b0858e6 100644
--- a/spec/frontend/monitoring/embed/embed_spec.js
+++ b/spec/frontend/monitoring/embed/embed_spec.js
@@ -61,8 +61,8 @@ describe('Embed', () => {
describe('metrics are available', () => {
beforeEach(() => {
- store.state.monitoringDashboard.groups = groups;
- store.state.monitoringDashboard.groups[0].metrics = metricsData;
+ store.state.monitoringDashboard.dashboard.panel_groups = groups;
+ store.state.monitoringDashboard.dashboard.panel_groups[0].metrics = metricsData;
store.state.monitoringDashboard.metricsWithData = metricsWithData;
mountComponent();
diff --git a/spec/frontend/monitoring/embed/mock_data.js b/spec/frontend/monitoring/embed/mock_data.js
index df4acb82e95..1685021fd4b 100644
--- a/spec/frontend/monitoring/embed/mock_data.js
+++ b/spec/frontend/monitoring/embed/mock_data.js
@@ -81,7 +81,9 @@ export const metricsData = [
export const initialState = {
monitoringDashboard: {},
- groups: [],
+ dashboard: {
+ panel_groups: [],
+ },
metricsWithData: [],
useDashboardEndpoint: true,
};
diff --git a/spec/graphql/mutations/merge_requests/set_milestone_spec.rb b/spec/graphql/mutations/merge_requests/set_milestone_spec.rb
new file mode 100644
index 00000000000..c2792a4bc25
--- /dev/null
+++ b/spec/graphql/mutations/merge_requests/set_milestone_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Mutations::MergeRequests::SetMilestone do
+ let(:merge_request) { create(:merge_request) }
+ let(:user) { create(:user) }
+ subject(:mutation) { described_class.new(object: nil, context: { current_user: user }) }
+
+ describe '#resolve' do
+ let(:milestone) { create(:milestone, project: merge_request.project) }
+ let(:mutated_merge_request) { subject[:merge_request] }
+ subject { mutation.resolve(project_path: merge_request.project.full_path, iid: merge_request.iid, milestone: milestone) }
+
+ it 'raises an error if the resource is not accessible to the user' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+
+ context 'when the user can update the merge request' do
+ before do
+ merge_request.project.add_developer(user)
+ end
+
+ it 'returns the merge request with the milestone' do
+ expect(mutated_merge_request).to eq(merge_request)
+ expect(mutated_merge_request.milestone).to eq(milestone)
+ expect(subject[:errors]).to be_empty
+ end
+
+ it 'returns errors merge request could not be updated' do
+ # Make the merge request invalid
+ merge_request.allow_broken = true
+ merge_request.update!(source_project: nil)
+
+ expect(subject[:errors]).not_to be_empty
+ end
+
+ context 'when passing milestone_id as nil' do
+ let(:milestone) { nil }
+
+ it 'removes the milestone' do
+ merge_request.update!(milestone: create(:milestone, project: merge_request.project))
+
+ expect(mutated_merge_request.milestone).to eq(nil)
+ end
+
+ it 'does not do anything if the MR already does not have a milestone' do
+ expect(mutated_merge_request.milestone).to eq(nil)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/javascripts/monitoring/charts/time_series_spec.js b/spec/javascripts/monitoring/charts/time_series_spec.js
index 31ea9ede9de..42feaca616b 100644
--- a/spec/javascripts/monitoring/charts/time_series_spec.js
+++ b/spec/javascripts/monitoring/charts/time_series_spec.js
@@ -23,7 +23,7 @@ describe('Time series component', () => {
store = createStore();
store.commit(`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`, MonitoringMock.data);
store.commit(`monitoringDashboard/${types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS}`, deploymentData);
- [mockGraphData] = store.state.monitoringDashboard.groups[0].metrics;
+ [, mockGraphData] = store.state.monitoringDashboard.dashboard.panel_groups[0].metrics;
makeTimeSeriesChart = (graphData, type) =>
shallowMount(TimeSeries, {
diff --git a/spec/javascripts/monitoring/components/dashboard_spec.js b/spec/javascripts/monitoring/components/dashboard_spec.js
index be7ab24185d..4070de4cc35 100644
--- a/spec/javascripts/monitoring/components/dashboard_spec.js
+++ b/spec/javascripts/monitoring/components/dashboard_spec.js
@@ -442,6 +442,28 @@ describe('Dashboard', () => {
expect(findEnabledDraggables()).toEqual(findDraggables());
});
+ it('metrics can be swapped', done => {
+ const firstDraggable = findDraggables().at(0);
+ const mockMetrics = [...metricsGroupsAPIResponse.data[0].metrics];
+ const value = () => firstDraggable.props('value');
+
+ expect(value().length).toBe(mockMetrics.length);
+ value().forEach((metric, i) => {
+ expect(metric.title).toBe(mockMetrics[i].title);
+ });
+
+ // swap two elements and `input` them
+ [mockMetrics[0], mockMetrics[1]] = [mockMetrics[1], mockMetrics[0]];
+ firstDraggable.vm.$emit('input', mockMetrics);
+
+ firstDraggable.vm.$nextTick(() => {
+ value().forEach((metric, i) => {
+ expect(metric.title).toBe(mockMetrics[i].title);
+ });
+ done();
+ });
+ });
+
it('shows a remove button, which removes a panel', done => {
expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false);
@@ -449,8 +471,6 @@ describe('Dashboard', () => {
findFirstDraggableRemoveButton().trigger('click');
wrapper.vm.$nextTick(() => {
- // At present graphs will not be removed in backend
- // See https://gitlab.com/gitlab-org/gitlab/issues/27835
expect(findDraggablePanels().length).toEqual(expectedPanelCount - 1);
done();
});
@@ -686,7 +706,9 @@ describe('Dashboard', () => {
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
MonitoringMock.data,
);
- [mockGraphData] = component.$store.state.monitoringDashboard.groups[0].metrics;
+ [
+ mockGraphData,
+ ] = component.$store.state.monitoringDashboard.dashboard.panel_groups[0].metrics;
});
describe('csvText', () => {
diff --git a/spec/javascripts/monitoring/store/actions_spec.js b/spec/javascripts/monitoring/store/actions_spec.js
index 1bd74f59282..4d602e3b0a2 100644
--- a/spec/javascripts/monitoring/store/actions_spec.js
+++ b/spec/javascripts/monitoring/store/actions_spec.js
@@ -291,9 +291,9 @@ describe('Monitoring store actions', () => {
it('dispatches fetchPrometheusMetric for each panel query', done => {
const params = {};
const state = storeState();
- state.groups = metricsDashboardResponse.dashboard.panel_groups;
+ state.dashboard.panel_groups = metricsDashboardResponse.dashboard.panel_groups;
- const metric = state.groups[0].panels[0].metrics[0];
+ const metric = state.dashboard.panel_groups[0].panels[0].metrics[0];
fetchPrometheusMetrics({ state, commit, dispatch }, params)
.then(() => {
diff --git a/spec/javascripts/monitoring/store/mutations_spec.js b/spec/javascripts/monitoring/store/mutations_spec.js
index bdddd83358c..49aed1b85e6 100644
--- a/spec/javascripts/monitoring/store/mutations_spec.js
+++ b/spec/javascripts/monitoring/store/mutations_spec.js
@@ -20,16 +20,26 @@ describe('Monitoring mutations', () => {
let groups;
beforeEach(() => {
- stateCopy.groups = [];
+ stateCopy.dashboard.panel_groups = [];
groups = metricsGroupsAPIResponse.data;
});
+ it('adds a key to the group', () => {
+ mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
+
+ expect(stateCopy.dashboard.panel_groups[0].key).toBe('kubernetes-0');
+ expect(stateCopy.dashboard.panel_groups[1].key).toBe('nginx-1');
+ });
+
it('normalizes values', () => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
const expectedTimestamp = '2017-05-25T08:22:34.925Z';
- const expectedValue = 0.0010794445585559514;
- const [timestamp, value] = stateCopy.groups[0].metrics[0].queries[0].result[0].values[0];
+ const expectedValue = 8.0390625;
+ const [
+ timestamp,
+ value,
+ ] = stateCopy.dashboard.panel_groups[0].metrics[0].queries[0].result[0].values[0];
expect(timestamp).toEqual(expectedTimestamp);
expect(value).toEqual(expectedValue);
@@ -38,25 +48,25 @@ describe('Monitoring mutations', () => {
it('contains two groups that contains, one of which has two queries sorted by priority', () => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
- expect(stateCopy.groups).toBeDefined();
- expect(stateCopy.groups.length).toEqual(2);
- expect(stateCopy.groups[0].metrics.length).toEqual(2);
+ expect(stateCopy.dashboard.panel_groups).toBeDefined();
+ expect(stateCopy.dashboard.panel_groups.length).toEqual(2);
+ expect(stateCopy.dashboard.panel_groups[0].metrics.length).toEqual(2);
});
it('assigns queries a metric id', () => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
- expect(stateCopy.groups[1].metrics[0].queries[0].metricId).toEqual('100');
+ expect(stateCopy.dashboard.panel_groups[1].metrics[0].queries[0].metricId).toEqual('100');
});
it('removes the data if all the values from a query are not defined', () => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
- expect(stateCopy.groups[1].metrics[0].queries[0].result.length).toEqual(0);
+ expect(stateCopy.dashboard.panel_groups[1].metrics[0].queries[0].result.length).toEqual(0);
});
it('assigns metric id of null if metric has no id', () => {
- stateCopy.groups = [];
+ stateCopy.dashboard.panel_groups = [];
const noId = groups.map(group => ({
...group,
...{
@@ -70,7 +80,7 @@ describe('Monitoring mutations', () => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, noId);
- stateCopy.groups.forEach(group => {
+ stateCopy.dashboard.panel_groups.forEach(group => {
group.metrics.forEach(metric => {
expect(metric.queries.every(query => query.metricId === null)).toBe(true);
});
@@ -87,13 +97,13 @@ describe('Monitoring mutations', () => {
it('aliases group panels to metrics for backwards compatibility', () => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
- expect(stateCopy.groups[0].metrics[0]).toBeDefined();
+ expect(stateCopy.dashboard.panel_groups[0].metrics[0]).toBeDefined();
});
it('aliases panel metrics to queries for backwards compatibility', () => {
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
- expect(stateCopy.groups[0].metrics[0].queries).toBeDefined();
+ expect(stateCopy.dashboard.panel_groups[0].metrics[0].queries).toBeDefined();
});
});
});
diff --git a/spec/lib/gitlab/prometheus/internal_spec.rb b/spec/lib/gitlab/prometheus/internal_spec.rb
new file mode 100644
index 00000000000..884bdcb4e9b
--- /dev/null
+++ b/spec/lib/gitlab/prometheus/internal_spec.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Prometheus::Internal do
+ let(:listen_address) { 'localhost:9090' }
+
+ let(:prometheus_settings) do
+ {
+ enable: true,
+ listen_address: listen_address
+ }
+ end
+
+ before do
+ stub_config(prometheus: prometheus_settings)
+ end
+
+ describe '.uri' do
+ shared_examples 'returns valid uri' do |uri_string|
+ it do
+ expect(described_class.uri).to eq(uri_string)
+ expect { Addressable::URI.parse(described_class.uri) }.not_to raise_error
+ end
+ end
+
+ it_behaves_like 'returns valid uri', 'http://localhost:9090'
+
+ context 'with non default prometheus address' do
+ let(:listen_address) { 'https://localhost:9090' }
+
+ it_behaves_like 'returns valid uri', 'https://localhost:9090'
+
+ context 'with :9090 symbol' do
+ let(:listen_address) { :':9090' }
+
+ it_behaves_like 'returns valid uri', 'http://localhost:9090'
+ end
+
+ context 'with 0.0.0.0:9090' do
+ let(:listen_address) { '0.0.0.0:9090' }
+
+ it_behaves_like 'returns valid uri', 'http://localhost:9090'
+ end
+ end
+
+ context 'when listen_address is nil' do
+ let(:listen_address) { nil }
+
+ it 'does not fail' do
+ expect(described_class.uri).to eq(nil)
+ end
+ end
+
+ context 'when prometheus listen address is blank in gitlab.yml' do
+ let(:listen_address) { '' }
+
+ it 'does not configure prometheus' do
+ expect(described_class.uri).to eq(nil)
+ end
+ end
+ end
+
+ describe 'prometheus_enabled?' do
+ it 'returns correct value' do
+ expect(described_class.prometheus_enabled?).to eq(true)
+ end
+
+ context 'when prometheus setting is disabled in gitlab.yml' do
+ let(:prometheus_settings) do
+ {
+ enable: false,
+ listen_address: listen_address
+ }
+ end
+
+ it 'returns correct value' do
+ expect(described_class.prometheus_enabled?).to eq(false)
+ end
+ end
+
+ context 'when prometheus setting is not present in gitlab.yml' do
+ before do
+ allow(Gitlab.config).to receive(:prometheus).and_raise(Settingslogic::MissingSetting)
+ end
+
+ it 'does not fail' do
+ expect(described_class.prometheus_enabled?).to eq(false)
+ end
+ end
+ end
+
+ describe '.listen_address' do
+ it 'returns correct value' do
+ expect(described_class.listen_address).to eq(listen_address)
+ end
+
+ context 'when prometheus setting is not present in gitlab.yml' do
+ before do
+ allow(Gitlab.config).to receive(:prometheus).and_raise(Settingslogic::MissingSetting)
+ end
+
+ it 'does not fail' do
+ expect(described_class.listen_address).to eq(nil)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb b/spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb
new file mode 100644
index 00000000000..bd558edf9c5
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Setting milestone of a merge request' do
+ include GraphqlHelpers
+
+ let(:current_user) { create(:user) }
+ let(:merge_request) { create(:merge_request) }
+ let(:project) { merge_request.project }
+ let(:milestone) { create(:milestone, project: project) }
+ let(:input) { { milestone_id: GitlabSchema.id_from_object(milestone).to_s } }
+
+ let(:mutation) do
+ variables = {
+ project_path: project.full_path,
+ iid: merge_request.iid.to_s
+ }
+ graphql_mutation(:merge_request_set_milestone, variables.merge(input),
+ <<-QL.strip_heredoc
+ clientMutationId
+ errors
+ mergeRequest {
+ id
+ milestone {
+ id
+ }
+ }
+ QL
+ )
+ end
+
+ def mutation_response
+ graphql_mutation_response(:merge_request_set_milestone)
+ end
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'returns an error if the user is not allowed to update the merge request' do
+ post_graphql_mutation(mutation, current_user: create(:user))
+
+ expect(graphql_errors).not_to be_empty
+ end
+
+ it 'sets the merge request milestone' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['mergeRequest']['milestone']['id']).to eq(milestone.to_global_id.to_s)
+ end
+
+ context 'when passing milestone_id nil as input' do
+ let(:input) { { milestone_id: nil } }
+
+ it 'removes the merge request milestone' do
+ merge_request.update!(milestone: milestone)
+
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(mutation_response['mergeRequest']['milestone']).to be_nil
+ end
+ end
+end
diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb
index e74dbca4f93..199156c53d7 100644
--- a/spec/support/helpers/kubernetes_helpers.rb
+++ b/spec/support/helpers/kubernetes_helpers.rb
@@ -319,10 +319,10 @@ module KubernetesHelpers
}
end
- def kube_knative_services_body(legacy_knative: false, **options)
+ def kube_knative_services_body(**options)
{
"kind" => "List",
- "items" => [legacy_knative ? knative_05_service(options) : kube_service(options)]
+ "items" => [knative_07_service(options)]
}
end
@@ -398,77 +398,171 @@ module KubernetesHelpers
}
end
- def kube_service(name: "kubetest", namespace: "default", domain: "example.com")
- {
- "metadata" => {
- "creationTimestamp" => "2018-11-21T06:16:33Z",
- "name" => name,
- "namespace" => namespace,
- "selfLink" => "/apis/serving.knative.dev/v1alpha1/namespaces/#{namespace}/services/#{name}"
- },
+ # noinspection RubyStringKeysInHashInspection
+ def knative_06_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production')
+ { "apiVersion" => "serving.knative.dev/v1alpha1",
+ "kind" => "Service",
+ "metadata" =>
+ { "annotations" =>
+ { "serving.knative.dev/creator" => "system:serviceaccount:#{namespace}:#{namespace}-service-account",
+ "serving.knative.dev/lastModifier" => "system:serviceaccount:#{namespace}:#{namespace}-service-account" },
+ "creationTimestamp" => "2019-10-22T21:19:20Z",
+ "generation" => 1,
+ "labels" => { "service" => name },
+ "name" => name,
+ "namespace" => namespace,
+ "resourceVersion" => "6042",
+ "selfLink" => "/apis/serving.knative.dev/v1alpha1/namespaces/#{namespace}/services/#{name}",
+ "uid" => "9c7f63d0-f511-11e9-8815-42010a80002f" },
"spec" => {
- "generation" => 2
+ "runLatest" => {
+ "configuration" => {
+ "revisionTemplate" => {
+ "metadata" => {
+ "annotations" => { "Description" => description },
+ "creationTimestamp" => "2019-10-22T21:19:20Z",
+ "labels" => { "service" => name }
+ },
+ "spec" => {
+ "container" => {
+ "env" => [{ "name" => "timestamp", "value" => "2019-10-22 21:19:20" }],
+ "image" => "image_name",
+ "name" => "",
+ "resources" => {}
+ },
+ "timeoutSeconds" => 300
+ }
+ }
+ }
+ }
},
"status" => {
- "url" => "http://#{name}.#{namespace}.#{domain}",
"address" => {
- "url" => "#{name}.#{namespace}.svc.cluster.local"
+ "hostname" => "#{name}.#{namespace}.svc.cluster.local",
+ "url" => "http://#{name}.#{namespace}.svc.cluster.local"
},
- "latestCreatedRevisionName" => "#{name}-00002",
- "latestReadyRevisionName" => "#{name}-00002",
- "observedGeneration" => 2
- }
- }
- end
-
- def knative_05_service(name: "kubetest", namespace: "default", domain: "example.com")
- {
- "metadata" => {
- "creationTimestamp" => "2018-11-21T06:16:33Z",
- "name" => name,
- "namespace" => namespace,
- "selfLink" => "/apis/serving.knative.dev/v1alpha1/namespaces/#{namespace}/services/#{name}"
- },
- "spec" => {
- "generation" => 2
- },
- "status" => {
+ "conditions" =>
+ [{ "lastTransitionTime" => "2019-10-22T21:20:25Z", "status" => "True", "type" => "ConfigurationsReady" },
+ { "lastTransitionTime" => "2019-10-22T21:20:25Z", "status" => "True", "type" => "Ready" },
+ { "lastTransitionTime" => "2019-10-22T21:20:25Z", "status" => "True", "type" => "RoutesReady" }],
"domain" => "#{name}.#{namespace}.#{domain}",
"domainInternal" => "#{name}.#{namespace}.svc.cluster.local",
- "latestCreatedRevisionName" => "#{name}-00002",
- "latestReadyRevisionName" => "#{name}-00002",
- "observedGeneration" => 2
- }
- }
- end
-
- def kube_service_full(name: "kubetest", namespace: "kube-ns", domain: "example.com")
- {
- "metadata" => {
- "creationTimestamp" => "2018-11-21T06:16:33Z",
- "name" => name,
- "namespace" => namespace,
- "selfLink" => "/apis/serving.knative.dev/v1alpha1/namespaces/#{namespace}/services/#{name}",
- "annotation" => {
- "description" => "This is a test description"
- }
+ "latestCreatedRevisionName" => "#{name}-bskx6",
+ "latestReadyRevisionName" => "#{name}-bskx6",
+ "observedGeneration" => 1,
+ "traffic" => [{ "latestRevision" => true, "percent" => 100, "revisionName" => "#{name}-bskx6" }],
+ "url" => "http://#{name}.#{namespace}.#{domain}"
},
+ "environment_scope" => environment,
+ "cluster_id" => 9,
+ "podcount" => 0 }
+ end
+
+ # noinspection RubyStringKeysInHashInspection
+ def knative_07_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production')
+ { "apiVersion" => "serving.knative.dev/v1alpha1",
+ "kind" => "Service",
+ "metadata" =>
+ { "annotations" =>
+ { "serving.knative.dev/creator" => "system:serviceaccount:#{namespace}:#{namespace}-service-account",
+ "serving.knative.dev/lastModifier" => "system:serviceaccount:#{namespace}:#{namespace}-service-account" },
+ "creationTimestamp" => "2019-10-22T21:19:13Z",
+ "generation" => 1,
+ "labels" => { "service" => name },
+ "name" => name,
+ "namespace" => namespace,
+ "resourceVersion" => "289726",
+ "selfLink" => "/apis/serving.knative.dev/v1alpha1/namespaces/#{namespace}/services/#{name}",
+ "uid" => "988349fa-f511-11e9-9ea1-42010a80005e" },
"spec" => {
- "generation" => 2,
- "build" => {
- "template" => "go-1.10.3"
+ "template" => {
+ "metadata" => {
+ "annotations" => { "Description" => description },
+ "creationTimestamp" => "2019-10-22T21:19:12Z",
+ "labels" => { "service" => name }
+ },
+ "spec" => {
+ "containers" => [{
+ "env" =>
+ [{ "name" => "timestamp", "value" => "2019-10-22 21:19:12" }],
+ "image" => "image_name",
+ "name" => "user-container",
+ "resources" => {}
+ }],
+ "timeoutSeconds" => 300
+ }
+ },
+ "traffic" => [{ "latestRevision" => true, "percent" => 100 }]
+ },
+ "status" =>
+ { "address" => { "url" => "http://#{name}.#{namespace}.svc.cluster.local" },
+ "conditions" =>
+ [{ "lastTransitionTime" => "2019-10-22T21:20:15Z", "status" => "True", "type" => "ConfigurationsReady" },
+ { "lastTransitionTime" => "2019-10-22T21:20:15Z", "status" => "True", "type" => "Ready" },
+ { "lastTransitionTime" => "2019-10-22T21:20:15Z", "status" => "True", "type" => "RoutesReady" }],
+ "latestCreatedRevisionName" => "#{name}-92tsj",
+ "latestReadyRevisionName" => "#{name}-92tsj",
+ "observedGeneration" => 1,
+ "traffic" => [{ "latestRevision" => true, "percent" => 100, "revisionName" => "#{name}-92tsj" }],
+ "url" => "http://#{name}.#{namespace}.#{domain}" },
+ "environment_scope" => environment,
+ "cluster_id" => 5,
+ "podcount" => 0 }
+ end
+
+ # noinspection RubyStringKeysInHashInspection
+ def knative_05_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production')
+ { "apiVersion" => "serving.knative.dev/v1alpha1",
+ "kind" => "Service",
+ "metadata" =>
+ { "annotations" =>
+ { "serving.knative.dev/creator" => "system:serviceaccount:#{namespace}:#{namespace}-service-account",
+ "serving.knative.dev/lastModifier" => "system:serviceaccount:#{namespace}:#{namespace}-service-account" },
+ "creationTimestamp" => "2019-10-22T21:19:19Z",
+ "generation" => 1,
+ "labels" => { "service" => name },
+ "name" => name,
+ "namespace" => namespace,
+ "resourceVersion" => "330390",
+ "selfLink" => "/apis/serving.knative.dev/v1alpha1/namespaces/#{namespace}/services/#{name}",
+ "uid" => "9c710da6-f511-11e9-9ba0-42010a800161" },
+ "spec" => {
+ "runLatest" => {
+ "configuration" => {
+ "revisionTemplate" => {
+ "metadata" => {
+ "annotations" => { "Description" => description },
+ "creationTimestamp" => "2019-10-22T21:19:19Z",
+ "labels" => { "service" => name }
+ },
+ "spec" => {
+ "container" => {
+ "env" => [{ "name" => "timestamp", "value" => "2019-10-22 21:19:19" }],
+ "image" => "image_name",
+ "name" => "",
+ "resources" => { "requests" => { "cpu" => "400m" } }
+ },
+ "timeoutSeconds" => 300
+ }
+ }
+ }
}
},
- "status" => {
- "url" => "http://#{name}.#{namespace}.#{domain}",
- "address" => {
- "url" => "#{name}.#{namespace}.svc.cluster.local"
- },
- "latestCreatedRevisionName" => "#{name}-00002",
- "latestReadyRevisionName" => "#{name}-00002",
- "observedGeneration" => 2
- }
- }
+ "status" =>
+ { "address" => { "hostname" => "#{name}.#{namespace}.svc.cluster.local" },
+ "conditions" =>
+ [{ "lastTransitionTime" => "2019-10-22T21:20:24Z", "status" => "True", "type" => "ConfigurationsReady" },
+ { "lastTransitionTime" => "2019-10-22T21:20:24Z", "status" => "True", "type" => "Ready" },
+ { "lastTransitionTime" => "2019-10-22T21:20:24Z", "status" => "True", "type" => "RoutesReady" }],
+ "domain" => "#{name}.#{namespace}.#{domain}",
+ "domainInternal" => "#{name}.#{namespace}.svc.cluster.local",
+ "latestCreatedRevisionName" => "#{name}-58qgr",
+ "latestReadyRevisionName" => "#{name}-58qgr",
+ "observedGeneration" => 1,
+ "traffic" => [{ "percent" => 100, "revisionName" => "#{name}-58qgr" }] },
+ "environment_scope" => environment,
+ "cluster_id" => 8,
+ "podcount" => 0 }
end
def kube_terminals(service, pod)