Ver Fonte

Tests for label stats calculation

David Kaltschmidt há 7 anos atrás
pai
commit
9f0b1e533f

+ 23 - 0
public/app/core/logs_model.ts

@@ -45,6 +45,13 @@ export interface LogRow {
   uniqueLabels?: LogsStreamLabels;
   uniqueLabels?: LogsStreamLabels;
 }
 }
 
 
+export interface LogsLabelStat {
+  active?: boolean;
+  count: number;
+  proportion: number;
+  value: string;
+}
+
 export enum LogsMetaKind {
 export enum LogsMetaKind {
   Number,
   Number,
   String,
   String,
@@ -88,6 +95,22 @@ export enum LogsDedupStrategy {
   signature = 'signature',
   signature = 'signature',
 }
 }
 
 
+export function calculateLogsLabelStats(rows: LogRow[], label: string): LogsLabelStat[] {
+  // Consider only rows that have the given label
+  const rowsWithLabel = rows.filter(row => row.labels[label] !== undefined);
+  const rowCount = rowsWithLabel.length;
+
+  // Get label value counts for eligible rows
+  const countsByValue = _.countBy(rowsWithLabel, row => (row as LogRow).labels[label]);
+  const sortedCounts = _.chain(countsByValue)
+    .map((count, value) => ({ count, value, proportion: count / rowCount }))
+    .sortBy('count')
+    .reverse()
+    .value();
+
+  return sortedCounts;
+}
+
 const isoDateRegexp = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d[,\.]\d+([+-][0-2]\d:[0-5]\d|Z)/g;
 const isoDateRegexp = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d[,\.]\d+([+-][0-2]\d:[0-5]\d|Z)/g;
 function isDuplicateRow(row: LogRow, other: LogRow, strategy: LogsDedupStrategy): boolean {
 function isDuplicateRow(row: LogRow, other: LogRow, strategy: LogsDedupStrategy): boolean {
   switch (strategy) {
   switch (strategy) {

+ 54 - 1
public/app/core/specs/logs_model.test.ts

@@ -1,4 +1,4 @@
-import { dedupLogRows, LogsDedupStrategy, LogsModel } from '../logs_model';
+import { calculateLogsLabelStats, dedupLogRows, LogsDedupStrategy, LogsModel } from '../logs_model';
 
 
 describe('dedupLogRows()', () => {
 describe('dedupLogRows()', () => {
   test('should return rows as is when dedup is set to none', () => {
   test('should return rows as is when dedup is set to none', () => {
@@ -106,3 +106,56 @@ describe('dedupLogRows()', () => {
     ]);
     ]);
   });
   });
 });
 });
+
+describe('calculateLogsLabelStats()', () => {
+  test('should return no stats for empty rows', () => {
+    expect(calculateLogsLabelStats([], '')).toEqual([]);
+  });
+
+  test('should return no stats of label is not found', () => {
+    const rows = [
+      {
+        entry: 'foo 1',
+        labels: {
+          foo: 'bar',
+        },
+      },
+    ];
+
+    expect(calculateLogsLabelStats(rows as any, 'baz')).toEqual([]);
+  });
+
+  test('should return stats for found labels', () => {
+    const rows = [
+      {
+        entry: 'foo 1',
+        labels: {
+          foo: 'bar',
+        },
+      },
+      {
+        entry: 'foo 0',
+        labels: {
+          foo: 'xxx',
+        },
+      },
+      {
+        entry: 'foo 2',
+        labels: {
+          foo: 'bar',
+        },
+      },
+    ];
+
+    expect(calculateLogsLabelStats(rows as any, 'foo')).toMatchObject([
+      {
+        value: 'bar',
+        count: 2,
+      },
+      {
+        value: 'xxx',
+        count: 1,
+      },
+    ]);
+  });
+});

+ 5 - 28
public/app/features/explore/LogLabels.tsx

@@ -2,32 +2,9 @@ import _ from 'lodash';
 import React, { PureComponent } from 'react';
 import React, { PureComponent } from 'react';
 import classnames from 'classnames';
 import classnames from 'classnames';
 
 
-import { LogsStreamLabels, LogRow } from 'app/core/logs_model';
+import { calculateLogsLabelStats, LogsLabelStat, LogsStreamLabels, LogRow } from 'app/core/logs_model';
 
 
-interface FieldStat {
-  active?: boolean;
-  value: string;
-  count: number;
-  proportion: number;
-}
-
-function calculateStats(rows: LogRow[], label: string): FieldStat[] {
-  // Consider only rows that have the given label
-  const rowsWithLabel = rows.filter(row => row.labels[label] !== undefined);
-  const rowCount = rowsWithLabel.length;
-
-  // Get label value counts for eligible rows
-  const countsByValue = _.countBy(rowsWithLabel, row => (row as LogRow).labels[label]);
-  const sortedCounts = _.chain(countsByValue)
-    .map((count, value) => ({ count, value, proportion: count / rowCount }))
-    .sortBy('count')
-    .reverse()
-    .value();
-
-  return sortedCounts;
-}
-
-function StatsRow({ active, count, proportion, value }: FieldStat) {
+function StatsRow({ active, count, proportion, value }: LogsLabelStat) {
   const percent = `${Math.round(proportion * 100)}%`;
   const percent = `${Math.round(proportion * 100)}%`;
   const barStyle = { width: percent };
   const barStyle = { width: percent };
   const className = classnames('logs-stats-row', { 'logs-stats-row--active': active });
   const className = classnames('logs-stats-row', { 'logs-stats-row--active': active });
@@ -48,7 +25,7 @@ function StatsRow({ active, count, proportion, value }: FieldStat) {
 
 
 const STATS_ROW_LIMIT = 5;
 const STATS_ROW_LIMIT = 5;
 class Stats extends PureComponent<{
 class Stats extends PureComponent<{
-  stats: FieldStat[];
+  stats: LogsLabelStat[];
   label: string;
   label: string;
   value: string;
   value: string;
   rowCount: number;
   rowCount: number;
@@ -92,7 +69,7 @@ class Label extends PureComponent<
     value: string;
     value: string;
     onClickLabel?: (label: string, value: string) => void;
     onClickLabel?: (label: string, value: string) => void;
   },
   },
-  { showStats: boolean; stats: FieldStat[] }
+  { showStats: boolean; stats: LogsLabelStat[] }
 > {
 > {
   state = {
   state = {
     stats: null,
     stats: null,
@@ -115,7 +92,7 @@ class Label extends PureComponent<
       if (state.showStats) {
       if (state.showStats) {
         return { showStats: false, stats: null };
         return { showStats: false, stats: null };
       }
       }
-      const stats = calculateStats(this.props.allRows, this.props.label);
+      const stats = calculateLogsLabelStats(this.props.allRows, this.props.label);
       return { showStats: true, stats };
       return { showStats: true, stats };
     });
     });
   };
   };