2017-12-20 05:33:33 -06:00
|
|
|
import { GraphiteDatasource } from '../datasource';
|
|
|
|
import _ from 'lodash';
|
2019-12-05 03:04:03 -06:00
|
|
|
|
2019-08-07 08:50:06 -05:00
|
|
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
Field: getFieldTitle as field / series display identity and use it in all field name matchers & field / series name displays (#24024)
* common title handling
* show labels
* update comment
* Update changelog for v7.0.0-beta1 (#24007)
Co-Authored-By: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-Authored-By: Andrej Ocenas <mr.ocenas@gmail.com>
Co-Authored-By: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
* verify-repo-update: Fix Dockerfile.deb (#24030)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Upgrade build pipeline tool (#24021)
* CircleCI: Upgrade build pipeline tool
* Devenv: ignore enterprise (#24037)
* Add header icon to Add data source page (#24033)
* latest.json: Update testing version (#24038)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Fix login page redirected from password reset (#24032)
* Storybook: Rewrite stories to CSF (#23989)
* ColorPicker to CSF format
* Convert stories to CSF
* Do not export ClipboardButton
* Update ConfirmButton
* Remove unused imports
* Fix feedback
* changelog enterprise 7.0.0-beta1 (#24039)
* CircleCI: Bump grafana/build-container revision (#24043)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Changelog: Updates changelog with more feature details (#24040)
* Changelog: Updates changelog with more feature details
* spell fix
* spell fix
* Updates
* Readme update
* Updates
* Select: fixes so component loses focus on selecting value or pressing outside of input. (#24008)
* changed the value container to a class component to get it to work with focus (maybe something with context?).
* added e2e tests to verify that the select focus is working as it should.
* fixed according to feedback.
* updated snapshot.
* Devenv: add remote renderer to grafana (#24050)
* NewPanelEditor: minor UI twekas (#24042)
* Forward ref for tabs, use html props
* Inspect: add inspect label to drawer title
* Add tooltips to sidebar pane tabs, copy changes
* Remove unused import
* Place tooltips over tabs
* Inspector: dont show transformations select if there is only one data frame
* Review
* Changelog: Add a breaking change (#24051)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Unpin grafana/docs-base (#24054)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Search: close overlay on Esc press (#24003)
* Search: Close on Esc
* Search: Increase bottom padding for the last item in section
* Search: Move closing search to keybindingsSrv
* Search: Fix folder view
* Search: Do not move folders if already in folder
* Docs: Adds deprecation notice to changelog and docs for scripted dashboards (#24060)
* Update CHANGELOG.md (#24047)
Fix typo
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
* Documentation: Alternative Team Sync Wording (#23960)
* Alternative wording for team sync docs
Signed-off-by: Joe Elliott <number101010@gmail.com>
* Update docs/sources/auth/team-sync.md
Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
* Fix misspell issues (#23905)
* Fix misspell issues
See,
$ golangci-lint run --timeout 10m --disable-all -E misspell ./...
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* Fix codespell issues
See,
$ codespell -S './.git*' -L 'uint,thru,pres,unknwon,serie,referer,uptodate,durationm'
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* ci please?
* non-empty commit - ci?
* Trigger build
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
* fix compile error
* better series display
* better display
* now with prometheus and loki
* a few more tests
* Improvements and tests
* thinking
* More advanced and smart default title generation
* Another fix
* Progress but dam this will be hard
* Reverting the time series Value field name change
* revert revert going in circles
* add a field state object
* Use state title when converting back to legacy format
* Improved the join (series to columsn) transformer
* Got tests running again
* Rewrite of seriesToColums that simplifies and fixing tests
* Fixed the tricky problem of multiple time field when not used in join
* Prometheus: Restoring prometheus formatting
* Graphite: Disable Grafana's series naming
* fixed imports
* Fixed tests and made rename transform change title instead
* Fixing more tests
* fix more tests
* fixed import issue
* Fixed more circular dependencies
* Renamed to getFieldTitle
* More rename
* Review feedback
* Fix for showing field title in calculate field transformer
* fieldOverride: Make it clear that state title after applying defaults & overrides
* Fixed ts issue
* Update packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
Co-authored-by: Leonard Gram <leo@xlson.com>
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: Richard Hartmann <RichiH@users.noreply.github.com>
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Mario Trangoni <mario@mariotrangoni.de>
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
2020-05-07 03:42:03 -05:00
|
|
|
import { dateTime, getFrameDisplayTitle } from '@grafana/data';
|
2020-01-21 03:08:07 -06:00
|
|
|
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
|
|
|
|
|
|
|
|
jest.mock('@grafana/runtime', () => ({
|
|
|
|
...jest.requireActual('@grafana/runtime'),
|
|
|
|
getBackendSrv: () => backendSrv,
|
|
|
|
}));
|
2017-12-20 05:33:33 -06:00
|
|
|
|
2020-03-18 07:00:14 -05:00
|
|
|
interface Context {
|
|
|
|
templateSrv: TemplateSrv;
|
|
|
|
ds: GraphiteDatasource;
|
|
|
|
}
|
|
|
|
|
2018-04-18 08:54:42 -05:00
|
|
|
describe('graphiteDatasource', () => {
|
2020-01-21 03:08:07 -06:00
|
|
|
const datasourceRequestMock = jest.spyOn(backendSrv, 'datasourceRequest');
|
|
|
|
|
2020-03-18 07:00:14 -05:00
|
|
|
let ctx = {} as Context;
|
2015-10-30 09:58:20 -05:00
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
beforeEach(() => {
|
2020-01-21 03:08:07 -06:00
|
|
|
jest.clearAllMocks();
|
2020-03-18 07:00:14 -05:00
|
|
|
|
|
|
|
const instanceSettings = {
|
|
|
|
url: '/api/datasources/proxy/1',
|
|
|
|
name: 'graphiteProd',
|
|
|
|
jsonData: {
|
|
|
|
rollupIndicatorEnabled: true,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const templateSrv = new TemplateSrv();
|
|
|
|
const ds = new GraphiteDatasource(instanceSettings, templateSrv);
|
|
|
|
ctx = { templateSrv, ds };
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('convertResponseToDataFrames', () => {
|
|
|
|
it('should transform regular result', () => {
|
|
|
|
const result = ctx.ds.convertResponseToDataFrames({
|
|
|
|
data: {
|
|
|
|
meta: {
|
|
|
|
stats: {
|
|
|
|
'executeplan.cache-hit-partial.count': 5,
|
|
|
|
'executeplan.cache-hit.count': 10,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
series: [
|
|
|
|
{
|
|
|
|
target: 'seriesA',
|
|
|
|
datapoints: [
|
|
|
|
[100, 200],
|
|
|
|
[101, 201],
|
|
|
|
],
|
|
|
|
meta: [
|
|
|
|
{
|
|
|
|
'aggnum-norm': 1,
|
|
|
|
'aggnum-rc': 7,
|
|
|
|
'archive-interval': 3600,
|
|
|
|
'archive-read': 1,
|
2020-04-28 03:48:21 -05:00
|
|
|
'consolidator-normfetch': 'AverageConsolidator',
|
|
|
|
'consolidator-rc': 'AverageConsolidator',
|
2020-03-18 07:00:14 -05:00
|
|
|
count: 1,
|
|
|
|
'schema-name': 'wpUsageMetrics',
|
|
|
|
'schema-retentions': '1h:35d:6h:2,2h:2y:6h:2',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
target: 'seriesB',
|
|
|
|
meta: [
|
|
|
|
{
|
|
|
|
'aggnum-norm': 1,
|
|
|
|
'aggnum-rc': 0,
|
|
|
|
'archive-interval': 3600,
|
|
|
|
'archive-read': 0,
|
2020-04-28 03:48:21 -05:00
|
|
|
'consolidator-normfetch': 'AverageConsolidator',
|
|
|
|
'consolidator-rc': 'NoneConsolidator',
|
2020-03-18 07:00:14 -05:00
|
|
|
count: 1,
|
|
|
|
'schema-name': 'wpUsageMetrics',
|
|
|
|
'schema-retentions': '1h:35d:6h:2,2h:2y:6h:2',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
datapoints: [
|
|
|
|
[200, 300],
|
|
|
|
[201, 301],
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(result.data.length).toBe(2);
|
Field: getFieldTitle as field / series display identity and use it in all field name matchers & field / series name displays (#24024)
* common title handling
* show labels
* update comment
* Update changelog for v7.0.0-beta1 (#24007)
Co-Authored-By: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-Authored-By: Andrej Ocenas <mr.ocenas@gmail.com>
Co-Authored-By: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
* verify-repo-update: Fix Dockerfile.deb (#24030)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Upgrade build pipeline tool (#24021)
* CircleCI: Upgrade build pipeline tool
* Devenv: ignore enterprise (#24037)
* Add header icon to Add data source page (#24033)
* latest.json: Update testing version (#24038)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Fix login page redirected from password reset (#24032)
* Storybook: Rewrite stories to CSF (#23989)
* ColorPicker to CSF format
* Convert stories to CSF
* Do not export ClipboardButton
* Update ConfirmButton
* Remove unused imports
* Fix feedback
* changelog enterprise 7.0.0-beta1 (#24039)
* CircleCI: Bump grafana/build-container revision (#24043)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Changelog: Updates changelog with more feature details (#24040)
* Changelog: Updates changelog with more feature details
* spell fix
* spell fix
* Updates
* Readme update
* Updates
* Select: fixes so component loses focus on selecting value or pressing outside of input. (#24008)
* changed the value container to a class component to get it to work with focus (maybe something with context?).
* added e2e tests to verify that the select focus is working as it should.
* fixed according to feedback.
* updated snapshot.
* Devenv: add remote renderer to grafana (#24050)
* NewPanelEditor: minor UI twekas (#24042)
* Forward ref for tabs, use html props
* Inspect: add inspect label to drawer title
* Add tooltips to sidebar pane tabs, copy changes
* Remove unused import
* Place tooltips over tabs
* Inspector: dont show transformations select if there is only one data frame
* Review
* Changelog: Add a breaking change (#24051)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* CircleCI: Unpin grafana/docs-base (#24054)
Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
* Search: close overlay on Esc press (#24003)
* Search: Close on Esc
* Search: Increase bottom padding for the last item in section
* Search: Move closing search to keybindingsSrv
* Search: Fix folder view
* Search: Do not move folders if already in folder
* Docs: Adds deprecation notice to changelog and docs for scripted dashboards (#24060)
* Update CHANGELOG.md (#24047)
Fix typo
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
* Documentation: Alternative Team Sync Wording (#23960)
* Alternative wording for team sync docs
Signed-off-by: Joe Elliott <number101010@gmail.com>
* Update docs/sources/auth/team-sync.md
Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
* Fix misspell issues (#23905)
* Fix misspell issues
See,
$ golangci-lint run --timeout 10m --disable-all -E misspell ./...
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* Fix codespell issues
See,
$ codespell -S './.git*' -L 'uint,thru,pres,unknwon,serie,referer,uptodate,durationm'
Signed-off-by: Mario Trangoni <mjtrangoni@gmail.com>
* ci please?
* non-empty commit - ci?
* Trigger build
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
* fix compile error
* better series display
* better display
* now with prometheus and loki
* a few more tests
* Improvements and tests
* thinking
* More advanced and smart default title generation
* Another fix
* Progress but dam this will be hard
* Reverting the time series Value field name change
* revert revert going in circles
* add a field state object
* Use state title when converting back to legacy format
* Improved the join (series to columsn) transformer
* Got tests running again
* Rewrite of seriesToColums that simplifies and fixing tests
* Fixed the tricky problem of multiple time field when not used in join
* Prometheus: Restoring prometheus formatting
* Graphite: Disable Grafana's series naming
* fixed imports
* Fixed tests and made rename transform change title instead
* Fixing more tests
* fix more tests
* fixed import issue
* Fixed more circular dependencies
* Renamed to getFieldTitle
* More rename
* Review feedback
* Fix for showing field title in calculate field transformer
* fieldOverride: Make it clear that state title after applying defaults & overrides
* Fixed ts issue
* Update packages/grafana-ui/src/components/TransformersUI/OrganizeFieldsTransformerEditor.tsx
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Andrej Ocenas <mr.ocenas@gmail.com>
Co-authored-by: Hugo Häggmark <hugo.haggmark@grafana.com>
Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
Co-authored-by: Leonard Gram <leo@xlson.com>
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: Marcus Andersson <marcus.andersson@grafana.com>
Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
Co-authored-by: Richard Hartmann <RichiH@users.noreply.github.com>
Co-authored-by: Daniel Lee <dan.limerick@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Mario Trangoni <mario@mariotrangoni.de>
Co-authored-by: bergquist <carl.bergquist@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
2020-05-07 03:42:03 -05:00
|
|
|
expect(getFrameDisplayTitle(result.data[0])).toBe('seriesA');
|
|
|
|
expect(getFrameDisplayTitle(result.data[1])).toBe('seriesB');
|
2020-03-18 07:00:14 -05:00
|
|
|
expect(result.data[0].length).toBe(2);
|
|
|
|
expect(result.data[0].meta.notices.length).toBe(1);
|
|
|
|
expect(result.data[0].meta.notices[0].text).toBe('Data is rolled up, aggregated over 2h using Average function');
|
|
|
|
expect(result.data[1].meta.notices).toBeUndefined();
|
|
|
|
});
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
describe('When querying graphite with one target using query editor target spec', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const query = {
|
2016-07-23 05:54:11 -05:00
|
|
|
panelId: 3,
|
2018-05-28 08:57:12 -05:00
|
|
|
dashboardId: 5,
|
2017-12-20 05:33:33 -06:00
|
|
|
rangeRaw: { from: 'now-1h', to: 'now' },
|
|
|
|
targets: [{ target: 'prod1.count' }, { target: 'prod2.count' }],
|
|
|
|
maxDataPoints: 500,
|
2015-09-28 08:23:53 -05:00
|
|
|
};
|
|
|
|
|
2019-07-05 09:46:46 -05:00
|
|
|
let results: any;
|
|
|
|
let requestOptions: any;
|
2015-09-28 08:23:53 -05:00
|
|
|
|
2018-04-18 08:54:42 -05:00
|
|
|
beforeEach(async () => {
|
2020-01-21 03:08:07 -06:00
|
|
|
datasourceRequestMock.mockImplementation((options: any) => {
|
2015-09-28 08:23:53 -05:00
|
|
|
requestOptions = options;
|
2019-12-05 03:04:03 -06:00
|
|
|
return Promise.resolve({
|
2019-11-19 07:59:39 -06:00
|
|
|
data: [
|
|
|
|
{
|
|
|
|
target: 'prod1.count',
|
|
|
|
datapoints: [
|
|
|
|
[10, 1],
|
|
|
|
[12, 1],
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
2017-12-19 09:06:54 -06:00
|
|
|
});
|
2020-01-21 03:08:07 -06:00
|
|
|
});
|
2015-09-28 08:23:53 -05:00
|
|
|
|
2020-03-18 07:00:14 -05:00
|
|
|
await ctx.ds.query(query as any).then((data: any) => {
|
2017-12-19 09:06:54 -06:00
|
|
|
results = data;
|
|
|
|
});
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
it('X-Dashboard and X-Panel headers to be set!', () => {
|
|
|
|
expect(requestOptions.headers['X-Dashboard-Id']).toBe(5);
|
|
|
|
expect(requestOptions.headers['X-Panel-Id']).toBe(3);
|
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should generate the correct query', () => {
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/render');
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should set unique requestId', () => {
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.requestId).toBe('graphiteProd.panelId.3');
|
2016-07-23 05:54:11 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should query correctly', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const params = requestOptions.data.split('&');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(params).toContain('target=prod1.count');
|
|
|
|
expect(params).toContain('target=prod2.count');
|
|
|
|
expect(params).toContain('from=-1h');
|
|
|
|
expect(params).toContain('until=now');
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should exclude undefined params', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const params = requestOptions.data.split('&');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(params).not.toContain('cacheTimeout=undefined');
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should return series list', () => {
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results.data.length).toBe(1);
|
2019-11-08 03:38:10 -06:00
|
|
|
expect(results.data[0].name).toBe('prod1.count');
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should convert to millisecond resolution', () => {
|
2020-04-03 13:11:28 -05:00
|
|
|
expect(results.data[0].fields[1].values.get(0)).toBe(10);
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-12-20 05:33:33 -06:00
|
|
|
describe('when fetching Graphite Events as annotations', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
let results: any;
|
2017-10-07 03:31:39 -05:00
|
|
|
|
|
|
|
const options = {
|
|
|
|
annotation: {
|
2017-12-20 05:33:33 -06:00
|
|
|
tags: 'tag1',
|
2017-10-07 03:31:39 -05:00
|
|
|
},
|
|
|
|
range: {
|
2019-05-08 06:51:44 -05:00
|
|
|
from: dateTime(1432288354),
|
|
|
|
to: dateTime(1432288401),
|
2017-10-07 03:31:39 -05:00
|
|
|
},
|
2017-12-20 05:33:33 -06:00
|
|
|
rangeRaw: { from: 'now-24h', to: 'now' },
|
2017-10-07 03:31:39 -05:00
|
|
|
};
|
|
|
|
|
2017-12-20 05:33:33 -06:00
|
|
|
describe('and tags are returned as string', () => {
|
2017-10-07 03:31:39 -05:00
|
|
|
const response = {
|
|
|
|
data: [
|
2017-12-19 09:06:54 -06:00
|
|
|
{
|
|
|
|
when: 1507222850,
|
2017-12-20 05:33:33 -06:00
|
|
|
tags: 'tag1 tag2',
|
|
|
|
data: 'some text',
|
2017-12-19 09:06:54 -06:00
|
|
|
id: 2,
|
2017-12-20 05:33:33 -06:00
|
|
|
what: 'Event - deploy',
|
|
|
|
},
|
|
|
|
],
|
2017-12-19 09:06:54 -06:00
|
|
|
};
|
2017-10-07 03:31:39 -05:00
|
|
|
|
2018-04-18 08:54:42 -05:00
|
|
|
beforeEach(async () => {
|
2020-01-21 03:08:07 -06:00
|
|
|
datasourceRequestMock.mockImplementation((options: any) => {
|
2019-12-05 03:04:03 -06:00
|
|
|
return Promise.resolve(response);
|
2020-01-21 03:08:07 -06:00
|
|
|
});
|
2019-07-05 09:46:46 -05:00
|
|
|
await ctx.ds.annotationQuery(options).then((data: any) => {
|
2017-12-19 09:06:54 -06:00
|
|
|
results = data;
|
|
|
|
});
|
2017-10-07 03:31:39 -05:00
|
|
|
});
|
|
|
|
|
2017-12-20 05:33:33 -06:00
|
|
|
it('should parse the tags string into an array', () => {
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(_.isArray(results[0].tags)).toEqual(true);
|
|
|
|
expect(results[0].tags.length).toEqual(2);
|
|
|
|
expect(results[0].tags[0]).toEqual('tag1');
|
|
|
|
expect(results[0].tags[1]).toEqual('tag2');
|
2017-10-07 03:31:39 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-12-20 05:33:33 -06:00
|
|
|
describe('and tags are returned as an array', () => {
|
2017-10-07 03:31:39 -05:00
|
|
|
const response = {
|
|
|
|
data: [
|
2017-12-19 09:06:54 -06:00
|
|
|
{
|
|
|
|
when: 1507222850,
|
2017-12-20 05:33:33 -06:00
|
|
|
tags: ['tag1', 'tag2'],
|
|
|
|
data: 'some text',
|
2017-12-19 09:06:54 -06:00
|
|
|
id: 2,
|
2017-12-20 05:33:33 -06:00
|
|
|
what: 'Event - deploy',
|
|
|
|
},
|
|
|
|
],
|
2017-12-19 09:06:54 -06:00
|
|
|
};
|
2017-10-07 03:31:39 -05:00
|
|
|
beforeEach(() => {
|
2020-01-21 03:08:07 -06:00
|
|
|
datasourceRequestMock.mockImplementation((options: any) => {
|
2019-12-05 03:04:03 -06:00
|
|
|
return Promise.resolve(response);
|
2020-01-21 03:08:07 -06:00
|
|
|
});
|
2017-10-07 03:31:39 -05:00
|
|
|
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.annotationQuery(options).then((data: any) => {
|
2017-12-19 09:06:54 -06:00
|
|
|
results = data;
|
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
// ctx.$rootScope.$apply();
|
2017-10-07 03:31:39 -05:00
|
|
|
});
|
|
|
|
|
2017-12-20 05:33:33 -06:00
|
|
|
it('should parse the tags string into an array', () => {
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(_.isArray(results[0].tags)).toEqual(true);
|
|
|
|
expect(results[0].tags.length).toEqual(2);
|
|
|
|
expect(results[0].tags[0]).toEqual('tag1');
|
|
|
|
expect(results[0].tags[1]).toEqual('tag2');
|
2017-10-07 03:31:39 -05:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
describe('building graphite params', () => {
|
|
|
|
it('should return empty array if no targets', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-20 05:33:33 -06:00
|
|
|
targets: [{}],
|
2015-12-14 11:33:44 -06:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results.length).toBe(0);
|
2015-12-14 11:33:44 -06:00
|
|
|
});
|
2015-09-28 08:23:53 -05:00
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should uri escape targets', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-20 05:33:33 -06:00
|
|
|
targets: [{ target: 'prod1.{test,test2}' }, { target: 'prod2.count' }],
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results).toContain('target=prod1.%7Btest%2Ctest2%7D');
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should replace target placeholder', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-21 01:39:31 -06:00
|
|
|
targets: [{ target: 'series1' }, { target: 'series2' }, { target: 'asPercent(#A,#B)' }],
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results[2]).toBe('target=asPercent(series1%2Cseries2)');
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should replace target placeholder for hidden series', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-19 09:06:54 -06:00
|
|
|
targets: [
|
2017-12-20 05:33:33 -06:00
|
|
|
{ target: 'series1', hide: true },
|
|
|
|
{ target: 'sumSeries(#A)', hide: true },
|
|
|
|
{ target: 'asPercent(#A,#B)' },
|
|
|
|
],
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results[0]).toBe('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))'));
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should replace target placeholder when nesting query references', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-21 01:39:31 -06:00
|
|
|
targets: [{ target: 'series1' }, { target: 'sumSeries(#A)' }, { target: 'asPercent(#A,#B)' }],
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results[2]).toBe('target=' + encodeURIComponent('asPercent(series1,sumSeries(series1))'));
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should fix wrong minute interval parameters', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-20 05:33:33 -06:00
|
|
|
targets: [{ target: "summarize(prod.25m.count, '25m', 'sum')" }],
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results[0]).toBe('target=' + encodeURIComponent("summarize(prod.25m.count, '25min', 'sum')"));
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should fix wrong month interval parameters', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-20 05:33:33 -06:00
|
|
|
targets: [{ target: "summarize(prod.5M.count, '5M', 'sum')" }],
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results[0]).toBe('target=' + encodeURIComponent("summarize(prod.5M.count, '5mon', 'sum')"));
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
|
|
|
|
2018-09-04 08:55:41 -05:00
|
|
|
it('should ignore empty targets', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
2017-12-20 05:33:33 -06:00
|
|
|
targets: [{ target: 'series1' }, { target: '' }],
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(results.length).toBe(2);
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2019-08-07 08:50:06 -05:00
|
|
|
|
|
|
|
describe('when formatting targets', () => {
|
|
|
|
it('does not attempt to glob for one variable', () => {
|
2020-03-18 07:00:14 -05:00
|
|
|
ctx.templateSrv.init([
|
2019-08-07 08:50:06 -05:00
|
|
|
{
|
|
|
|
type: 'query',
|
|
|
|
name: 'metric',
|
|
|
|
current: { value: ['b'] },
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
|
|
|
targets: [{ target: 'my.$metric.*' }],
|
|
|
|
});
|
|
|
|
expect(results).toStrictEqual(['target=my.b.*', 'format=json']);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('globs for more than one variable', () => {
|
2020-03-18 07:00:14 -05:00
|
|
|
ctx.templateSrv.init([
|
2019-08-07 08:50:06 -05:00
|
|
|
{
|
|
|
|
type: 'query',
|
|
|
|
name: 'metric',
|
|
|
|
current: { value: ['a', 'b'] },
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const results = ctx.ds.buildGraphiteParams({
|
|
|
|
targets: [{ target: 'my.[[metric]].*' }],
|
|
|
|
});
|
2020-03-18 07:00:14 -05:00
|
|
|
|
2019-08-07 08:50:06 -05:00
|
|
|
expect(results).toStrictEqual(['target=my.%7Ba%2Cb%7D.*', 'format=json']);
|
|
|
|
});
|
|
|
|
});
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-04-17 11:39:59 -05:00
|
|
|
|
|
|
|
describe('querying for template variables', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
let results: any;
|
|
|
|
let requestOptions: any;
|
2018-04-17 11:39:59 -05:00
|
|
|
|
|
|
|
beforeEach(() => {
|
2020-01-21 03:08:07 -06:00
|
|
|
datasourceRequestMock.mockImplementation((options: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
requestOptions = options;
|
2019-12-05 03:04:03 -06:00
|
|
|
return Promise.resolve({
|
2018-04-18 08:54:42 -05:00
|
|
|
data: ['backend_01', 'backend_02'],
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
2020-01-21 03:08:07 -06:00
|
|
|
});
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should generate tags query', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('tags()').then((data: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/tags');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.params.expr).toEqual([]);
|
|
|
|
expect(results).not.toBe(null);
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should generate tags query with a filter expression', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('tags(server=backend_01)').then((data: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/tags');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.params.expr).toEqual(['server=backend_01']);
|
|
|
|
expect(results).not.toBe(null);
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
|
|
|
|
2018-04-18 08:54:42 -05:00
|
|
|
it('should generate tags query for an expression with whitespace after', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('tags(server=backend_01 )').then((data: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/tags');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.params.expr).toEqual(['server=backend_01']);
|
|
|
|
expect(results).not.toBe(null);
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should generate tag values query for one tag', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('tag_values(server)').then((data: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.params.tag).toBe('server');
|
|
|
|
expect(requestOptions.params.expr).toEqual([]);
|
|
|
|
expect(results).not.toBe(null);
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should generate tag values query for a tag and expression', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('tag_values(server,server=~backend*)').then((data: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.params.tag).toBe('server');
|
|
|
|
expect(requestOptions.params.expr).toEqual(['server=~backend*']);
|
|
|
|
expect(results).not.toBe(null);
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should generate tag values query for a tag with whitespace after', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('tag_values(server )').then((data: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.params.tag).toBe('server');
|
|
|
|
expect(requestOptions.params.expr).toEqual([]);
|
|
|
|
expect(results).not.toBe(null);
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
it('should generate tag values query for a tag and expression with whitespace after', () => {
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('tag_values(server , server=~backend* )').then((data: any) => {
|
2018-04-17 11:39:59 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/tags/autoComplete/values');
|
2018-04-18 08:54:42 -05:00
|
|
|
expect(requestOptions.params.tag).toBe('server');
|
|
|
|
expect(requestOptions.params.expr).toEqual(['server=~backend*']);
|
|
|
|
expect(results).not.toBe(null);
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
2019-06-28 08:21:32 -05:00
|
|
|
|
|
|
|
it('/metrics/find should be POST', () => {
|
2020-03-18 07:00:14 -05:00
|
|
|
ctx.templateSrv.init([
|
2019-08-07 08:50:06 -05:00
|
|
|
{
|
|
|
|
type: 'query',
|
|
|
|
name: 'foo',
|
|
|
|
current: { value: ['bar'] },
|
|
|
|
},
|
|
|
|
]);
|
2019-07-05 09:46:46 -05:00
|
|
|
ctx.ds.metricFindQuery('[[foo]]').then((data: any) => {
|
2019-06-28 08:21:32 -05:00
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/metrics/find');
|
|
|
|
expect(requestOptions.method).toEqual('POST');
|
|
|
|
expect(requestOptions.headers).toHaveProperty('Content-Type', 'application/x-www-form-urlencoded');
|
|
|
|
expect(requestOptions.data).toMatch(`query=bar`);
|
|
|
|
expect(requestOptions).toHaveProperty('params');
|
|
|
|
});
|
2019-10-18 04:40:08 -05:00
|
|
|
|
|
|
|
it('should interpolate $__searchFilter with searchFilter', () => {
|
|
|
|
ctx.ds.metricFindQuery('app.$__searchFilter', { searchFilter: 'backend' }).then((data: any) => {
|
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/metrics/find');
|
|
|
|
expect(requestOptions.params).toEqual({});
|
|
|
|
expect(requestOptions.data).toEqual('query=app.backend*');
|
|
|
|
expect(results).not.toBe(null);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should interpolate $__searchFilter with default when searchFilter is missing', () => {
|
|
|
|
ctx.ds.metricFindQuery('app.$__searchFilter', {}).then((data: any) => {
|
|
|
|
results = data;
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(requestOptions.url).toBe('/api/datasources/proxy/1/metrics/find');
|
|
|
|
expect(requestOptions.params).toEqual({});
|
|
|
|
expect(requestOptions.data).toEqual('query=app.*');
|
|
|
|
expect(results).not.toBe(null);
|
|
|
|
});
|
2018-04-17 11:39:59 -05:00
|
|
|
});
|
2015-09-28 08:23:53 -05:00
|
|
|
});
|
2018-05-28 08:57:12 -05:00
|
|
|
|
2019-07-05 09:46:46 -05:00
|
|
|
function accessScenario(name: string, url: string, fn: any) {
|
2018-09-04 08:55:41 -05:00
|
|
|
describe('access scenario ' + name, () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const ctx: any = {
|
2019-07-05 09:46:46 -05:00
|
|
|
// @ts-ignore
|
2019-08-07 08:50:06 -05:00
|
|
|
templateSrv: new TemplateSrv(),
|
2018-05-28 08:57:12 -05:00
|
|
|
instanceSettings: { url: 'url', name: 'graphiteProd', jsonData: {} },
|
|
|
|
};
|
|
|
|
|
2018-08-26 10:14:40 -05:00
|
|
|
const httpOptions = {
|
2018-05-28 08:57:12 -05:00
|
|
|
headers: {},
|
|
|
|
};
|
|
|
|
|
|
|
|
describe('when using proxy mode', () => {
|
2018-08-26 10:14:40 -05:00
|
|
|
const options = { dashboardId: 1, panelId: 2 };
|
2018-05-28 08:57:12 -05:00
|
|
|
|
|
|
|
it('tracing headers should be added', () => {
|
|
|
|
ctx.instanceSettings.url = url;
|
2020-01-21 03:08:07 -06:00
|
|
|
const ds = new GraphiteDatasource(ctx.instanceSettings, ctx.templateSrv);
|
2018-05-28 08:57:12 -05:00
|
|
|
ds.addTracingHeaders(httpOptions, options);
|
|
|
|
fn(httpOptions);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-05 09:46:46 -05:00
|
|
|
accessScenario('with proxy access', '/api/datasources/proxy/1', (httpOptions: any) => {
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(httpOptions.headers['X-Dashboard-Id']).toBe(1);
|
|
|
|
expect(httpOptions.headers['X-Panel-Id']).toBe(2);
|
|
|
|
});
|
|
|
|
|
2019-07-05 09:46:46 -05:00
|
|
|
accessScenario('with direct access', 'http://localhost:8080', (httpOptions: any) => {
|
2018-05-28 08:57:12 -05:00
|
|
|
expect(httpOptions.headers['X-Dashboard-Id']).toBe(undefined);
|
|
|
|
expect(httpOptions.headers['X-Panel-Id']).toBe(undefined);
|
|
|
|
});
|