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  }