github.com/thanos-io/thanos@v0.32.5/pkg/ui/react-app/src/pages/graph/DataTable.test.tsx (about) 1 import * as React from 'react'; 2 import { shallow } from 'enzyme'; 3 import DataTable, { QueryResult } from './DataTable'; 4 import HistogramString, { HistogramStringProps } from './DataTable'; 5 import { UncontrolledAlert, Table } from 'reactstrap'; 6 import SeriesName from './SeriesName'; 7 8 describe('DataTable', () => { 9 describe('when data is null', () => { 10 it('renders an alert', () => { 11 const table = shallow(<DataTable data={null} />); 12 const alert = table.find(UncontrolledAlert); 13 expect(Object.keys(alert.props())).toHaveLength(2); 14 expect(alert.prop('color')).toEqual('light'); 15 expect(alert.prop('children')).toEqual('No data queried yet'); 16 }); 17 }); 18 19 describe('when data.result is empty', () => { 20 it('renders an alert', () => { 21 const dataTableProps: QueryResult = { 22 data: { 23 resultType: 'vector', 24 result: [], 25 }, 26 }; 27 const table = shallow(<DataTable {...dataTableProps} />); 28 const alert = table.find(UncontrolledAlert); 29 expect(Object.keys(alert.props())).toHaveLength(2); 30 expect(alert.prop('color')).toEqual('secondary'); 31 expect(alert.prop('children')).toEqual('Empty query result'); 32 }); 33 }); 34 35 describe('when resultType is a vector with values', () => { 36 const dataTableProps: QueryResult = { 37 data: { 38 resultType: 'vector', 39 result: [ 40 { 41 metric: { 42 __name__: 'metric_name_1', 43 label1: 'value_1', 44 labeln: 'value_n', 45 }, 46 value: [1572098246.599, '0'], 47 }, 48 { 49 metric: { 50 __name__: 'metric_name_2', 51 label1: 'value_1', 52 labeln: 'value_n', 53 }, 54 value: [1572098246.599, '1'], 55 }, 56 ], 57 }, 58 }; 59 const dataTable = shallow(<DataTable {...dataTableProps} />); 60 61 it('renders a table', () => { 62 const table = dataTable.find(Table); 63 expect(table.prop('hover')).toBe(true); 64 expect(table.prop('size')).toEqual('sm'); 65 expect(table.prop('className')).toEqual('data-table'); 66 expect(table.find('tbody')).toHaveLength(1); 67 }); 68 69 it('renders rows', () => { 70 const table = dataTable.find(Table); 71 table.find('tr').forEach((row, idx) => { 72 expect(row.find(SeriesName)).toHaveLength(1); 73 expect(row.find('td').at(1).text()).toEqual(`${idx} <HistogramString />`); 74 }); 75 }); 76 }); 77 78 describe('when resultType is a vector with histograms', () => { 79 const dataTableProps: QueryResult = { 80 data: { 81 resultType: 'vector', 82 result: [ 83 { 84 metric: { 85 __name__: 'metric_name_1', 86 label1: 'value_1', 87 labeln: 'value_n', 88 }, 89 histogram: [ 90 1572098246.599, 91 { 92 count: '10', 93 sum: '3.3', 94 buckets: [ 95 [1, '-1', '-0.5', '2'], 96 [3, '-0.5', '0.5', '3'], 97 [0, '0.5', '1', '5'], 98 ], 99 }, 100 ], 101 }, 102 { 103 metric: { 104 __name__: 'metric_name_2', 105 label1: 'value_1', 106 labeln: 'value_n', 107 }, 108 histogram: [ 109 1572098247.599, 110 { 111 count: '5', 112 sum: '1.11', 113 buckets: [ 114 [0, '0.5', '1', '2'], 115 [0, '1', '2', '3'], 116 ], 117 }, 118 ], 119 }, 120 { 121 metric: { 122 __name__: 'metric_name_2', 123 label1: 'value_1', 124 labeln: 'value_n', 125 }, 126 }, 127 ], 128 }, 129 }; 130 const dataTable = shallow(<DataTable {...dataTableProps} />); 131 132 it('renders a table', () => { 133 const table = dataTable.find(Table); 134 expect(table.prop('hover')).toBe(true); 135 expect(table.prop('size')).toEqual('sm'); 136 expect(table.prop('className')).toEqual('data-table'); 137 expect(table.find('tbody')).toHaveLength(1); 138 }); 139 140 it('renders rows', () => { 141 const table = dataTable.find(Table); 142 table.find('tr').forEach((row, idx) => { 143 expect(row.find(SeriesName)).toHaveLength(1); 144 // TODO(beorn7): This doesn't actually test the rendoring yet. Need to trigger it somehow. 145 expect(row.find('td').at(1).text()).toEqual(` <HistogramString />`); 146 }); 147 }); 148 }); 149 150 describe('when resultType is a vector with too many values', () => { 151 const dataTableProps: QueryResult = { 152 data: { 153 resultType: 'vector', 154 result: Array.from(Array(10001).keys()).map((i) => { 155 return { 156 metric: { 157 __name__: `metric_name_${i}`, 158 label1: 'value_1', 159 labeln: 'value_n', 160 }, 161 value: [1572098246.599, `${i}`], 162 }; 163 }), 164 }, 165 }; 166 const dataTable = shallow(<DataTable {...dataTableProps} />); 167 168 it('renders limited rows', () => { 169 const table = dataTable.find(Table); 170 expect(table.find('tr')).toHaveLength(10000); 171 }); 172 173 it('renders a warning', () => { 174 const alerts = dataTable.find(UncontrolledAlert); 175 expect(alerts.first().render().text()).toContain('Warning: Fetched 10001 metrics, only displaying first 10000.'); 176 }); 177 }); 178 179 describe('when resultType is vector and size is more than maximum limit of formatting', () => { 180 const dataTableProps: QueryResult = { 181 data: { 182 resultType: 'vector', 183 result: Array.from(Array(1001).keys()).map((i) => { 184 return { 185 metric: { 186 __name__: `metric_name_${i}`, 187 label1: 'value_1', 188 labeln: 'value_n', 189 }, 190 value: [1572098246.599, `${i}`], 191 }; 192 }), 193 }, 194 }; 195 const dataTable = shallow(<DataTable {...dataTableProps} />); 196 197 it('renders a warning', () => { 198 const alerts = dataTable.find(UncontrolledAlert); 199 expect(alerts.first().render().text()).toContain( 200 'Notice: Showing more than 1000 series, turning off label formatting for performance reasons.' 201 ); 202 }); 203 }); 204 205 describe('when result type is a matrix', () => { 206 const dataTableProps: QueryResult = { 207 data: { 208 resultType: 'matrix', 209 result: [ 210 { 211 metric: { 212 __name__: 'promhttp_metric_handler_requests_total', 213 code: '200', 214 instance: 'localhost:9090', 215 job: 'prometheus', 216 }, 217 values: [ 218 [1572097950.93, '9'], 219 [1572097965.931, '10'], 220 [1572097980.929, '11'], 221 [1572097995.931, '12'], 222 [1572098010.932, '13'], 223 [1572098025.933, '14'], 224 [1572098040.93, '15'], 225 [1572098055.93, '16'], 226 [1572098070.93, '17'], 227 [1572098085.936, '18'], 228 [1572098100.936, '19'], 229 [1572098115.933, '20'], 230 [1572098130.932, '21'], 231 [1572098145.932, '22'], 232 [1572098160.933, '23'], 233 [1572098175.934, '24'], 234 [1572098190.937, '25'], 235 [1572098205.934, '26'], 236 [1572098220.933, '27'], 237 [1572098235.934, '28'], 238 ], 239 }, 240 { 241 metric: { 242 __name__: 'promhttp_metric_handler_requests_total', 243 code: '500', 244 instance: 'localhost:9090', 245 job: 'prometheus', 246 }, 247 values: [ 248 [1572097950.93, '0'], 249 [1572097965.931, '0'], 250 [1572097980.929, '0'], 251 [1572097995.931, '0'], 252 [1572098010.932, '0'], 253 [1572098025.933, '0'], 254 [1572098040.93, '0'], 255 [1572098055.93, '0'], 256 [1572098070.93, '0'], 257 [1572098085.936, '0'], 258 [1572098100.936, '0'], 259 [1572098115.933, '0'], 260 [1572098130.932, '0'], 261 [1572098145.932, '0'], 262 [1572098160.933, '0'], 263 [1572098175.934, '0'], 264 [1572098190.937, '0'], 265 [1572098205.934, '0'], 266 [1572098220.933, '0'], 267 [1572098235.934, '0'], 268 ], 269 }, 270 { 271 metric: { 272 __name__: 'promhttp_metric_handler_requests_total', 273 code: '503', 274 instance: 'localhost:9090', 275 job: 'prometheus', 276 }, 277 values: [ 278 [1572097950.93, '0'], 279 [1572097965.931, '0'], 280 [1572097980.929, '0'], 281 [1572097995.931, '0'], 282 [1572098010.932, '0'], 283 [1572098025.933, '0'], 284 [1572098040.93, '0'], 285 [1572098055.93, '0'], 286 [1572098070.93, '0'], 287 [1572098085.936, '0'], 288 [1572098100.936, '0'], 289 [1572098115.933, '0'], 290 [1572098130.932, '0'], 291 [1572098145.932, '0'], 292 [1572098160.933, '0'], 293 [1572098175.934, '0'], 294 [1572098190.937, '0'], 295 [1572098205.934, '0'], 296 [1572098220.933, '0'], 297 [1572098235.934, '0'], 298 ], 299 }, 300 ], 301 }, 302 }; 303 const dataTable = shallow(<DataTable {...dataTableProps} />); 304 it('renders rows', () => { 305 const table = dataTable.find(Table); 306 const rows = table.find('tr'); 307 expect(table.find('tr')).toHaveLength(3); 308 const row = rows.at(0); 309 expect(row.text()).toEqual(`<SeriesName />9 @1572097950.93 310 10 @1572097965.931 311 11 @1572097980.929 312 12 @1572097995.931 313 13 @1572098010.932 314 14 @1572098025.933 315 15 @1572098040.93 316 16 @1572098055.93 317 17 @1572098070.93 318 18 @1572098085.936 319 19 @1572098100.936 320 20 @1572098115.933 321 21 @1572098130.932 322 22 @1572098145.932 323 23 @1572098160.933 324 24 @1572098175.934 325 25 @1572098190.937 326 26 @1572098205.934 327 27 @1572098220.933 328 28 @1572098235.934 `); 329 }); 330 }); 331 332 describe('when resultType is a scalar', () => { 333 const dataTableProps: QueryResult = { 334 data: { 335 resultType: 'scalar', 336 result: [1572098246.599, '5'], 337 }, 338 }; 339 const dataTable = shallow(<DataTable {...dataTableProps} />); 340 it('renders a scalar row', () => { 341 const table = dataTable.find(Table); 342 const rows = table.find('tr'); 343 expect(rows.text()).toEqual('scalar5'); 344 }); 345 }); 346 347 describe('when resultType is a string', () => { 348 const dataTableProps: QueryResult = { 349 data: { 350 resultType: 'string', 351 result: 'string', 352 }, 353 }; 354 const dataTable = shallow(<DataTable {...dataTableProps} />); 355 it('renders a string row', () => { 356 const table = dataTable.find(Table); 357 const rows = table.find('tr'); 358 expect(rows.text()).toEqual('stringt'); 359 }); 360 }); 361 });