github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/targets/windows/win_eventlog/util_test.go (about) 1 // The MIT License (MIT) 2 3 // Copyright (c) 2015-2020 InfluxData Inc. 4 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 12 // The above copyright notice and this permission notice shall be included in all 13 // copies or substantial portions of the Software. 14 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 // SOFTWARE. 22 //go:build windows 23 // +build windows 24 25 //revive:disable-next-line:var-naming 26 // Package win_eventlog Input plugin to collect Windows Event Log messages 27 package win_eventlog 28 29 import ( 30 "bytes" 31 "encoding/binary" 32 "encoding/xml" 33 "io" 34 "reflect" 35 "testing" 36 "unicode/utf16" 37 ) 38 39 func TestDecodeUTF16(t *testing.T) { 40 testString := "Test String" 41 utf16s := utf16.Encode([]rune(testString)) 42 var bytesUtf16 bytes.Buffer 43 writer := io.Writer(&bytesUtf16) 44 lb := len(utf16s) 45 for i := 0; i < lb; i++ { 46 word := make([]byte, 2) 47 binary.LittleEndian.PutUint16(word, utf16s[i]) 48 _, err := writer.Write(word) 49 if err != nil { 50 t.Errorf("error preparing UTF-16 test string") 51 return 52 } 53 } 54 type args struct { 55 b []byte 56 } 57 tests := []struct { 58 name string 59 args args 60 want []byte 61 wantErr bool 62 }{ 63 { 64 name: "Wrong UTF-16", 65 args: args{b: append(bytesUtf16.Bytes(), byte('\x00'))}, 66 wantErr: true, 67 }, 68 { 69 name: "UTF-16", 70 args: args{b: bytesUtf16.Bytes()}, 71 want: []byte(testString), 72 }, 73 } 74 for _, tt := range tests { 75 t.Run(tt.name, func(t *testing.T) { 76 got, err := DecodeUTF16(tt.args.b) 77 if (err != nil) != tt.wantErr { 78 t.Errorf("DecodeUTF16() error = %v, wantErr %v", err, tt.wantErr) 79 return 80 } 81 if !reflect.DeepEqual(got, tt.want) { 82 t.Errorf("DecodeUTF16() = %v, want %v", got, tt.want) 83 } 84 }) 85 } 86 } 87 88 var xmlbroken = ` 89 <BrokenXML> 90 <Data/>qq</Data> 91 </BrokenXML> 92 ` 93 94 var xmldata = ` 95 <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> 96 <UserData> 97 <CbsPackageChangeState xmlns="http://manifests.microsoft.com/win/2004/08/windows/setup_provider"> 98 <IntendedPackageState>5111</IntendedPackageState> 99 <ErrorCode><Code>0x0</Code></ErrorCode> 100 </CbsPackageChangeState> 101 </UserData> 102 <EventData> 103 <Data>2120-07-26T15:24:25Z</Data> 104 <Data>RulesEngine</Data> 105 <Data Name="Engine">RulesEngine</Data> 106 </EventData> 107 </Event> 108 ` 109 110 type testEvent struct { 111 UserData struct { 112 InnerXML []byte `xml:",innerxml"` 113 } `xml:"UserData"` 114 EventData struct { 115 InnerXML []byte `xml:",innerxml"` 116 } `xml:"EventData"` 117 } 118 119 func TestUnrollXMLFields(t *testing.T) { 120 container := testEvent{} 121 err := xml.Unmarshal([]byte(xmldata), &container) 122 if err != nil { 123 t.Errorf("couldn't unmarshal precooked xml string xmldata") 124 return 125 } 126 127 type args struct { 128 data []byte 129 fieldsUsage map[string]int 130 } 131 tests := []struct { 132 name string 133 args args 134 want1 []EventField 135 want2 map[string]int 136 }{ 137 { 138 name: "Broken XML", 139 args: args{ 140 data: []byte(xmlbroken), 141 fieldsUsage: map[string]int{}, 142 }, 143 want1: nil, 144 want2: map[string]int{}, 145 }, 146 { 147 name: "EventData with non-unique names and one Name attr", 148 args: args{ 149 data: container.EventData.InnerXML, 150 fieldsUsage: map[string]int{}, 151 }, 152 want1: []EventField{ 153 {Name: "Data", Value: "2120-07-26T15:24:25Z"}, 154 {Name: "Data", Value: "RulesEngine"}, 155 {Name: "Data_Engine", Value: "RulesEngine"}, 156 }, 157 want2: map[string]int{"Data": 2, "Data_Engine": 1}, 158 }, 159 { 160 name: "UserData with non-unique names and three levels of depth", 161 args: args{ 162 data: container.UserData.InnerXML, 163 fieldsUsage: map[string]int{}, 164 }, 165 want1: []EventField{ 166 {Name: "CbsPackageChangeState_IntendedPackageState", Value: "5111"}, 167 {Name: "CbsPackageChangeState_ErrorCode_Code", Value: "0x0"}, 168 }, 169 want2: map[string]int{ 170 "CbsPackageChangeState_ErrorCode_Code": 1, 171 "CbsPackageChangeState_IntendedPackageState": 1, 172 }, 173 }, 174 } 175 for _, tt := range tests { 176 t.Run(tt.name, func(t *testing.T) { 177 got, got1 := UnrollXMLFields(tt.args.data, tt.args.fieldsUsage, "_") 178 if !reflect.DeepEqual(got, tt.want1) { 179 t.Errorf("ExtractFields() got = %v, want %v", got, tt.want1) 180 } 181 if !reflect.DeepEqual(got1, tt.want2) { 182 t.Errorf("ExtractFields() got1 = %v, want %v", got1, tt.want2) 183 } 184 }) 185 } 186 } 187 188 func TestUniqueFieldNames(t *testing.T) { 189 type args struct { 190 fields []EventField 191 fieldsUsage map[string]int 192 } 193 tests := []struct { 194 name string 195 args args 196 want []EventField 197 }{ 198 { 199 name: "Unique values", 200 args: args{ 201 fields: []EventField{ 202 {Name: "Data", Value: "2120-07-26T15:24:25Z"}, 203 {Name: "Data", Value: "RulesEngine"}, 204 {Name: "Engine", Value: "RulesEngine"}, 205 }, 206 fieldsUsage: map[string]int{"Data": 2, "Engine": 1}, 207 }, 208 want: []EventField{ 209 {Name: "Data_1", Value: "2120-07-26T15:24:25Z"}, 210 {Name: "Data_2", Value: "RulesEngine"}, 211 {Name: "Engine", Value: "RulesEngine"}, 212 }, 213 }, 214 } 215 for _, tt := range tests { 216 t.Run(tt.name, func(t *testing.T) { 217 if got := UniqueFieldNames(tt.args.fields, tt.args.fieldsUsage, "_"); !reflect.DeepEqual(got, tt.want) { 218 t.Errorf("PrintFields() = %v, want %v", got, tt.want) 219 } 220 }) 221 } 222 }