update metadata fetch
This commit is contained in:
@@ -725,6 +725,136 @@ describe('Prometheus Language Provider', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMetricsMetadata', () => {
|
||||
it('should fetch metadata if not already loaded', async () => {
|
||||
const mockMetadata = {
|
||||
metric1: [
|
||||
{
|
||||
type: 'counter',
|
||||
help: 'help text 1',
|
||||
},
|
||||
],
|
||||
metric2: [
|
||||
{
|
||||
type: 'gauge',
|
||||
help: 'help text 2',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const expectedMetadata = {
|
||||
metric1: {
|
||||
type: 'counter',
|
||||
help: 'help text 1',
|
||||
},
|
||||
metric2: {
|
||||
type: 'gauge',
|
||||
help: 'help text 2',
|
||||
},
|
||||
};
|
||||
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
metadataRequest: () => ({ data: { data: mockMetadata } }),
|
||||
} as unknown as PrometheusDatasource);
|
||||
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
|
||||
const result = await languageProvider.getMetricsMetadata();
|
||||
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
'/api/v1/metadata',
|
||||
{},
|
||||
{
|
||||
showErrorAlert: false,
|
||||
headers: { 'X-Grafana-Cache': 'private, max-age=86400' },
|
||||
}
|
||||
);
|
||||
expect(result).toEqual(expect.objectContaining(expectedMetadata));
|
||||
});
|
||||
|
||||
it('should return cached metadata without fetching if already loaded', async () => {
|
||||
const mockMetadata = {
|
||||
metric1: [
|
||||
{
|
||||
type: 'counter',
|
||||
help: 'help text 1',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const expectedMetadata = {
|
||||
metric1: {
|
||||
type: 'counter',
|
||||
help: 'help text 1',
|
||||
},
|
||||
};
|
||||
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
metadataRequest: () => ({ data: { data: mockMetadata } }),
|
||||
} as unknown as PrometheusDatasource);
|
||||
|
||||
// First call to load metadata
|
||||
const firstResult = await languageProvider.getMetricsMetadata();
|
||||
expect(firstResult).toEqual(expect.objectContaining(expectedMetadata));
|
||||
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
|
||||
// Second call should use cached data
|
||||
const result = await languageProvider.getMetricsMetadata();
|
||||
|
||||
expect(requestSpy).not.toHaveBeenCalled();
|
||||
expect(result).toEqual(expect.objectContaining(expectedMetadata));
|
||||
});
|
||||
|
||||
it('should handle empty metadata response', async () => {
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
metadataRequest: () => ({ data: { data: {} } }),
|
||||
} as unknown as PrometheusDatasource);
|
||||
|
||||
const result = await languageProvider.getMetricsMetadata();
|
||||
|
||||
// Even with empty input, fixSummariesMetadata might add some default entries
|
||||
expect(Object.keys(result).length).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
it('should handle error during metadata fetch', async () => {
|
||||
jest.spyOn(console, 'error').mockImplementation();
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
metadataRequest: () => Promise.reject(new Error('Metadata fetch failed')),
|
||||
} as unknown as PrometheusDatasource);
|
||||
|
||||
const result = await languageProvider.getMetricsMetadata();
|
||||
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('should use configured cache duration from datasource', async () => {
|
||||
const mockDays = 7;
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
getDaysToCacheMetadata: () => mockDays,
|
||||
metadataRequest: () => ({ data: { data: {} } }),
|
||||
} as unknown as PrometheusDatasource);
|
||||
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
|
||||
await languageProvider.getMetricsMetadata();
|
||||
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
'/api/v1/metadata',
|
||||
{},
|
||||
{
|
||||
showErrorAlert: false,
|
||||
headers: { 'X-Grafana-Cache': `private, max-age=${mockDays * 86400}` },
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeQuotesIfExist', () => {
|
||||
|
||||
@@ -84,13 +84,19 @@ const getDefaultCacheHeaders = (cacheLevel: PrometheusCacheLevel) => {
|
||||
};
|
||||
|
||||
export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
declare startTask: Promise<any>;
|
||||
declare labelFetchTs: number;
|
||||
|
||||
private _metricsMetadata?: PromMetricsMetadata;
|
||||
|
||||
histogramMetrics: string[];
|
||||
metrics: string[];
|
||||
/**
|
||||
* @deprecated Use getMetricsMetadata() method instead
|
||||
*/
|
||||
metricsMetadata?: PromMetricsMetadata;
|
||||
declare startTask: Promise<any>;
|
||||
datasource: PrometheusDatasource;
|
||||
labelKeys: string[] = [];
|
||||
declare labelFetchTs: number;
|
||||
|
||||
constructor(datasource: PrometheusDatasource, initialValues?: Partial<PromQlLanguageProvider>) {
|
||||
super();
|
||||
@@ -142,7 +148,7 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
*
|
||||
* @returns {Promise<PromMetricsMetadata>} Promise that resolves when metadata has been fetched
|
||||
*/
|
||||
fetchMetadata = async () => {
|
||||
private _fetchMetadata = async () => {
|
||||
const secondsInDay = 86400;
|
||||
const headers = buildCacheHeaders(this.datasource.getDaysToCacheMetadata() * secondsInDay);
|
||||
const metadata = await this.request(
|
||||
@@ -153,8 +159,7 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
...headers,
|
||||
}
|
||||
);
|
||||
this.metricsMetadata = fixSummariesMetadata(metadata);
|
||||
return this.metricsMetadata;
|
||||
return fixSummariesMetadata(metadata);
|
||||
};
|
||||
|
||||
// ===================================
|
||||
@@ -256,11 +261,32 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
|
||||
// ======================================================================
|
||||
|
||||
public getMetricsMetadata = async (): Promise<PromMetricsMetadata> => {
|
||||
if (!this._metricsMetadata) {
|
||||
this._metricsMetadata = await this._fetchMetadata();
|
||||
}
|
||||
|
||||
return this._metricsMetadata;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
/**
|
||||
* @deprecated Use fetchMetadata instead
|
||||
* @deprecated Use _fetchMetadata instead. If you want metadata itself use getMetricsMetadata() method.
|
||||
*/
|
||||
async loadMetricsMetadata() {
|
||||
this.fetchMetadata();
|
||||
const secondsInDay = 86400;
|
||||
const headers = buildCacheHeaders(this.datasource.getDaysToCacheMetadata() * secondsInDay);
|
||||
this.metricsMetadata = fixSummariesMetadata(
|
||||
await this.request(
|
||||
API_V1.METADATA,
|
||||
{},
|
||||
{
|
||||
showErrorAlert: false,
|
||||
...headers,
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getLabelKeys(): string[] {
|
||||
|
||||
Reference in New Issue
Block a user