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 }