Skip to content

Commit

Permalink
xdsclient integration tests (envoyproxy#63)
Browse files Browse the repository at this point in the history
The xdsimpl integration tests doesn't need a envoy sidecar and can be written as integration tests rather than [e2e tests](envoyproxy#62).

The integration tests help in strengthening the grpc mock behaviors in the upstream client unit tests.

The tests use g-c-p server and xdsclient interacting over real grpc.

Signed-off-by: Jyoti Mahapatra <jmahapatra@lyft.com>
  • Loading branch information
jyotimahapatra authored Apr 24, 2020
1 parent 22fd938 commit 2cbd631
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 31 deletions.
47 changes: 16 additions & 31 deletions integration/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
Expand All @@ -16,6 +15,8 @@ import (
"testing"
"time"

"github.com/envoyproxy/xds-relay/internal/pkg/log"

gcpcachev2 "github.com/envoyproxy/go-control-plane/pkg/cache/v2"
gcpserverv2 "github.com/envoyproxy/go-control-plane/pkg/server/v2"
gcpserverv3 "github.com/envoyproxy/go-control-plane/pkg/server/v3"
Expand All @@ -29,6 +30,8 @@ import (
"github.com/onsi/gomega"
)

var testLogger = log.New("fatal")

func TestMain(m *testing.M) {
// We force a 1 second sleep before running a test to let the OS close any lingering socket from previous
// tests.
Expand Down Expand Up @@ -75,7 +78,7 @@ func TestSnapshotCacheSingleEnvoyAndXdsRelayServer(t *testing.T) {

for i := 0; i < nUpdates; i++ {
snapshotv2.Version = fmt.Sprintf("v%d", i)
log.Printf("Update snapshot %v\n", snapshotv2.Version)
testLogger.Info(ctx, "Update snapshot %v\n", snapshotv2.Version)

snapshotv2 := snapshotv2.Generate()
if err := snapshotv2.Consistent(); err != nil {
Expand All @@ -85,27 +88,27 @@ func TestSnapshotCacheSingleEnvoyAndXdsRelayServer(t *testing.T) {
// TODO: parametrize node-id in bootstrap files.
err := configv2.SetSnapshot("test-id", snapshotv2)
if err != nil {
t.Fatalf("Snapshot error %q for %+v\n", err, snapshotv2)
testLogger.Fatal(ctx, "Snapshot error %q for %+v\n", err, snapshotv2)
}

g.Eventually(func() (int, int) {
ok, failed := callLocalService(basePort, nListeners)
log.Printf("Request batch: ok %v, failed %v\n", ok, failed)
testLogger.Info(ctx, "Request batch: ok %v, failed %v\n", ok, failed)
return ok, failed
}, 1*time.Second, 100*time.Millisecond).Should(gomega.Equal(nListeners))
}

// TODO(https://github.com/envoyproxy/xds-relay/issues/66): figure out a way to only only copy
// envoy logs in case of failures.
log.Printf("Envoy logs: \n%s", envoyLogsBuffer.String())
testLogger.Info(ctx, "Envoy logs: \n%s", envoyLogsBuffer.String())
}

func startSnapshotCache(ctx context.Context, upstreamPort uint, basePort uint, nClusters int, nListeners int, port uint) (gcpcachev2.SnapshotCache, gcpresourcev2.TestSnapshot, chan struct{}) {
// Create a cache
signal := make(chan struct{})
cbv2 := &gcptestv2.Callbacks{Signal: signal}

configv2 := gcpcachev2.NewSnapshotCache(false, gcpcachev2.IDHash{}, logger{})
configv2 := gcpcachev2.NewSnapshotCache(false, gcpcachev2.IDHash{}, gcpLogger{logger: testLogger})
srv2 := gcpserverv2.NewServer(ctx, configv2, cbv2)
// We don't have support for v3 yet, but this is left here in preparation for the eventual
// inclusion of v3 resources.
Expand All @@ -130,22 +133,22 @@ func startXdsRelayServer(ctx context.Context, cancel context.CancelFunc, bootstr
keyerConfigurationFilePath string) {
bootstrapConfigFileContent, err := ioutil.ReadFile(bootstrapConfigFilePath)
if err != nil {
log.Fatal("failed to read bootstrap config file: ", err)
testLogger.Fatal(ctx, "failed to read bootstrap config file: ", err)
}
var bootstrapConfig bootstrapv1.Bootstrap
err = yamlproto.FromYAMLToBootstrapConfiguration(string(bootstrapConfigFileContent), &bootstrapConfig)
if err != nil {
log.Fatal("failed to translate bootstrap config: ", err)
testLogger.Fatal(ctx, "failed to translate bootstrap config: ", err)
}

aggregationRulesFileContent, err := ioutil.ReadFile(keyerConfigurationFilePath)
if err != nil {
log.Fatal("failed to read aggregation rules file: ", err)
testLogger.Fatal(ctx, "failed to read aggregation rules file: ", err)
}
var aggregationRulesConfig aggregationv1.KeyerConfiguration
err = yamlproto.FromYAMLToKeyerConfiguration(string(aggregationRulesFileContent), &aggregationRulesConfig)
if err != nil {
log.Fatal("failed to translate aggregation rules: ", err)
testLogger.Fatal(ctx, "failed to translate aggregation rules: ", err)
}
go server.RunWithContext(ctx, cancel, &bootstrapConfig, &aggregationRulesConfig, "debug", "serve")
}
Expand All @@ -161,13 +164,13 @@ func startEnvoy(ctx context.Context, bootstrapFilePath string, signal chan struc
envoyCmd.SysProcAttr = &syscall.SysProcAttr{Pdeathsig: syscall.SIGKILL}
envoyCmd.Start()

log.Println("Waiting for the first request...")
testLogger.Info(ctx, "Waiting for the first request...")
select {
case <-signal:
break
case <-time.After(1 * time.Minute):
log.Printf("Envoy logs: \n%s", b.String())
log.Fatalf("Timeout waiting for the first request")
testLogger.Info(ctx, "Envoy logs: \n%s", b.String())
testLogger.Fatal(ctx, "Timeout waiting for the first request")
}

return b
Expand Down Expand Up @@ -215,21 +218,3 @@ func callLocalService(basePort uint, nListeners int) (int, int) {
}
}
}

type logger struct{}

func (logger logger) Debugf(format string, args ...interface{}) {
log.Printf(format+"\n", args...)
}

func (logger logger) Infof(format string, args ...interface{}) {
log.Printf(format+"\n", args...)
}

func (logger logger) Warnf(format string, args ...interface{}) {
log.Printf(format+"\n", args...)
}

func (logger logger) Errorf(format string, args ...interface{}) {
log.Printf(format+"\n", args...)
}
28 changes: 28 additions & 0 deletions integration/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package integration

import (
"context"

"github.com/envoyproxy/xds-relay/internal/pkg/log"
)

// nolint
type gcpLogger struct {
logger log.Logger
}

func (logger gcpLogger) Debugf(format string, args ...interface{}) {
logger.logger.Debug(context.Background(), format, args)
}

func (logger gcpLogger) Infof(format string, args ...interface{}) {
logger.logger.Info(context.Background(), format, args)
}

func (logger gcpLogger) Warnf(format string, args ...interface{}) {
logger.logger.Warn(context.Background(), format, args)
}

func (logger gcpLogger) Errorf(format string, args ...interface{}) {
logger.logger.Error(context.Background(), format, args)
}
Loading

0 comments on commit 2cbd631

Please sign in to comment.