github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/logcli/output/default_test.go (about)

     1  package output
     2  
     3  import (
     4  	"bytes"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/grafana/loki/pkg/loghttp"
    12  )
    13  
    14  func TestDefaultOutput_Format(t *testing.T) {
    15  	t.Parallel()
    16  
    17  	timestamp, _ := time.Parse(time.RFC3339, "2006-01-02T15:04:05+07:00")
    18  	emptyLabels := loghttp.LabelSet{}
    19  	someLabels := loghttp.LabelSet(map[string]string{
    20  		"type": "test",
    21  	})
    22  
    23  	tests := map[string]struct {
    24  		options      *LogOutputOptions
    25  		timestamp    time.Time
    26  		lbls         loghttp.LabelSet
    27  		maxLabelsLen int
    28  		line         string
    29  		expected     string
    30  	}{
    31  		"empty line with no labels": {
    32  			&LogOutputOptions{Timezone: time.UTC, NoLabels: false},
    33  			timestamp,
    34  			emptyLabels,
    35  			0,
    36  			"",
    37  			"2006-01-02T08:04:05Z {} \n",
    38  		},
    39  		"empty line with labels": {
    40  			&LogOutputOptions{Timezone: time.UTC, NoLabels: false},
    41  			timestamp,
    42  			someLabels,
    43  			len(someLabels.String()),
    44  			"",
    45  			"2006-01-02T08:04:05Z {type=\"test\"} \n",
    46  		},
    47  		"max labels length shorter than input labels": {
    48  			&LogOutputOptions{Timezone: time.UTC, NoLabels: false},
    49  			timestamp,
    50  			someLabels,
    51  			0,
    52  			"Hello",
    53  			"2006-01-02T08:04:05Z {type=\"test\"} Hello\n",
    54  		},
    55  		"max labels length longer than input labels": {
    56  			&LogOutputOptions{Timezone: time.UTC, NoLabels: false},
    57  			timestamp,
    58  			someLabels,
    59  			20,
    60  			"Hello",
    61  			"2006-01-02T08:04:05Z {type=\"test\"}        Hello\n",
    62  		},
    63  		"timezone option set to a Local one": {
    64  			&LogOutputOptions{Timezone: time.FixedZone("test", 2*60*60), NoLabels: false},
    65  			timestamp,
    66  			someLabels,
    67  			0,
    68  			"Hello",
    69  			"2006-01-02T10:04:05+02:00 {type=\"test\"} Hello\n",
    70  		},
    71  		"labels output disabled": {
    72  			&LogOutputOptions{Timezone: time.UTC, NoLabels: true},
    73  			timestamp,
    74  			someLabels,
    75  			0,
    76  			"Hello",
    77  			"2006-01-02T08:04:05Z Hello\n",
    78  		},
    79  	}
    80  
    81  	for testName, testData := range tests {
    82  		testData := testData
    83  
    84  		t.Run(testName, func(t *testing.T) {
    85  			t.Parallel()
    86  			writer := &bytes.Buffer{}
    87  			out := &DefaultOutput{writer, testData.options}
    88  			out.FormatAndPrintln(testData.timestamp, testData.lbls, testData.maxLabelsLen, testData.line)
    89  
    90  			assert.Equal(t, testData.expected, writer.String())
    91  		})
    92  	}
    93  }
    94  
    95  func TestDefaultOutput_FormatLabelsPadding(t *testing.T) {
    96  	t.Parallel()
    97  
    98  	// Define a list of labels that - once formatted - have a different length
    99  	labelsList := []loghttp.LabelSet{
   100  		loghttp.LabelSet(map[string]string{
   101  			"type": "test",
   102  		}),
   103  		loghttp.LabelSet(map[string]string{
   104  			"type": "test",
   105  			"foo":  "bar",
   106  		}),
   107  		loghttp.LabelSet(map[string]string{
   108  			"type": "a-longer-test",
   109  		}),
   110  	}
   111  
   112  	timestamp, _ := time.Parse(time.RFC3339, "2006-01-02T15:04:05+07:00")
   113  	maxLabelsLen := findMaxLabelsLength(labelsList)
   114  	options := &LogOutputOptions{Timezone: time.UTC, NoLabels: false}
   115  	writer := &bytes.Buffer{}
   116  	out := &DefaultOutput{writer, options}
   117  
   118  	// Format the same log line with different labels
   119  	formattedEntries := make([]string, 0, len(labelsList))
   120  	for _, lbls := range labelsList {
   121  		out.FormatAndPrintln(timestamp, lbls, maxLabelsLen, "XXX")
   122  		formattedEntries = append(formattedEntries, writer.String())
   123  		writer.Reset()
   124  	}
   125  
   126  	// Ensure the log line starts at the same position in each formatted output
   127  	assert.Equal(t, len(labelsList), len(formattedEntries))
   128  
   129  	expectedIndex := strings.Index(formattedEntries[0], "XXX")
   130  	if expectedIndex <= 0 {
   131  		assert.FailNowf(t, "Unexpected starting position for log line in the formatted output", "position: %d", expectedIndex)
   132  	}
   133  
   134  	for _, entry := range formattedEntries {
   135  		assert.Equal(t, expectedIndex, strings.Index(entry, "XXX"))
   136  	}
   137  }
   138  
   139  func TestColorForLabels(t *testing.T) {
   140  	tests := map[string]struct {
   141  		labels      loghttp.LabelSet
   142  		otherLabels loghttp.LabelSet
   143  		expected    bool
   144  	}{
   145  
   146  		"different labels": {
   147  			loghttp.LabelSet(map[string]string{
   148  				"type": "test",
   149  				"app":  "loki",
   150  			}),
   151  			loghttp.LabelSet(map[string]string{
   152  				"type": "test",
   153  				"app":  "grafana-loki",
   154  			}),
   155  			false,
   156  		},
   157  		"same labels": {
   158  			loghttp.LabelSet(map[string]string{
   159  				"type": "test",
   160  				"app":  "loki",
   161  			}),
   162  			loghttp.LabelSet(map[string]string{
   163  				"type": "test",
   164  				"app":  "loki",
   165  			}),
   166  			true,
   167  		},
   168  	}
   169  
   170  	for testName, testData := range tests {
   171  		testData := testData
   172  
   173  		t.Run(testName, func(t *testing.T) {
   174  			t.Parallel()
   175  			labelsColor := getColor(testData.labels.String())
   176  			otherLablesColor := getColor(testData.otherLabels.String())
   177  			assert.Equal(t, testData.expected, labelsColor.Equals(otherLablesColor))
   178  		})
   179  	}
   180  }
   181  
   182  func findMaxLabelsLength(labelsList []loghttp.LabelSet) int {
   183  	maxLabelsLen := 0
   184  
   185  	for _, lbls := range labelsList {
   186  		len := len(lbls.String())
   187  		if maxLabelsLen < len {
   188  			maxLabelsLen = len
   189  		}
   190  	}
   191  
   192  	return maxLabelsLen
   193  }