mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-24 03:18:57 +00:00
Fix regression in kube-proxy (#106214)
* Fix regression in kube-proxy Don't use a prepend() - that allocates. Instead, make Write() take either strings or slices (I wish we could express that better). * WIP: switch to intf * WIP: less appends * tests and ipvs
This commit is contained in:
@@ -472,17 +472,29 @@ type LineBuffer struct {
|
||||
b bytes.Buffer
|
||||
}
|
||||
|
||||
// Write joins all words with spaces, terminates with newline and writes to buf.
|
||||
func (buf *LineBuffer) Write(words ...string) {
|
||||
// We avoid strings.Join for performance reasons.
|
||||
for i := range words {
|
||||
buf.b.WriteString(words[i])
|
||||
if i < len(words)-1 {
|
||||
// Write takes a list of arguments, each a string or []string, joins all the
|
||||
// individual strings with spaces, terminates with newline, and writes to buf.
|
||||
// Any other argument type will panic.
|
||||
func (buf *LineBuffer) Write(args ...interface{}) {
|
||||
for i, arg := range args {
|
||||
if i > 0 {
|
||||
buf.b.WriteByte(' ')
|
||||
} else {
|
||||
buf.b.WriteByte('\n')
|
||||
}
|
||||
switch x := arg.(type) {
|
||||
case string:
|
||||
buf.b.WriteString(x)
|
||||
case []string:
|
||||
for j, s := range x {
|
||||
if j > 0 {
|
||||
buf.b.WriteByte(' ')
|
||||
}
|
||||
buf.b.WriteString(s)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown argument type: %T", x))
|
||||
}
|
||||
}
|
||||
buf.b.WriteByte('\n')
|
||||
}
|
||||
|
||||
// WriteBytes writes bytes to buffer, and terminates with newline.
|
||||
|
@@ -1148,41 +1148,56 @@ func TestRevertPorts(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteLine(t *testing.T) {
|
||||
func TestLineBufferWrite(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
words []string
|
||||
input []interface{}
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "write no word",
|
||||
words: []string{},
|
||||
expected: "",
|
||||
name: "none",
|
||||
input: []interface{}{},
|
||||
expected: "\n",
|
||||
},
|
||||
{
|
||||
name: "write one word",
|
||||
words: []string{"test1"},
|
||||
name: "one string",
|
||||
input: []interface{}{"test1"},
|
||||
expected: "test1\n",
|
||||
},
|
||||
{
|
||||
name: "write multi word",
|
||||
words: []string{"test1", "test2", "test3"},
|
||||
expected: "test1 test2 test3\n",
|
||||
name: "one slice",
|
||||
input: []interface{}{[]string{"test1", "test2"}},
|
||||
expected: "test1 test2\n",
|
||||
},
|
||||
{
|
||||
name: "mixed",
|
||||
input: []interface{}{"s1", "s2", []string{"s3", "s4"}, "", "s5", []string{}, []string{"s6"}, "s7"},
|
||||
expected: "s1 s2 s3 s4 s5 s6 s7\n",
|
||||
},
|
||||
}
|
||||
testBuffer := LineBuffer{}
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
testBuffer.Reset()
|
||||
testBuffer.Write(testCase.words...)
|
||||
testBuffer.Write(testCase.input...)
|
||||
if want, got := testCase.expected, string(testBuffer.Bytes()); !strings.EqualFold(want, got) {
|
||||
t.Fatalf("write word is %v\n expected: %s, got: %s", testCase.words, want, got)
|
||||
t.Fatalf("write word is %v\n expected: %q, got: %q", testCase.input, want, got)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteBytesLine(t *testing.T) {
|
||||
func TestLineBufferWritePanic(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("did not panic")
|
||||
}
|
||||
}()
|
||||
testBuffer := LineBuffer{}
|
||||
testBuffer.Write("string", []string{"a", "slice"}, 1234)
|
||||
}
|
||||
|
||||
func TestLineBufferWriteBytes(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
bytes []byte
|
||||
|
Reference in New Issue
Block a user