diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-04 12:06:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-04 12:06:21 +0300 |
commit | 2b7a5214342baa2575b35868316ea9413d2afe1f (patch) | |
tree | f80a862f7fa382620b8f8a695d07b6d1734fc5f5 /spec | |
parent | 15a2d004be2f79160752d77f701c0f08e7f96973 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/projects/serverless/functions_controller_spec.rb | 94 | ||||
-rw-r--r-- | spec/frontend/api_spec.js | 20 | ||||
-rw-r--r-- | spec/frontend/clusters/clusters_bundle_spec.js | 7 | ||||
-rw-r--r-- | spec/frontend/fixtures/static/environments_logs.html | 3 | ||||
-rw-r--r-- | spec/frontend/monitoring/embed/embed_spec.js | 4 | ||||
-rw-r--r-- | spec/frontend/monitoring/embed/mock_data.js | 4 | ||||
-rw-r--r-- | spec/graphql/mutations/merge_requests/set_milestone_spec.rb | 53 | ||||
-rw-r--r-- | spec/javascripts/monitoring/charts/time_series_spec.js | 2 | ||||
-rw-r--r-- | spec/javascripts/monitoring/components/dashboard_spec.js | 28 | ||||
-rw-r--r-- | spec/javascripts/monitoring/store/actions_spec.js | 4 | ||||
-rw-r--r-- | spec/javascripts/monitoring/store/mutations_spec.js | 34 | ||||
-rw-r--r-- | spec/lib/gitlab/prometheus/internal_spec.rb | 108 | ||||
-rw-r--r-- | spec/requests/api/graphql/mutations/merge_requests/set_milestone_spec.rb | 66 | ||||
-rw-r--r-- | spec/support/helpers/kubernetes_helpers.rb | 218 |
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) |