k8s.io/apiserver@v0.31.1/plugin/pkg/audit/truncate/truncate_test.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package truncate 18 19 import ( 20 "strings" 21 "testing" 22 23 "github.com/stretchr/testify/require" 24 25 "k8s.io/apimachinery/pkg/runtime" 26 auditinternal "k8s.io/apiserver/pkg/apis/audit" 27 auditv1 "k8s.io/apiserver/pkg/apis/audit/v1" 28 "k8s.io/apiserver/plugin/pkg/audit/fake" 29 // Importing just for the schema definitions. 30 _ "k8s.io/apiserver/plugin/pkg/audit/webhook" 31 ) 32 33 var ( 34 defaultConfig = Config{ 35 MaxBatchSize: 4 * 1024 * 1024, 36 MaxEventSize: 100 * 1024, 37 } 38 ) 39 40 func TestTruncatingEvents(t *testing.T) { 41 testCases := []struct { 42 desc string 43 event *auditinternal.Event 44 wantDropped bool 45 wantTruncated bool 46 }{ 47 { 48 desc: "Empty event should not be truncated", 49 event: &auditinternal.Event{}, 50 }, 51 { 52 desc: "Event with too large body should be truncated", 53 event: &auditinternal.Event{ 54 Level: auditinternal.LevelRequest, 55 RequestObject: &runtime.Unknown{ 56 Raw: []byte("\"" + strings.Repeat("A", int(defaultConfig.MaxEventSize)) + "\""), 57 }, 58 }, 59 wantTruncated: true, 60 }, 61 { 62 desc: "Event with too large metadata should be dropped", 63 event: &auditinternal.Event{ 64 Annotations: map[string]string{ 65 "key": strings.Repeat("A", int(defaultConfig.MaxEventSize)), 66 }, 67 }, 68 wantDropped: true, 69 }, 70 } 71 72 for _, tc := range testCases { 73 tc := tc 74 t.Run(tc.desc, func(t *testing.T) { 75 t.Parallel() 76 77 var event *auditinternal.Event 78 79 fb := &fake.Backend{ 80 OnRequest: func(events []*auditinternal.Event) { 81 require.Len(t, events, 1, "Expected single event in batch") 82 event = events[0] 83 }, 84 } 85 b := NewBackend(fb, defaultConfig, auditv1.SchemeGroupVersion) 86 b.ProcessEvents(tc.event) 87 88 require.Equal(t, !tc.wantDropped, event != nil, "Incorrect event presence") 89 if tc.wantTruncated { 90 require.Equal(t, annotationValue, event.Annotations[annotationKey], "Annotation should be present") 91 require.Nil(t, event.RequestObject, "After truncation request should be nil") 92 require.Nil(t, event.ResponseObject, "After truncation response should be nil") 93 } 94 }) 95 } 96 } 97 98 func TestSplittingBatches(t *testing.T) { 99 testCases := []struct { 100 desc string 101 config Config 102 events []*auditinternal.Event 103 wantBatchCount int 104 }{ 105 { 106 desc: "Events fitting in one batch should not be split", 107 config: defaultConfig, 108 events: []*auditinternal.Event{{}}, 109 wantBatchCount: 1, 110 }, 111 { 112 desc: "Events not fitting in one batch should be split", 113 config: Config{ 114 MaxEventSize: defaultConfig.MaxEventSize, 115 MaxBatchSize: 1, 116 }, 117 events: []*auditinternal.Event{ 118 {Annotations: map[string]string{"key": strings.Repeat("A", int(50))}}, 119 {Annotations: map[string]string{"key": strings.Repeat("A", int(50))}}, 120 }, 121 wantBatchCount: 2, 122 }, 123 } 124 for _, tc := range testCases { 125 tc := tc 126 t.Run(tc.desc, func(t *testing.T) { 127 t.Parallel() 128 129 var gotBatchCount int 130 fb := &fake.Backend{ 131 OnRequest: func(events []*auditinternal.Event) { 132 gotBatchCount++ 133 }, 134 } 135 b := NewBackend(fb, tc.config, auditv1.SchemeGroupVersion) 136 b.ProcessEvents(tc.events...) 137 138 require.Equal(t, tc.wantBatchCount, gotBatchCount) 139 }) 140 } 141 }