datasource.test.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. import StackdriverDataSource from '../datasource';
  2. import { metricDescriptors } from './testData';
  3. import moment from 'moment';
  4. import { TemplateSrvStub } from 'test/specs/helpers';
  5. describe('StackdriverDataSource', () => {
  6. const instanceSettings = {
  7. jsonData: {
  8. projectName: 'testproject',
  9. },
  10. };
  11. const templateSrv = new TemplateSrvStub();
  12. const timeSrv = {};
  13. describe('when performing testDataSource', () => {
  14. describe('and call to stackdriver api succeeds', () => {
  15. let ds;
  16. let result;
  17. beforeEach(async () => {
  18. const backendSrv = {
  19. async datasourceRequest() {
  20. return Promise.resolve({ status: 200 });
  21. },
  22. };
  23. ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
  24. result = await ds.testDatasource();
  25. });
  26. it('should return successfully', () => {
  27. expect(result.status).toBe('success');
  28. });
  29. });
  30. describe('and a list of metricDescriptors are returned', () => {
  31. let ds;
  32. let result;
  33. beforeEach(async () => {
  34. const backendSrv = {
  35. datasourceRequest: async () => Promise.resolve({ status: 200, data: metricDescriptors }),
  36. };
  37. ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
  38. result = await ds.testDatasource();
  39. });
  40. it('should return status success', () => {
  41. expect(result.status).toBe('success');
  42. });
  43. });
  44. describe('and call to stackdriver api fails with 400 error', () => {
  45. let ds;
  46. let result;
  47. beforeEach(async () => {
  48. const backendSrv = {
  49. datasourceRequest: async () =>
  50. Promise.reject({
  51. statusText: 'Bad Request',
  52. data: { error: { code: 400, message: 'Field interval.endTime had an invalid value' } },
  53. }),
  54. };
  55. ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
  56. result = await ds.testDatasource();
  57. });
  58. it('should return error status and a detailed error message', () => {
  59. expect(result.status).toEqual('error');
  60. expect(result.message).toBe('Stackdriver: Bad Request: 400. Field interval.endTime had an invalid value');
  61. });
  62. });
  63. });
  64. describe('when performing getProjects', () => {
  65. describe('and call to resource manager api succeeds', () => {
  66. let ds;
  67. let result;
  68. beforeEach(async () => {
  69. const response = {
  70. projects: [
  71. {
  72. projectNumber: '853996325002',
  73. projectId: 'test-project',
  74. lifecycleState: 'ACTIVE',
  75. name: 'Test Project',
  76. createTime: '2015-06-02T14:16:08.520Z',
  77. parent: {
  78. type: 'organization',
  79. id: '853996325002',
  80. },
  81. },
  82. ],
  83. };
  84. const backendSrv = {
  85. async datasourceRequest() {
  86. return Promise.resolve({ status: 200, data: response });
  87. },
  88. };
  89. ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
  90. result = await ds.getProjects();
  91. });
  92. it('should return successfully', () => {
  93. expect(result.length).toBe(1);
  94. expect(result[0].id).toBe('test-project');
  95. expect(result[0].name).toBe('Test Project');
  96. });
  97. });
  98. });
  99. describe('When performing query', () => {
  100. const options = {
  101. range: {
  102. from: moment.utc('2017-08-22T20:00:00Z'),
  103. to: moment.utc('2017-08-22T23:59:00Z'),
  104. },
  105. rangeRaw: {
  106. from: 'now-4h',
  107. to: 'now',
  108. },
  109. targets: [
  110. {
  111. refId: 'A',
  112. aggregation: {},
  113. },
  114. ],
  115. };
  116. describe('and no time series data is returned', () => {
  117. let ds;
  118. const response = {
  119. results: {
  120. A: {
  121. refId: 'A',
  122. meta: {
  123. rawQuery: 'arawquerystring',
  124. },
  125. series: null,
  126. tables: null,
  127. },
  128. },
  129. };
  130. beforeEach(() => {
  131. const backendSrv = {
  132. datasourceRequest: async () => Promise.resolve({ status: 200, data: response }),
  133. };
  134. ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
  135. });
  136. it('should return a list of datapoints', () => {
  137. return ds.query(options).then(results => {
  138. expect(results.data.length).toBe(0);
  139. });
  140. });
  141. });
  142. });
  143. describe('when performing getMetricTypes', () => {
  144. describe('and call to stackdriver api succeeds', () => {});
  145. let ds;
  146. let result;
  147. beforeEach(async () => {
  148. const backendSrv = {
  149. async datasourceRequest() {
  150. return Promise.resolve({
  151. data: {
  152. metricDescriptors: [
  153. {
  154. displayName: 'test metric name 1',
  155. type: 'compute.googleapis.com/instance/cpu/test-metric-type-1',
  156. description: 'A description',
  157. },
  158. {
  159. type: 'logging.googleapis.com/user/logbased-metric-with-no-display-name',
  160. },
  161. ],
  162. },
  163. });
  164. },
  165. };
  166. ds = new StackdriverDataSource(instanceSettings, backendSrv, templateSrv, timeSrv);
  167. result = await ds.getMetricTypes();
  168. });
  169. it('should return successfully', () => {
  170. expect(result.length).toBe(2);
  171. expect(result[0].service).toBe('compute.googleapis.com');
  172. expect(result[0].serviceShortName).toBe('compute');
  173. expect(result[0].type).toBe('compute.googleapis.com/instance/cpu/test-metric-type-1');
  174. expect(result[0].displayName).toBe('test metric name 1');
  175. expect(result[0].description).toBe('A description');
  176. expect(result[1].type).toBe('logging.googleapis.com/user/logbased-metric-with-no-display-name');
  177. expect(result[1].displayName).toBe('logging.googleapis.com/user/logbased-metric-with-no-display-name');
  178. });
  179. });
  180. describe('when interpolating a template variable for group bys', () => {
  181. let interpolated;
  182. describe('and is single value variable', () => {
  183. beforeEach(() => {
  184. templateSrv.data = {
  185. test: 'groupby1',
  186. };
  187. const ds = new StackdriverDataSource(instanceSettings, {}, templateSrv, timeSrv);
  188. interpolated = ds.interpolateGroupBys(['[[test]]'], {});
  189. });
  190. it('should replace the variable with the value', () => {
  191. expect(interpolated.length).toBe(1);
  192. expect(interpolated[0]).toBe('groupby1');
  193. });
  194. });
  195. describe('and is multi value variable', () => {
  196. beforeEach(() => {
  197. templateSrv.data = {
  198. test: 'groupby1,groupby2',
  199. };
  200. const ds = new StackdriverDataSource(instanceSettings, {}, templateSrv, timeSrv);
  201. interpolated = ds.interpolateGroupBys(['[[test]]'], {});
  202. });
  203. it('should replace the variable with an array of group bys', () => {
  204. expect(interpolated.length).toBe(2);
  205. expect(interpolated[0]).toBe('groupby1');
  206. expect(interpolated[1]).toBe('groupby2');
  207. });
  208. });
  209. });
  210. describe('unit parsing', () => {
  211. let ds, res;
  212. beforeEach(() => {
  213. ds = new StackdriverDataSource(instanceSettings, {}, templateSrv, timeSrv);
  214. });
  215. describe('when theres only one target', () => {
  216. describe('and the stackdriver unit doesnt have a corresponding grafana unit', () => {
  217. beforeEach(() => {
  218. res = ds.resolvePanelUnitFromTargets([{ unit: 'megaseconds' }]);
  219. });
  220. it('should return none', () => {
  221. expect(res).toEqual('none');
  222. });
  223. });
  224. describe('and the stackdriver unit has a corresponding grafana unit', () => {
  225. beforeEach(() => {
  226. res = ds.resolvePanelUnitFromTargets([{ unit: 'bit' }]);
  227. });
  228. it('should return bits', () => {
  229. expect(res).toEqual('bits');
  230. });
  231. });
  232. });
  233. describe('when theres more than one target', () => {
  234. describe('and all target units are the same', () => {
  235. beforeEach(() => {
  236. res = ds.resolvePanelUnitFromTargets([{ unit: 'bit' }, { unit: 'bit' }]);
  237. });
  238. it('should return bits', () => {
  239. expect(res).toEqual('bits');
  240. });
  241. });
  242. describe('and all target units are the same but doesnt have grafana mappings', () => {
  243. beforeEach(() => {
  244. res = ds.resolvePanelUnitFromTargets([{ unit: 'megaseconds' }, { unit: 'megaseconds' }]);
  245. });
  246. it('should return the default value - none', () => {
  247. expect(res).toEqual('none');
  248. });
  249. });
  250. describe('and all target units are not the same', () => {
  251. beforeEach(() => {
  252. res = ds.resolvePanelUnitFromTargets([{ unit: 'bit' }, { unit: 'min' }]);
  253. });
  254. it('should return the default value - none', () => {
  255. expect(res).toEqual('none');
  256. });
  257. });
  258. });
  259. });
  260. });