unit test kube-proxy conntrack flags

Assert the flag behavior on kube-proxy using unit tests.
This commit is contained in:
Antonio Ojea 2024-10-02 12:47:51 +00:00
parent 22a30e7cbb
commit df7215a144
3 changed files with 186 additions and 5 deletions

View File

@ -525,6 +525,22 @@ kind: KubeProxyConfiguration
"empty": {
expected: expected,
},
"conntrack": {
flags: []string{
"--conntrack-max-per-core=0",
"--conntrack-min=0",
"--conntrack-tcp-timeout-established=0",
"--conntrack-tcp-timeout-close-wait=0",
},
expected: func() *kubeproxyconfig.KubeProxyConfiguration {
c := expected.DeepCopy()
c.Linux.Conntrack.MaxPerCore = ptr.To(int32(0))
c.Linux.Conntrack.Min = ptr.To(int32(0))
c.Linux.Conntrack.TCPEstablishedTimeout = ptr.To(metav1.Duration{})
c.Linux.Conntrack.TCPCloseWaitTimeout = ptr.To(metav1.Duration{})
return c
}(),
},
"empty-config": {
config: header,
expected: expected,

View File

@ -93,7 +93,8 @@ func (s *ProxyServer) platformSetup(ctx context.Context) error {
logger.Info("NodeInfo", "podCIDRs", node.Spec.PodCIDRs)
}
err := s.setupConntrack(ctx)
ct := &realConntracker{}
err := s.setupConntrack(ctx, ct)
if err != nil {
return err
}
@ -334,9 +335,7 @@ func (s *ProxyServer) createProxier(ctx context.Context, config *proxyconfigapi.
return proxier, nil
}
func (s *ProxyServer) setupConntrack(ctx context.Context) error {
ct := &realConntracker{}
func (s *ProxyServer) setupConntrack(ctx context.Context, ct Conntracker) error {
max, err := getConntrackMax(ctx, s.Config.Linux.Conntrack)
if err != nil {
return err

View File

@ -20,6 +20,8 @@ limitations under the License.
package app
import (
"context"
"errors"
"fmt"
"net"
"os"
@ -30,8 +32,8 @@ import (
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/spf13/pflag"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@ -719,3 +721,167 @@ func TestProxyServer_platformSetup(t *testing.T) {
})
}
}
type fakeConntracker struct {
called []string
err error
}
// SetMax value is calculated based on the number of CPUs by getConntrackMax()
func (fc *fakeConntracker) SetMax(ctx context.Context, max int) error {
fc.called = append(fc.called, "SetMax")
return fc.err
}
func (fc *fakeConntracker) SetTCPEstablishedTimeout(ctx context.Context, seconds int) error {
fc.called = append(fc.called, fmt.Sprintf("SetTCPEstablishedTimeout(%d)", seconds))
return fc.err
}
func (fc *fakeConntracker) SetTCPCloseWaitTimeout(ctx context.Context, seconds int) error {
fc.called = append(fc.called, fmt.Sprintf("SetTCPCloseWaitTimeout(%d)", seconds))
return fc.err
}
func (fc *fakeConntracker) SetTCPBeLiberal(ctx context.Context, value int) error {
fc.called = append(fc.called, fmt.Sprintf("SetTCPBeLiberal(%d)", value))
return fc.err
}
func (fc *fakeConntracker) SetUDPTimeout(ctx context.Context, seconds int) error {
fc.called = append(fc.called, fmt.Sprintf("SetUDPTimeout(%d)", seconds))
return fc.err
}
func (fc *fakeConntracker) SetUDPStreamTimeout(ctx context.Context, seconds int) error {
fc.called = append(fc.called, fmt.Sprintf("SetUDPStreamTimeout(%d)", seconds))
return fc.err
}
func TestSetupConntrack(t *testing.T) {
_, ctx := ktesting.NewTestContext(t)
tests := []struct {
name string
config proxyconfigapi.KubeProxyConntrackConfiguration
expect []string
conntrackErr error
wantErr bool
}{
{
name: "do nothing if conntrack config is empty",
config: proxyconfigapi.KubeProxyConntrackConfiguration{},
expect: nil,
},
{
name: "SetMax is called if conntrack.maxPerCore is specified",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
MaxPerCore: ptr.To(int32(12)),
},
expect: []string{"SetMax"},
},
{
name: "SetMax is not called if conntrack.maxPerCore is 0",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
MaxPerCore: ptr.To(int32(0)),
},
expect: nil,
},
{
name: "SetTCPEstablishedTimeout is called if conntrack.tcpEstablishedTimeout is specified",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
expect: []string{"SetTCPEstablishedTimeout(5)"},
},
{
name: "SetTCPEstablishedTimeout is not called if conntrack.tcpEstablishedTimeout is 0",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
TCPEstablishedTimeout: &metav1.Duration{Duration: 0 * time.Second},
},
expect: nil,
},
{
name: "SetTCPCloseWaitTimeout is called if conntrack.tcpCloseWaitTimeout is specified",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
TCPCloseWaitTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
expect: []string{"SetTCPCloseWaitTimeout(5)"},
},
{
name: "SetTCPCloseWaitTimeout is not called if conntrack.tcpCloseWaitTimeout is 0",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
TCPCloseWaitTimeout: &metav1.Duration{Duration: 0 * time.Second},
},
expect: nil,
},
{
name: "SetTCPBeLiberal is called if conntrack.tcpBeLiberal is true",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
TCPBeLiberal: true,
},
expect: []string{"SetTCPBeLiberal(1)"},
},
{
name: "SetTCPBeLiberal is not called if conntrack.tcpBeLiberal is false",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
TCPBeLiberal: false,
},
expect: nil,
},
{
name: "SetUDPTimeout is called if conntrack.udpTimeout is specified",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
UDPTimeout: metav1.Duration{Duration: 5 * time.Second},
},
expect: []string{"SetUDPTimeout(5)"},
},
{
name: "SetUDPTimeout is called if conntrack.udpTimeout is zero",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
UDPTimeout: metav1.Duration{Duration: 0 * time.Second},
},
expect: nil,
},
{
name: "SetUDPStreamTimeout is called if conntrack.udpStreamTimeout is specified",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
UDPStreamTimeout: metav1.Duration{Duration: 5 * time.Second},
},
expect: []string{"SetUDPStreamTimeout(5)"},
},
{
name: "SetUDPStreamTimeout is called if conntrack.udpStreamTimeout is zero",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
UDPStreamTimeout: metav1.Duration{Duration: 0 * time.Second},
},
expect: nil,
},
{
name: "an error is returned if conntrack.SetTCPEstablishedTimeout fails",
config: proxyconfigapi.KubeProxyConntrackConfiguration{
TCPEstablishedTimeout: &metav1.Duration{Duration: 5 * time.Second},
},
expect: []string{"SetTCPEstablishedTimeout(5)"},
conntrackErr: errors.New("random error"),
wantErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fc := &fakeConntracker{err: test.conntrackErr}
s := &ProxyServer{
Config: &proxyconfigapi.KubeProxyConfiguration{
Linux: proxyconfigapi.KubeProxyLinuxConfiguration{
Conntrack: test.config,
},
},
}
err := s.setupConntrack(ctx, fc)
if test.wantErr && err == nil {
t.Errorf("Test %q: Expected error, got nil", test.name)
}
if !test.wantErr && err != nil {
t.Errorf("Test %q: Expected no error, got %v", test.name, err)
}
if !cmp.Equal(fc.called, test.expect) {
t.Errorf("Test %q: Expected conntrack calls: %v, got: %v", test.name, test.expect, fc.called)
}
})
}
}