mirror of
https://github.com/rancher/dynamiclistener.git
synced 2025-06-01 03:16:00 +00:00
Tests for Marking additional connections as ready
This commit is contained in:
parent
e73d5f2fca
commit
3adafb7edb
225
listener_test.go
Normal file
225
listener_test.go
Normal file
@ -0,0 +1,225 @@
|
||||
package dynamiclistener
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/dynamiclistener/factory"
|
||||
"github.com/stretchr/testify/assert"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apiError "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func Test_getCertificate(t *testing.T) {
|
||||
beforeKey, beforeCert, err := newCertificate()
|
||||
assert.NoError(t, err, "Error when setting up test - unable to construct before key for test")
|
||||
beforeTLSCert, err := tls.X509KeyPair(beforeCert, beforeKey)
|
||||
assert.NoError(t, err, "Error when setting up test - unable to convert before to tls.Certificate")
|
||||
afterKey, afterCert, err := newCertificate()
|
||||
assert.NoError(t, err, "Error when setting up test - unable to construct after key for test")
|
||||
afterTLSCert, err := tls.X509KeyPair(afterCert, afterKey)
|
||||
assert.NoError(t, err, "Error when setting up test - unable to convert after to tls.Certificate")
|
||||
tests := []struct {
|
||||
// input test vars
|
||||
name string
|
||||
secret *v1.Secret
|
||||
secretErr error
|
||||
cachedCert *tls.Certificate
|
||||
cachedVersion string
|
||||
currentConn *closeWrapper
|
||||
otherConns map[int]*closeWrapper
|
||||
|
||||
// output/result test vars
|
||||
closedConns []int
|
||||
expectedCert *tls.Certificate
|
||||
wantError bool
|
||||
}{
|
||||
{
|
||||
name: "no secret found",
|
||||
secret: nil,
|
||||
secretErr: apiError.NewNotFound(schema.GroupResource{
|
||||
Group: "",
|
||||
Resource: "Secret",
|
||||
}, "testSecret"),
|
||||
currentConn: &closeWrapper{id: 0},
|
||||
otherConns: map[int]*closeWrapper{},
|
||||
|
||||
expectedCert: nil,
|
||||
wantError: true,
|
||||
},
|
||||
{
|
||||
name: "secret found, and is up to date",
|
||||
secret: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: "1",
|
||||
Name: "testSecret",
|
||||
Namespace: "test",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
v1.TLSCertKey: beforeCert,
|
||||
v1.TLSPrivateKeyKey: beforeKey,
|
||||
},
|
||||
},
|
||||
cachedVersion: "1",
|
||||
cachedCert: &beforeTLSCert,
|
||||
currentConn: &closeWrapper{id: 0},
|
||||
otherConns: map[int]*closeWrapper{},
|
||||
|
||||
expectedCert: &beforeTLSCert,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "secret found, is not up to date, but k8s secret is not valid",
|
||||
secret: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: "2",
|
||||
Name: "testSecret",
|
||||
Namespace: "test",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
v1.TLSPrivateKeyKey: []byte("strawberry"),
|
||||
},
|
||||
},
|
||||
cachedVersion: "1",
|
||||
cachedCert: &beforeTLSCert,
|
||||
currentConn: &closeWrapper{id: 0},
|
||||
otherConns: map[int]*closeWrapper{},
|
||||
|
||||
expectedCert: &beforeTLSCert,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "secret found, but is not up to date",
|
||||
secret: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: "2",
|
||||
Name: "testSecret",
|
||||
Namespace: "test",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
v1.TLSCertKey: afterCert,
|
||||
v1.TLSPrivateKeyKey: afterKey,
|
||||
},
|
||||
},
|
||||
cachedVersion: "1",
|
||||
cachedCert: &beforeTLSCert,
|
||||
currentConn: &closeWrapper{id: 0},
|
||||
otherConns: map[int]*closeWrapper{},
|
||||
|
||||
expectedCert: &afterTLSCert,
|
||||
wantError: false,
|
||||
},
|
||||
{
|
||||
name: "secret found, is not up to date, and we have conns using current cert",
|
||||
secret: &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
ResourceVersion: "2",
|
||||
Name: "testSecret",
|
||||
Namespace: "test",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
v1.TLSCertKey: afterCert,
|
||||
v1.TLSPrivateKeyKey: afterKey,
|
||||
},
|
||||
},
|
||||
cachedVersion: "1",
|
||||
cachedCert: &beforeTLSCert,
|
||||
currentConn: &closeWrapper{id: 0},
|
||||
otherConns: map[int]*closeWrapper{
|
||||
1: {
|
||||
id: 1,
|
||||
ready: false,
|
||||
Conn: &fakeConn{},
|
||||
},
|
||||
2: {
|
||||
id: 2,
|
||||
ready: true,
|
||||
Conn: &fakeConn{},
|
||||
},
|
||||
},
|
||||
|
||||
closedConns: []int{2},
|
||||
expectedCert: &afterTLSCert,
|
||||
wantError: false,
|
||||
},
|
||||
}
|
||||
for i := range tests {
|
||||
test := tests[i]
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
testConns := test.otherConns
|
||||
if testConns != nil {
|
||||
testConns[test.currentConn.id] = test.currentConn
|
||||
// make sure our conn is listed as one of the current connections
|
||||
}
|
||||
l := listener{
|
||||
cert: test.cachedCert,
|
||||
version: test.cachedVersion,
|
||||
storage: &MockTLSStorage{
|
||||
Secret: test.secret,
|
||||
SecretErr: test.secretErr,
|
||||
},
|
||||
conns: testConns,
|
||||
}
|
||||
for _, conn := range testConns {
|
||||
conn.l = &l
|
||||
}
|
||||
newCert, err := l.getCertificate(&tls.ClientHelloInfo{Conn: test.currentConn})
|
||||
if test.wantError {
|
||||
assert.Errorf(t, err, "expected an error but none was provdied")
|
||||
} else {
|
||||
assert.NoError(t, err, "did not expect an error but got one")
|
||||
}
|
||||
assert.Equal(t, test.expectedCert, newCert, "expected cert did not match actual cert")
|
||||
if test.expectedCert != nil && test.wantError == false && test.currentConn != nil && test.otherConns != nil {
|
||||
assert.True(t, test.currentConn.ready, "expected connection to be ready but it was not")
|
||||
} else {
|
||||
if test.currentConn != nil {
|
||||
assert.False(t, test.currentConn.ready, "did not expect connection to be ready")
|
||||
}
|
||||
}
|
||||
for _, closedConn := range test.closedConns {
|
||||
_, ok := l.conns[closedConn]
|
||||
assert.False(t, ok, "closed conns should not be found")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newCertificate() ([]byte, []byte, error) {
|
||||
cert, key, err := factory.GenCA()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return factory.MarshalChain(key, cert)
|
||||
}
|
||||
|
||||
type MockTLSStorage struct {
|
||||
Secret *v1.Secret
|
||||
SecretErr error
|
||||
}
|
||||
|
||||
func (m *MockTLSStorage) Get() (*v1.Secret, error) {
|
||||
return m.Secret, m.SecretErr
|
||||
}
|
||||
|
||||
func (m *MockTLSStorage) Update(secret *v1.Secret) error {
|
||||
panic("Not implemented")
|
||||
}
|
||||
|
||||
// adapted from k8s.io/apimachinery@v0.18.8/pkg/util.proxy/ugradeaware_test.go
|
||||
type fakeConn struct{}
|
||||
|
||||
func (f *fakeConn) Read([]byte) (int, error) { return 0, nil }
|
||||
func (f *fakeConn) Write([]byte) (int, error) { return 0, nil }
|
||||
func (f *fakeConn) Close() error { return nil }
|
||||
func (fakeConn) LocalAddr() net.Addr { return nil }
|
||||
func (fakeConn) RemoteAddr() net.Addr { return nil }
|
||||
func (fakeConn) SetDeadline(t time.Time) error { return nil }
|
||||
func (fakeConn) SetReadDeadline(t time.Time) error { return nil }
|
||||
func (fakeConn) SetWriteDeadline(t time.Time) error { return nil }
|
Loading…
Reference in New Issue
Block a user