Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
3318518149
commit
57e3d49fc0
|
@ -11,7 +11,7 @@ import {
|
||||||
GlModalDirective,
|
GlModalDirective,
|
||||||
GlTooltipDirective,
|
GlTooltipDirective,
|
||||||
} from '@gitlab/ui';
|
} from '@gitlab/ui';
|
||||||
import { __, s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import Icon from '~/vue_shared/components/icon.vue';
|
import Icon from '~/vue_shared/components/icon.vue';
|
||||||
import { getParameterValues, mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
|
import { getParameterValues, mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
|
||||||
|
@ -167,6 +167,7 @@ export default {
|
||||||
formIsValid: null,
|
formIsValid: null,
|
||||||
selectedTimeWindow: {},
|
selectedTimeWindow: {},
|
||||||
isRearrangingPanels: false,
|
isRearrangingPanels: false,
|
||||||
|
hasValidDates: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -185,7 +186,9 @@ export default {
|
||||||
'additionalPanelTypesEnabled',
|
'additionalPanelTypesEnabled',
|
||||||
]),
|
]),
|
||||||
firstDashboard() {
|
firstDashboard() {
|
||||||
return this.allDashboards[0] || {};
|
return this.environmentsEndpoint.length > 0 && this.allDashboards.length > 0
|
||||||
|
? this.allDashboards[0]
|
||||||
|
: {};
|
||||||
},
|
},
|
||||||
selectedDashboard() {
|
selectedDashboard() {
|
||||||
return this.allDashboards.find(d => d.path === this.currentDashboard) || this.firstDashboard;
|
return this.allDashboards.find(d => d.path === this.currentDashboard) || this.firstDashboard;
|
||||||
|
@ -199,9 +202,6 @@ export default {
|
||||||
addingMetricsAvailable() {
|
addingMetricsAvailable() {
|
||||||
return IS_EE && this.canAddMetrics && !this.showEmptyState;
|
return IS_EE && this.canAddMetrics && !this.showEmptyState;
|
||||||
},
|
},
|
||||||
alertWidgetAvailable() {
|
|
||||||
return IS_EE && this.prometheusAlertsAvailable && this.alertsEndpoint;
|
|
||||||
},
|
|
||||||
hasHeaderButtons() {
|
hasHeaderButtons() {
|
||||||
return (
|
return (
|
||||||
this.addingMetricsAvailable ||
|
this.addingMetricsAvailable ||
|
||||||
|
@ -237,8 +237,10 @@ export default {
|
||||||
this.selectedTimeWindow = range;
|
this.selectedTimeWindow = range;
|
||||||
|
|
||||||
if (!isValidDate(start) || !isValidDate(end)) {
|
if (!isValidDate(start) || !isValidDate(end)) {
|
||||||
|
this.hasValidDates = false;
|
||||||
this.showInvalidDateError();
|
this.showInvalidDateError();
|
||||||
} else {
|
} else {
|
||||||
|
this.hasValidDates = true;
|
||||||
this.fetchData(range);
|
this.fetchData(range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,44 +250,13 @@ export default {
|
||||||
'fetchData',
|
'fetchData',
|
||||||
'setGettingStartedEmptyState',
|
'setGettingStartedEmptyState',
|
||||||
'setEndpoints',
|
'setEndpoints',
|
||||||
'setDashboardEnabled',
|
|
||||||
'setPanelGroupMetrics',
|
'setPanelGroupMetrics',
|
||||||
]),
|
]),
|
||||||
chartsWithData(charts) {
|
chartsWithData(charts) {
|
||||||
if (!this.useDashboardEndpoint) {
|
|
||||||
return charts;
|
|
||||||
}
|
|
||||||
return charts.filter(chart =>
|
return charts.filter(chart =>
|
||||||
chart.metrics.some(metric => this.metricsWithData.includes(metric.metric_id)),
|
chart.metrics.some(metric => this.metricsWithData.includes(metric.metric_id)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
csvText(graphData) {
|
|
||||||
const chartData = graphData.queries[0].result[0].values;
|
|
||||||
const yLabel = graphData.y_label;
|
|
||||||
const header = `timestamp,${yLabel}\r\n`; // eslint-disable-line @gitlab/i18n/no-non-i18n-strings
|
|
||||||
return chartData.reduce((csv, data) => {
|
|
||||||
const row = data.join(',');
|
|
||||||
return `${csv}${row}\r\n`;
|
|
||||||
}, header);
|
|
||||||
},
|
|
||||||
downloadCsv(graphData) {
|
|
||||||
const data = new Blob([this.csvText(graphData)], { type: 'text/plain' });
|
|
||||||
return window.URL.createObjectURL(data);
|
|
||||||
},
|
|
||||||
// TODO: BEGIN, Duplicated code with panel_type until feature flag is removed
|
|
||||||
// Issue number: https://gitlab.com/gitlab-org/gitlab-foss/issues/63845
|
|
||||||
getGraphAlerts(queries) {
|
|
||||||
if (!this.allAlerts) return {};
|
|
||||||
const metricIdsForChart = queries.map(q => q.metricId);
|
|
||||||
return _.pick(this.allAlerts, alert => metricIdsForChart.includes(alert.metricId));
|
|
||||||
},
|
|
||||||
getGraphAlertValues(queries) {
|
|
||||||
return Object.values(this.getGraphAlerts(queries));
|
|
||||||
},
|
|
||||||
showToast() {
|
|
||||||
this.$toast.show(__('Link copied'));
|
|
||||||
},
|
|
||||||
// TODO: END
|
|
||||||
updateMetrics(key, metrics) {
|
updateMetrics(key, metrics) {
|
||||||
this.setPanelGroupMetrics({
|
this.setPanelGroupMetrics({
|
||||||
metrics,
|
metrics,
|
||||||
|
@ -298,6 +269,11 @@ export default {
|
||||||
key,
|
key,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
removeGraph(metrics, graphIndex) {
|
||||||
|
// At present graphs will not be removed, they should removed using the vuex store
|
||||||
|
// See https://gitlab.com/gitlab-org/gitlab/issues/27835
|
||||||
|
metrics.splice(graphIndex, 1);
|
||||||
|
},
|
||||||
showInvalidDateError() {
|
showInvalidDateError() {
|
||||||
createFlash(s__('Metrics|Link contains an invalid time window.'));
|
createFlash(s__('Metrics|Link contains an invalid time window.'));
|
||||||
},
|
},
|
||||||
|
@ -387,7 +363,7 @@ export default {
|
||||||
</gl-form-group>
|
</gl-form-group>
|
||||||
|
|
||||||
<gl-form-group
|
<gl-form-group
|
||||||
v-if="!showEmptyState"
|
v-if="hasValidDates"
|
||||||
:label="s__('Metrics|Show last')"
|
:label="s__('Metrics|Show last')"
|
||||||
label-size="sm"
|
label-size="sm"
|
||||||
label-for="monitor-time-window-dropdown"
|
label-for="monitor-time-window-dropdown"
|
||||||
|
@ -480,7 +456,6 @@ export default {
|
||||||
:show-panels="showPanels"
|
:show-panels="showPanels"
|
||||||
:collapse-group="groupHasData(groupData)"
|
:collapse-group="groupHasData(groupData)"
|
||||||
>
|
>
|
||||||
<template v-if="additionalPanelTypesEnabled">
|
|
||||||
<vue-draggable
|
<vue-draggable
|
||||||
:value="groupData.metrics"
|
:value="groupData.metrics"
|
||||||
group="metrics-dashboard"
|
group="metrics-dashboard"
|
||||||
|
@ -498,7 +473,7 @@ export default {
|
||||||
<div
|
<div
|
||||||
v-if="isRearrangingPanels"
|
v-if="isRearrangingPanels"
|
||||||
class="draggable-remove js-draggable-remove p-2 w-100 position-absolute d-flex justify-content-end"
|
class="draggable-remove js-draggable-remove p-2 w-100 position-absolute d-flex justify-content-end"
|
||||||
@click="removeMetric(groupData.key, groupData.metrics, graphIndex)"
|
@click="removeGraph(groupData.metrics, graphIndex)"
|
||||||
>
|
>
|
||||||
<a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')"
|
<a class="mx-2 p-2 draggable-remove-link" :aria-label="__('Remove')"
|
||||||
><icon name="close"
|
><icon name="close"
|
||||||
|
@ -506,9 +481,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<panel-type
|
<panel-type
|
||||||
:clipboard-text="
|
:clipboard-text="generateLink(groupData.group, graphData.title, graphData.y_label)"
|
||||||
generateLink(groupData.group, graphData.title, graphData.y_label)
|
|
||||||
"
|
|
||||||
:graph-data="graphData"
|
:graph-data="graphData"
|
||||||
:alerts-endpoint="alertsEndpoint"
|
:alerts-endpoint="alertsEndpoint"
|
||||||
:prometheus-alerts-available="prometheusAlertsAvailable"
|
:prometheus-alerts-available="prometheusAlertsAvailable"
|
||||||
|
@ -517,72 +490,6 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</vue-draggable>
|
</vue-draggable>
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<monitor-time-series-chart
|
|
||||||
v-for="(graphData, graphIndex) in chartsWithData(groupData.metrics)"
|
|
||||||
:key="graphIndex"
|
|
||||||
class="col-12 col-lg-6 pb-3"
|
|
||||||
:graph-data="graphData"
|
|
||||||
:deployment-data="deploymentData"
|
|
||||||
:thresholds="getGraphAlertValues(graphData.queries)"
|
|
||||||
:project-path="projectPath"
|
|
||||||
group-id="monitor-time-series-chart"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="d-flex align-items-center"
|
|
||||||
:class="alertWidgetAvailable ? 'justify-content-between' : 'justify-content-end'"
|
|
||||||
>
|
|
||||||
<alert-widget
|
|
||||||
v-if="alertWidgetAvailable && graphData"
|
|
||||||
:modal-id="`alert-modal-${index}-${graphIndex}`"
|
|
||||||
:alerts-endpoint="alertsEndpoint"
|
|
||||||
:relevant-queries="graphData.queries"
|
|
||||||
:alerts-to-manage="getGraphAlerts(graphData.queries)"
|
|
||||||
@setAlerts="setAlerts"
|
|
||||||
/>
|
|
||||||
<gl-dropdown
|
|
||||||
v-gl-tooltip
|
|
||||||
class="ml-2 mr-3"
|
|
||||||
toggle-class="btn btn-transparent border-0"
|
|
||||||
:right="true"
|
|
||||||
:no-caret="true"
|
|
||||||
:title="__('More actions')"
|
|
||||||
>
|
|
||||||
<template slot="button-content">
|
|
||||||
<icon name="ellipsis_v" class="text-secondary" />
|
|
||||||
</template>
|
|
||||||
<gl-dropdown-item
|
|
||||||
v-track-event="downloadCSVOptions(graphData.title)"
|
|
||||||
:href="downloadCsv(graphData)"
|
|
||||||
download="chart_metrics.csv"
|
|
||||||
>
|
|
||||||
{{ __('Download CSV') }}
|
|
||||||
</gl-dropdown-item>
|
|
||||||
<gl-dropdown-item
|
|
||||||
v-track-event="
|
|
||||||
generateLinkToChartOptions(
|
|
||||||
generateLink(groupData.group, graphData.title, graphData.y_label),
|
|
||||||
)
|
|
||||||
"
|
|
||||||
class="js-chart-link"
|
|
||||||
:data-clipboard-text="
|
|
||||||
generateLink(groupData.group, graphData.title, graphData.y_label)
|
|
||||||
"
|
|
||||||
@click="showToast"
|
|
||||||
>
|
|
||||||
{{ __('Generate link to chart') }}
|
|
||||||
</gl-dropdown-item>
|
|
||||||
<gl-dropdown-item
|
|
||||||
v-if="alertWidgetAvailable"
|
|
||||||
v-gl-modal="`alert-modal-${index}-${graphIndex}`"
|
|
||||||
>
|
|
||||||
{{ __('Alerts') }}
|
|
||||||
</gl-dropdown-item>
|
|
||||||
</gl-dropdown>
|
|
||||||
</div>
|
|
||||||
</monitor-time-series-chart>
|
|
||||||
</template>
|
|
||||||
</graph-group>
|
</graph-group>
|
||||||
</div>
|
</div>
|
||||||
<empty-state
|
<empty-state
|
||||||
|
|
|
@ -56,16 +56,10 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
const range = getTimeWindow(this.selectedTimeWindow);
|
this.verifyTimeRange();
|
||||||
if (range) {
|
},
|
||||||
this.selectedTimeWindowText = this.timeWindows[range];
|
updated() {
|
||||||
} else {
|
this.verifyTimeRange();
|
||||||
this.customTime = {
|
|
||||||
from: truncateZerosInDateTime(ISODateToString(this.selectedTimeWindow.start)),
|
|
||||||
to: truncateZerosInDateTime(ISODateToString(this.selectedTimeWindow.end)),
|
|
||||||
};
|
|
||||||
this.selectedTimeWindowText = sprintf(s__('%{from} to %{to}'), this.customTime);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
activeTimeWindow(key) {
|
activeTimeWindow(key) {
|
||||||
|
@ -87,6 +81,18 @@ export default {
|
||||||
closeDropdown() {
|
closeDropdown() {
|
||||||
this.$refs.dropdown.hide();
|
this.$refs.dropdown.hide();
|
||||||
},
|
},
|
||||||
|
verifyTimeRange() {
|
||||||
|
const range = getTimeWindow(this.selectedTimeWindow);
|
||||||
|
if (range) {
|
||||||
|
this.selectedTimeWindowText = this.timeWindows[range];
|
||||||
|
} else {
|
||||||
|
this.customTime = {
|
||||||
|
from: truncateZerosInDateTime(ISODateToString(this.selectedTimeWindow.start)),
|
||||||
|
to: truncateZerosInDateTime(ISODateToString(this.selectedTimeWindow.end)),
|
||||||
|
};
|
||||||
|
this.selectedTimeWindowText = sprintf(s__('%{from} to %{to}'), this.customTime);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -78,9 +78,6 @@ export default {
|
||||||
}, sidebarAnimationDuration);
|
}, sidebarAnimationDuration);
|
||||||
},
|
},
|
||||||
setInitialState() {
|
setInitialState() {
|
||||||
this.setFeatureFlags({
|
|
||||||
prometheusEndpointEnabled: true,
|
|
||||||
});
|
|
||||||
this.setEndpoints({
|
this.setEndpoints({
|
||||||
dashboardEndpoint: removeParams(['start', 'end'], this.dashboardUrl),
|
dashboardEndpoint: removeParams(['start', 'end'], this.dashboardUrl),
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,13 +11,6 @@ export default (props = {}) => {
|
||||||
const el = document.getElementById('prometheus-graphs');
|
const el = document.getElementById('prometheus-graphs');
|
||||||
|
|
||||||
if (el && el.dataset) {
|
if (el && el.dataset) {
|
||||||
if (gon.features) {
|
|
||||||
store.dispatch('monitoringDashboard/setFeatureFlags', {
|
|
||||||
prometheusEndpointEnabled: gon.features.environmentMetricsUsePrometheusEndpoint,
|
|
||||||
additionalPanelTypesEnabled: gon.features.environmentMetricsAdditionalPanelTypes,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const [currentDashboard] = getParameterValues('dashboard');
|
const [currentDashboard] = getParameterValues('dashboard');
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
// eslint-disable-next-line no-new
|
||||||
|
|
|
@ -35,14 +35,6 @@ export const setEndpoints = ({ commit }, endpoints) => {
|
||||||
commit(types.SET_ENDPOINTS, endpoints);
|
commit(types.SET_ENDPOINTS, endpoints);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const setFeatureFlags = (
|
|
||||||
{ commit },
|
|
||||||
{ prometheusEndpointEnabled, additionalPanelTypesEnabled },
|
|
||||||
) => {
|
|
||||||
commit(types.SET_DASHBOARD_ENABLED, prometheusEndpointEnabled);
|
|
||||||
commit(types.SET_ADDITIONAL_PANEL_TYPES_ENABLED, additionalPanelTypesEnabled);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setShowErrorBanner = ({ commit }, enabled) => {
|
export const setShowErrorBanner = ({ commit }, enabled) => {
|
||||||
commit(types.SET_SHOW_ERROR_BANNER, enabled);
|
commit(types.SET_SHOW_ERROR_BANNER, enabled);
|
||||||
};
|
};
|
||||||
|
@ -79,29 +71,7 @@ export const fetchData = ({ dispatch }, params) => {
|
||||||
dispatch('fetchEnvironmentsData');
|
dispatch('fetchEnvironmentsData');
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchMetricsData = ({ state, dispatch }, params) => {
|
export const fetchMetricsData = ({ dispatch }, params) => dispatch('fetchDashboard', params);
|
||||||
if (state.useDashboardEndpoint) {
|
|
||||||
return dispatch('fetchDashboard', params);
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch('requestMetricsData');
|
|
||||||
|
|
||||||
return backOffRequest(() => axios.get(state.metricsEndpoint, { params }))
|
|
||||||
.then(resp => resp.data)
|
|
||||||
.then(response => {
|
|
||||||
if (!response || !response.data || !response.success) {
|
|
||||||
dispatch('receiveMetricsDataFailure', null);
|
|
||||||
createFlash(s__('Metrics|Unexpected metrics data response from prometheus endpoint'));
|
|
||||||
}
|
|
||||||
dispatch('receiveMetricsDataSuccess', response.data);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch('receiveMetricsDataFailure', error);
|
|
||||||
if (state.setShowErrorBanner) {
|
|
||||||
createFlash(s__('Metrics|There was an error while retrieving metrics'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchDashboard = ({ state, dispatch }, params) => {
|
export const fetchDashboard = ({ state, dispatch }, params) => {
|
||||||
dispatch('requestMetricsDashboard');
|
dispatch('requestMetricsDashboard');
|
||||||
|
|
|
@ -9,8 +9,6 @@ export const RECEIVE_ENVIRONMENTS_DATA_SUCCESS = 'RECEIVE_ENVIRONMENTS_DATA_SUCC
|
||||||
export const RECEIVE_ENVIRONMENTS_DATA_FAILURE = 'RECEIVE_ENVIRONMENTS_DATA_FAILURE';
|
export const RECEIVE_ENVIRONMENTS_DATA_FAILURE = 'RECEIVE_ENVIRONMENTS_DATA_FAILURE';
|
||||||
export const SET_QUERY_RESULT = 'SET_QUERY_RESULT';
|
export const SET_QUERY_RESULT = 'SET_QUERY_RESULT';
|
||||||
export const SET_TIME_WINDOW = 'SET_TIME_WINDOW';
|
export const SET_TIME_WINDOW = 'SET_TIME_WINDOW';
|
||||||
export const SET_DASHBOARD_ENABLED = 'SET_DASHBOARD_ENABLED';
|
|
||||||
export const SET_ADDITIONAL_PANEL_TYPES_ENABLED = 'SET_ADDITIONAL_PANEL_TYPES_ENABLED';
|
|
||||||
export const SET_ALL_DASHBOARDS = 'SET_ALL_DASHBOARDS';
|
export const SET_ALL_DASHBOARDS = 'SET_ALL_DASHBOARDS';
|
||||||
export const SET_ENDPOINTS = 'SET_ENDPOINTS';
|
export const SET_ENDPOINTS = 'SET_ENDPOINTS';
|
||||||
export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE';
|
export const SET_GETTING_STARTED_EMPTY_STATE = 'SET_GETTING_STARTED_EMPTY_STATE';
|
||||||
|
|
|
@ -25,12 +25,10 @@ export default {
|
||||||
// for backwards compatibility, and to limit Vue template changes:
|
// for backwards compatibility, and to limit Vue template changes:
|
||||||
// for each group alias panels to metrics
|
// for each group alias panels to metrics
|
||||||
// for each panel alias metrics to queries
|
// for each panel alias metrics to queries
|
||||||
if (state.useDashboardEndpoint) {
|
|
||||||
metrics = panels.map(panel => ({
|
metrics = panels.map(panel => ({
|
||||||
...panel,
|
...panel,
|
||||||
queries: panel.metrics,
|
queries: panel.metrics,
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...group,
|
...group,
|
||||||
|
@ -42,8 +40,6 @@ export default {
|
||||||
|
|
||||||
if (!state.dashboard.panel_groups.length) {
|
if (!state.dashboard.panel_groups.length) {
|
||||||
state.emptyState = 'noData';
|
state.emptyState = 'noData';
|
||||||
} else {
|
|
||||||
state.showEmptyState = false;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[types.RECEIVE_METRICS_DATA_FAILURE](state, error) {
|
[types.RECEIVE_METRICS_DATA_FAILURE](state, error) {
|
||||||
|
@ -90,9 +86,6 @@ export default {
|
||||||
state.currentDashboard = endpoints.currentDashboard;
|
state.currentDashboard = endpoints.currentDashboard;
|
||||||
state.projectPath = endpoints.projectPath;
|
state.projectPath = endpoints.projectPath;
|
||||||
},
|
},
|
||||||
[types.SET_DASHBOARD_ENABLED](state, enabled) {
|
|
||||||
state.useDashboardEndpoint = enabled;
|
|
||||||
},
|
|
||||||
[types.SET_GETTING_STARTED_EMPTY_STATE](state) {
|
[types.SET_GETTING_STARTED_EMPTY_STATE](state) {
|
||||||
state.emptyState = 'gettingStarted';
|
state.emptyState = 'gettingStarted';
|
||||||
},
|
},
|
||||||
|
@ -103,9 +96,6 @@ export default {
|
||||||
[types.SET_ALL_DASHBOARDS](state, dashboards) {
|
[types.SET_ALL_DASHBOARDS](state, dashboards) {
|
||||||
state.allDashboards = dashboards;
|
state.allDashboards = dashboards;
|
||||||
},
|
},
|
||||||
[types.SET_ADDITIONAL_PANEL_TYPES_ENABLED](state, enabled) {
|
|
||||||
state.additionalPanelTypesEnabled = enabled;
|
|
||||||
},
|
|
||||||
[types.SET_SHOW_ERROR_BANNER](state, enabled) {
|
[types.SET_SHOW_ERROR_BANNER](state, enabled) {
|
||||||
state.showErrorBanner = enabled;
|
state.showErrorBanner = enabled;
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,8 +7,6 @@ export default () => ({
|
||||||
environmentsEndpoint: null,
|
environmentsEndpoint: null,
|
||||||
deploymentsEndpoint: null,
|
deploymentsEndpoint: null,
|
||||||
dashboardEndpoint: invalidUrl,
|
dashboardEndpoint: invalidUrl,
|
||||||
useDashboardEndpoint: false,
|
|
||||||
additionalPanelTypesEnabled: false,
|
|
||||||
emptyState: 'gettingStarted',
|
emptyState: 'gettingStarted',
|
||||||
showEmptyState: true,
|
showEmptyState: true,
|
||||||
showErrorBanner: true,
|
showErrorBanner: true,
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default {
|
||||||
:title="tooltipText"
|
:title="tooltipText"
|
||||||
:class="cssClass"
|
:class="cssClass"
|
||||||
:disabled="isDisabled"
|
:disabled="isDisabled"
|
||||||
class="js-ci-action btn btn-blank btn-transparent ci-action-icon-container ci-action-icon-wrapper"
|
class="js-ci-action btn btn-blank btn-transparent ci-action-icon-container ci-action-icon-wrapper d-flex align-items-center justify-content-center"
|
||||||
@click="onClickAction"
|
@click="onClickAction"
|
||||||
>
|
>
|
||||||
<gl-loading-icon v-if="isLoading" class="js-action-icon-loading" />
|
<gl-loading-icon v-if="isLoading" class="js-action-icon-loading" />
|
||||||
|
|
|
@ -871,7 +871,7 @@ button.mini-pipeline-graph-dropdown-toggle {
|
||||||
height: $ci-action-dropdown-svg-size;
|
height: $ci-action-dropdown-svg-size;
|
||||||
fill: $gl-text-color-secondary;
|
fill: $gl-text-color-secondary;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 1px;
|
top: auto;
|
||||||
vertical-align: initial;
|
vertical-align: initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
|
||||||
before_action :verify_api_request!, only: :terminal_websocket_authorize
|
before_action :verify_api_request!, only: :terminal_websocket_authorize
|
||||||
before_action :expire_etag_cache, only: [:index]
|
before_action :expire_etag_cache, only: [:index]
|
||||||
before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do
|
before_action only: [:metrics, :additional_metrics, :metrics_dashboard] do
|
||||||
push_frontend_feature_flag(:environment_metrics_use_prometheus_endpoint, default_enabled: true)
|
|
||||||
push_frontend_feature_flag(:environment_metrics_additional_panel_types)
|
|
||||||
push_frontend_feature_flag(:prometheus_computed_alerts)
|
push_frontend_feature_flag(:prometheus_computed_alerts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ class GrafanaIntegration < ApplicationRecord
|
||||||
|
|
||||||
validates :enabled, inclusion: { in: [true, false] }
|
validates :enabled, inclusion: { in: [true, false] }
|
||||||
|
|
||||||
|
scope :enabled, -> { where(enabled: true) }
|
||||||
|
|
||||||
def client
|
def client
|
||||||
return unless enabled?
|
return unless enabled?
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ In addition to this page, the following resources can help you craft and contrib
|
||||||
|
|
||||||
## Source files and rendered web locations
|
## Source files and rendered web locations
|
||||||
|
|
||||||
Documentation for GitLab, GitLab Runner, Omnibus GitLab and Charts are published to <https://docs.gitlab.com>. Documentation for GitLab is also published within the application at `/help` on the domain of the GitLab instance.
|
Documentation for GitLab, GitLab Runner, Omnibus GitLab and Charts is published to <https://docs.gitlab.com>. Documentation for GitLab is also published within the application at `/help` on the domain of the GitLab instance.
|
||||||
At `/help`, only help for your current edition and version is included. Help for other versions is available at <https://docs.gitlab.com/archives/>.
|
At `/help`, only help for your current edition and version is included. Help for other versions is available at <https://docs.gitlab.com/archives/>.
|
||||||
|
|
||||||
The source of the documentation exists within the codebase of each GitLab application in the following repository locations:
|
The source of the documentation exists within the codebase of each GitLab application in the following repository locations:
|
||||||
|
|
|
@ -588,7 +588,7 @@ You can specify a different Git repository by providing it as an extra parameter
|
||||||
sudo -u git -H bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workhorse,https://example.com/gitlab-workhorse.git]" RAILS_ENV=production
|
sudo -u git -H bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workhorse,https://example.com/gitlab-workhorse.git]" RAILS_ENV=production
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install GitLab-Elasticsearch-indexer`
|
### Install GitLab-Elasticsearch-indexer
|
||||||
|
|
||||||
GitLab-Elasticsearch-Indexer uses [GNU Make](https://www.gnu.org/software/make/). The
|
GitLab-Elasticsearch-Indexer uses [GNU Make](https://www.gnu.org/software/make/). The
|
||||||
following command-line will install GitLab-Elasticsearch-Indexer in `/home/git/gitlab-elasticsearch-indexer`
|
following command-line will install GitLab-Elasticsearch-Indexer in `/home/git/gitlab-elasticsearch-indexer`
|
||||||
|
|
|
@ -123,7 +123,7 @@ For more details on creating groups, watch the video [GitLab Namespaces (users,
|
||||||
## Add users to a group
|
## Add users to a group
|
||||||
|
|
||||||
A benefit of putting multiple projects in one group is that you can
|
A benefit of putting multiple projects in one group is that you can
|
||||||
give a user to access to all projects in the group with one action.
|
give a user access to all projects in the group with one action.
|
||||||
|
|
||||||
Add members to a group by navigating to the group's dashboard and clicking **Members**.
|
Add members to a group by navigating to the group's dashboard and clicking **Members**.
|
||||||
|
|
||||||
|
@ -135,14 +135,14 @@ Consider a group with two projects:
|
||||||
|
|
||||||
- On the **Group Members** page, you can now add a new user to the group.
|
- On the **Group Members** page, you can now add a new user to the group.
|
||||||
- Now, because this user is a **Developer** member of the group, they automatically
|
- Now, because this user is a **Developer** member of the group, they automatically
|
||||||
gets **Developer** access to **all projects** within that group.
|
get **Developer** access to **all projects** within that group.
|
||||||
|
|
||||||
To increase the access level of an existing user for a specific project,
|
To increase the access level of an existing user for a specific project,
|
||||||
add them again as a new member to the project with the desired permission level.
|
add them again as a new member to the project with the desired permission level.
|
||||||
|
|
||||||
## Request access to a group
|
## Request access to a group
|
||||||
|
|
||||||
As a group owner, you can enable or disable the ability for non members to request access to
|
As a group owner, you can enable or disable the ability for non-members to request access to
|
||||||
your group. Go to the group settings, and click **Allow users to request access**.
|
your group. Go to the group settings, and click **Allow users to request access**.
|
||||||
|
|
||||||
As a user, you can request to be a member of a group, if that setting is enabled. Go to the group for which you'd like to be a member, and click the **Request Access** button on the right
|
As a user, you can request to be a member of a group, if that setting is enabled. Go to the group for which you'd like to be a member, and click the **Request Access** button on the right
|
||||||
|
@ -356,7 +356,7 @@ Restriction currently applies to:
|
||||||
- [From GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/issues/12874), API access.
|
- [From GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/issues/12874), API access.
|
||||||
- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/32113), Git actions via SSH.
|
- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/32113), Git actions via SSH.
|
||||||
|
|
||||||
To avoid accidental lock-out, admins and group owners are are able to access
|
To avoid accidental lock-out, admins and group owners are able to access
|
||||||
the group regardless of the IP restriction.
|
the group regardless of the IP restriction.
|
||||||
|
|
||||||
#### Allowed domain restriction **(PREMIUM)**
|
#### Allowed domain restriction **(PREMIUM)**
|
||||||
|
@ -385,7 +385,7 @@ Some domains cannot be restricted. These are the most popular public email domai
|
||||||
To enable this feature:
|
To enable this feature:
|
||||||
|
|
||||||
1. Navigate to the group's **Settings > General** page.
|
1. Navigate to the group's **Settings > General** page.
|
||||||
1. Expand the **Permissions, LFS, 2FA** section, and enter domain name into **Restrict membership by email** field.
|
1. Expand the **Permissions, LFS, 2FA** section, and enter the domain name into **Restrict membership by email** field.
|
||||||
1. Click **Save changes**.
|
1. Click **Save changes**.
|
||||||
|
|
||||||
This will enable the domain-checking for all new users added to the group from this moment on.
|
This will enable the domain-checking for all new users added to the group from this moment on.
|
||||||
|
@ -445,7 +445,7 @@ To enable this feature:
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/13294) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.0.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/13294) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.0.
|
||||||
|
|
||||||
A group owner can check the aggregated storage usage for all the project in a group, sub-groups included, in the **Storage** tab of the **Usage Quotas** page available to the group page settings list.
|
A group owner can check the aggregated storage usage for all the projects in a group, sub-groups included, in the **Storage** tab of the **Usage Quotas** page available to the group page settings list.
|
||||||
|
|
||||||
![Group storage usage quota](img/group_storage_usage_quota.png)
|
![Group storage usage quota](img/group_storage_usage_quota.png)
|
||||||
|
|
||||||
|
|
|
@ -405,6 +405,7 @@ GFM will recognize the following:
|
||||||
| label by ID | `~123` | `namespace/project~123` | `project~123` |
|
| label by ID | `~123` | `namespace/project~123` | `project~123` |
|
||||||
| one-word label by name | `~bug` | `namespace/project~bug` | `project~bug` |
|
| one-word label by name | `~bug` | `namespace/project~bug` | `project~bug` |
|
||||||
| multi-word label by name | `~"feature request"` | `namespace/project~"feature request"` | `project~"feature request"` |
|
| multi-word label by name | `~"feature request"` | `namespace/project~"feature request"` | `project~"feature request"` |
|
||||||
|
| scoped label by name | `~"priority::high"` | `namespace/project~"priority::high"` | `project~"priority::high"` |
|
||||||
| project milestone by ID | `%123` | `namespace/project%123` | `project%123` |
|
| project milestone by ID | `%123` | `namespace/project%123` | `project%123` |
|
||||||
| one-word milestone by name | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
|
| one-word milestone by name | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
|
||||||
| multi-word milestone by name | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
|
| multi-word milestone by name | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 493 KiB |
|
@ -32,13 +32,14 @@ on the search field on the top-right of your screen:
|
||||||
If you want to search for issues present in a specific project, navigate to
|
If you want to search for issues present in a specific project, navigate to
|
||||||
a project's **Issues** tab, and click on the field **Search or filter results...**. It will
|
a project's **Issues** tab, and click on the field **Search or filter results...**. It will
|
||||||
display a dropdown menu, from which you can add filters per author, assignee, milestone,
|
display a dropdown menu, from which you can add filters per author, assignee, milestone,
|
||||||
label, weight, and 'my-reaction' (based on your emoji votes). When done, press **Enter** on your keyboard to filter the issues.
|
release, label, weight, confidentiality, and "my-reaction" (based on your emoji votes).
|
||||||
|
When done, press **Enter** on your keyboard to filter the issues.
|
||||||
|
|
||||||
![filter issues in a project](img/issue_search_filter.png)
|
![filter issues in a project](img/issue_search_filter_v12_5.png)
|
||||||
|
|
||||||
The same process is valid for merge requests. Navigate to your project's **Merge Requests** tab,
|
The same process is valid for merge requests. Navigate to your project's **Merge Requests** tab,
|
||||||
and click **Search or filter results...**. Merge requests can be filtered by author, assignee,
|
and click **Search or filter results...**. Merge requests can be filtered by author, assignee,
|
||||||
milestone, and label.
|
approver, milestone, release, label, "my-reaction", "work in progess" status, and target branch.
|
||||||
|
|
||||||
### Filtering by **None** / **Any**
|
### Filtering by **None** / **Any**
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
.auto-deploy:
|
.dast-auto-deploy:
|
||||||
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.4.0"
|
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.4.0"
|
||||||
|
|
||||||
dast_environment_deploy:
|
dast_environment_deploy:
|
||||||
extends: .auto-deploy
|
extends: .dast-auto-deploy
|
||||||
stage: review
|
stage: review
|
||||||
script:
|
script:
|
||||||
- auto-deploy check_kube_domain
|
- auto-deploy check_kube_domain
|
||||||
|
@ -31,7 +31,7 @@ dast_environment_deploy:
|
||||||
- $DAST_WEBSITE # we don't need to create a review app if a URL is already given
|
- $DAST_WEBSITE # we don't need to create a review app if a URL is already given
|
||||||
|
|
||||||
stop_dast_environment:
|
stop_dast_environment:
|
||||||
extends: .auto-deploy
|
extends: .dast-auto-deploy
|
||||||
stage: cleanup
|
stage: cleanup
|
||||||
variables:
|
variables:
|
||||||
GIT_STRATEGY: none
|
GIT_STRATEGY: none
|
||||||
|
|
|
@ -78,6 +78,7 @@ module Gitlab
|
||||||
clusters_applications_knative: count(::Clusters::Applications::Knative.available),
|
clusters_applications_knative: count(::Clusters::Applications::Knative.available),
|
||||||
clusters_applications_elastic_stack: count(::Clusters::Applications::ElasticStack.available),
|
clusters_applications_elastic_stack: count(::Clusters::Applications::ElasticStack.available),
|
||||||
in_review_folder: count(::Environment.in_review_folder),
|
in_review_folder: count(::Environment.in_review_folder),
|
||||||
|
grafana_integrated_projects: count(GrafanaIntegration.enabled),
|
||||||
groups: count(Group),
|
groups: count(Group),
|
||||||
issues: count(Issue),
|
issues: count(Issue),
|
||||||
issues_with_associated_zoom_link: count(ZoomMeeting.added_to_issue),
|
issues_with_associated_zoom_link: count(ZoomMeeting.added_to_issue),
|
||||||
|
|
|
@ -10810,9 +10810,6 @@ msgstr ""
|
||||||
msgid "Metrics|Unexpected deployment data response from prometheus endpoint"
|
msgid "Metrics|Unexpected deployment data response from prometheus endpoint"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Metrics|Unexpected metrics data response from prometheus endpoint"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Metrics|Unit label"
|
msgid "Metrics|Unit label"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
import { setTestTimeout } from 'helpers/timeout';
|
||||||
import { createStore } from '~/monitoring/stores';
|
import { createStore } from '~/monitoring/stores';
|
||||||
import { GlLink } from '@gitlab/ui';
|
import { GlLink } from '@gitlab/ui';
|
||||||
import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
|
import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
|
||||||
import { shallowWrapperContainsSlotText } from 'helpers/vue_test_utils_helper';
|
import { shallowWrapperContainsSlotText } from 'helpers/vue_test_utils_helper';
|
||||||
import TimeSeries from '~/monitoring/components/charts/time_series.vue';
|
import TimeSeries from '~/monitoring/components/charts/time_series.vue';
|
||||||
import * as types from '~/monitoring/stores/mutation_types';
|
import * as types from '~/monitoring/stores/mutation_types';
|
||||||
import { TEST_HOST } from 'spec/test_constants';
|
import {
|
||||||
import MonitoringMock, {
|
|
||||||
deploymentData,
|
deploymentData,
|
||||||
mockProjectPath,
|
metricsGroupsAPIResponse,
|
||||||
} from '../../../javascripts/monitoring/mock_data';
|
mockedQueryResultPayload,
|
||||||
|
mockProjectDir,
|
||||||
|
mockHost,
|
||||||
|
} from '../mock_data';
|
||||||
|
|
||||||
import * as iconUtils from '~/lib/utils/icon_utils';
|
import * as iconUtils from '~/lib/utils/icon_utils';
|
||||||
|
|
||||||
const mockSvgPathContent = 'mockSvgPathContent';
|
const mockSvgPathContent = 'mockSvgPathContent';
|
||||||
const mockSha = 'mockSha';
|
|
||||||
const mockWidgets = 'mockWidgets';
|
const mockWidgets = 'mockWidgets';
|
||||||
const projectPath = `${TEST_HOST}${mockProjectPath}`;
|
|
||||||
const commitUrl = `${projectPath}/commit/${mockSha}`;
|
|
||||||
|
|
||||||
jest.mock('~/lib/utils/icon_utils', () => ({
|
jest.mock('~/lib/utils/icon_utils', () => ({
|
||||||
getSvgIconPathContent: jest.fn().mockImplementation(
|
getSvgIconPathContent: jest.fn().mockImplementation(
|
||||||
|
@ -33,32 +34,44 @@ describe('Time series component', () => {
|
||||||
let store;
|
let store;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
setTestTimeout(1000);
|
||||||
|
|
||||||
store = createStore();
|
store = createStore();
|
||||||
store.commit(`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`, MonitoringMock.data);
|
|
||||||
|
store.commit(
|
||||||
|
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
||||||
|
metricsGroupsAPIResponse,
|
||||||
|
);
|
||||||
|
|
||||||
store.commit(`monitoringDashboard/${types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS}`, deploymentData);
|
store.commit(`monitoringDashboard/${types.RECEIVE_DEPLOYMENTS_DATA_SUCCESS}`, deploymentData);
|
||||||
[, mockGraphData] = store.state.monitoringDashboard.dashboard.panel_groups[0].metrics;
|
|
||||||
|
// Mock data contains 2 panels, pick the first one
|
||||||
|
store.commit(`monitoringDashboard/${types.SET_QUERY_RESULT}`, mockedQueryResultPayload);
|
||||||
|
|
||||||
|
[mockGraphData] = store.state.monitoringDashboard.dashboard.panel_groups[0].metrics;
|
||||||
|
|
||||||
makeTimeSeriesChart = (graphData, type) =>
|
makeTimeSeriesChart = (graphData, type) =>
|
||||||
shallowMount(TimeSeries, {
|
shallowMount(TimeSeries, {
|
||||||
attachToDocument: true,
|
|
||||||
propsData: {
|
propsData: {
|
||||||
graphData: { ...graphData, type },
|
graphData: { ...graphData, type },
|
||||||
deploymentData: store.state.monitoringDashboard.deploymentData,
|
deploymentData: store.state.monitoringDashboard.deploymentData,
|
||||||
projectPath,
|
projectPath: `${mockHost}${mockProjectDir}`,
|
||||||
},
|
},
|
||||||
slots: {
|
slots: {
|
||||||
default: mockWidgets,
|
default: mockWidgets,
|
||||||
},
|
},
|
||||||
sync: false,
|
sync: false,
|
||||||
store,
|
store,
|
||||||
|
attachToDocument: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('general functions', () => {
|
describe('general functions', () => {
|
||||||
let timeSeriesChart;
|
let timeSeriesChart;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(done => {
|
||||||
timeSeriesChart = makeTimeSeriesChart(mockGraphData, 'area-chart');
|
timeSeriesChart = makeTimeSeriesChart(mockGraphData, 'area-chart');
|
||||||
|
timeSeriesChart.vm.$nextTick(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders chart title', () => {
|
it('renders chart title', () => {
|
||||||
|
@ -83,9 +96,14 @@ describe('Time series component', () => {
|
||||||
|
|
||||||
describe('methods', () => {
|
describe('methods', () => {
|
||||||
describe('formatTooltipText', () => {
|
describe('formatTooltipText', () => {
|
||||||
const mockDate = deploymentData[0].created_at;
|
let mockDate;
|
||||||
const mockCommitUrl = deploymentData[0].commitUrl;
|
let mockCommitUrl;
|
||||||
const generateSeriesData = type => ({
|
let generateSeriesData;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockDate = deploymentData[0].created_at;
|
||||||
|
mockCommitUrl = deploymentData[0].commitUrl;
|
||||||
|
generateSeriesData = type => ({
|
||||||
seriesData: [
|
seriesData: [
|
||||||
{
|
{
|
||||||
seriesName: timeSeriesChart.vm.chartData[0].name,
|
seriesName: timeSeriesChart.vm.chartData[0].name,
|
||||||
|
@ -96,6 +114,7 @@ describe('Time series component', () => {
|
||||||
],
|
],
|
||||||
value: mockDate,
|
value: mockDate,
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when series is of line type', () => {
|
describe('when series is of line type', () => {
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
|
@ -104,11 +123,11 @@ describe('Time series component', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('formats tooltip title', () => {
|
it('formats tooltip title', () => {
|
||||||
expect(timeSeriesChart.vm.tooltip.title).toBe('31 May 2017, 9:23PM');
|
expect(timeSeriesChart.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('formats tooltip content', () => {
|
it('formats tooltip content', () => {
|
||||||
const name = 'Core Usage';
|
const name = 'Pod average';
|
||||||
const value = '5.556';
|
const value = '5.556';
|
||||||
const dataIndex = 0;
|
const dataIndex = 0;
|
||||||
const seriesLabel = timeSeriesChart.find(GlChartSeriesLabel);
|
const seriesLabel = timeSeriesChart.find(GlChartSeriesLabel);
|
||||||
|
@ -129,13 +148,13 @@ describe('Time series component', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when series is of scatter type', () => {
|
describe('when series is of scatter type, for deployments', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
timeSeriesChart.vm.formatTooltipText(generateSeriesData('scatter'));
|
timeSeriesChart.vm.formatTooltipText(generateSeriesData('scatter'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('formats tooltip title', () => {
|
it('formats tooltip title', () => {
|
||||||
expect(timeSeriesChart.vm.tooltip.title).toBe('31 May 2017, 9:23PM');
|
expect(timeSeriesChart.vm.tooltip.title).toBe('16 Jul 2019, 10:14AM');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('formats tooltip sha', () => {
|
it('formats tooltip sha', () => {
|
||||||
|
@ -274,9 +293,9 @@ describe('Time series component', () => {
|
||||||
describe('scatterSeries', () => {
|
describe('scatterSeries', () => {
|
||||||
it('utilizes deployment data', () => {
|
it('utilizes deployment data', () => {
|
||||||
expect(timeSeriesChart.vm.scatterSeries.data).toEqual([
|
expect(timeSeriesChart.vm.scatterSeries.data).toEqual([
|
||||||
['2017-05-31T21:23:37.881Z', 0],
|
['2019-07-16T10:14:25.589Z', 0],
|
||||||
['2017-05-30T20:08:04.629Z', 0],
|
['2019-07-16T11:14:25.589Z', 0],
|
||||||
['2017-05-30T17:42:38.409Z', 0],
|
['2019-07-16T12:14:25.589Z', 0],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(timeSeriesChart.vm.scatterSeries.symbolSize).toBe(14);
|
expect(timeSeriesChart.vm.scatterSeries.symbolSize).toBe(14);
|
||||||
|
@ -285,7 +304,7 @@ describe('Time series component', () => {
|
||||||
|
|
||||||
describe('yAxisLabel', () => {
|
describe('yAxisLabel', () => {
|
||||||
it('constructs a label for the chart y-axis', () => {
|
it('constructs a label for the chart y-axis', () => {
|
||||||
expect(timeSeriesChart.vm.yAxisLabel).toBe('CPU');
|
expect(timeSeriesChart.vm.yAxisLabel).toBe('Memory Used per Pod');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -318,6 +337,10 @@ describe('Time series component', () => {
|
||||||
timeSeriesAreaChart.vm.$nextTick(done);
|
timeSeriesAreaChart.vm.$nextTick(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
timeSeriesAreaChart.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
it('is a Vue instance', () => {
|
it('is a Vue instance', () => {
|
||||||
expect(glChart.exists()).toBe(true);
|
expect(glChart.exists()).toBe(true);
|
||||||
expect(glChart.isVueInstance()).toBe(true);
|
expect(glChart.isVueInstance()).toBe(true);
|
||||||
|
@ -343,6 +366,9 @@ describe('Time series component', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when tooltip is showing deployment data', () => {
|
describe('when tooltip is showing deployment data', () => {
|
||||||
|
const mockSha = 'mockSha';
|
||||||
|
const commitUrl = `${mockProjectDir}/commit/${mockSha}`;
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
timeSeriesAreaChart.vm.tooltip.isDeployment = true;
|
timeSeriesAreaChart.vm.tooltip.isDeployment = true;
|
||||||
timeSeriesAreaChart.vm.$nextTick(done);
|
timeSeriesAreaChart.vm.$nextTick(done);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
export const mockHost = 'http://test.host';
|
||||||
export const mockProjectDir = '/frontend-fixtures/environments-project';
|
export const mockProjectDir = '/frontend-fixtures/environments-project';
|
||||||
|
|
||||||
export const anomalyDeploymentData = [
|
export const anomalyDeploymentData = [
|
||||||
|
@ -159,3 +160,171 @@ export const anomalyMockGraphData = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deploymentData = [
|
||||||
|
{
|
||||||
|
id: 111,
|
||||||
|
iid: 3,
|
||||||
|
sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
||||||
|
commitUrl:
|
||||||
|
'http://test.host/frontend-fixtures/environments-project/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
||||||
|
ref: {
|
||||||
|
name: 'master',
|
||||||
|
},
|
||||||
|
created_at: '2019-07-16T10:14:25.589Z',
|
||||||
|
tag: false,
|
||||||
|
tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
|
||||||
|
'last?': true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 110,
|
||||||
|
iid: 2,
|
||||||
|
sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
||||||
|
commitUrl:
|
||||||
|
'http://test.host/frontend-fixtures/environments-project/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
||||||
|
ref: {
|
||||||
|
name: 'master',
|
||||||
|
},
|
||||||
|
created_at: '2019-07-16T11:14:25.589Z',
|
||||||
|
tag: false,
|
||||||
|
tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
|
||||||
|
'last?': false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 109,
|
||||||
|
iid: 1,
|
||||||
|
sha: '6511e58faafaa7ad2228990ec57f19d66f7db7c2',
|
||||||
|
commitUrl:
|
||||||
|
'http://test.host/frontend-fixtures/environments-project/commit/6511e58faafaa7ad2228990ec57f19d66f7db7c2',
|
||||||
|
ref: {
|
||||||
|
name: 'update2-readme',
|
||||||
|
},
|
||||||
|
created_at: '2019-07-16T12:14:25.589Z',
|
||||||
|
tag: false,
|
||||||
|
tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
|
||||||
|
'last?': false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const metricsNewGroupsAPIResponse = [
|
||||||
|
{
|
||||||
|
group: 'System metrics (Kubernetes)',
|
||||||
|
priority: 5,
|
||||||
|
panels: [
|
||||||
|
{
|
||||||
|
title: 'Memory Usage (Pod average)',
|
||||||
|
type: 'area-chart',
|
||||||
|
y_label: 'Memory Used per Pod',
|
||||||
|
weight: 2,
|
||||||
|
metrics: [
|
||||||
|
{
|
||||||
|
id: 'system_metrics_kubernetes_container_memory_average',
|
||||||
|
query_range:
|
||||||
|
'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024',
|
||||||
|
label: 'Pod average',
|
||||||
|
unit: 'MB',
|
||||||
|
metric_id: 17,
|
||||||
|
prometheus_endpoint_path:
|
||||||
|
'/root/autodevops-deploy/environments/32/prometheus/api/v1/query_range?query=avg%28sum%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+by+%28job%29%29+without+%28job%29+%2F+count%28avg%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+without+%28job%29%29+%2F1024%2F1024',
|
||||||
|
appearance: {
|
||||||
|
line: {
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const mockedQueryResultPayload = {
|
||||||
|
metricId: '17_system_metrics_kubernetes_container_memory_average',
|
||||||
|
result: [
|
||||||
|
{
|
||||||
|
metric: {},
|
||||||
|
values: [
|
||||||
|
[1563272065.589, '10.396484375'],
|
||||||
|
[1563272125.589, '10.333984375'],
|
||||||
|
[1563272185.589, '10.333984375'],
|
||||||
|
[1563272245.589, '10.333984375'],
|
||||||
|
[1563272305.589, '10.333984375'],
|
||||||
|
[1563272365.589, '10.333984375'],
|
||||||
|
[1563272425.589, '10.38671875'],
|
||||||
|
[1563272485.589, '10.333984375'],
|
||||||
|
[1563272545.589, '10.333984375'],
|
||||||
|
[1563272605.589, '10.333984375'],
|
||||||
|
[1563272665.589, '10.333984375'],
|
||||||
|
[1563272725.589, '10.333984375'],
|
||||||
|
[1563272785.589, '10.396484375'],
|
||||||
|
[1563272845.589, '10.333984375'],
|
||||||
|
[1563272905.589, '10.333984375'],
|
||||||
|
[1563272965.589, '10.3984375'],
|
||||||
|
[1563273025.589, '10.337890625'],
|
||||||
|
[1563273085.589, '10.34765625'],
|
||||||
|
[1563273145.589, '10.337890625'],
|
||||||
|
[1563273205.589, '10.337890625'],
|
||||||
|
[1563273265.589, '10.337890625'],
|
||||||
|
[1563273325.589, '10.337890625'],
|
||||||
|
[1563273385.589, '10.337890625'],
|
||||||
|
[1563273445.589, '10.337890625'],
|
||||||
|
[1563273505.589, '10.337890625'],
|
||||||
|
[1563273565.589, '10.337890625'],
|
||||||
|
[1563273625.589, '10.337890625'],
|
||||||
|
[1563273685.589, '10.337890625'],
|
||||||
|
[1563273745.589, '10.337890625'],
|
||||||
|
[1563273805.589, '10.337890625'],
|
||||||
|
[1563273865.589, '10.390625'],
|
||||||
|
[1563273925.589, '10.390625'],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const metricsGroupsAPIResponse = [
|
||||||
|
{
|
||||||
|
group: 'System metrics (Kubernetes)',
|
||||||
|
priority: 5,
|
||||||
|
panels: [
|
||||||
|
{
|
||||||
|
title: 'Memory Usage (Pod average)',
|
||||||
|
type: 'area-chart',
|
||||||
|
y_label: 'Memory Used per Pod',
|
||||||
|
weight: 2,
|
||||||
|
metrics: [
|
||||||
|
{
|
||||||
|
id: 'system_metrics_kubernetes_container_memory_average',
|
||||||
|
query_range:
|
||||||
|
'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024',
|
||||||
|
label: 'Pod average',
|
||||||
|
unit: 'MB',
|
||||||
|
metric_id: 17,
|
||||||
|
prometheus_endpoint_path:
|
||||||
|
'/root/autodevops-deploy/environments/32/prometheus/api/v1/query_range?query=avg%28sum%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+by+%28job%29%29+without+%28job%29+%2F+count%28avg%28container_memory_usage_bytes%7Bcontainer_name%21%3D%22POD%22%2Cpod_name%3D~%22%5E%25%7Bci_environment_slug%7D-%28%5B%5Ec%5D.%2A%7Cc%28%5B%5Ea%5D%7Ca%28%5B%5En%5D%7Cn%28%5B%5Ea%5D%7Ca%28%5B%5Er%5D%7Cr%5B%5Ey%5D%29%29%29%29.%2A%7C%29-%28.%2A%29%22%2Cnamespace%3D%22%25%7Bkube_namespace%7D%22%7D%29+without+%28job%29%29+%2F1024%2F1024',
|
||||||
|
appearance: {
|
||||||
|
line: {
|
||||||
|
width: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Core Usage (Total)',
|
||||||
|
type: 'area-chart',
|
||||||
|
y_label: 'Total Cores',
|
||||||
|
weight: 3,
|
||||||
|
metrics: [
|
||||||
|
{
|
||||||
|
id: 'system_metrics_kubernetes_container_cores_total',
|
||||||
|
query_range:
|
||||||
|
'avg(sum(rate(container_cpu_usage_seconds_total{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}[15m])) by (job)) without (job)',
|
||||||
|
label: 'Total',
|
||||||
|
unit: 'cores',
|
||||||
|
metric_id: 13,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import AxiosMockAdapter from 'axios-mock-adapter';
|
import AxiosMockAdapter from 'axios-mock-adapter';
|
||||||
|
import { setTestTimeout } from 'helpers/timeout';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import PanelType from '~/monitoring/components/panel_type.vue';
|
import PanelType from '~/monitoring/components/panel_type.vue';
|
||||||
import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
|
import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
|
||||||
|
@ -10,15 +11,17 @@ import { anomalyMockGraphData } from '../../frontend/monitoring/mock_data';
|
||||||
import { createStore } from '~/monitoring/stores';
|
import { createStore } from '~/monitoring/stores';
|
||||||
|
|
||||||
global.IS_EE = true;
|
global.IS_EE = true;
|
||||||
global.URL.createObjectURL = jest.fn(() => {});
|
global.URL.createObjectURL = jest.fn();
|
||||||
|
|
||||||
describe('Panel Type component', () => {
|
describe('Panel Type component', () => {
|
||||||
let axiosMock;
|
let axiosMock;
|
||||||
let store;
|
let store;
|
||||||
let panelType;
|
let panelType;
|
||||||
const dashboardWidth = 100;
|
const dashboardWidth = 100;
|
||||||
|
const exampleText = 'example_text';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
setTestTimeout(1000);
|
||||||
axiosMock = new AxiosMockAdapter(axios);
|
axiosMock = new AxiosMockAdapter(axios);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,6 +43,7 @@ describe('Panel Type component', () => {
|
||||||
graphData: graphDataNoResult,
|
graphData: graphDataNoResult,
|
||||||
},
|
},
|
||||||
sync: false,
|
sync: false,
|
||||||
|
attachToDocument: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,14 +69,13 @@ describe('Panel Type component', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when Graph data is available', () => {
|
describe('when Graph data is available', () => {
|
||||||
const exampleText = 'example_text';
|
|
||||||
const propsData = {
|
const propsData = {
|
||||||
clipboardText: exampleText,
|
clipboardText: exampleText,
|
||||||
dashboardWidth,
|
dashboardWidth,
|
||||||
graphData: graphDataPrometheusQueryRange,
|
graphData: graphDataPrometheusQueryRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(done => {
|
||||||
store = createStore();
|
store = createStore();
|
||||||
panelType = shallowMount(PanelType, {
|
panelType = shallowMount(PanelType, {
|
||||||
propsData,
|
propsData,
|
||||||
|
@ -80,6 +83,11 @@ describe('Panel Type component', () => {
|
||||||
sync: false,
|
sync: false,
|
||||||
attachToDocument: true,
|
attachToDocument: true,
|
||||||
});
|
});
|
||||||
|
panelType.vm.$nextTick(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
panelType.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Time Series Chart panel type', () => {
|
describe('Time Series Chart panel type', () => {
|
||||||
|
@ -110,4 +118,49 @@ describe('Panel Type component', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when downloading metrics data as CSV', () => {
|
||||||
|
beforeEach(done => {
|
||||||
|
graphDataPrometheusQueryRange.y_label = 'metric';
|
||||||
|
store = createStore();
|
||||||
|
panelType = shallowMount(PanelType, {
|
||||||
|
propsData: {
|
||||||
|
clipboardText: exampleText,
|
||||||
|
dashboardWidth,
|
||||||
|
graphData: graphDataPrometheusQueryRange,
|
||||||
|
},
|
||||||
|
store,
|
||||||
|
sync: false,
|
||||||
|
attachToDocument: true,
|
||||||
|
});
|
||||||
|
panelType.vm.$nextTick(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
panelType.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('csvText', () => {
|
||||||
|
it('converts metrics data from json to csv', () => {
|
||||||
|
const header = `timestamp,${graphDataPrometheusQueryRange.y_label}`;
|
||||||
|
const data = graphDataPrometheusQueryRange.queries[0].result[0].values;
|
||||||
|
const firstRow = `${data[0][0]},${data[0][1]}`;
|
||||||
|
const secondRow = `${data[1][0]},${data[1][1]}`;
|
||||||
|
|
||||||
|
expect(panelType.vm.csvText).toBe(`${header}\r\n${firstRow}\r\n${secondRow}\r\n`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('downloadCsv', () => {
|
||||||
|
it('produces a link with a Blob', () => {
|
||||||
|
expect(global.URL.createObjectURL).toHaveBeenLastCalledWith(expect.any(Blob));
|
||||||
|
expect(global.URL.createObjectURL).toHaveBeenLastCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
size: panelType.vm.csvText.length,
|
||||||
|
type: 'text/plain',
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,11 +7,12 @@ import Dashboard from '~/monitoring/components/dashboard.vue';
|
||||||
import * as types from '~/monitoring/stores/mutation_types';
|
import * as types from '~/monitoring/stores/mutation_types';
|
||||||
import { createStore } from '~/monitoring/stores';
|
import { createStore } from '~/monitoring/stores';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import MonitoringMock, {
|
import {
|
||||||
metricsGroupsAPIResponse,
|
metricsGroupsAPIResponse,
|
||||||
|
mockedQueryResultPayload,
|
||||||
|
mockedQueryResultPayloadCoresTotal,
|
||||||
mockApiEndpoint,
|
mockApiEndpoint,
|
||||||
environmentData,
|
environmentData,
|
||||||
singleGroupResponse,
|
|
||||||
dashboardGitResponse,
|
dashboardGitResponse,
|
||||||
} from '../mock_data';
|
} from '../mock_data';
|
||||||
|
|
||||||
|
@ -44,12 +45,33 @@ const resetSpy = spy => {
|
||||||
|
|
||||||
export default propsData;
|
export default propsData;
|
||||||
|
|
||||||
|
function setupComponentStore(component) {
|
||||||
|
component.$store.commit(
|
||||||
|
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
||||||
|
metricsGroupsAPIResponse,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Load 2 panels to the dashboard
|
||||||
|
component.$store.commit(
|
||||||
|
`monitoringDashboard/${types.SET_QUERY_RESULT}`,
|
||||||
|
mockedQueryResultPayload,
|
||||||
|
);
|
||||||
|
component.$store.commit(
|
||||||
|
`monitoringDashboard/${types.SET_QUERY_RESULT}`,
|
||||||
|
mockedQueryResultPayloadCoresTotal,
|
||||||
|
);
|
||||||
|
|
||||||
|
component.$store.commit(
|
||||||
|
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
|
||||||
|
environmentData,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
describe('Dashboard', () => {
|
describe('Dashboard', () => {
|
||||||
let DashboardComponent;
|
let DashboardComponent;
|
||||||
let mock;
|
let mock;
|
||||||
let store;
|
let store;
|
||||||
let component;
|
let component;
|
||||||
let mockGraphData;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
setFixtures(`
|
setFixtures(`
|
||||||
|
@ -123,25 +145,6 @@ describe('Dashboard', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('hides the legend when showLegend is false', done => {
|
|
||||||
component = new DashboardComponent({
|
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
|
||||||
propsData: {
|
|
||||||
...propsData,
|
|
||||||
hasMetrics: true,
|
|
||||||
showLegend: false,
|
|
||||||
},
|
|
||||||
store,
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(component.showEmptyState).toEqual(false);
|
|
||||||
expect(component.$el.querySelector('.legend-group')).toEqual(null);
|
|
||||||
expect(component.$el.querySelector('.prometheus-graph-group')).toBeTruthy();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('hides the group panels when showPanels is false', done => {
|
it('hides the group panels when showPanels is false', done => {
|
||||||
component = new DashboardComponent({
|
component = new DashboardComponent({
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
el: document.querySelector('.prometheus-graphs'),
|
||||||
|
@ -153,34 +156,34 @@ describe('Dashboard', () => {
|
||||||
store,
|
store,
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setupComponentStore(component);
|
||||||
|
|
||||||
|
Vue.nextTick()
|
||||||
|
.then(() => {
|
||||||
expect(component.showEmptyState).toEqual(false);
|
expect(component.showEmptyState).toEqual(false);
|
||||||
expect(component.$el.querySelector('.prometheus-panel')).toEqual(null);
|
expect(component.$el.querySelector('.prometheus-panel')).toEqual(null);
|
||||||
expect(component.$el.querySelector('.prometheus-graph-group')).toBeTruthy();
|
expect(component.$el.querySelector('.prometheus-graph-group')).toBeTruthy();
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the environments dropdown with a number of environments', done => {
|
describe('when all the requests have been commited by the store', () => {
|
||||||
|
beforeEach(() => {
|
||||||
component = new DashboardComponent({
|
component = new DashboardComponent({
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
el: document.querySelector('.prometheus-graphs'),
|
||||||
propsData: {
|
propsData: {
|
||||||
...propsData,
|
...propsData,
|
||||||
hasMetrics: true,
|
hasMetrics: true,
|
||||||
showPanels: false,
|
|
||||||
},
|
},
|
||||||
store,
|
store,
|
||||||
});
|
});
|
||||||
|
|
||||||
component.$store.commit(
|
setupComponentStore(component);
|
||||||
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
|
});
|
||||||
environmentData,
|
|
||||||
);
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
|
||||||
singleGroupResponse,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
it('renders the environments dropdown with a number of environments', done => {
|
||||||
Vue.nextTick()
|
Vue.nextTick()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const dropdownMenuEnvironments = component.$el.querySelectorAll(
|
const dropdownMenuEnvironments = component.$el.querySelectorAll(
|
||||||
|
@ -201,21 +204,37 @@ describe('Dashboard', () => {
|
||||||
.catch(done.fail);
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders the environments dropdown with a single active element', done => {
|
||||||
|
Vue.nextTick()
|
||||||
|
.then(() => {
|
||||||
|
const dropdownItems = component.$el.querySelectorAll(
|
||||||
|
'.js-environments-dropdown .dropdown-item.active',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(dropdownItems.length).toEqual(1);
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done.fail);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('hides the environments dropdown list when there is no environments', done => {
|
it('hides the environments dropdown list when there is no environments', done => {
|
||||||
component = new DashboardComponent({
|
component = new DashboardComponent({
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
el: document.querySelector('.prometheus-graphs'),
|
||||||
propsData: {
|
propsData: {
|
||||||
...propsData,
|
...propsData,
|
||||||
hasMetrics: true,
|
hasMetrics: true,
|
||||||
showPanels: false,
|
|
||||||
},
|
},
|
||||||
store,
|
store,
|
||||||
});
|
});
|
||||||
|
|
||||||
component.$store.commit(`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`, []);
|
|
||||||
component.$store.commit(
|
component.$store.commit(
|
||||||
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
||||||
singleGroupResponse,
|
metricsGroupsAPIResponse,
|
||||||
|
);
|
||||||
|
component.$store.commit(
|
||||||
|
`monitoringDashboard/${types.SET_QUERY_RESULT}`,
|
||||||
|
mockedQueryResultPayload,
|
||||||
);
|
);
|
||||||
|
|
||||||
Vue.nextTick()
|
Vue.nextTick()
|
||||||
|
@ -230,58 +249,6 @@ describe('Dashboard', () => {
|
||||||
.catch(done.fail);
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders the environments dropdown with a single active element', done => {
|
|
||||||
component = new DashboardComponent({
|
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
|
||||||
propsData: {
|
|
||||||
...propsData,
|
|
||||||
hasMetrics: true,
|
|
||||||
showPanels: false,
|
|
||||||
},
|
|
||||||
store,
|
|
||||||
});
|
|
||||||
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
|
|
||||||
environmentData,
|
|
||||||
);
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
|
||||||
singleGroupResponse,
|
|
||||||
);
|
|
||||||
|
|
||||||
Vue.nextTick()
|
|
||||||
.then(() => {
|
|
||||||
const dropdownItems = component.$el.querySelectorAll(
|
|
||||||
'.js-environments-dropdown .dropdown-item.active',
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(dropdownItems.length).toEqual(1);
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
.catch(done.fail);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('hides the dropdown', done => {
|
|
||||||
component = new DashboardComponent({
|
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
|
||||||
propsData: {
|
|
||||||
...propsData,
|
|
||||||
hasMetrics: true,
|
|
||||||
showPanels: false,
|
|
||||||
environmentsEndpoint: '',
|
|
||||||
},
|
|
||||||
store,
|
|
||||||
});
|
|
||||||
|
|
||||||
Vue.nextTick(() => {
|
|
||||||
const dropdownIsActiveElement = component.$el.querySelectorAll('.environments');
|
|
||||||
|
|
||||||
expect(dropdownIsActiveElement.length).toEqual(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders the datetimepicker dropdown', done => {
|
it('renders the datetimepicker dropdown', done => {
|
||||||
component = new DashboardComponent({
|
component = new DashboardComponent({
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
el: document.querySelector('.prometheus-graphs'),
|
||||||
|
@ -293,10 +260,14 @@ describe('Dashboard', () => {
|
||||||
store,
|
store,
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setupComponentStore(component);
|
||||||
|
|
||||||
|
Vue.nextTick()
|
||||||
|
.then(() => {
|
||||||
expect(component.$el.querySelector('.js-time-window-dropdown')).not.toBeNull();
|
expect(component.$el.querySelector('.js-time-window-dropdown')).not.toBeNull();
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fetches the metrics data with proper time window', done => {
|
it('fetches the metrics data with proper time window', done => {
|
||||||
|
@ -347,14 +318,21 @@ describe('Dashboard', () => {
|
||||||
el: document.querySelector('.prometheus-graphs'),
|
el: document.querySelector('.prometheus-graphs'),
|
||||||
propsData: { ...propsData, hasMetrics: true },
|
propsData: { ...propsData, hasMetrics: true },
|
||||||
store,
|
store,
|
||||||
|
sync: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setupComponentStore(component);
|
||||||
const selectedTimeWindow = component.$el.querySelector('.js-time-window-dropdown .active');
|
|
||||||
|
Vue.nextTick()
|
||||||
|
.then(() => {
|
||||||
|
const selectedTimeWindow = component.$el.querySelector(
|
||||||
|
'.js-time-window-dropdown .active',
|
||||||
|
);
|
||||||
|
|
||||||
expect(selectedTimeWindow.textContent.trim()).toEqual('30 minutes');
|
expect(selectedTimeWindow.textContent.trim()).toEqual('30 minutes');
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows an error message if invalid url parameters are passed', done => {
|
it('shows an error message if invalid url parameters are passed', done => {
|
||||||
|
@ -381,29 +359,36 @@ describe('Dashboard', () => {
|
||||||
describe('drag and drop function', () => {
|
describe('drag and drop function', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let expectedPanelCount; // also called metrics, naming to be improved: https://gitlab.com/gitlab-org/gitlab/issues/31565
|
let expectedPanelCount; // also called metrics, naming to be improved: https://gitlab.com/gitlab-org/gitlab/issues/31565
|
||||||
|
|
||||||
const findDraggables = () => wrapper.findAll(VueDraggable);
|
const findDraggables = () => wrapper.findAll(VueDraggable);
|
||||||
const findEnabledDraggables = () => findDraggables().filter(f => !f.attributes('disabled'));
|
const findEnabledDraggables = () => findDraggables().filter(f => !f.attributes('disabled'));
|
||||||
const findDraggablePanels = () => wrapper.findAll('.js-draggable-panel');
|
const findDraggablePanels = () => wrapper.findAll('.js-draggable-panel');
|
||||||
const findRearrangeButton = () => wrapper.find('.js-rearrange-button');
|
const findRearrangeButton = () => wrapper.find('.js-rearrange-button');
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach(() => {
|
||||||
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
|
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
|
||||||
expectedPanelCount = metricsGroupsAPIResponse.data.reduce(
|
expectedPanelCount = metricsGroupsAPIResponse.reduce(
|
||||||
(acc, d) => d.metrics.length + acc,
|
(acc, group) => group.panels.length + acc,
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
store.dispatch('monitoringDashboard/setFeatureFlags', { additionalPanelTypesEnabled: true });
|
});
|
||||||
|
|
||||||
|
beforeEach(done => {
|
||||||
wrapper = shallowMount(DashboardComponent, {
|
wrapper = shallowMount(DashboardComponent, {
|
||||||
localVue,
|
localVue,
|
||||||
sync: false,
|
sync: false,
|
||||||
propsData: { ...propsData, hasMetrics: true },
|
propsData: { ...propsData, hasMetrics: true },
|
||||||
store,
|
store,
|
||||||
|
attachToDocument: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// not using $nextTicket becuase we must wait for the dashboard
|
setupComponentStore(wrapper.vm);
|
||||||
// to be populated with the mock data results.
|
|
||||||
setTimeout(done);
|
wrapper.vm.$nextTick(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('wraps vuedraggable', () => {
|
it('wraps vuedraggable', () => {
|
||||||
|
@ -444,7 +429,7 @@ describe('Dashboard', () => {
|
||||||
|
|
||||||
it('metrics can be swapped', done => {
|
it('metrics can be swapped', done => {
|
||||||
const firstDraggable = findDraggables().at(0);
|
const firstDraggable = findDraggables().at(0);
|
||||||
const mockMetrics = [...metricsGroupsAPIResponse.data[0].metrics];
|
const mockMetrics = [...metricsGroupsAPIResponse[0].panels];
|
||||||
const value = () => firstDraggable.props('value');
|
const value = () => firstDraggable.props('value');
|
||||||
|
|
||||||
expect(value().length).toBe(mockMetrics.length);
|
expect(value().length).toBe(mockMetrics.length);
|
||||||
|
@ -486,10 +471,6 @@ describe('Dashboard', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
wrapper.destroy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// https://gitlab.com/gitlab-org/gitlab-ce/issues/66922
|
// https://gitlab.com/gitlab-org/gitlab-ce/issues/66922
|
||||||
|
@ -577,24 +558,7 @@ describe('Dashboard', () => {
|
||||||
store,
|
store,
|
||||||
});
|
});
|
||||||
|
|
||||||
component.$store.dispatch('monitoringDashboard/setFeatureFlags', {
|
setupComponentStore(component);
|
||||||
prometheusEndpoint: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
|
|
||||||
environmentData,
|
|
||||||
);
|
|
||||||
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
|
||||||
singleGroupResponse,
|
|
||||||
);
|
|
||||||
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
|
|
||||||
dashboardGitResponse,
|
|
||||||
);
|
|
||||||
|
|
||||||
return Vue.nextTick().then(() => {
|
return Vue.nextTick().then(() => {
|
||||||
promPanel = component.$el.querySelector('.prometheus-panel');
|
promPanel = component.$el.querySelector('.prometheus-panel');
|
||||||
|
@ -707,20 +671,6 @@ describe('Dashboard', () => {
|
||||||
store,
|
store,
|
||||||
});
|
});
|
||||||
|
|
||||||
component.$store.dispatch('monitoringDashboard/setFeatureFlags', {
|
|
||||||
prometheusEndpoint: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_ENVIRONMENTS_DATA_SUCCESS}`,
|
|
||||||
environmentData,
|
|
||||||
);
|
|
||||||
|
|
||||||
component.$store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
|
||||||
singleGroupResponse,
|
|
||||||
);
|
|
||||||
|
|
||||||
component.$store.commit(
|
component.$store.commit(
|
||||||
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
|
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
|
||||||
dashboardGitResponse,
|
dashboardGitResponse,
|
||||||
|
@ -736,38 +686,4 @@ describe('Dashboard', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when downloading metrics data as CSV', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
component = new DashboardComponent({
|
|
||||||
propsData: {
|
|
||||||
...propsData,
|
|
||||||
},
|
|
||||||
store,
|
|
||||||
});
|
|
||||||
store.commit(
|
|
||||||
`monitoringDashboard/${types.RECEIVE_METRICS_DATA_SUCCESS}`,
|
|
||||||
MonitoringMock.data,
|
|
||||||
);
|
|
||||||
[
|
|
||||||
mockGraphData,
|
|
||||||
] = component.$store.state.monitoringDashboard.dashboard.panel_groups[0].metrics;
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('csvText', () => {
|
|
||||||
it('converts metrics data from json to csv', () => {
|
|
||||||
const header = `timestamp,${mockGraphData.y_label}`;
|
|
||||||
const data = mockGraphData.queries[0].result[0].values;
|
|
||||||
const firstRow = `${data[0][0]},${data[0][1]}`;
|
|
||||||
|
|
||||||
expect(component.csvText(mockGraphData)).toMatch(`^${header}\r\n${firstRow}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('downloadCsv', () => {
|
|
||||||
it('produces a link with a Blob', () => {
|
|
||||||
expect(component.downloadCsv(mockGraphData)).toContain(`blob:`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,822 +1,105 @@
|
||||||
import { anomalyMockGraphData as importedAnomalyMockGraphData } from '../../frontend/monitoring/mock_data';
|
import {
|
||||||
|
anomalyMockGraphData as importedAnomalyMockGraphData,
|
||||||
|
deploymentData as importedDeploymentData,
|
||||||
|
metricsNewGroupsAPIResponse as importedMetricsNewGroupsAPIResponse,
|
||||||
|
metricsGroupsAPIResponse as importedMetricsGroupsAPIResponse,
|
||||||
|
} from '../../frontend/monitoring/mock_data';
|
||||||
|
|
||||||
|
// TODO Check if these exports are still needed
|
||||||
export const anomalyMockGraphData = importedAnomalyMockGraphData;
|
export const anomalyMockGraphData = importedAnomalyMockGraphData;
|
||||||
|
export const deploymentData = importedDeploymentData;
|
||||||
|
export const metricsNewGroupsAPIResponse = importedMetricsNewGroupsAPIResponse;
|
||||||
|
export const metricsGroupsAPIResponse = importedMetricsGroupsAPIResponse;
|
||||||
|
|
||||||
export const mockApiEndpoint = `${gl.TEST_HOST}/monitoring/mock`;
|
export const mockApiEndpoint = `${gl.TEST_HOST}/monitoring/mock`;
|
||||||
|
|
||||||
export const mockProjectPath = '/frontend-fixtures/environments-project';
|
export const mockProjectPath = '/frontend-fixtures/environments-project';
|
||||||
|
|
||||||
export const metricsGroupsAPIResponse = {
|
export const mockedQueryResultPayload = {
|
||||||
success: true,
|
metricId: '17_system_metrics_kubernetes_container_memory_average',
|
||||||
data: [
|
|
||||||
{
|
|
||||||
group: 'Kubernetes',
|
|
||||||
priority: 1,
|
|
||||||
metrics: [
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
title: 'Memory usage',
|
|
||||||
weight: 1,
|
|
||||||
queries: [
|
|
||||||
{
|
|
||||||
query_range: 'avg(container_memory_usage_bytes{%{environment_filter}}) / 2^20',
|
|
||||||
label: 'Memory',
|
|
||||||
unit: 'MiB',
|
|
||||||
result: [
|
result: [
|
||||||
{
|
{
|
||||||
metric: {},
|
metric: {},
|
||||||
values: [
|
values: [
|
||||||
[1495700554.925, '8.0390625'],
|
[1563272065.589, '10.396484375'],
|
||||||
[1495700614.925, '8.0390625'],
|
[1563272125.589, '10.333984375'],
|
||||||
[1495700674.925, '8.0390625'],
|
[1563272185.589, '10.333984375'],
|
||||||
[1495700734.925, '8.0390625'],
|
[1563272245.589, '10.333984375'],
|
||||||
[1495700794.925, '8.0390625'],
|
[1563272305.589, '10.333984375'],
|
||||||
[1495700854.925, '8.0390625'],
|
[1563272365.589, '10.333984375'],
|
||||||
[1495700914.925, '8.0390625'],
|
[1563272425.589, '10.38671875'],
|
||||||
[1495700974.925, '8.0390625'],
|
[1563272485.589, '10.333984375'],
|
||||||
[1495701034.925, '8.0390625'],
|
[1563272545.589, '10.333984375'],
|
||||||
[1495701094.925, '8.0390625'],
|
[1563272605.589, '10.333984375'],
|
||||||
[1495701154.925, '8.0390625'],
|
[1563272665.589, '10.333984375'],
|
||||||
[1495701214.925, '8.0390625'],
|
[1563272725.589, '10.333984375'],
|
||||||
[1495701274.925, '8.0390625'],
|
[1563272785.589, '10.396484375'],
|
||||||
[1495701334.925, '8.0390625'],
|
[1563272845.589, '10.333984375'],
|
||||||
[1495701394.925, '8.0390625'],
|
[1563272905.589, '10.333984375'],
|
||||||
[1495701454.925, '8.0390625'],
|
[1563272965.589, '10.3984375'],
|
||||||
[1495701514.925, '8.0390625'],
|
[1563273025.589, '10.337890625'],
|
||||||
[1495701574.925, '8.0390625'],
|
[1563273085.589, '10.34765625'],
|
||||||
[1495701634.925, '8.0390625'],
|
[1563273145.589, '10.337890625'],
|
||||||
[1495701694.925, '8.0390625'],
|
[1563273205.589, '10.337890625'],
|
||||||
[1495701754.925, '8.0390625'],
|
[1563273265.589, '10.337890625'],
|
||||||
[1495701814.925, '8.0390625'],
|
[1563273325.589, '10.337890625'],
|
||||||
[1495701874.925, '8.0390625'],
|
[1563273385.589, '10.337890625'],
|
||||||
[1495701934.925, '8.0390625'],
|
[1563273445.589, '10.337890625'],
|
||||||
[1495701994.925, '8.0390625'],
|
[1563273505.589, '10.337890625'],
|
||||||
[1495702054.925, '8.0390625'],
|
[1563273565.589, '10.337890625'],
|
||||||
[1495702114.925, '8.0390625'],
|
[1563273625.589, '10.337890625'],
|
||||||
[1495702174.925, '8.0390625'],
|
[1563273685.589, '10.337890625'],
|
||||||
[1495702234.925, '8.0390625'],
|
[1563273745.589, '10.337890625'],
|
||||||
[1495702294.925, '8.0390625'],
|
[1563273805.589, '10.337890625'],
|
||||||
[1495702354.925, '8.0390625'],
|
[1563273865.589, '10.390625'],
|
||||||
[1495702414.925, '8.0390625'],
|
[1563273925.589, '10.390625'],
|
||||||
[1495702474.925, '8.0390625'],
|
|
||||||
[1495702534.925, '8.0390625'],
|
|
||||||
[1495702594.925, '8.0390625'],
|
|
||||||
[1495702654.925, '8.0390625'],
|
|
||||||
[1495702714.925, '8.0390625'],
|
|
||||||
[1495702774.925, '8.0390625'],
|
|
||||||
[1495702834.925, '8.0390625'],
|
|
||||||
[1495702894.925, '8.0390625'],
|
|
||||||
[1495702954.925, '8.0390625'],
|
|
||||||
[1495703014.925, '8.0390625'],
|
|
||||||
[1495703074.925, '8.0390625'],
|
|
||||||
[1495703134.925, '8.0390625'],
|
|
||||||
[1495703194.925, '8.0390625'],
|
|
||||||
[1495703254.925, '8.03515625'],
|
|
||||||
[1495703314.925, '8.03515625'],
|
|
||||||
[1495703374.925, '8.03515625'],
|
|
||||||
[1495703434.925, '8.03515625'],
|
|
||||||
[1495703494.925, '8.03515625'],
|
|
||||||
[1495703554.925, '8.03515625'],
|
|
||||||
[1495703614.925, '8.03515625'],
|
|
||||||
[1495703674.925, '8.03515625'],
|
|
||||||
[1495703734.925, '8.03515625'],
|
|
||||||
[1495703794.925, '8.03515625'],
|
|
||||||
[1495703854.925, '8.03515625'],
|
|
||||||
[1495703914.925, '8.03515625'],
|
|
||||||
[1495703974.925, '8.03515625'],
|
|
||||||
[1495704034.925, '8.03515625'],
|
|
||||||
[1495704094.925, '8.03515625'],
|
|
||||||
[1495704154.925, '8.03515625'],
|
|
||||||
[1495704214.925, '7.9296875'],
|
|
||||||
[1495704274.925, '7.9296875'],
|
|
||||||
[1495704334.925, '7.9296875'],
|
|
||||||
[1495704394.925, '7.9296875'],
|
|
||||||
[1495704454.925, '7.9296875'],
|
|
||||||
[1495704514.925, '7.9296875'],
|
|
||||||
[1495704574.925, '7.9296875'],
|
|
||||||
[1495704634.925, '7.9296875'],
|
|
||||||
[1495704694.925, '7.9296875'],
|
|
||||||
[1495704754.925, '7.9296875'],
|
|
||||||
[1495704814.925, '7.9296875'],
|
|
||||||
[1495704874.925, '7.9296875'],
|
|
||||||
[1495704934.925, '7.9296875'],
|
|
||||||
[1495704994.925, '7.9296875'],
|
|
||||||
[1495705054.925, '7.9296875'],
|
|
||||||
[1495705114.925, '7.9296875'],
|
|
||||||
[1495705174.925, '7.9296875'],
|
|
||||||
[1495705234.925, '7.9296875'],
|
|
||||||
[1495705294.925, '7.9296875'],
|
|
||||||
[1495705354.925, '7.9296875'],
|
|
||||||
[1495705414.925, '7.9296875'],
|
|
||||||
[1495705474.925, '7.9296875'],
|
|
||||||
[1495705534.925, '7.9296875'],
|
|
||||||
[1495705594.925, '7.9296875'],
|
|
||||||
[1495705654.925, '7.9296875'],
|
|
||||||
[1495705714.925, '7.9296875'],
|
|
||||||
[1495705774.925, '7.9296875'],
|
|
||||||
[1495705834.925, '7.9296875'],
|
|
||||||
[1495705894.925, '7.9296875'],
|
|
||||||
[1495705954.925, '7.9296875'],
|
|
||||||
[1495706014.925, '7.9296875'],
|
|
||||||
[1495706074.925, '7.9296875'],
|
|
||||||
[1495706134.925, '7.9296875'],
|
|
||||||
[1495706194.925, '7.9296875'],
|
|
||||||
[1495706254.925, '7.9296875'],
|
|
||||||
[1495706314.925, '7.9296875'],
|
|
||||||
[1495706374.925, '7.9296875'],
|
|
||||||
[1495706434.925, '7.9296875'],
|
|
||||||
[1495706494.925, '7.9296875'],
|
|
||||||
[1495706554.925, '7.9296875'],
|
|
||||||
[1495706614.925, '7.9296875'],
|
|
||||||
[1495706674.925, '7.9296875'],
|
|
||||||
[1495706734.925, '7.9296875'],
|
|
||||||
[1495706794.925, '7.9296875'],
|
|
||||||
[1495706854.925, '7.9296875'],
|
|
||||||
[1495706914.925, '7.9296875'],
|
|
||||||
[1495706974.925, '7.9296875'],
|
|
||||||
[1495707034.925, '7.9296875'],
|
|
||||||
[1495707094.925, '7.9296875'],
|
|
||||||
[1495707154.925, '7.9296875'],
|
|
||||||
[1495707214.925, '7.9296875'],
|
|
||||||
[1495707274.925, '7.9296875'],
|
|
||||||
[1495707334.925, '7.9296875'],
|
|
||||||
[1495707394.925, '7.9296875'],
|
|
||||||
[1495707454.925, '7.9296875'],
|
|
||||||
[1495707514.925, '7.9296875'],
|
|
||||||
[1495707574.925, '7.9296875'],
|
|
||||||
[1495707634.925, '7.9296875'],
|
|
||||||
[1495707694.925, '7.9296875'],
|
|
||||||
[1495707754.925, '7.9296875'],
|
|
||||||
[1495707814.925, '7.9296875'],
|
|
||||||
[1495707874.925, '7.9296875'],
|
|
||||||
[1495707934.925, '7.9296875'],
|
|
||||||
[1495707994.925, '7.9296875'],
|
|
||||||
[1495708054.925, '7.9296875'],
|
|
||||||
[1495708114.925, '7.9296875'],
|
|
||||||
[1495708174.925, '7.9296875'],
|
|
||||||
[1495708234.925, '7.9296875'],
|
|
||||||
[1495708294.925, '7.9296875'],
|
|
||||||
[1495708354.925, '7.9296875'],
|
|
||||||
[1495708414.925, '7.9296875'],
|
|
||||||
[1495708474.925, '7.9296875'],
|
|
||||||
[1495708534.925, '7.9296875'],
|
|
||||||
[1495708594.925, '7.9296875'],
|
|
||||||
[1495708654.925, '7.9296875'],
|
|
||||||
[1495708714.925, '7.9296875'],
|
|
||||||
[1495708774.925, '7.9296875'],
|
|
||||||
[1495708834.925, '7.9296875'],
|
|
||||||
[1495708894.925, '7.9296875'],
|
|
||||||
[1495708954.925, '7.8984375'],
|
|
||||||
[1495709014.925, '7.8984375'],
|
|
||||||
[1495709074.925, '7.8984375'],
|
|
||||||
[1495709134.925, '7.8984375'],
|
|
||||||
[1495709194.925, '7.8984375'],
|
|
||||||
[1495709254.925, '7.89453125'],
|
|
||||||
[1495709314.925, '7.89453125'],
|
|
||||||
[1495709374.925, '7.89453125'],
|
|
||||||
[1495709434.925, '7.89453125'],
|
|
||||||
[1495709494.925, '7.89453125'],
|
|
||||||
[1495709554.925, '7.89453125'],
|
|
||||||
[1495709614.925, '7.89453125'],
|
|
||||||
[1495709674.925, '7.89453125'],
|
|
||||||
[1495709734.925, '7.89453125'],
|
|
||||||
[1495709794.925, '7.89453125'],
|
|
||||||
[1495709854.925, '7.89453125'],
|
|
||||||
[1495709914.925, '7.89453125'],
|
|
||||||
[1495709974.925, '7.89453125'],
|
|
||||||
[1495710034.925, '7.89453125'],
|
|
||||||
[1495710094.925, '7.89453125'],
|
|
||||||
[1495710154.925, '7.89453125'],
|
|
||||||
[1495710214.925, '7.89453125'],
|
|
||||||
[1495710274.925, '7.89453125'],
|
|
||||||
[1495710334.925, '7.89453125'],
|
|
||||||
[1495710394.925, '7.89453125'],
|
|
||||||
[1495710454.925, '7.89453125'],
|
|
||||||
[1495710514.925, '7.89453125'],
|
|
||||||
[1495710574.925, '7.89453125'],
|
|
||||||
[1495710634.925, '7.89453125'],
|
|
||||||
[1495710694.925, '7.89453125'],
|
|
||||||
[1495710754.925, '7.89453125'],
|
|
||||||
[1495710814.925, '7.89453125'],
|
|
||||||
[1495710874.925, '7.89453125'],
|
|
||||||
[1495710934.925, '7.89453125'],
|
|
||||||
[1495710994.925, '7.89453125'],
|
|
||||||
[1495711054.925, '7.89453125'],
|
|
||||||
[1495711114.925, '7.89453125'],
|
|
||||||
[1495711174.925, '7.8515625'],
|
|
||||||
[1495711234.925, '7.8515625'],
|
|
||||||
[1495711294.925, '7.8515625'],
|
|
||||||
[1495711354.925, '7.8515625'],
|
|
||||||
[1495711414.925, '7.8515625'],
|
|
||||||
[1495711474.925, '7.8515625'],
|
|
||||||
[1495711534.925, '7.8515625'],
|
|
||||||
[1495711594.925, '7.8515625'],
|
|
||||||
[1495711654.925, '7.8515625'],
|
|
||||||
[1495711714.925, '7.8515625'],
|
|
||||||
[1495711774.925, '7.8515625'],
|
|
||||||
[1495711834.925, '7.8515625'],
|
|
||||||
[1495711894.925, '7.8515625'],
|
|
||||||
[1495711954.925, '7.8515625'],
|
|
||||||
[1495712014.925, '7.8515625'],
|
|
||||||
[1495712074.925, '7.8515625'],
|
|
||||||
[1495712134.925, '7.8515625'],
|
|
||||||
[1495712194.925, '7.8515625'],
|
|
||||||
[1495712254.925, '7.8515625'],
|
|
||||||
[1495712314.925, '7.8515625'],
|
|
||||||
[1495712374.925, '7.8515625'],
|
|
||||||
[1495712434.925, '7.83203125'],
|
|
||||||
[1495712494.925, '7.83203125'],
|
|
||||||
[1495712554.925, '7.83203125'],
|
|
||||||
[1495712614.925, '7.83203125'],
|
|
||||||
[1495712674.925, '7.83203125'],
|
|
||||||
[1495712734.925, '7.83203125'],
|
|
||||||
[1495712794.925, '7.83203125'],
|
|
||||||
[1495712854.925, '7.83203125'],
|
|
||||||
[1495712914.925, '7.83203125'],
|
|
||||||
[1495712974.925, '7.83203125'],
|
|
||||||
[1495713034.925, '7.83203125'],
|
|
||||||
[1495713094.925, '7.83203125'],
|
|
||||||
[1495713154.925, '7.83203125'],
|
|
||||||
[1495713214.925, '7.83203125'],
|
|
||||||
[1495713274.925, '7.83203125'],
|
|
||||||
[1495713334.925, '7.83203125'],
|
|
||||||
[1495713394.925, '7.8125'],
|
|
||||||
[1495713454.925, '7.8125'],
|
|
||||||
[1495713514.925, '7.8125'],
|
|
||||||
[1495713574.925, '7.8125'],
|
|
||||||
[1495713634.925, '7.8125'],
|
|
||||||
[1495713694.925, '7.8125'],
|
|
||||||
[1495713754.925, '7.8125'],
|
|
||||||
[1495713814.925, '7.8125'],
|
|
||||||
[1495713874.925, '7.8125'],
|
|
||||||
[1495713934.925, '7.8125'],
|
|
||||||
[1495713994.925, '7.8125'],
|
|
||||||
[1495714054.925, '7.8125'],
|
|
||||||
[1495714114.925, '7.8125'],
|
|
||||||
[1495714174.925, '7.8125'],
|
|
||||||
[1495714234.925, '7.8125'],
|
|
||||||
[1495714294.925, '7.8125'],
|
|
||||||
[1495714354.925, '7.80859375'],
|
|
||||||
[1495714414.925, '7.80859375'],
|
|
||||||
[1495714474.925, '7.80859375'],
|
|
||||||
[1495714534.925, '7.80859375'],
|
|
||||||
[1495714594.925, '7.80859375'],
|
|
||||||
[1495714654.925, '7.80859375'],
|
|
||||||
[1495714714.925, '7.80859375'],
|
|
||||||
[1495714774.925, '7.80859375'],
|
|
||||||
[1495714834.925, '7.80859375'],
|
|
||||||
[1495714894.925, '7.80859375'],
|
|
||||||
[1495714954.925, '7.80859375'],
|
|
||||||
[1495715014.925, '7.80859375'],
|
|
||||||
[1495715074.925, '7.80859375'],
|
|
||||||
[1495715134.925, '7.80859375'],
|
|
||||||
[1495715194.925, '7.80859375'],
|
|
||||||
[1495715254.925, '7.80859375'],
|
|
||||||
[1495715314.925, '7.80859375'],
|
|
||||||
[1495715374.925, '7.80859375'],
|
|
||||||
[1495715434.925, '7.80859375'],
|
|
||||||
[1495715494.925, '7.80859375'],
|
|
||||||
[1495715554.925, '7.80859375'],
|
|
||||||
[1495715614.925, '7.80859375'],
|
|
||||||
[1495715674.925, '7.80859375'],
|
|
||||||
[1495715734.925, '7.80859375'],
|
|
||||||
[1495715794.925, '7.80859375'],
|
|
||||||
[1495715854.925, '7.80859375'],
|
|
||||||
[1495715914.925, '7.80078125'],
|
|
||||||
[1495715974.925, '7.80078125'],
|
|
||||||
[1495716034.925, '7.80078125'],
|
|
||||||
[1495716094.925, '7.80078125'],
|
|
||||||
[1495716154.925, '7.80078125'],
|
|
||||||
[1495716214.925, '7.796875'],
|
|
||||||
[1495716274.925, '7.796875'],
|
|
||||||
[1495716334.925, '7.796875'],
|
|
||||||
[1495716394.925, '7.796875'],
|
|
||||||
[1495716454.925, '7.796875'],
|
|
||||||
[1495716514.925, '7.796875'],
|
|
||||||
[1495716574.925, '7.796875'],
|
|
||||||
[1495716634.925, '7.796875'],
|
|
||||||
[1495716694.925, '7.796875'],
|
|
||||||
[1495716754.925, '7.796875'],
|
|
||||||
[1495716814.925, '7.796875'],
|
|
||||||
[1495716874.925, '7.79296875'],
|
|
||||||
[1495716934.925, '7.79296875'],
|
|
||||||
[1495716994.925, '7.79296875'],
|
|
||||||
[1495717054.925, '7.79296875'],
|
|
||||||
[1495717114.925, '7.79296875'],
|
|
||||||
[1495717174.925, '7.7890625'],
|
|
||||||
[1495717234.925, '7.7890625'],
|
|
||||||
[1495717294.925, '7.7890625'],
|
|
||||||
[1495717354.925, '7.7890625'],
|
|
||||||
[1495717414.925, '7.7890625'],
|
|
||||||
[1495717474.925, '7.7890625'],
|
|
||||||
[1495717534.925, '7.7890625'],
|
|
||||||
[1495717594.925, '7.7890625'],
|
|
||||||
[1495717654.925, '7.7890625'],
|
|
||||||
[1495717714.925, '7.7890625'],
|
|
||||||
[1495717774.925, '7.7890625'],
|
|
||||||
[1495717834.925, '7.77734375'],
|
|
||||||
[1495717894.925, '7.77734375'],
|
|
||||||
[1495717954.925, '7.77734375'],
|
|
||||||
[1495718014.925, '7.77734375'],
|
|
||||||
[1495718074.925, '7.77734375'],
|
|
||||||
[1495718134.925, '7.7421875'],
|
|
||||||
[1495718194.925, '7.7421875'],
|
|
||||||
[1495718254.925, '7.7421875'],
|
|
||||||
[1495718314.925, '7.7421875'],
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
title: 'CPU usage',
|
|
||||||
y_label: 'CPU',
|
|
||||||
weight: 1,
|
|
||||||
queries: [
|
|
||||||
{
|
|
||||||
appearance: {
|
|
||||||
line: {
|
|
||||||
width: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
query_range:
|
|
||||||
'avg(rate(container_cpu_usage_seconds_total{%{environment_filter}}[2m])) * 100',
|
|
||||||
label: 'Core Usage',
|
|
||||||
unit: 'Cores',
|
|
||||||
result: [
|
|
||||||
{
|
|
||||||
metric: {},
|
|
||||||
values: [
|
|
||||||
[1495700554.925, '0.0010794445585559514'],
|
|
||||||
[1495700614.925, '0.003927214935433527'],
|
|
||||||
[1495700674.925, '0.0053045219047619975'],
|
|
||||||
[1495700734.925, '0.0048892095238097155'],
|
|
||||||
[1495700794.925, '0.005827140952381137'],
|
|
||||||
[1495700854.925, '0.00569846906219937'],
|
|
||||||
[1495700914.925, '0.004972616802849382'],
|
|
||||||
[1495700974.925, '0.005117509523809902'],
|
|
||||||
[1495701034.925, '0.00512389061919564'],
|
|
||||||
[1495701094.925, '0.005199100501890691'],
|
|
||||||
[1495701154.925, '0.005415746394885837'],
|
|
||||||
[1495701214.925, '0.005607682788146286'],
|
|
||||||
[1495701274.925, '0.005641300000000118'],
|
|
||||||
[1495701334.925, '0.0071166279368766495'],
|
|
||||||
[1495701394.925, '0.0063242138095234044'],
|
|
||||||
[1495701454.925, '0.005793314698235304'],
|
|
||||||
[1495701514.925, '0.00703934942237556'],
|
|
||||||
[1495701574.925, '0.006357007076123191'],
|
|
||||||
[1495701634.925, '0.003753167300126738'],
|
|
||||||
[1495701694.925, '0.005018469678430698'],
|
|
||||||
[1495701754.925, '0.0045217153371887'],
|
|
||||||
[1495701814.925, '0.006140104285714119'],
|
|
||||||
[1495701874.925, '0.004818684285714102'],
|
|
||||||
[1495701934.925, '0.005079509718955242'],
|
|
||||||
[1495701994.925, '0.005059981142498263'],
|
|
||||||
[1495702054.925, '0.005269098389538773'],
|
|
||||||
[1495702114.925, '0.005269954285714175'],
|
|
||||||
[1495702174.925, '0.014199241435795856'],
|
|
||||||
[1495702234.925, '0.01511936843111017'],
|
|
||||||
[1495702294.925, '0.0060933692920682875'],
|
|
||||||
[1495702354.925, '0.004945682380952493'],
|
|
||||||
[1495702414.925, '0.005641266666666565'],
|
|
||||||
[1495702474.925, '0.005223752857142996'],
|
|
||||||
[1495702534.925, '0.005743098505699831'],
|
|
||||||
[1495702594.925, '0.00538493380952391'],
|
|
||||||
[1495702654.925, '0.005507793883751339'],
|
|
||||||
[1495702714.925, '0.005666705714285466'],
|
|
||||||
[1495702774.925, '0.006231530000000112'],
|
|
||||||
[1495702834.925, '0.006570768635394899'],
|
|
||||||
[1495702894.925, '0.005551146666666895'],
|
|
||||||
[1495702954.925, '0.005602604737098058'],
|
|
||||||
[1495703014.925, '0.00613993580402159'],
|
|
||||||
[1495703074.925, '0.004770258764368832'],
|
|
||||||
[1495703134.925, '0.005512376671364914'],
|
|
||||||
[1495703194.925, '0.005254436666666674'],
|
|
||||||
[1495703254.925, '0.0050109839141320505'],
|
|
||||||
[1495703314.925, '0.0049478019256960016'],
|
|
||||||
[1495703374.925, '0.0037666860965123463'],
|
|
||||||
[1495703434.925, '0.004813526061656314'],
|
|
||||||
[1495703494.925, '0.005047748095238278'],
|
|
||||||
[1495703554.925, '0.00386494081008772'],
|
|
||||||
[1495703614.925, '0.004304037408111405'],
|
|
||||||
[1495703674.925, '0.004999466661587168'],
|
|
||||||
[1495703734.925, '0.004689140476190834'],
|
|
||||||
[1495703794.925, '0.004746126153582475'],
|
|
||||||
[1495703854.925, '0.004482706382572302'],
|
|
||||||
[1495703914.925, '0.004032808931864524'],
|
|
||||||
[1495703974.925, '0.005728319047618988'],
|
|
||||||
[1495704034.925, '0.004436139179627006'],
|
|
||||||
[1495704094.925, '0.004553455714285617'],
|
|
||||||
[1495704154.925, '0.003455244285714341'],
|
|
||||||
[1495704214.925, '0.004742244761904621'],
|
|
||||||
[1495704274.925, '0.005366978571428422'],
|
|
||||||
[1495704334.925, '0.004257954837665058'],
|
|
||||||
[1495704394.925, '0.005431603259831257'],
|
|
||||||
[1495704454.925, '0.0052009214498621986'],
|
|
||||||
[1495704514.925, '0.004317201904761618'],
|
|
||||||
[1495704574.925, '0.004307384285714157'],
|
|
||||||
[1495704634.925, '0.004789801146644822'],
|
|
||||||
[1495704694.925, '0.0051429795906706485'],
|
|
||||||
[1495704754.925, '0.005322495714285479'],
|
|
||||||
[1495704814.925, '0.004512809333244233'],
|
|
||||||
[1495704874.925, '0.004953843582568726'],
|
|
||||||
[1495704934.925, '0.005812690120858119'],
|
|
||||||
[1495704994.925, '0.004997024285714838'],
|
|
||||||
[1495705054.925, '0.005246216154439592'],
|
|
||||||
[1495705114.925, '0.0063494966618726795'],
|
|
||||||
[1495705174.925, '0.005306004342898225'],
|
|
||||||
[1495705234.925, '0.005081412857142978'],
|
|
||||||
[1495705294.925, '0.00511409523809522'],
|
|
||||||
[1495705354.925, '0.0047861001481192'],
|
|
||||||
[1495705414.925, '0.005107688228042962'],
|
|
||||||
[1495705474.925, '0.005271929582294012'],
|
|
||||||
[1495705534.925, '0.004453254502681249'],
|
|
||||||
[1495705594.925, '0.005799134293959226'],
|
|
||||||
[1495705654.925, '0.005340865929502478'],
|
|
||||||
[1495705714.925, '0.004911654761904942'],
|
|
||||||
[1495705774.925, '0.005888234873953261'],
|
|
||||||
[1495705834.925, '0.005565283333332954'],
|
|
||||||
[1495705894.925, '0.005522869047618869'],
|
|
||||||
[1495705954.925, '0.005177549737621646'],
|
|
||||||
[1495706014.925, '0.0053145810232096465'],
|
|
||||||
[1495706074.925, '0.004751095238095275'],
|
|
||||||
[1495706134.925, '0.006242077142856976'],
|
|
||||||
[1495706194.925, '0.00621034406957871'],
|
|
||||||
[1495706254.925, '0.006887592738978596'],
|
|
||||||
[1495706314.925, '0.006328128779726213'],
|
|
||||||
[1495706374.925, '0.007488363809523927'],
|
|
||||||
[1495706434.925, '0.006193758571428157'],
|
|
||||||
[1495706494.925, '0.0068798371839706935'],
|
|
||||||
[1495706554.925, '0.005757034340423128'],
|
|
||||||
[1495706614.925, '0.004571388497294698'],
|
|
||||||
[1495706674.925, '0.00620283044923395'],
|
|
||||||
[1495706734.925, '0.005607562380952455'],
|
|
||||||
[1495706794.925, '0.005506969933620308'],
|
|
||||||
[1495706854.925, '0.005621118095238131'],
|
|
||||||
[1495706914.925, '0.004876606098698849'],
|
|
||||||
[1495706974.925, '0.0047871205988517206'],
|
|
||||||
[1495707034.925, '0.00526405939458784'],
|
|
||||||
[1495707094.925, '0.005716323800605852'],
|
|
||||||
[1495707154.925, '0.005301459523809575'],
|
|
||||||
[1495707214.925, '0.0051613042857144905'],
|
|
||||||
[1495707274.925, '0.005384792857142714'],
|
|
||||||
[1495707334.925, '0.005259719047619222'],
|
|
||||||
[1495707394.925, '0.00584101142857182'],
|
|
||||||
[1495707454.925, '0.0060066121920326326'],
|
|
||||||
[1495707514.925, '0.006359978571428453'],
|
|
||||||
[1495707574.925, '0.006315876322151109'],
|
|
||||||
[1495707634.925, '0.005590012517198831'],
|
|
||||||
[1495707694.925, '0.005517419877137072'],
|
|
||||||
[1495707754.925, '0.006089813430348506'],
|
|
||||||
[1495707814.925, '0.00466754476190479'],
|
|
||||||
[1495707874.925, '0.006059954380517721'],
|
|
||||||
[1495707934.925, '0.005085657142856972'],
|
|
||||||
[1495707994.925, '0.005897665238095296'],
|
|
||||||
[1495708054.925, '0.0062282023199555885'],
|
|
||||||
[1495708114.925, '0.00526214553236979'],
|
|
||||||
[1495708174.925, '0.0044803300000000644'],
|
|
||||||
[1495708234.925, '0.005421443333333592'],
|
|
||||||
[1495708294.925, '0.005694326244512144'],
|
|
||||||
[1495708354.925, '0.005527721904761457'],
|
|
||||||
[1495708414.925, '0.005988819523809819'],
|
|
||||||
[1495708474.925, '0.005484704285714448'],
|
|
||||||
[1495708534.925, '0.005041123649230085'],
|
|
||||||
[1495708594.925, '0.005717767639612059'],
|
|
||||||
[1495708654.925, '0.005412954417342863'],
|
|
||||||
[1495708714.925, '0.005833343333333254'],
|
|
||||||
[1495708774.925, '0.005448135238094969'],
|
|
||||||
[1495708834.925, '0.005117341428571432'],
|
|
||||||
[1495708894.925, '0.005888345825277833'],
|
|
||||||
[1495708954.925, '0.005398543809524135'],
|
|
||||||
[1495709014.925, '0.005325611428571416'],
|
|
||||||
[1495709074.925, '0.005848668571428527'],
|
|
||||||
[1495709134.925, '0.005135003105145044'],
|
|
||||||
[1495709194.925, '0.0054551400000003'],
|
|
||||||
[1495709254.925, '0.005319472937322171'],
|
|
||||||
[1495709314.925, '0.00585677857142792'],
|
|
||||||
[1495709374.925, '0.0062146261904759215'],
|
|
||||||
[1495709434.925, '0.0067105060904182265'],
|
|
||||||
[1495709494.925, '0.005829691904762108'],
|
|
||||||
[1495709554.925, '0.005719280952381261'],
|
|
||||||
[1495709614.925, '0.005682603793416407'],
|
|
||||||
[1495709674.925, '0.0055272846277326934'],
|
|
||||||
[1495709734.925, '0.0057123680952386735'],
|
|
||||||
[1495709794.925, '0.00520597958075818'],
|
|
||||||
[1495709854.925, '0.005584358957263837'],
|
|
||||||
[1495709914.925, '0.005601104275197466'],
|
|
||||||
[1495709974.925, '0.005991657142857066'],
|
|
||||||
[1495710034.925, '0.00553722238095218'],
|
|
||||||
[1495710094.925, '0.005127883122696293'],
|
|
||||||
[1495710154.925, '0.005498111927534584'],
|
|
||||||
[1495710214.925, '0.005609934069084202'],
|
|
||||||
[1495710274.925, '0.00459206285714307'],
|
|
||||||
[1495710334.925, '0.0047910828571428084'],
|
|
||||||
[1495710394.925, '0.0056014671288845685'],
|
|
||||||
[1495710454.925, '0.005686936791078528'],
|
|
||||||
[1495710514.925, '0.00444480476190448'],
|
|
||||||
[1495710574.925, '0.005780394696738921'],
|
|
||||||
[1495710634.925, '0.0053107227550210365'],
|
|
||||||
[1495710694.925, '0.005096031495761817'],
|
|
||||||
[1495710754.925, '0.005451377979091524'],
|
|
||||||
[1495710814.925, '0.005328136666667083'],
|
|
||||||
[1495710874.925, '0.006020612857143043'],
|
|
||||||
[1495710934.925, '0.0061063585714285365'],
|
|
||||||
[1495710994.925, '0.006018346015752312'],
|
|
||||||
[1495711054.925, '0.005069130952381193'],
|
|
||||||
[1495711114.925, '0.005458406190476052'],
|
|
||||||
[1495711174.925, '0.00577219190476179'],
|
|
||||||
[1495711234.925, '0.005760814645658314'],
|
|
||||||
[1495711294.925, '0.005371875716579101'],
|
|
||||||
[1495711354.925, '0.0064232666666665834'],
|
|
||||||
[1495711414.925, '0.009369806836906667'],
|
|
||||||
[1495711474.925, '0.008956864761904692'],
|
|
||||||
[1495711534.925, '0.005266849368559271'],
|
|
||||||
[1495711594.925, '0.005335111364934262'],
|
|
||||||
[1495711654.925, '0.006461778319586945'],
|
|
||||||
[1495711714.925, '0.004687939890762393'],
|
|
||||||
[1495711774.925, '0.004438831245760684'],
|
|
||||||
[1495711834.925, '0.005142786666666613'],
|
|
||||||
[1495711894.925, '0.007257734212054963'],
|
|
||||||
[1495711954.925, '0.005621991904761494'],
|
|
||||||
[1495712014.925, '0.007868689999999862'],
|
|
||||||
[1495712074.925, '0.00910970215275738'],
|
|
||||||
[1495712134.925, '0.006151004285714278'],
|
|
||||||
[1495712194.925, '0.005447120924961522'],
|
|
||||||
[1495712254.925, '0.005150705153929503'],
|
|
||||||
[1495712314.925, '0.006358108714969314'],
|
|
||||||
[1495712374.925, '0.0057725354795696475'],
|
|
||||||
[1495712434.925, '0.005232139047619015'],
|
|
||||||
[1495712494.925, '0.004932809617949037'],
|
|
||||||
[1495712554.925, '0.004511607508499662'],
|
|
||||||
[1495712614.925, '0.00440487701522666'],
|
|
||||||
[1495712674.925, '0.005479113333333174'],
|
|
||||||
[1495712734.925, '0.004726317619047547'],
|
|
||||||
[1495712794.925, '0.005582041102958029'],
|
|
||||||
[1495712854.925, '0.006381481216082099'],
|
|
||||||
[1495712914.925, '0.005474260014095208'],
|
|
||||||
[1495712974.925, '0.00567597142857188'],
|
|
||||||
[1495713034.925, '0.0064741233333332985'],
|
|
||||||
[1495713094.925, '0.005467475714285271'],
|
|
||||||
[1495713154.925, '0.004868648393824457'],
|
|
||||||
[1495713214.925, '0.005254923286444893'],
|
|
||||||
[1495713274.925, '0.005599217150312865'],
|
|
||||||
[1495713334.925, '0.005105413720618919'],
|
|
||||||
[1495713394.925, '0.007246073333333279'],
|
|
||||||
[1495713454.925, '0.005990312380952272'],
|
|
||||||
[1495713514.925, '0.005594601853351101'],
|
|
||||||
[1495713574.925, '0.004739258673727054'],
|
|
||||||
[1495713634.925, '0.003932121428571783'],
|
|
||||||
[1495713694.925, '0.005018188268459395'],
|
|
||||||
[1495713754.925, '0.004538238095237985'],
|
|
||||||
[1495713814.925, '0.00561816643265435'],
|
|
||||||
[1495713874.925, '0.0063132584495033586'],
|
|
||||||
[1495713934.925, '0.00442385238095213'],
|
|
||||||
[1495713994.925, '0.004181795887658453'],
|
|
||||||
[1495714054.925, '0.004437759047619037'],
|
|
||||||
[1495714114.925, '0.006421748157178241'],
|
|
||||||
[1495714174.925, '0.006525143809523842'],
|
|
||||||
[1495714234.925, '0.004715904935144247'],
|
|
||||||
[1495714294.925, '0.005966040152763461'],
|
|
||||||
[1495714354.925, '0.005614535466921674'],
|
|
||||||
[1495714414.925, '0.004934375119415906'],
|
|
||||||
[1495714474.925, '0.0054122933333327385'],
|
|
||||||
[1495714534.925, '0.004926540699612279'],
|
|
||||||
[1495714594.925, '0.006124649517134237'],
|
|
||||||
[1495714654.925, '0.004629427092013995'],
|
|
||||||
[1495714714.925, '0.005117951257607005'],
|
|
||||||
[1495714774.925, '0.004868774512685422'],
|
|
||||||
[1495714834.925, '0.005310093333333399'],
|
|
||||||
[1495714894.925, '0.0054907752286127345'],
|
|
||||||
[1495714954.925, '0.004597678117351089'],
|
|
||||||
[1495715014.925, '0.0059622552380952'],
|
|
||||||
[1495715074.925, '0.005352457072655368'],
|
|
||||||
[1495715134.925, '0.005491630952381143'],
|
|
||||||
[1495715194.925, '0.006391770078379791'],
|
|
||||||
[1495715254.925, '0.005933472857142518'],
|
|
||||||
[1495715314.925, '0.005301314285714163'],
|
|
||||||
[1495715374.925, '0.0058352959724814165'],
|
|
||||||
[1495715434.925, '0.006154755147867044'],
|
|
||||||
[1495715494.925, '0.009391935637482038'],
|
|
||||||
[1495715554.925, '0.007846462857142592'],
|
|
||||||
[1495715614.925, '0.00477608215316353'],
|
|
||||||
[1495715674.925, '0.006132865238094998'],
|
|
||||||
[1495715734.925, '0.006159762457649516'],
|
|
||||||
[1495715794.925, '0.005957307073265968'],
|
|
||||||
[1495715854.925, '0.006652319091792501'],
|
|
||||||
[1495715914.925, '0.005493557402895287'],
|
|
||||||
[1495715974.925, '0.0058652434829145166'],
|
|
||||||
[1495716034.925, '0.005627400430468021'],
|
|
||||||
[1495716094.925, '0.006240656190475609'],
|
|
||||||
[1495716154.925, '0.006305997676168624'],
|
|
||||||
[1495716214.925, '0.005388057732783248'],
|
|
||||||
[1495716274.925, '0.0052814916048421244'],
|
|
||||||
[1495716334.925, '0.00699498614272497'],
|
|
||||||
[1495716394.925, '0.00627768693035141'],
|
|
||||||
[1495716454.925, '0.0042411487048161145'],
|
|
||||||
[1495716514.925, '0.005348647473627653'],
|
|
||||||
[1495716574.925, '0.0047176657142853975'],
|
|
||||||
[1495716634.925, '0.004437898571428686'],
|
|
||||||
[1495716694.925, '0.004923527366927261'],
|
|
||||||
[1495716754.925, '0.005131935066048421'],
|
|
||||||
[1495716814.925, '0.005046949523809611'],
|
|
||||||
[1495716874.925, '0.00547184095238092'],
|
|
||||||
[1495716934.925, '0.005224140016380444'],
|
|
||||||
[1495716994.925, '0.005297991171665292'],
|
|
||||||
[1495717054.925, '0.005492965995623498'],
|
|
||||||
[1495717114.925, '0.005754660000000403'],
|
|
||||||
[1495717174.925, '0.005949557138639285'],
|
|
||||||
[1495717234.925, '0.006091816112534666'],
|
|
||||||
[1495717294.925, '0.005554210080192063'],
|
|
||||||
[1495717354.925, '0.006411504395279871'],
|
|
||||||
[1495717414.925, '0.006319643996609606'],
|
|
||||||
[1495717474.925, '0.005539174405717675'],
|
|
||||||
[1495717534.925, '0.0053157078842772255'],
|
|
||||||
[1495717594.925, '0.005247480952381066'],
|
|
||||||
[1495717654.925, '0.004820141620396252'],
|
|
||||||
[1495717714.925, '0.005906173868322844'],
|
|
||||||
[1495717774.925, '0.006173117219570961'],
|
|
||||||
[1495717834.925, '0.005963340952380661'],
|
|
||||||
[1495717894.925, '0.005698976627681527'],
|
|
||||||
[1495717954.925, '0.004751279096346378'],
|
|
||||||
[1495718014.925, '0.005733142379359711'],
|
|
||||||
[1495718074.925, '0.004831689010348035'],
|
|
||||||
[1495718134.925, '0.005188370476191092'],
|
|
||||||
[1495718194.925, '0.004793227554547938'],
|
|
||||||
[1495718254.925, '0.003997442857142731'],
|
|
||||||
[1495718314.925, '0.004386040132951264'],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
group: 'NGINX',
|
|
||||||
priority: 2,
|
|
||||||
metrics: [
|
|
||||||
{
|
|
||||||
id: 100,
|
|
||||||
title: 'Http Error Rate',
|
|
||||||
weight: 100,
|
|
||||||
queries: [
|
|
||||||
{
|
|
||||||
query_range:
|
|
||||||
'sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"nginx-test-8691397-production-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"nginx-test-8691397-production-.*"}[2m])) * 100',
|
|
||||||
label: '5xx errors',
|
|
||||||
unit: '%',
|
|
||||||
result: [
|
|
||||||
{
|
|
||||||
metric: {},
|
|
||||||
values: [
|
|
||||||
[1495700554.925, NaN],
|
|
||||||
[1495700614.925, NaN],
|
|
||||||
[1495700674.925, NaN],
|
|
||||||
[1495700734.925, NaN],
|
|
||||||
[1495700794.925, NaN],
|
|
||||||
[1495700854.925, NaN],
|
|
||||||
[1495700914.925, NaN],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
last_update: '2017-05-25T13:18:34.949Z',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const singleGroupResponse = [
|
|
||||||
{
|
|
||||||
group: 'System metrics (Kubernetes)',
|
|
||||||
priority: 5,
|
|
||||||
metrics: [
|
|
||||||
{
|
|
||||||
title: 'Memory Usage (Total)',
|
|
||||||
weight: 0,
|
|
||||||
y_label: 'Total Memory Used',
|
|
||||||
queries: [
|
|
||||||
{
|
|
||||||
query_range:
|
|
||||||
'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^production-(.*)",namespace="autodevops-deploy-33"}) by (job)) without (job) /1024/1024/1024',
|
|
||||||
unit: 'GB',
|
|
||||||
label: 'Total',
|
|
||||||
result: [
|
|
||||||
{
|
|
||||||
metric: {},
|
|
||||||
values: [
|
|
||||||
[1558453960.079, '0.0357666015625'],
|
|
||||||
[1558454020.079, '0.035675048828125'],
|
|
||||||
[1558454080.079, '0.035152435302734375'],
|
|
||||||
[1558454140.079, '0.035221099853515625'],
|
|
||||||
[1558454200.079, '0.0352325439453125'],
|
|
||||||
[1558454260.079, '0.03479766845703125'],
|
|
||||||
[1558454320.079, '0.034793853759765625'],
|
|
||||||
[1558454380.079, '0.034931182861328125'],
|
|
||||||
[1558454440.079, '0.034816741943359375'],
|
|
||||||
[1558454500.079, '0.034816741943359375'],
|
|
||||||
[1558454560.079, '0.034816741943359375'],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
id: 15,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default metricsGroupsAPIResponse;
|
|
||||||
|
|
||||||
export const deploymentData = [
|
|
||||||
{
|
|
||||||
id: 111,
|
|
||||||
iid: 3,
|
|
||||||
sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
|
||||||
commitUrl:
|
|
||||||
'http://test.host/frontend-fixtures/environments-project/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
|
||||||
ref: {
|
|
||||||
name: 'master',
|
|
||||||
},
|
|
||||||
created_at: '2017-05-31T21:23:37.881Z',
|
|
||||||
tag: false,
|
|
||||||
tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
|
|
||||||
'last?': true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 110,
|
|
||||||
iid: 2,
|
|
||||||
sha: 'f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
|
||||||
commitUrl:
|
|
||||||
'http://test.host/frontend-fixtures/environments-project/commit/f5bcd1d9dac6fa4137e2510b9ccd134ef2e84187',
|
|
||||||
ref: {
|
|
||||||
name: 'master',
|
|
||||||
},
|
|
||||||
created_at: '2017-05-30T20:08:04.629Z',
|
|
||||||
tag: false,
|
|
||||||
tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
|
|
||||||
'last?': false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 109,
|
|
||||||
iid: 1,
|
|
||||||
sha: '6511e58faafaa7ad2228990ec57f19d66f7db7c2',
|
|
||||||
commitUrl:
|
|
||||||
'http://test.host/frontend-fixtures/environments-project/commit/6511e58faafaa7ad2228990ec57f19d66f7db7c2',
|
|
||||||
ref: {
|
|
||||||
name: 'update2-readme',
|
|
||||||
},
|
|
||||||
created_at: '2017-05-30T17:42:38.409Z',
|
|
||||||
tag: false,
|
|
||||||
tagUrl: 'http://test.host/frontend-fixtures/environments-project/tags/false',
|
|
||||||
'last?': false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const statePaths = {
|
|
||||||
settingsPath: '/root/hello-prometheus/services/prometheus/edit',
|
|
||||||
clustersPath: '/root/hello-prometheus/clusters',
|
|
||||||
documentationPath: '/help/administration/monitoring/prometheus/index.md',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const queryWithoutData = {
|
|
||||||
title: 'HTTP Error rate',
|
|
||||||
weight: 10,
|
|
||||||
y_label: 'Http Error Rate',
|
|
||||||
queries: [
|
|
||||||
{
|
|
||||||
query_range:
|
|
||||||
'sum(rate(nginx_upstream_responses_total{status_code="5xx", upstream=~"nginx-test-8691397-production-.*"}[2m])) / sum(rate(nginx_upstream_responses_total{upstream=~"nginx-test-8691397-production-.*"}[2m])) * 100',
|
|
||||||
label: '5xx errors',
|
|
||||||
unit: '%',
|
|
||||||
result: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function convertDatesMultipleSeries(multipleSeries) {
|
export const mockedQueryResultPayloadCoresTotal = {
|
||||||
const convertedMultiple = multipleSeries;
|
metricId: '13_system_metrics_kubernetes_container_cores_total',
|
||||||
multipleSeries.forEach((column, index) => {
|
result: [
|
||||||
let convertedResult = [];
|
{
|
||||||
convertedResult = column.queries[0].result.map(resultObj => {
|
metric: {},
|
||||||
const convertedMetrics = {};
|
values: [
|
||||||
convertedMetrics.values = resultObj.values.map(val => ({
|
[1563272065.589, '9.396484375'],
|
||||||
time: new Date(val.time),
|
[1563272125.589, '9.333984375'],
|
||||||
value: val.value,
|
[1563272185.589, '9.333984375'],
|
||||||
}));
|
[1563272245.589, '9.333984375'],
|
||||||
convertedMetrics.metric = resultObj.metric;
|
[1563272305.589, '9.333984375'],
|
||||||
return convertedMetrics;
|
[1563272365.589, '9.333984375'],
|
||||||
});
|
[1563272425.589, '9.38671875'],
|
||||||
convertedMultiple[index].queries[0].result = convertedResult;
|
[1563272485.589, '9.333984375'],
|
||||||
});
|
[1563272545.589, '9.333984375'],
|
||||||
return convertedMultiple;
|
[1563272605.589, '9.333984375'],
|
||||||
}
|
[1563272665.589, '9.333984375'],
|
||||||
|
[1563272725.589, '9.333984375'],
|
||||||
|
[1563272785.589, '9.396484375'],
|
||||||
|
[1563272845.589, '9.333984375'],
|
||||||
|
[1563272905.589, '9.333984375'],
|
||||||
|
[1563272965.589, '9.3984375'],
|
||||||
|
[1563273025.589, '9.337890625'],
|
||||||
|
[1563273085.589, '9.34765625'],
|
||||||
|
[1563273145.589, '9.337890625'],
|
||||||
|
[1563273205.589, '9.337890625'],
|
||||||
|
[1563273265.589, '9.337890625'],
|
||||||
|
[1563273325.589, '9.337890625'],
|
||||||
|
[1563273385.589, '9.337890625'],
|
||||||
|
[1563273445.589, '9.337890625'],
|
||||||
|
[1563273505.589, '9.337890625'],
|
||||||
|
[1563273565.589, '9.337890625'],
|
||||||
|
[1563273625.589, '9.337890625'],
|
||||||
|
[1563273685.589, '9.337890625'],
|
||||||
|
[1563273745.589, '9.337890625'],
|
||||||
|
[1563273805.589, '9.337890625'],
|
||||||
|
[1563273865.589, '9.390625'],
|
||||||
|
[1563273925.589, '9.390625'],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
export const environmentData = [
|
export const environmentData = [
|
||||||
{
|
{
|
||||||
|
@ -1006,7 +289,7 @@ export const graphDataPrometheusQueryRange = {
|
||||||
],
|
],
|
||||||
queries: [
|
queries: [
|
||||||
{
|
{
|
||||||
metricId: null,
|
metricId: '10',
|
||||||
id: 'metric_a1',
|
id: 'metric_a1',
|
||||||
metric_id: 2,
|
metric_id: 2,
|
||||||
query_range:
|
query_range:
|
||||||
|
|
|
@ -317,7 +317,7 @@ describe('Monitoring store actions', () => {
|
||||||
const metric = metricsDashboardResponse.dashboard.panel_groups[0].panels[0].metrics[0];
|
const metric = metricsDashboardResponse.dashboard.panel_groups[0].panels[0].metrics[0];
|
||||||
const state = storeState();
|
const state = storeState();
|
||||||
|
|
||||||
const data = metricsGroupsAPIResponse.data[0].metrics[0].queries[0];
|
const data = metricsGroupsAPIResponse[0].panels[0].metrics[0];
|
||||||
const response = { data };
|
const response = { data };
|
||||||
mock.onGet('http://test').reply(200, response);
|
mock.onGet('http://test').reply(200, response);
|
||||||
|
|
||||||
|
|
|
@ -21,79 +21,46 @@ describe('Monitoring mutations', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
stateCopy.dashboard.panel_groups = [];
|
stateCopy.dashboard.panel_groups = [];
|
||||||
groups = metricsGroupsAPIResponse.data;
|
groups = metricsGroupsAPIResponse;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds a key to the group', () => {
|
it('adds a key to the group', () => {
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
||||||
|
|
||||||
expect(stateCopy.dashboard.panel_groups[0].key).toBe('kubernetes-0');
|
expect(stateCopy.dashboard.panel_groups[0].key).toBe('system-metrics-kubernetes--0');
|
||||||
expect(stateCopy.dashboard.panel_groups[1].key).toBe('nginx-1');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('normalizes values', () => {
|
it('normalizes values', () => {
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
||||||
|
|
||||||
const expectedTimestamp = '2017-05-25T08:22:34.925Z';
|
const expectedLabel = 'Pod average';
|
||||||
const expectedValue = 8.0390625;
|
const { label, query_range } = stateCopy.dashboard.panel_groups[0].metrics[0].metrics[0];
|
||||||
const [
|
|
||||||
timestamp,
|
|
||||||
value,
|
|
||||||
] = stateCopy.dashboard.panel_groups[0].metrics[0].queries[0].result[0].values[0];
|
|
||||||
|
|
||||||
expect(timestamp).toEqual(expectedTimestamp);
|
expect(label).toEqual(expectedLabel);
|
||||||
expect(value).toEqual(expectedValue);
|
expect(query_range.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contains two groups that contains, one of which has two queries sorted by priority', () => {
|
it('contains one group, which it has two panels and one metrics property', () => {
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
||||||
|
|
||||||
expect(stateCopy.dashboard.panel_groups).toBeDefined();
|
expect(stateCopy.dashboard.panel_groups).toBeDefined();
|
||||||
expect(stateCopy.dashboard.panel_groups.length).toEqual(2);
|
expect(stateCopy.dashboard.panel_groups.length).toEqual(1);
|
||||||
expect(stateCopy.dashboard.panel_groups[0].metrics.length).toEqual(2);
|
expect(stateCopy.dashboard.panel_groups[0].panels.length).toEqual(2);
|
||||||
|
expect(stateCopy.dashboard.panel_groups[0].panels[0].metrics.length).toEqual(1);
|
||||||
|
expect(stateCopy.dashboard.panel_groups[0].panels[1].metrics.length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('assigns queries a metric id', () => {
|
it('assigns queries a metric id', () => {
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
||||||
|
|
||||||
expect(stateCopy.dashboard.panel_groups[1].metrics[0].queries[0].metricId).toEqual('100');
|
expect(stateCopy.dashboard.panel_groups[0].metrics[0].queries[0].metricId).toEqual(
|
||||||
|
'17_system_metrics_kubernetes_container_memory_average',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('removes the data if all the values from a query are not defined', () => {
|
describe('dashboard endpoint', () => {
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, groups);
|
|
||||||
|
|
||||||
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.dashboard.panel_groups = [];
|
|
||||||
const noId = groups.map(group => ({
|
|
||||||
...group,
|
|
||||||
...{
|
|
||||||
metrics: group.metrics.map(metric => {
|
|
||||||
const { id, ...metricWithoutId } = metric;
|
|
||||||
|
|
||||||
return metricWithoutId;
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, noId);
|
|
||||||
|
|
||||||
stateCopy.dashboard.panel_groups.forEach(group => {
|
|
||||||
group.metrics.forEach(metric => {
|
|
||||||
expect(metric.queries.every(query => query.metricId === null)).toBe(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('dashboard endpoint enabled', () => {
|
|
||||||
const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
|
const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
stateCopy.useDashboardEndpoint = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('aliases group panels to metrics for backwards compatibility', () => {
|
it('aliases group panels to metrics for backwards compatibility', () => {
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
|
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
|
||||||
|
|
||||||
|
@ -143,7 +110,6 @@ describe('Monitoring mutations', () => {
|
||||||
const result = [{ values: [[0, 1], [1, 1], [1, 3]] }];
|
const result = [{ values: [[0, 1], [1, 1], [1, 3]] }];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
stateCopy.useDashboardEndpoint = true;
|
|
||||||
const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
|
const dashboardGroups = metricsDashboardResponse.dashboard.panel_groups;
|
||||||
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
|
mutations[types.RECEIVE_METRICS_DATA_SUCCESS](stateCopy, dashboardGroups);
|
||||||
});
|
});
|
||||||
|
|
|
@ -48,6 +48,10 @@ describe Gitlab::UsageData do
|
||||||
create(:clusters_applications_knative, :installed, cluster: gcp_cluster)
|
create(:clusters_applications_knative, :installed, cluster: gcp_cluster)
|
||||||
create(:clusters_applications_elastic_stack, :installed, cluster: gcp_cluster)
|
create(:clusters_applications_elastic_stack, :installed, cluster: gcp_cluster)
|
||||||
|
|
||||||
|
create(:grafana_integration, project: projects[0], enabled: true)
|
||||||
|
create(:grafana_integration, project: projects[1], enabled: true)
|
||||||
|
create(:grafana_integration, project: projects[2], enabled: false)
|
||||||
|
|
||||||
ProjectFeature.first.update_attribute('repository_access_level', 0)
|
ProjectFeature.first.update_attribute('repository_access_level', 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -140,6 +144,7 @@ describe Gitlab::UsageData do
|
||||||
clusters_applications_knative
|
clusters_applications_knative
|
||||||
clusters_applications_elastic_stack
|
clusters_applications_elastic_stack
|
||||||
in_review_folder
|
in_review_folder
|
||||||
|
grafana_integrated_projects
|
||||||
groups
|
groups
|
||||||
issues
|
issues
|
||||||
issues_with_associated_zoom_link
|
issues_with_associated_zoom_link
|
||||||
|
@ -221,6 +226,7 @@ describe Gitlab::UsageData do
|
||||||
expect(count_data[:clusters_applications_runner]).to eq(1)
|
expect(count_data[:clusters_applications_runner]).to eq(1)
|
||||||
expect(count_data[:clusters_applications_knative]).to eq(1)
|
expect(count_data[:clusters_applications_knative]).to eq(1)
|
||||||
expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
|
expect(count_data[:clusters_applications_elastic_stack]).to eq(1)
|
||||||
|
expect(count_data[:grafana_integrated_projects]).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'works when queries time out' do
|
it 'works when queries time out' do
|
||||||
|
|
Loading…
Reference in New Issue