Repository: envoyproxy/gateway

Issue:
Add a brief documentation on running fuzz tests locally using oss-fuzz infra.


Discussion:

Solution patch:
diff --git a/internal/cmd/server.go b/internal/cmd/server.go
index f2b395b65..80808a420 100644
--- a/internal/cmd/server.go
+++ b/internal/cmd/server.go
@@ -28,6 +28,11 @@ import (
 	xdstranslatorrunner "github.com/envoyproxy/gateway/internal/xds/translator/runner"
 )
 
+type Runner interface {
+	Start(context.Context) error
+	Name() string
+}
+
 // cfgPath is the path to the EnvoyGateway configuration file.
 var cfgPath string
 
@@ -127,6 +132,18 @@ func getConfigByPath(logOut io.Writer, cfgPath string) (*config.Server, error) {
 // setupRunners starts all the runners required for the Envoy Gateway to
 // fulfill its tasks.
 func setupRunners(ctx context.Context, cfg *config.Server) (err error) {
+	channels := struct {
+		pResources *message.ProviderResources
+		xdsIR      *message.XdsIR
+		infraIR    *message.InfraIR
+		xds        *message.Xds
+	}{
+		pResources: new(message.ProviderResources),
+		xdsIR:      new(message.XdsIR),
+		infraIR:    new(message.InfraIR),
+		xds:        new(message.Xds),
+	}
+
 	// The Elected channel is used to block the tasks that are waiting for the leader to be elected.
 	// It will be closed once the leader is elected in the controller manager.
 	cfg.Elected = make(chan struct{})
@@ -134,99 +151,101 @@ func setupRunners(ctx context.Context, cfg *config.Server) (err error) {
 	// Setup the Extension Manager
 	var extMgr types.Manager
 	if cfg.EnvoyGateway.Provider.Type == egv1a1.ProviderTypeKubernetes {
-		extMgr, err = extensionregistry.NewManager(cfg)
-		if err != nil {
+		if extMgr, err = extensionregistry.NewManager(cfg); err != nil {
 			return err
 		}
 	}
 
-	pResources := new(message.ProviderResources)
-	// Start the Provider Service
-	// It fetches the resources from the configured provider type
-	// and publishes it.
-	// It also subscribes to status resources and once it receives
-	// a status resource back, it writes it out.
-	providerRunner := providerrunner.New(&providerrunner.Config{
-		Server:            *cfg,
-		ProviderResources: pResources,
-	})
-	if err = providerRunner.Start(ctx); err != nil {
-		return err
-	}
-
-	xdsIR := new(message.XdsIR)
-	infraIR := new(message.InfraIR)
-	// Start the GatewayAPI Translator Runner
-	// It subscribes to the provider resources, translates it to xDS IR
-	// and infra IR resources and publishes them.
-	gwRunner := gatewayapirunner.New(&gatewayapirunner.Config{
-		Server:            *cfg,
-		ProviderResources: pResources,
-		XdsIR:             xdsIR,
-		InfraIR:           infraIR,
-		ExtensionManager:  extMgr,
-	})
-	if err = gwRunner.Start(ctx); err != nil {
-		return err
-	}
-
-	xds := new(message.Xds)
-	// Start the Xds Translator Service
-	// It subscribes to the xdsIR, translates it into xds Resources and publishes it.
-	// It also computes the EnvoyPatchPolicy statuses and publishes it.
-	xdsTranslatorRunner := xdstranslatorrunner.New(&xdstranslatorrunner.Config{
-		Server:            *cfg,
-		XdsIR:             xdsIR,
-		Xds:               xds,
-		ExtensionManager:  extMgr,
-		ProviderResources: pResources,
-	})
-	if err = xdsTranslatorRunner.Start(ctx); err != nil {
-		return err
-	}
-
-	// Start the Infra Manager Runner
-	// It subscribes to the infraIR, translates it into Envoy Proxy infrastructure
-	// resources such as K8s deployment and services.
-	infraRunner := infrarunner.New(&infrarunner.Config{
-		Server:  *cfg,
-		InfraIR: infraIR,
-	})
-	if err = infraRunner.Start(ctx); err != nil {
-		return err
+	runners := []struct {
+		runner Runner
+	}{
+		{
+			// Start the Provider Service
+			// It fetches the resources from the configured provider type
+			// and publishes it.
+			// It also subscribes to status resources and once it receives
+			// a status resource back, it writes it out.
+			runner: providerrunner.New(&providerrunner.Config{
+				Server:            *cfg,
+				ProviderResources: channels.pResources,
+			}),
+		},
+		{
+			// Start the GatewayAPI Translator Runner
+			// It subscribes to the provider resources, translates it to xDS IR
+			// and infra IR resources and publishes them.
+			runner: gatewayapirunner.New(&gatewayapirunner.Config{
+				Server:            *cfg,
+				ProviderResources: channels.pResources,
+				XdsIR:             channels.xdsIR,
+				InfraIR:           channels.infraIR,
+				ExtensionManager:  extMgr,
+			}),
+		},
+		{
+			// Start the Xds Translator Service
+			// It subscribes to the xdsIR, translates it into xds Resources and publishes it.
+			// It also computes the EnvoyPatchPolicy statuses and publishes it.
+			runner: xdstranslatorrunner.New(&xdstranslatorrunner.Config{
+				Server:            *cfg,
+				XdsIR:             channels.xdsIR,
+				Xds:               channels.xds,
+				ExtensionManager:  extMgr,
+				ProviderResources: channels.pResources,
+			}),
+		},
+		{
+			// Start the Infra Manager Runner
+			// It subscribes to the infraIR, translates it into Envoy Proxy infrastructure
+			// resources such as K8s deployment and services.
+			runner: infrarunner.New(&infrarunner.Config{
+				Server:  *cfg,
+				InfraIR: channels.infraIR,
+			}),
+		},
+		{
+			// Start the xDS Server
+			// It subscribes to the xds Resources and configures the remote Envoy Proxy
+			// via the xDS Protocol.
+			runner: xdsserverrunner.New(&xdsserverrunner.Config{
+				Server: *cfg,
+				Xds:    channels.xds,
+			}),
+		},
 	}
 
-	// Start the xDS Server
-	// It subscribes to the xds Resources and configures the remote Envoy Proxy
-	// via the xDS Protocol.
-	xdsServerRunner := xdsserverrunner.New(&xdsserverrunner.Config{
-		Server: *cfg,
-		Xds:    xds,
-	})
-	if err = xdsServerRunner.Start(ctx); err != nil {
-		return err
+	// Start all runners
+	for _, r := range runners {
+		if err = startRunner(ctx, cfg, r.runner); err != nil {
+			return err
+		}
 	}
-
 	// Start the global rateLimit if it has been enabled through the config
 	if cfg.EnvoyGateway.RateLimit != nil {
 		// Start the Global RateLimit xDS Server
 		// It subscribes to the xds Resources and translates it to Envoy Ratelimit configuration.
 		rateLimitRunner := ratelimitrunner.New(&ratelimitrunner.Config{
 			Server: *cfg,
-			XdsIR:  xdsIR,
+			XdsIR:  channels.xdsIR,
 		})
-		if err = rateLimitRunner.Start(ctx); err != nil {
+		if err = startRunner(ctx, cfg, rateLimitRunner); err != nil {
 			return err
 		}
 	}
 
 	// Wait until done
 	<-ctx.Done()
+
 	// Close messages
-	pResources.Close()
-	xdsIR.Close()
-	infraIR.Close()
-	xds.Close()
+	closeChannels := []interface{ Close() }{
+		channels.pResources,
+		channels.xdsIR,
+		channels.infraIR,
+		channels.xds,
+	}
+	for _, ch := range closeChannels {
+		ch.Close()
+	}
 
 	cfg.Logger.Info("runners are shutting down")
 
@@ -239,3 +258,12 @@ func setupRunners(ctx context.Context, cfg *config.Server) (err error) {
 
 	return nil
 }
+
+func startRunner(ctx context.Context, cfg *config.Server, runner Runner) error {
+	cfg.Logger.Info("Starting runner", "name", runner.Name())
+	if err := runner.Start(ctx); err != nil {
+		cfg.Logger.Error(err, "Failed to start runner", "name", runner.Name())
+		return err
+	}
+	return nil
+}



Test patch:
diff --git a/test/fuzz/README.md b/test/fuzz/README.md
new file mode 100644
index 000000000..ef6addb47
--- /dev/null
+++ b/test/fuzz/README.md
@@ -0,0 +1,35 @@
+# Envoy Gateway Fuzzing
+
+Envoy Gateway fuzzers are run continuously on [OSS-Fuzz](https://google.github.io/oss-fuzz/). Design documents is
+available [here](https://gateway.envoyproxy.io/contributions/design/fuzzing/).
+
+## Local testing
+
+### Run the fuzzers locally
+
+Run following command from the root of the repository.
+
+```bash
+make go.test.fuzz FUZZ_TIME=10s
+```
+
+
+### Run the fuzzers locally with OSS-Fuzz infra
+
+To build the fuzzers using oss-fuzz infra, use the following commands:
+
+```bash
+git clone --depth=1 https://github.com/google/oss-fuzz.git
+
+cd oss-fuzz
+
+python3 infra/helper.py build_image gateway
+
+python3 infra/helper.py build_fuzzers gateway 
+```
+
+To run the fuzzers use `python3 infra/helper.py run_fuzzer gateway <Fuzzer Name>`. For example:
+
+```bash
+python3 infra/helper.py run_fuzzer gateway FuzzGatewayAPIToXDS
+```
\ No newline at end of file