mirror of
https://github.com/grafana/grafana.git
synced 2024-12-30 10:47:30 -06:00
Explore: Remove exploreMixedDatasource feature toggle (#71534)
This commit is contained in:
parent
480ccf6e8f
commit
c5d2d55654
@ -66,11 +66,3 @@ Available in Grafana 7.3 and later versions.
|
||||
{{% /admonition %}}
|
||||
|
||||
The Share shortened link capability allows you to create smaller and simpler URLs of the format /goto/:uid instead of using longer URLs with query parameters. To create a shortened link to the executed query, click the **Share** option in the Explore toolbar. A shortened link that is never used will automatically get deleted after seven (7) days.
|
||||
|
||||
## Available feature toggles
|
||||
|
||||
### exploreMixedDatasource
|
||||
|
||||
Enabled by default, allows users in Explore to have different data sources for different queries. If compatible, results will be combined.
|
||||
|
||||
Learn more about how to use [Mixed data source]({{< relref "../datasources/#special-data-sources" >}}).
|
||||
|
@ -53,6 +53,8 @@ Filter query history in Query history and Starred tab by data source name:
|
||||
1. Click the **Filter queries for specific data source(s)** field.
|
||||
1. Select the data source for which you would like to filter your history. You can select multiple data sources.
|
||||
|
||||
> **Note:** Queries ran using the Mixed data source will appear only when filtering for Mixed and not when filtering by their individual data sources.
|
||||
|
||||
In **Query history** tab it is also possible to filter queries by date using the slider:
|
||||
|
||||
- Use vertical slider to filter queries by date.
|
||||
|
@ -23,7 +23,6 @@ Some features are enabled by default. You can disable these feature by setting t
|
||||
| ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
|
||||
| `featureHighlights` | Highlight Grafana Enterprise features | |
|
||||
| `exploreMixedDatasource` | Enable mixed datasource in Explore | Yes |
|
||||
| `dataConnectionsConsole` | Enables a new top-level page called Connections. This page is an experiment that provides a better experience when you install and configure data sources and other plugins. | Yes |
|
||||
| `topnav` | Enables new top navigation and page layouts | Yes |
|
||||
| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes |
|
||||
|
@ -29,7 +29,6 @@ export interface FeatureToggles {
|
||||
featureHighlights?: boolean;
|
||||
migrationLocking?: boolean;
|
||||
storage?: boolean;
|
||||
exploreMixedDatasource?: boolean;
|
||||
newTraceViewHeader?: boolean;
|
||||
correlations?: boolean;
|
||||
datasourceQueryMultiStatus?: boolean;
|
||||
|
@ -79,14 +79,6 @@ var (
|
||||
Stage: FeatureStageExperimental,
|
||||
Owner: grafanaAppPlatformSquad,
|
||||
},
|
||||
{
|
||||
Name: "exploreMixedDatasource",
|
||||
Description: "Enable mixed datasource in Explore",
|
||||
Stage: FeatureStageGeneralAvailability,
|
||||
FrontendOnly: true,
|
||||
Expression: "true", // turned on by default
|
||||
Owner: grafanaExploreSquad,
|
||||
},
|
||||
{
|
||||
Name: "newTraceViewHeader",
|
||||
Description: "Shows the new trace view header",
|
||||
|
@ -10,7 +10,6 @@ lokiExperimentalStreaming,experimental,@grafana/observability-logs,false,false,f
|
||||
featureHighlights,GA,@grafana/grafana-as-code,false,false,false,false
|
||||
migrationLocking,preview,@grafana/backend-platform,false,false,false,false
|
||||
storage,experimental,@grafana/grafana-app-platform-squad,false,false,false,false
|
||||
exploreMixedDatasource,GA,@grafana/explore-squad,false,false,false,true
|
||||
newTraceViewHeader,experimental,@grafana/observability-traces-and-profiling,false,false,false,true
|
||||
correlations,preview,@grafana/explore-squad,false,false,false,false
|
||||
datasourceQueryMultiStatus,experimental,@grafana/plugins-platform-backend,false,false,false,false
|
||||
|
|
@ -51,10 +51,6 @@ const (
|
||||
// Configurable storage for dashboards, datasources, and resources
|
||||
FlagStorage = "storage"
|
||||
|
||||
// FlagExploreMixedDatasource
|
||||
// Enable mixed datasource in Explore
|
||||
FlagExploreMixedDatasource = "exploreMixedDatasource"
|
||||
|
||||
// FlagNewTraceViewHeader
|
||||
// Shows the new trace view header
|
||||
FlagNewTraceViewHeader = "newTraceViewHeader"
|
||||
|
@ -74,22 +74,6 @@ export async function getExploreUrl(args: GetExploreUrlArguments): Promise<strin
|
||||
.map((t) => omit(t, 'legendFormat'))
|
||||
.filter((t) => t.datasource?.uid !== ExpressionDatasourceUID);
|
||||
let url: string | undefined;
|
||||
// if the mixed datasource is not enabled for explore, choose only one datasource
|
||||
if (
|
||||
config.featureToggles.exploreMixedDatasource === false &&
|
||||
exploreDatasource.meta?.id === 'mixed' &&
|
||||
exploreTargets
|
||||
) {
|
||||
// Find first explore datasource among targets
|
||||
for (const t of exploreTargets) {
|
||||
const datasource = await datasourceSrv.get(t.datasource || undefined);
|
||||
if (datasource) {
|
||||
exploreDatasource = datasource;
|
||||
exploreTargets = panel.targets.filter((t) => t.datasource === datasource.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (exploreDatasource) {
|
||||
const range = timeSrv.timeRangeForUrl();
|
||||
|
@ -8,7 +8,6 @@ import { createErrorNotification, createWarningNotification } from 'app/core/cop
|
||||
import { dispatch } from 'app/store/store';
|
||||
import { RichHistoryQuery } from 'app/types/explore';
|
||||
|
||||
import { config } from '../config';
|
||||
import {
|
||||
RichHistoryResults,
|
||||
RichHistoryServiceError,
|
||||
@ -218,7 +217,7 @@ export function mapQueriesToHeadings(query: RichHistoryQuery[], sortOrder: SortO
|
||||
*/
|
||||
export function createDatasourcesList() {
|
||||
return getDataSourceSrv()
|
||||
.getList({ mixed: config.featureToggles.exploreMixedDatasource === true })
|
||||
.getList({ mixed: true })
|
||||
.map((dsSettings) => {
|
||||
return {
|
||||
name: dsSettings.name,
|
||||
|
@ -4,7 +4,7 @@ import React, { RefObject, useMemo } from 'react';
|
||||
import { shallowEqual } from 'react-redux';
|
||||
|
||||
import { DataSourceInstanceSettings, RawTimeRange } from '@grafana/data';
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { defaultIntervals, PageToolbar, RefreshPicker, SetInterval, ToolbarButton, ButtonGroup } from '@grafana/ui';
|
||||
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
|
||||
import { createAndCopyShortLink } from 'app/core/utils/shortLinks';
|
||||
@ -135,7 +135,7 @@ export function ExploreToolbar({ exploreId, topOfViewRef, onChangeTime }: Props)
|
||||
leftItems={[
|
||||
<DataSourcePicker
|
||||
key={`${exploreId}-ds-picker`}
|
||||
mixed={config.featureToggles.exploreMixedDatasource === true}
|
||||
mixed
|
||||
onChange={onChangeDatasource}
|
||||
current={datasourceInstance?.getRef()}
|
||||
hideTextValue={showSmallDataSourcePicker}
|
||||
|
@ -54,10 +54,9 @@ function defaultDsGetter(datasources: Array<ReturnType<typeof makeDatasourceSetu
|
||||
|
||||
interface SetupParams {
|
||||
queryParams?: UrlQueryMap;
|
||||
exploreMixedDatasource?: boolean;
|
||||
datasourceGetter?: (datasources: Array<ReturnType<typeof makeDatasourceSetup>>) => DataSourceSrv['get'];
|
||||
}
|
||||
function setup({ queryParams = {}, exploreMixedDatasource = false, datasourceGetter = defaultDsGetter }: SetupParams) {
|
||||
function setup({ queryParams = {}, datasourceGetter = defaultDsGetter }: SetupParams) {
|
||||
const history = createMemoryHistory({
|
||||
initialEntries: [{ pathname: '/explore', search: stringify(queryParams) }],
|
||||
});
|
||||
@ -67,12 +66,9 @@ function setup({ queryParams = {}, exploreMixedDatasource = false, datasourceGet
|
||||
const datasources = [
|
||||
makeDatasourceSetup({ name: 'loki', uid: 'loki-uid' }),
|
||||
makeDatasourceSetup({ name: 'elastic', uid: 'elastic-uid' }),
|
||||
makeDatasourceSetup({ name: MIXED_DATASOURCE_NAME, uid: MIXED_DATASOURCE_NAME, id: 999 }),
|
||||
];
|
||||
|
||||
if (exploreMixedDatasource) {
|
||||
datasources.push(makeDatasourceSetup({ name: MIXED_DATASOURCE_NAME, uid: MIXED_DATASOURCE_NAME, id: 999 }));
|
||||
}
|
||||
|
||||
setDataSourceSrv({
|
||||
get: datasourceGetter(datasources),
|
||||
getInstanceSettings: jest.fn(),
|
||||
@ -104,12 +100,6 @@ function setup({ queryParams = {}, exploreMixedDatasource = false, datasourceGet
|
||||
grafanaContext={{
|
||||
...context,
|
||||
location,
|
||||
config: {
|
||||
...context.config,
|
||||
featureToggles: {
|
||||
exploreMixedDatasource,
|
||||
},
|
||||
},
|
||||
}}
|
||||
store={store}
|
||||
>
|
||||
@ -408,7 +398,6 @@ describe('useStateSync', () => {
|
||||
|
||||
it('uses the first query datasource if no root datasource is specified in the URL', async () => {
|
||||
const { waitForNextUpdate, store } = setup({
|
||||
exploreMixedDatasource: true,
|
||||
queryParams: {
|
||||
panes: JSON.stringify({
|
||||
one: {
|
||||
@ -429,7 +418,6 @@ describe('useStateSync', () => {
|
||||
|
||||
it('updates the URL opening and closing a pane datasource changes', async () => {
|
||||
const { waitForNextUpdate, store, location } = setup({
|
||||
exploreMixedDatasource: true,
|
||||
queryParams: {
|
||||
panes: JSON.stringify({
|
||||
one: {
|
||||
@ -467,28 +455,25 @@ describe('useStateSync', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('with exploreMixedDatasource enabled', () => {
|
||||
it('filters out queries from the URL that do not have a datasource', async () => {
|
||||
const { waitForNextUpdate, store } = setup({
|
||||
exploreMixedDatasource: true,
|
||||
queryParams: {
|
||||
panes: JSON.stringify({
|
||||
one: {
|
||||
datasource: MIXED_DATASOURCE_NAME,
|
||||
queries: [
|
||||
{ expr: 'a', refId: 'A' },
|
||||
{ expr: 'b', datasource: { uid: 'loki-uid', type: 'logs' }, refId: 'B' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
schemaVersion: 1,
|
||||
},
|
||||
});
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(store.getState().explore.panes['one']?.queries.length).toBe(1);
|
||||
expect(store.getState().explore.panes['one']?.queries[0]).toMatchObject({ expr: 'b', refId: 'B' });
|
||||
it('filters out queries from the URL that do not have a datasource', async () => {
|
||||
const { waitForNextUpdate, store } = setup({
|
||||
queryParams: {
|
||||
panes: JSON.stringify({
|
||||
one: {
|
||||
datasource: MIXED_DATASOURCE_NAME,
|
||||
queries: [
|
||||
{ expr: 'a', refId: 'A' },
|
||||
{ expr: 'b', datasource: { uid: 'loki-uid', type: 'logs' }, refId: 'B' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
schemaVersion: 1,
|
||||
},
|
||||
});
|
||||
|
||||
await waitForNextUpdate();
|
||||
|
||||
expect(store.getState().explore.panes['one']?.queries.length).toBe(1);
|
||||
expect(store.getState().explore.panes['one']?.queries[0]).toMatchObject({ expr: 'b', refId: 'B' });
|
||||
});
|
||||
});
|
||||
|
@ -25,12 +25,7 @@ import { parseURL } from './parseURL';
|
||||
* Bi-directionally syncs URL changes with Explore's state.
|
||||
*/
|
||||
export function useStateSync(params: ExploreQueryParams) {
|
||||
const {
|
||||
location,
|
||||
config: {
|
||||
featureToggles: { exploreMixedDatasource },
|
||||
},
|
||||
} = useGrafana();
|
||||
const { location } = useGrafana();
|
||||
const dispatch = useDispatch();
|
||||
const panesState = useSelector(selectPanes);
|
||||
const orgId = useSelector((state) => state.user.orgId);
|
||||
@ -170,7 +165,7 @@ export function useStateSync(params: ExploreQueryParams) {
|
||||
|
||||
Promise.all(
|
||||
Object.entries(urlState.panes).map(([exploreId, { datasource, queries, range, panelsState }]) => {
|
||||
return getPaneDatasource(datasource, queries, orgId, !!exploreMixedDatasource).then((paneDatasource) => {
|
||||
return getPaneDatasource(datasource, queries, orgId).then((paneDatasource) => {
|
||||
return Promise.resolve(
|
||||
// Given the Grafana datasource will always be present, this should always be defined.
|
||||
paneDatasource
|
||||
@ -254,7 +249,7 @@ export function useStateSync(params: ExploreQueryParams) {
|
||||
prevParams.current = params;
|
||||
|
||||
isURLOutOfSync && initState.current === 'done' && sync();
|
||||
}, [dispatch, panesState, exploreMixedDatasource, orgId, location, params]);
|
||||
}, [dispatch, panesState, orgId, location, params]);
|
||||
}
|
||||
|
||||
function getDefaultQuery(ds: DataSourceApi) {
|
||||
@ -303,7 +298,7 @@ async function removeQueriesWithInvalidDatasource(queries: DataQuery[]) {
|
||||
|
||||
/**
|
||||
* Returns the datasource that an explore pane should be using.
|
||||
* If the URL specifies a datasource and that datasource exists, it will be used unless said datasource is mixed and `allowMixed` is false.
|
||||
* If the URL specifies a datasource and that datasource exists, it will be used unless said datasource is mixed.
|
||||
* Otherwise the datasource will be extracetd from the the first query specifying a valid datasource.
|
||||
*
|
||||
* If there's no datasource in the queries, the last used datasource will be used.
|
||||
@ -312,28 +307,22 @@ async function removeQueriesWithInvalidDatasource(queries: DataQuery[]) {
|
||||
* @param rootDatasource the top-level datasource specified in the URL
|
||||
* @param queries the queries in the pane
|
||||
* @param orgId the orgId of the user
|
||||
* @param allowMixed whether mixed datasources are allowed
|
||||
*
|
||||
* @returns the datasource UID that the pane should use, undefined if no suitable datasource is found
|
||||
*/
|
||||
async function getPaneDatasource(
|
||||
rootDatasource: DataSourceRef | string | null | undefined,
|
||||
queries: DataQuery[],
|
||||
orgId: number,
|
||||
allowMixed: boolean
|
||||
orgId: number
|
||||
) {
|
||||
// If there's a root datasource, use it unless it's mixed and we don't allow mixed.
|
||||
// If there's a root datasource, use it unless it's unavailable
|
||||
if (rootDatasource) {
|
||||
try {
|
||||
const ds = await getDatasourceSrv().get(rootDatasource);
|
||||
|
||||
if (!isMixedDatasource(ds) || allowMixed) {
|
||||
return ds;
|
||||
}
|
||||
return await getDatasourceSrv().get(rootDatasource);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
// TODO: if queries have multiple datasources and allowMixed is true, we should return mixed datasource
|
||||
// TODO: if queries have multiple datasources we should return mixed datasource
|
||||
// Else we try to find a datasource in the queries, returning the first one that exists
|
||||
const queriesWithDS = queries.filter((q) => q.datasource);
|
||||
for (const query of queriesWithDS) {
|
||||
|
@ -25,12 +25,6 @@ describe('useTimeSrvFix', () => {
|
||||
grafanaContext={{
|
||||
...context,
|
||||
location,
|
||||
config: {
|
||||
...context.config,
|
||||
featureToggles: {
|
||||
exploreMixedDatasource: true,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
@ -18,7 +18,6 @@ import {
|
||||
import {
|
||||
setDataSourceSrv,
|
||||
setEchoSrv,
|
||||
config,
|
||||
setLocationService,
|
||||
HistoryWrapper,
|
||||
LocationService,
|
||||
@ -45,7 +44,6 @@ type SetupOptions = {
|
||||
datasources?: DatasourceSetup[];
|
||||
urlParams?: ExploreQueryParams;
|
||||
prevUsedDatasource?: { orgId: number; datasource: string };
|
||||
mixedEnabled?: boolean;
|
||||
};
|
||||
|
||||
export function setupExplore(options?: SetupOptions): {
|
||||
@ -71,12 +69,9 @@ export function setupExplore(options?: SetupOptions): {
|
||||
const defaultDatasources: DatasourceSetup[] = [
|
||||
makeDatasourceSetup(),
|
||||
makeDatasourceSetup({ name: 'elastic', id: 2 }),
|
||||
makeDatasourceSetup({ name: MIXED_DATASOURCE_NAME, uid: MIXED_DATASOURCE_NAME, id: 999 }),
|
||||
];
|
||||
|
||||
if (config.featureToggles.exploreMixedDatasource) {
|
||||
defaultDatasources.push(makeDatasourceSetup({ name: MIXED_DATASOURCE_NAME, uid: MIXED_DATASOURCE_NAME, id: 999 }));
|
||||
}
|
||||
|
||||
const dsSettings = options?.datasources || defaultDatasources;
|
||||
|
||||
setDataSourceSrv({
|
||||
@ -138,17 +133,7 @@ export function setupExplore(options?: SetupOptions): {
|
||||
|
||||
const { unmount, container } = render(
|
||||
<Provider store={storeState}>
|
||||
<GrafanaContext.Provider
|
||||
value={{
|
||||
...contextMock,
|
||||
config: {
|
||||
...contextMock.config,
|
||||
featureToggles: {
|
||||
exploreMixedDatasource: options?.mixedEnabled ?? false,
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<GrafanaContext.Provider value={contextMock}>
|
||||
<Router history={history}>
|
||||
<Route
|
||||
path="/explore"
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
RawTimeRange,
|
||||
SupplementaryQueryType,
|
||||
} from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { DataQuery, DataSourceRef } from '@grafana/schema';
|
||||
import { createAsyncThunk, ExploreItemState, StoreState, ThunkDispatch } from 'app/types';
|
||||
|
||||
@ -99,9 +98,6 @@ jest.mock('@grafana/runtime', () => ({
|
||||
},
|
||||
};
|
||||
},
|
||||
config: {
|
||||
featureToggles: { exploreMixedDatasource: false },
|
||||
},
|
||||
}));
|
||||
|
||||
function setupQueryResponse(state: StoreState) {
|
||||
@ -447,155 +443,102 @@ describe('importing queries', () => {
|
||||
});
|
||||
|
||||
describe('adding new query rows', () => {
|
||||
describe('with mixed datasources disabled', () => {
|
||||
it('should add query row when there is not yet a row and meta.mixed === true (impossible in UI)', async () => {
|
||||
const queries: DataQuery[] = [];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: () => {
|
||||
return { type: 'loki', uid: 'uid-loki' };
|
||||
},
|
||||
meta: {
|
||||
id: 'mixed',
|
||||
mixed: true,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
it('should add another query row if there are two rows already', async () => {
|
||||
const queries = [
|
||||
{
|
||||
datasource: { type: 'loki', uid: 'ds3' },
|
||||
refId: 'C',
|
||||
},
|
||||
{
|
||||
datasource: { type: 'loki', uid: 'ds4' },
|
||||
refId: 'D',
|
||||
},
|
||||
];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: jest.fn(),
|
||||
meta: {
|
||||
id: 'loki',
|
||||
mixed: false,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('mixed');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(true);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(1);
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['uid-loki-0']);
|
||||
});
|
||||
it('should add query row when there is not yet a row and meta.mixed === false', async () => {
|
||||
const queries: DataQuery[] = [];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: () => {
|
||||
return { type: 'loki', uid: 'uid-loki' };
|
||||
},
|
||||
meta: {
|
||||
id: 'loki',
|
||||
mixed: false,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(false);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(1);
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['uid-loki-0']);
|
||||
});
|
||||
|
||||
it('should add another query row if there are two rows already', async () => {
|
||||
const queries = [
|
||||
{
|
||||
datasource: { type: 'loki', uid: 'ds3' },
|
||||
refId: 'C',
|
||||
},
|
||||
{
|
||||
datasource: { type: 'loki', uid: 'ds4' },
|
||||
refId: 'D',
|
||||
},
|
||||
];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: jest.fn(),
|
||||
meta: {
|
||||
id: 'loki',
|
||||
mixed: false,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(false);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(3);
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['ds3-0', 'ds4-1', 'ds4-2']);
|
||||
});
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(false);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(3);
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['ds3-0', 'ds4-1', 'ds4-2']);
|
||||
});
|
||||
describe('with mixed datasources enabled', () => {
|
||||
beforeEach(() => {
|
||||
config.featureToggles.exploreMixedDatasource = true;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
config.featureToggles.exploreMixedDatasource = false;
|
||||
});
|
||||
it('should add query row whith root ds (without overriding the default ds) when there is not yet a row', async () => {
|
||||
const queries: DataQuery[] = [];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: jest.fn(),
|
||||
meta: {
|
||||
id: 'mixed',
|
||||
mixed: true,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
|
||||
it('should add query row whith root ds (without overriding the default ds) when there is not yet a row', async () => {
|
||||
const queries: DataQuery[] = [];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: jest.fn(),
|
||||
meta: {
|
||||
id: 'mixed',
|
||||
mixed: true,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('mixed');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(true);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(1);
|
||||
expect(getState().explore.panes[exploreId]!.queries[0]?.datasource?.type).toBe('postgres');
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['ds1-0']);
|
||||
});
|
||||
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('mixed');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(true);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(1);
|
||||
expect(getState().explore.panes[exploreId]!.queries[0]?.datasource?.type).toBe('postgres');
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['ds1-0']);
|
||||
});
|
||||
it('should add query row whith root ds (with overriding the default ds) when there is not yet a row', async () => {
|
||||
const queries: DataQuery[] = [];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: () => {
|
||||
return { type: 'loki', uid: 'uid-loki' };
|
||||
},
|
||||
meta: {
|
||||
id: 'loki',
|
||||
mixed: false,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
|
||||
it('should add query row whith root ds (with overriding the default ds) when there is not yet a row', async () => {
|
||||
const queries: DataQuery[] = [];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: () => {
|
||||
return { type: 'loki', uid: 'uid-loki' };
|
||||
},
|
||||
meta: {
|
||||
id: 'loki',
|
||||
mixed: false,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(false);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(1);
|
||||
expect(getState().explore.panes[exploreId]!.queries[0]?.datasource?.type).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['uid-loki-0']);
|
||||
});
|
||||
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(false);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(1);
|
||||
expect(getState().explore.panes[exploreId]!.queries[0]?.datasource?.type).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['uid-loki-0']);
|
||||
});
|
||||
it('should add another query row if there are two rows already', async () => {
|
||||
const queries = [
|
||||
{
|
||||
datasource: { type: 'postgres', uid: 'ds3' },
|
||||
refId: 'C',
|
||||
},
|
||||
{
|
||||
datasource: { type: 'loki', uid: 'ds4' },
|
||||
refId: 'D',
|
||||
},
|
||||
];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: jest.fn(),
|
||||
meta: {
|
||||
id: 'mixed',
|
||||
mixed: true,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
|
||||
it('should add another query row if there are two rows already (impossible in UI)', async () => {
|
||||
const queries = [
|
||||
{
|
||||
datasource: { type: 'postgres', uid: 'ds3' },
|
||||
refId: 'C',
|
||||
},
|
||||
{
|
||||
datasource: { type: 'loki', uid: 'ds4' },
|
||||
refId: 'D',
|
||||
},
|
||||
];
|
||||
const datasourceInstance = {
|
||||
query: jest.fn(),
|
||||
getRef: jest.fn(),
|
||||
meta: {
|
||||
// datasourceInstance.meta.id is set to postgres because it's the default datasource
|
||||
id: 'postgres',
|
||||
mixed: false,
|
||||
} as unknown as DataSourcePluginMeta<{}>,
|
||||
};
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
const getState = await setupStore(queries, datasourceInstance);
|
||||
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('postgres');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(false);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(3);
|
||||
expect(getState().explore.panes[exploreId]!.queries[2]?.datasource?.type).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['ds3-0', 'ds4-1', 'ds4-2']);
|
||||
});
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.id).toBe('mixed');
|
||||
expect(getState().explore.panes[exploreId]!.datasourceInstance?.meta?.mixed).toBe(true);
|
||||
expect(getState().explore.panes[exploreId]!.queries).toHaveLength(3);
|
||||
expect(getState().explore.panes[exploreId]!.queries[2]?.datasource?.type).toBe('loki');
|
||||
expect(getState().explore.panes[exploreId]!.queryKeys).toEqual(['ds3-0', 'ds4-1', 'ds4-2']);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -258,7 +258,7 @@ export function addQueryRow(exploreId: string, index: number): ThunkResult<void>
|
||||
// if it's not mixed, send it as an override. generateEmptyQuery doesn't have access to state
|
||||
if (queries.length === 0) {
|
||||
const rootDatasource = getState().explore.panes[exploreId]!.datasourceInstance;
|
||||
if (!config.featureToggles.exploreMixedDatasource || !rootDatasource?.meta.mixed) {
|
||||
if (!rootDatasource?.meta.mixed) {
|
||||
datasourceOverride = rootDatasource;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user