Revision 9831d981fc90760e810066f2f7d67bd2dc9e6b1c authored by Daniel Borkmann on 18 November 2020, 15:46:58 UTC, committed by Daniel Borkmann on 20 November 2020, 10:28:57 UTC
Example invocation: ./daemon/cilium-agent --enable-ipv4=true --enable-ipv6=true \ --datapath-mode=lb-only --bpf-lb-algorithm=maglev \ --bpf-lb-maglev-table-size=65521 --bpf-lb-mode=dsr \ --bpf-lb-acceleration=native --bpf-lb-dsr-dispatch=ipip \ --devices=enp2s0np0 Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 03f14fe
envoy_test.go
// Copyright 2018 Authors of Cilium
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !privileged_tests
package envoy
import (
"context"
"io/ioutil"
"net"
"os"
"path/filepath"
"testing"
"time"
"github.com/cilium/cilium/pkg/checker"
"github.com/cilium/cilium/pkg/completion"
"github.com/cilium/cilium/pkg/envoy/xds"
"github.com/cilium/cilium/pkg/flowdebug"
"github.com/cilium/cilium/pkg/identity"
"github.com/cilium/cilium/pkg/logging"
"github.com/cilium/cilium/pkg/option"
"github.com/cilium/cilium/pkg/policy"
"github.com/cilium/cilium/pkg/proxy/accesslog"
. "gopkg.in/check.v1"
)
// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }
type EnvoySuite struct {
waitGroup *completion.WaitGroup
}
var _ = Suite(&EnvoySuite{})
func (s *EnvoySuite) waitForProxyCompletion() error {
start := time.Now()
log.Debug("Waiting for proxy updates to complete...")
err := s.waitGroup.Wait()
log.Debug("Wait time for proxy updates: ", time.Since(start))
return err
}
type dummyEndpointInfoRegistry struct{}
func (r *dummyEndpointInfoRegistry) FillEndpointIdentityByID(id identity.NumericIdentity, info *accesslog.EndpointInfo) bool {
return false
}
func (r *dummyEndpointInfoRegistry) FillEndpointIdentityByIP(ip net.IP, info *accesslog.EndpointInfo) bool {
return false
}
func (s *EnvoySuite) TestEnvoy(c *C) {
option.Config.Populate()
option.Config.ProxyConnectTimeout = 1
c.Assert(option.Config.ProxyConnectTimeout, Not(Equals), 0)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
s.waitGroup = completion.NewWaitGroup(ctx)
if os.Getenv("CILIUM_ENABLE_ENVOY_UNIT_TEST") == "" {
c.Skip("skipping envoy unit test; CILIUM_ENABLE_ENVOY_UNIT_TEST not set")
}
logging.ConfigureLogLevel(true) // Use 'true' for debugging
flowdebug.Enable()
stateLogDir, err := ioutil.TempDir("", "envoy_go_test")
c.Assert(err, IsNil)
log.Debugf("state log directory: %s", stateLogDir)
xdsServer := StartXDSServer(stateLogDir)
defer xdsServer.stop()
StartAccessLogServer(stateLogDir, xdsServer, &dummyEndpointInfoRegistry{})
// launch debug variant of the Envoy proxy
envoyProxy := StartEnvoy(stateLogDir, filepath.Join(stateLogDir, "cilium-envoy.log"), 0)
c.Assert(envoyProxy, NotNil)
log.Debug("started Envoy")
log.Debug("adding metrics listener")
xdsServer.AddMetricsListener(9095, s.waitGroup)
err = s.waitForProxyCompletion()
c.Assert(err, IsNil)
log.Debug("completed adding metrics listener")
s.waitGroup = completion.NewWaitGroup(ctx)
log.Debug("adding listener1")
xdsServer.AddListener("listener1", policy.ParserTypeHTTP, 8081, true, false, s.waitGroup)
log.Debug("adding listener2")
xdsServer.AddListener("listener2", policy.ParserTypeHTTP, 8082, true, false, s.waitGroup)
log.Debug("adding listener3")
xdsServer.AddListener("listener3", policy.ParserTypeHTTP, 8083, false, false, s.waitGroup)
err = s.waitForProxyCompletion()
c.Assert(err, IsNil)
log.Debug("completed adding listener1, listener2, listener3")
s.waitGroup = completion.NewWaitGroup(ctx)
// Remove listener3
log.Debug("removing listener 3")
xdsServer.RemoveListener("listener3", s.waitGroup)
err = s.waitForProxyCompletion()
c.Assert(err, IsNil)
log.Debug("completed removing listener 3")
s.waitGroup = completion.NewWaitGroup(ctx)
// Add listener3 again
log.Debug("adding listener 3")
xdsServer.AddListener("listener3", policy.L7ParserType("test.headerparser"), 8083, false, false, s.waitGroup)
err = s.waitForProxyCompletion()
c.Assert(err, IsNil)
log.Debug("completed adding listener 3")
s.waitGroup = completion.NewWaitGroup(ctx)
log.Debug("stopping Envoy")
err = envoyProxy.StopEnvoy()
c.Assert(err, IsNil)
time.Sleep(2 * time.Second) // Wait for Envoy to really terminate.
// Remove listener3 again, and wait for timeout after stopping Envoy.
log.Debug("removing listener 3")
xdsServer.RemoveListener("listener3", s.waitGroup)
err = s.waitForProxyCompletion()
c.Assert(err, NotNil)
log.Debugf("failed to remove listener 3: %s", err)
}
func (s *EnvoySuite) TestEnvoyNACK(c *C) {
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Second)
defer cancel()
s.waitGroup = completion.NewWaitGroup(ctx)
if os.Getenv("CILIUM_ENABLE_ENVOY_UNIT_TEST") == "" {
c.Skip("skipping envoy unit test; CILIUM_ENABLE_ENVOY_UNIT_TEST not set")
}
flowdebug.Enable()
stateLogDir, err := ioutil.TempDir("", "envoy_go_test")
c.Assert(err, IsNil)
log.Debugf("state log directory: %s", stateLogDir)
xdsServer := StartXDSServer(stateLogDir)
defer xdsServer.stop()
StartAccessLogServer(stateLogDir, xdsServer, &dummyEndpointInfoRegistry{})
// launch debug variant of the Envoy proxy
envoyProxy := StartEnvoy(stateLogDir, filepath.Join(stateLogDir, "cilium-envoy.log"), 42)
c.Assert(envoyProxy, NotNil)
log.Debug("started Envoy")
rName := "listener:22"
log.Debug("adding ", rName)
xdsServer.AddListener(rName, policy.ParserTypeHTTP, 22, true, false, s.waitGroup)
err = s.waitForProxyCompletion()
c.Assert(err, Not(IsNil))
c.Assert(err, checker.DeepEquals, &xds.ProxyError{Err: xds.ErrNackReceived, Detail: "Error adding/updating listener(s) listener:22: cannot bind '[::]:22': Address already in use\n"})
s.waitGroup = completion.NewWaitGroup(ctx)
// Remove listener1
log.Debug("removing ", rName)
xdsServer.RemoveListener(rName, s.waitGroup)
err = s.waitForProxyCompletion()
c.Assert(err, IsNil)
}
Computing file changes ...