123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- import {
- DataSourceApi,
- DataSourceInstanceSettings,
- DataSourcePlugin,
- DataSourcePluginMeta,
- ScopedVar,
- } from '@grafana/data';
- import { DatasourceSrv } from 'app/features/plugins/datasource_srv';
- // Datasource variable $datasource with current value 'BBB'
- const templateSrv: any = {
- getVariables: () => [
- {
- type: 'datasource',
- name: 'datasource',
- current: {
- value: 'BBB',
- },
- },
- {
- type: 'datasource',
- name: 'datasourceDefault',
- current: {
- value: 'default',
- },
- },
- ],
- replace: (v: string, scopedVars: ScopedVar) => {
- if (scopedVars && scopedVars.datasource) {
- return v.replace('${datasource}', scopedVars.datasource.value);
- }
- let result = v.replace('${datasource}', 'BBB');
- result = result.replace('${datasourceDefault}', 'default');
- return result;
- },
- };
- class TestDataSource {
- constructor(public instanceSettings: DataSourceInstanceSettings) {}
- }
- jest.mock('../plugin_loader', () => ({
- importDataSourcePlugin: (meta: DataSourcePluginMeta) => {
- return Promise.resolve(new DataSourcePlugin(TestDataSource as any));
- },
- }));
- const getBackendSrvGetMock = jest.fn();
- jest.mock('@grafana/runtime', () => ({
- ...jest.requireActual('@grafana/runtime'),
- getBackendSrv: () => ({
- get: getBackendSrvGetMock,
- }),
- }));
- describe('datasource_srv', () => {
- beforeEach(() => {
- jest.resetModules();
- });
- const dataSourceSrv = new DatasourceSrv(templateSrv);
- const dataSourceInit = {
- mmm: {
- type: 'test-db',
- name: 'mmm',
- uid: 'uid-code-mmm',
- meta: { metrics: true, annotations: true } as any,
- },
- '-- Grafana --': {
- type: 'grafana',
- name: '-- Grafana --',
- meta: { builtIn: true, metrics: true, id: 'grafana' },
- },
- '-- Dashboard --': {
- type: 'dashboard',
- name: '-- Dashboard --',
- meta: { builtIn: true, metrics: true, id: 'dashboard' },
- },
- '-- Mixed --': {
- type: 'test-db',
- name: '-- Mixed --',
- meta: { builtIn: true, metrics: true, id: 'mixed' },
- },
- ZZZ: {
- type: 'test-db',
- name: 'ZZZ',
- uid: 'uid-code-ZZZ',
- meta: { metrics: true },
- },
- aaa: {
- type: 'test-db',
- name: 'aaa',
- uid: 'uid-code-aaa',
- meta: { metrics: true },
- },
- BBB: {
- type: 'test-db',
- name: 'BBB',
- uid: 'uid-code-BBB',
- meta: { metrics: true },
- isDefault: true,
- },
- Jaeger: {
- type: 'jaeger-db',
- name: 'Jaeger',
- uid: 'uid-code-Jaeger',
- meta: { tracing: true, id: 'jaeger' },
- },
- CannotBeQueried: {
- type: 'no-query',
- name: 'no-query',
- uid: 'no-query',
- meta: { id: 'no-query' },
- },
- };
- describe('Given a list of data sources', () => {
- beforeEach(() => {
- dataSourceSrv.init(dataSourceInit as any, 'BBB');
- });
- describe('when getting data source class instance', () => {
- it('should load plugin and create instance and set meta', async () => {
- const ds = (await dataSourceSrv.get('mmm')) as any;
- expect(ds.meta).toBe(dataSourceInit.mmm.meta);
- expect(ds.instanceSettings).toBe(dataSourceInit.mmm);
- // validate that it caches instance
- const ds2 = await dataSourceSrv.get('mmm');
- expect(ds).toBe(ds2);
- });
- it('should be able to load data source using uid as well', async () => {
- const dsByUid = await dataSourceSrv.get('uid-code-mmm');
- const dsByName = await dataSourceSrv.get('mmm');
- expect(dsByUid.meta).toBe(dsByName.meta);
- expect(dsByUid).toBe(dsByName);
- });
- it('should patch legacy datasources', async () => {
- expect(TestDataSource instanceof DataSourceApi).toBe(false);
- const instance = await dataSourceSrv.get('mmm');
- expect(instance.name).toBe('mmm');
- expect(instance.type).toBe('test-db');
- expect(instance.uid).toBe('uid-code-mmm');
- expect(instance.getRef()).toEqual({ type: 'test-db', uid: 'uid-code-mmm' });
- });
- it('Can get by variable', async () => {
- const ds = (await dataSourceSrv.get('${datasource}')) as any;
- expect(ds.meta).toBe(dataSourceInit.BBB.meta);
- const ds2 = await dataSourceSrv.get('${datasource}', { datasource: { text: 'Prom', value: 'uid-code-aaa' } });
- expect(ds2.uid).toBe(dataSourceInit.aaa.uid);
- });
- });
- describe('when getting instance settings', () => {
- it('should work by name or uid', () => {
- const ds = dataSourceSrv.getInstanceSettings('mmm');
- expect(dataSourceSrv.getInstanceSettings('uid-code-mmm')).toBe(ds);
- expect(dataSourceSrv.getInstanceSettings({ uid: 'uid-code-mmm' })).toBe(ds);
- });
- it('should work with variable', () => {
- const ds = dataSourceSrv.getInstanceSettings('${datasource}');
- expect(ds?.name).toBe('${datasource}');
- expect(ds?.uid).toBe('${datasource}');
- expect(ds?.rawRef).toMatchInlineSnapshot(`
- Object {
- "type": "test-db",
- "uid": "uid-code-BBB",
- }
- `);
- });
- it('should work with variable via scopedVars', () => {
- const ds = dataSourceSrv.getInstanceSettings('${datasource}', {
- datasource: { text: 'Prom', value: 'uid-code-aaa' },
- });
- expect(ds?.rawRef?.uid).toBe('uid-code-aaa');
- });
- it('should not set isDefault when being fetched via variable', () => {
- const ds = dataSourceSrv.getInstanceSettings('${datasource}');
- expect(ds?.isDefault).toBe(false);
- });
- it('should work with variable', () => {
- const ds = dataSourceSrv.getInstanceSettings('${datasourceDefault}');
- expect(ds?.name).toBe('${datasourceDefault}');
- expect(ds?.uid).toBe('${datasourceDefault}');
- expect(ds?.rawRef).toMatchInlineSnapshot(`
- Object {
- "type": "test-db",
- "uid": "uid-code-BBB",
- }
- `);
- });
- });
- describe('when getting external metric sources', () => {
- it('should return list of explore sources', () => {
- const externalSources = dataSourceSrv.getExternal();
- expect(externalSources.length).toBe(6);
- });
- });
- it('Should by default filter out data sources that cannot be queried', () => {
- const list = dataSourceSrv.getList({});
- expect(list.find((x) => x.name === 'no-query')).toBeUndefined();
- const all = dataSourceSrv.getList({ all: true });
- expect(all.find((x) => x.name === 'no-query')).toBeDefined();
- });
- it('Can get list of data sources with variables: true', () => {
- const list = dataSourceSrv.getList({ metrics: true, variables: true });
- expect(list[0].name).toBe('${datasourceDefault}');
- expect(list[1].name).toBe('${datasource}');
- });
- it('Can get list of data sources with tracing: true', () => {
- const list = dataSourceSrv.getList({ tracing: true });
- expect(list[0].name).toBe('Jaeger');
- });
- it('Can get list of data sources with annotation: true', () => {
- const list = dataSourceSrv.getList({ annotations: true });
- expect(list[0].name).toBe('mmm');
- });
- it('Can get get list and filter by pluginId', () => {
- const list = dataSourceSrv.getList({ pluginId: 'jaeger' });
- expect(list[0].name).toBe('Jaeger');
- expect(list.length).toBe(1);
- });
- it('Can get list of data sources with metrics: true, builtIn: true, mixed: true', () => {
- expect(dataSourceSrv.getList({ metrics: true, dashboard: true, mixed: true })).toMatchInlineSnapshot(`
- Array [
- Object {
- "meta": Object {
- "metrics": true,
- },
- "name": "aaa",
- "type": "test-db",
- "uid": "uid-code-aaa",
- },
- Object {
- "isDefault": true,
- "meta": Object {
- "metrics": true,
- },
- "name": "BBB",
- "type": "test-db",
- "uid": "uid-code-BBB",
- },
- Object {
- "meta": Object {
- "annotations": true,
- "metrics": true,
- },
- "name": "mmm",
- "type": "test-db",
- "uid": "uid-code-mmm",
- },
- Object {
- "meta": Object {
- "metrics": true,
- },
- "name": "ZZZ",
- "type": "test-db",
- "uid": "uid-code-ZZZ",
- },
- Object {
- "meta": Object {
- "builtIn": true,
- "id": "mixed",
- "metrics": true,
- },
- "name": "-- Mixed --",
- "type": "test-db",
- "uid": "-- Mixed --",
- },
- Object {
- "meta": Object {
- "builtIn": true,
- "id": "dashboard",
- "metrics": true,
- },
- "name": "-- Dashboard --",
- "type": "dashboard",
- "uid": "-- Dashboard --",
- },
- Object {
- "meta": Object {
- "builtIn": true,
- "id": "grafana",
- "metrics": true,
- },
- "name": "-- Grafana --",
- "type": "grafana",
- "uid": "-- Grafana --",
- },
- ]
- `);
- });
- it('Should reload the datasource', async () => {
- // arrange
- getBackendSrvGetMock.mockReturnValueOnce({
- datasources: {
- ...dataSourceInit,
- },
- defaultDatasource: 'aaa',
- });
- const initMock = jest.spyOn(dataSourceSrv, 'init').mockImplementation(() => {});
- // act
- await dataSourceSrv.reload();
- // assert
- expect(getBackendSrvGetMock).toHaveBeenCalledWith('/api/frontend/settings');
- expect(initMock).toHaveBeenCalledWith(dataSourceInit, 'aaa');
- });
- });
- });
|