| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- import '../datasource';
- import CloudWatchDatasource from '../datasource';
- import * as dateMath from 'app/core/utils/datemath';
- import _ from 'lodash';
- describe('CloudWatchDatasource', function() {
- const instanceSettings = {
- jsonData: { defaultRegion: 'us-east-1', access: 'proxy' },
- };
- const templateSrv = {
- data: {},
- templateSettings: { interpolate: /\[\[([\s\S]+?)\]\]/g },
- replace: text => _.template(text, templateSrv.templateSettings)(templateSrv.data),
- variableExists: () => false,
- };
- const timeSrv = {
- time: { from: 'now-1h', to: 'now' },
- timeRange: () => {
- return {
- from: dateMath.parse(timeSrv.time.from, false),
- to: dateMath.parse(timeSrv.time.to, true),
- };
- },
- };
- const backendSrv = {};
- const ctx = {
- backendSrv,
- templateSrv,
- } as any;
- beforeEach(() => {
- ctx.ds = new CloudWatchDatasource(instanceSettings, {}, backendSrv, templateSrv, timeSrv);
- });
- describe('When performing CloudWatch query', function() {
- let requestParams;
- const query = {
- range: { from: 'now-1h', to: 'now' },
- rangeRaw: { from: 1483228800, to: 1483232400 },
- targets: [
- {
- region: 'us-east-1',
- namespace: 'AWS/EC2',
- metricName: 'CPUUtilization',
- dimensions: {
- InstanceId: 'i-12345678',
- },
- statistics: ['Average'],
- period: '300',
- },
- ],
- };
- const response = {
- timings: [null],
- results: {
- A: {
- error: '',
- refId: 'A',
- series: [
- {
- name: 'CPUUtilization_Average',
- points: [[1, 1483228800000], [2, 1483229100000], [5, 1483229700000]],
- tags: {
- InstanceId: 'i-12345678',
- },
- },
- ],
- },
- },
- };
- beforeEach(() => {
- ctx.backendSrv.datasourceRequest = jest.fn(params => {
- requestParams = params.data;
- return Promise.resolve({ data: response });
- });
- });
- it('should generate the correct query', function(done) {
- ctx.ds.query(query).then(function() {
- const params = requestParams.queries[0];
- expect(params.namespace).toBe(query.targets[0].namespace);
- expect(params.metricName).toBe(query.targets[0].metricName);
- expect(params.dimensions['InstanceId']).toBe('i-12345678');
- expect(params.statistics).toEqual(query.targets[0].statistics);
- expect(params.period).toBe(query.targets[0].period);
- done();
- });
- });
- it('should generate the correct query with interval variable', function(done) {
- ctx.templateSrv.data = {
- period: '10m',
- };
- const query = {
- range: { from: 'now-1h', to: 'now' },
- rangeRaw: { from: 1483228800, to: 1483232400 },
- targets: [
- {
- region: 'us-east-1',
- namespace: 'AWS/EC2',
- metricName: 'CPUUtilization',
- dimensions: {
- InstanceId: 'i-12345678',
- },
- statistics: ['Average'],
- period: '[[period]]',
- },
- ],
- };
- ctx.ds.query(query).then(function() {
- const params = requestParams.queries[0];
- expect(params.period).toBe('600');
- done();
- });
- });
- it('should cancel query for invalid extended statistics', function() {
- const query = {
- range: { from: 'now-1h', to: 'now' },
- rangeRaw: { from: 1483228800, to: 1483232400 },
- targets: [
- {
- region: 'us-east-1',
- namespace: 'AWS/EC2',
- metricName: 'CPUUtilization',
- dimensions: {
- InstanceId: 'i-12345678',
- },
- statistics: ['pNN.NN'],
- period: '60s',
- },
- ],
- };
- expect(ctx.ds.query.bind(ctx.ds, query)).toThrow(/Invalid extended statistics/);
- });
- it('should return series list', function(done) {
- ctx.ds.query(query).then(function(result) {
- expect(result.data[0].target).toBe(response.results.A.series[0].name);
- expect(result.data[0].datapoints[0][0]).toBe(response.results.A.series[0].points[0][0]);
- done();
- });
- });
- });
- describe('When query region is "default"', function() {
- it('should return the datasource region if empty or "default"', function() {
- const defaultRegion = instanceSettings.jsonData.defaultRegion;
- expect(ctx.ds.getActualRegion()).toBe(defaultRegion);
- expect(ctx.ds.getActualRegion('')).toBe(defaultRegion);
- expect(ctx.ds.getActualRegion('default')).toBe(defaultRegion);
- });
- it('should return the specified region if specified', function() {
- expect(ctx.ds.getActualRegion('some-fake-region-1')).toBe('some-fake-region-1');
- });
- let requestParams;
- beforeEach(function() {
- ctx.ds.performTimeSeriesQuery = jest.fn(request => {
- requestParams = request;
- return Promise.resolve({ data: {} });
- });
- });
- it('should query for the datasource region if empty or "default"', function(done) {
- const query = {
- range: { from: 'now-1h', to: 'now' },
- rangeRaw: { from: 1483228800, to: 1483232400 },
- targets: [
- {
- region: 'default',
- namespace: 'AWS/EC2',
- metricName: 'CPUUtilization',
- dimensions: {
- InstanceId: 'i-12345678',
- },
- statistics: ['Average'],
- period: 300,
- },
- ],
- };
- ctx.ds.query(query).then(function(result) {
- expect(requestParams.queries[0].region).toBe(instanceSettings.jsonData.defaultRegion);
- done();
- });
- });
- });
- describe('When performing CloudWatch query for extended statistics', function() {
- const query = {
- range: { from: 'now-1h', to: 'now' },
- rangeRaw: { from: 1483228800, to: 1483232400 },
- targets: [
- {
- region: 'us-east-1',
- namespace: 'AWS/ApplicationELB',
- metricName: 'TargetResponseTime',
- dimensions: {
- LoadBalancer: 'lb',
- TargetGroup: 'tg',
- },
- statistics: ['p90.00'],
- period: 300,
- },
- ],
- };
- const response = {
- timings: [null],
- results: {
- A: {
- error: '',
- refId: 'A',
- series: [
- {
- name: 'TargetResponseTime_p90.00',
- points: [[1, 1483228800000], [2, 1483229100000], [5, 1483229700000]],
- tags: {
- LoadBalancer: 'lb',
- TargetGroup: 'tg',
- },
- },
- ],
- },
- },
- };
- beforeEach(function() {
- ctx.backendSrv.datasourceRequest = jest.fn(params => {
- return Promise.resolve({ data: response });
- });
- });
- it('should return series list', function(done) {
- ctx.ds.query(query).then(function(result) {
- expect(result.data[0].target).toBe(response.results.A.series[0].name);
- expect(result.data[0].datapoints[0][0]).toBe(response.results.A.series[0].points[0][0]);
- done();
- });
- });
- });
- function describeMetricFindQuery(query, func) {
- describe('metricFindQuery ' + query, () => {
- const scenario: any = {};
- scenario.setup = setupCallback => {
- beforeEach(() => {
- setupCallback();
- ctx.backendSrv.datasourceRequest = jest.fn(args => {
- scenario.request = args.data;
- return Promise.resolve({ data: scenario.requestResponse });
- });
- ctx.ds.metricFindQuery(query).then(args => {
- scenario.result = args;
- });
- });
- };
- func(scenario);
- });
- }
- describeMetricFindQuery('regions()', scenario => {
- scenario.setup(() => {
- scenario.requestResponse = {
- results: {
- metricFindQuery: {
- tables: [{ rows: [['us-east-1', 'us-east-1']] }],
- },
- },
- };
- });
- it('should call __GetRegions and return result', () => {
- expect(scenario.result[0].text).toContain('us-east-1');
- expect(scenario.request.queries[0].type).toBe('metricFindQuery');
- expect(scenario.request.queries[0].subtype).toBe('regions');
- });
- });
- describeMetricFindQuery('namespaces()', scenario => {
- scenario.setup(() => {
- scenario.requestResponse = {
- results: {
- metricFindQuery: {
- tables: [{ rows: [['AWS/EC2', 'AWS/EC2']] }],
- },
- },
- };
- });
- it('should call __GetNamespaces and return result', () => {
- expect(scenario.result[0].text).toContain('AWS/EC2');
- expect(scenario.request.queries[0].type).toBe('metricFindQuery');
- expect(scenario.request.queries[0].subtype).toBe('namespaces');
- });
- });
- describeMetricFindQuery('metrics(AWS/EC2)', scenario => {
- scenario.setup(() => {
- scenario.requestResponse = {
- results: {
- metricFindQuery: {
- tables: [{ rows: [['CPUUtilization', 'CPUUtilization']] }],
- },
- },
- };
- });
- it('should call __GetMetrics and return result', () => {
- expect(scenario.result[0].text).toBe('CPUUtilization');
- expect(scenario.request.queries[0].type).toBe('metricFindQuery');
- expect(scenario.request.queries[0].subtype).toBe('metrics');
- });
- });
- describeMetricFindQuery('dimension_keys(AWS/EC2)', scenario => {
- scenario.setup(() => {
- scenario.requestResponse = {
- results: {
- metricFindQuery: {
- tables: [{ rows: [['InstanceId', 'InstanceId']] }],
- },
- },
- };
- });
- it('should call __GetDimensions and return result', () => {
- expect(scenario.result[0].text).toBe('InstanceId');
- expect(scenario.request.queries[0].type).toBe('metricFindQuery');
- expect(scenario.request.queries[0].subtype).toBe('dimension_keys');
- });
- });
- describeMetricFindQuery('dimension_values(us-east-1,AWS/EC2,CPUUtilization,InstanceId)', scenario => {
- scenario.setup(() => {
- scenario.requestResponse = {
- results: {
- metricFindQuery: {
- tables: [{ rows: [['i-12345678', 'i-12345678']] }],
- },
- },
- };
- });
- it('should call __ListMetrics and return result', () => {
- expect(scenario.result[0].text).toContain('i-12345678');
- expect(scenario.request.queries[0].type).toBe('metricFindQuery');
- expect(scenario.request.queries[0].subtype).toBe('dimension_values');
- });
- });
- describeMetricFindQuery('dimension_values(default,AWS/EC2,CPUUtilization,InstanceId)', scenario => {
- scenario.setup(() => {
- scenario.requestResponse = {
- results: {
- metricFindQuery: {
- tables: [{ rows: [['i-12345678', 'i-12345678']] }],
- },
- },
- };
- });
- it('should call __ListMetrics and return result', () => {
- expect(scenario.result[0].text).toContain('i-12345678');
- expect(scenario.request.queries[0].type).toBe('metricFindQuery');
- expect(scenario.request.queries[0].subtype).toBe('dimension_values');
- });
- });
- it('should caclculate the correct period', function() {
- const hourSec = 60 * 60;
- const daySec = hourSec * 24;
- const start = 1483196400 * 1000;
- const testData: any[] = [
- [
- { period: 60, namespace: 'AWS/EC2' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3,
- 60,
- ],
- [
- { period: null, namespace: 'AWS/EC2' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3,
- 300,
- ],
- [
- { period: 60, namespace: 'AWS/ELB' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3,
- 60,
- ],
- [
- { period: null, namespace: 'AWS/ELB' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3,
- 60,
- ],
- [
- { period: 1, namespace: 'CustomMetricsNamespace' },
- {
- range: {
- from: new Date(start),
- to: new Date(start + (1440 - 1) * 1000),
- },
- },
- hourSec * 3 - 1,
- 1,
- ],
- [
- { period: 1, namespace: 'CustomMetricsNamespace' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3 - 1,
- 60,
- ],
- [
- { period: 60, namespace: 'CustomMetricsNamespace' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3,
- 60,
- ],
- [
- { period: null, namespace: 'CustomMetricsNamespace' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3 - 1,
- 60,
- ],
- [
- { period: null, namespace: 'CustomMetricsNamespace' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- hourSec * 3,
- 60,
- ],
- [
- { period: null, namespace: 'CustomMetricsNamespace' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- daySec * 15,
- 60,
- ],
- [
- { period: null, namespace: 'CustomMetricsNamespace' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- daySec * 63,
- 300,
- ],
- [
- { period: null, namespace: 'CustomMetricsNamespace' },
- { range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
- daySec * 455,
- 3600,
- ],
- ];
- for (const t of testData) {
- const target = t[0];
- const options = t[1];
- const now = new Date(options.range.from.valueOf() + t[2] * 1000);
- const expected = t[3];
- const actual = ctx.ds.getPeriod(target, options, now);
- expect(actual).toBe(expected);
- }
- });
- });
|