README
¶
In Memory End-to-End tests
See the developer e2e testing guide for more information about the philosophy of these tests.
Note: All commands should be run from the root directory of the Gloo repository
Local Development
Setup
For these tests to run, we require that our gateway-proxy component be previously built as a docker image.
If you have not made local changes to the component, you can rely on a previously published image and no setup is required.
However, if you have made changes to the component, refer to the Envoyinit README for build instructions.
Run Tests
The test
make target runs ginkgo with a set of useful flags. See run-tests for more details about common techniques and common environment variables used when running tests. The following environment variables can also be configured for this target:
Name | Default | Description |
---|---|---|
ENVOY_IMAGE_TAG | "" | The tag of the gloo-envoy-wrapper-docker image built during setup |
SERVICE_LOG_LEVEL | "" | The log levels used for services. See "Controlling Log Verbosity of Services" below. |
Controlling Log Verbosity of Services
Multiple services (Gloo, Envoy, Discovery) are executed in parallel to run these tests. By default, these services log at the info
level. To change the log level of a service, set the SERVICE_LOG_LEVEL
environment variable to a comma separated list of service:level
pairs.
Options for services are:
- gateway-proxy
- gloo
- uds
- fds
Options for log levels are:
- debug
- info
- warn
- error
For example, to set the log level of the Gloo service to debug
and the Envoy service to error
, you would set:
SERVICE_LOG_LEVEL=gloo:debug,gateway-proxy:error TEST_PKG=./test/e2e/... make test
If the same service has multiple log levels specified, we will log a warning and the last one defined will be used.
Controlling Log Verbosity of Ginkgo Runner
Ginkgo has 4 verbosity settings, whose details can be found in the Ginkgo docs
To control these settings, you must pass the flags using the GINKGO_USER_FLAGS
environment variable.
For example, to set the Ginkgo runner to very verbose
mode, you would set:
GINKGO_USER_FLAGS=-vv TEST_PKG=./test/e2e/... make test
Using Recently Published Image (Most Common)
This is the most common pattern. If you did not make changes to the gateway-proxy
component, and do not specify an ENVOY_IMAGE_TAG
our tests will identify the most recently published image (for your LTS branch) and use that version.
TEST_PKG=./test/e2e/... make test
Using Previously Published Image
If you want to specify a particular version that was previously published, you can also do that by specifying the ENVOY_IMAGE_TAG
.
ENVOY_IMAGE_TAG=1.13.0 TEST_PKG=./test/e2e/... make test
Using Locally Built Image
If you have made changes to the component, you will have had to rebuild the image locally (see setup tests). After you rebuild the image, you need to supply the tag of that image when running the tests:
ENVOY_IMAGE_TAG=0.0.1-local TEST_PKG=./test/e2e/... make test
Running Tests in Parallel
It is possible to run tests in parallel locally, however it is not recommended, because debugging failures becomes more difficult. If you do want to run tests in parallel, you can do so by passing in the relevant GINKGO_USER_FLAGS
values:
GINKGO_USER_FLAGS=-procs=4 TEST_PKG=./test/e2e/... make test
Note: When using Docker to run Envoy, we have seen occasional failures: Error response from daemon: dial unix docker.raw.sock: connect: connection refused
Debugging Tests
See debugging tests for more details about common techniques for debugging tests.
Use WAIT_ON_FAIL
When Ginkgo encounters a test failure it will attempt to clean up relevant resources, which includes stopping the running instance of Envoy, preventing the developer from inspecting the state of the Envoy instance for useful clues.
To avoid this clean up, run the test(s) with WAIT_ON_FAIL=1
. When the test fails, it will halt execution, allowing you to inspect the state of the Envoy instance.
Once halted, use docker ps
to determine the admin port for the Envoy instance, and follow the recommendations for debugging Envoy, specifically the parts around interacting with the Administration interface.
Use INVALID_TEST_REQS
Certain tests require environmental conditions to be true for them to succeed. For example, there are tests that only run on Linux machines.
By setting INVALID_TEST_REQS=skip
, you can run all tests locally, and any tests which will not run in your local environment will be skipped. The default behavior is that they fail.
Notes
AWS Tests
To run AWS tests locally, see our AWS testing guide.
Documentation
¶
Index ¶
- Constants
- type TestContext
- func (c *TestContext) AfterEach()
- func (c *TestContext) BeforeEach()
- func (c *TestContext) Ctx() context.Context
- func (c *TestContext) EnvoyInstance() *envoy.Instance
- func (c *TestContext) EventuallyProxyAccepted()
- func (c *TestContext) GetHttpRequestBuilder() *testutils.HttpRequestBuilder
- func (c *TestContext) GetHttpsRequestBuilder() *testutils.HttpRequestBuilder
- func (c *TestContext) JustAfterEach()
- func (c *TestContext) JustBeforeEach()
- func (c *TestContext) PatchDefaultGateway(mutator func(*v1.Gateway) *v1.Gateway)
- func (c *TestContext) PatchDefaultUpstream(mutator func(*gloov1.Upstream) *gloov1.Upstream)
- func (c *TestContext) PatchDefaultVirtualService(mutator func(*v1.VirtualService) *v1.VirtualService)
- func (c *TestContext) ReadDefaultProxy() (*gloov1.Proxy, error)
- func (c *TestContext) ResourcesToCreate() *gloosnapshot.ApiSnapshot
- func (c *TestContext) SetRunServices(services services.What)
- func (c *TestContext) SetRunSettings(settings *gloov1.Settings)
- func (c *TestContext) SetUpstreamGenerator(generator func(ctx context.Context, addr string) *v1helpers.TestUpstream)
- func (c *TestContext) TestClients() services.TestClients
- func (c *TestContext) TestUpstream() *v1helpers.TestUpstream
- type TestContextFactory
- func (f *TestContextFactory) NewTestContext(testRequirements ...testutils.Requirement) *TestContext
- func (f *TestContextFactory) NewTestContextWithConsul(testRequirements ...testutils.Requirement) *TestContextWithConsul
- func (f *TestContextFactory) NewTestContextWithVault(testRequirements ...testutils.Requirement) *TestContextWithVault
- type TestContextWithConsul
- type TestContextWithVault
Constants ¶
const (
WriteNamespace = defaults.GlooSystem
DefaultVirtualServiceName = "vs-test"
DefaultRouteName = "route-test"
DefaultGatewayName = gatewaydefaults.GatewayProxyName
DefaultProxyName = gatewaydefaults.GatewayProxyName
// DefaultHost defines the Host header that should be used to route traffic to the
// default VirtualService that the TestContext creates
// To make our tests more explicit we define VirtualServices with an explicit set
// of domains (which match the `Host` header of a request), and DefaultHost
// is the domain we use by default
DefaultHost = "jsonplaceholder.typicode.com"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type TestContext ¶
type TestContext struct {
// contains filtered or unexported fields
}
TestContext represents the aggregate set of configuration needed to run a single e2e test It is intended to remove some boilerplate setup/teardown of tests out of the test themselves to ensure that tests are easier to read and maintain since they only contain the resource changes that we are validating
func (*TestContext) BeforeEach ¶
func (c *TestContext) BeforeEach()
func (*TestContext) Ctx ¶
func (c *TestContext) Ctx() context.Context
Ctx returns the Context maintained by the TestContext The Context is cancelled during the AfterEach portion of tests
func (*TestContext) EnvoyInstance ¶
func (c *TestContext) EnvoyInstance() *envoy.Instance
EnvoyInstance returns the wrapper for the running instance of Envoy that this test is using It contains utility methods to easily inspect the live configuration and statistics for the instance
func (*TestContext) EventuallyProxyAccepted ¶
func (c *TestContext) EventuallyProxyAccepted()
For tests that rely on changing an existing configuration.
func (*TestContext) GetHttpRequestBuilder ¶
func (c *TestContext) GetHttpRequestBuilder() *testutils.HttpRequestBuilder
GetHttpRequestBuilder returns an HttpRequestBuilder to easily build http requests used in e2e tests
func (*TestContext) GetHttpsRequestBuilder ¶
func (c *TestContext) GetHttpsRequestBuilder() *testutils.HttpRequestBuilder
GetHttpsRequestBuilder returns an HttpRequestBuilder to easily build https requests used in e2e tests
func (*TestContext) JustAfterEach ¶
func (c *TestContext) JustAfterEach()
func (*TestContext) JustBeforeEach ¶
func (c *TestContext) JustBeforeEach()
func (*TestContext) PatchDefaultGateway ¶
func (c *TestContext) PatchDefaultGateway(mutator func(*v1.Gateway) *v1.Gateway)
PatchDefaultGateway mutates the existing Gateway generated by the TestContext
func (*TestContext) PatchDefaultUpstream ¶
func (c *TestContext) PatchDefaultUpstream(mutator func(*gloov1.Upstream) *gloov1.Upstream)
PatchDefaultUpstream mutates the existing Upstream generated by the TestContext
func (*TestContext) PatchDefaultVirtualService ¶
func (c *TestContext) PatchDefaultVirtualService(mutator func(*v1.VirtualService) *v1.VirtualService)
PatchDefaultVirtualService mutates the existing VirtualService generated by the TestContext
func (*TestContext) ReadDefaultProxy ¶
func (c *TestContext) ReadDefaultProxy() (*gloov1.Proxy, error)
ReadDefaultProxy returns the Proxy object that will be generated by the resources in the TestContext
func (*TestContext) ResourcesToCreate ¶
func (c *TestContext) ResourcesToCreate() *gloosnapshot.ApiSnapshot
ResourcesToCreate returns the ApiSnapshot of resources the TestContext maintains This snapshot is what is written to storage during the JustBeforeEach portion We return a reference to the object, so that individual tests can modify the snapshot before we write it to storage
func (*TestContext) SetRunServices ¶
func (c *TestContext) SetRunServices(services services.What)
SetRunServices can be used to modify the services (gloo, fds, uds) which will run for a test This should be called after the TestContext.BeforeEach (when the default services are applied) and before the TestContext.JustBeforeEach (when the services are run)
func (*TestContext) SetRunSettings ¶
func (c *TestContext) SetRunSettings(settings *gloov1.Settings)
SetRunSettings can be used to modify the runtime Settings object for a test This should be called after the TestContext.BeforeEach (when the default settings are applied) and before the TestContext.JustBeforeEach (when the settings are consumed)
func (*TestContext) SetUpstreamGenerator ¶
func (c *TestContext) SetUpstreamGenerator(generator func(ctx context.Context, addr string) *v1helpers.TestUpstream)
SetUpstreamGenerator Use a different function to create a test upstream call before testContext.BeforeEach() Used for example with helpers.NewTestGrpcUpstream which has the side effect of also starting a grpc service
func (*TestContext) TestClients ¶
func (c *TestContext) TestClients() services.TestClients
TestClients returns the set of resource clients that can be used to perform CRUD operations on resources used by these tests Instead of using the resource clients directly, we recommend placing resources on the ResourcesToCreate object, and letting the TestContext handle the lifecycle of those objects
func (*TestContext) TestUpstream ¶
func (c *TestContext) TestUpstream() *v1helpers.TestUpstream
TestUpstream returns the TestUpstream object that the TestContext built A TestUpstream is used to run an echo server and define the Gloo Upstream object to route to it
type TestContextFactory ¶
type TestContextFactory struct {
EnvoyFactory envoy.Factory
VaultFactory *services.VaultFactory
ConsulFactory *services.ConsulFactory
}
func (*TestContextFactory) NewTestContext ¶
func (f *TestContextFactory) NewTestContext(testRequirements ...testutils.Requirement) *TestContext
func (*TestContextFactory) NewTestContextWithConsul ¶
func (f *TestContextFactory) NewTestContextWithConsul(testRequirements ...testutils.Requirement) *TestContextWithConsul
func (*TestContextFactory) NewTestContextWithVault ¶
func (f *TestContextFactory) NewTestContextWithVault(testRequirements ...testutils.Requirement) *TestContextWithVault
type TestContextWithConsul ¶
type TestContextWithConsul struct {
*TestContext
// contains filtered or unexported fields
}
TestContextWithConsul represents the aggregate set of configuration needed to run a single e2e test using Consul as a service registry to route traffic to. This is used rarely in tests, so we intentionally try to separate the consul logic from the core TestContext to avoid adding complexity
func (*TestContextWithConsul) ConsulInstance ¶
func (c *TestContextWithConsul) ConsulInstance() *services.ConsulInstance
ConsulInstance returns the wrapper for the running instance of Vault that this test is using
type TestContextWithVault ¶
type TestContextWithVault struct {
*TestContext
// contains filtered or unexported fields
}
TestContextWithVault represents the aggregate set of configuration needed to run a single e2e test using Vault as a secret store. This is used rarely in tests, so we intentionally try to separate the vault logic from the core TestContext to avoid adding complexity
func (*TestContextWithVault) RunVault ¶
func (v *TestContextWithVault) RunVault()
RunVault starts running the VaultInstance and blocks until it has successfully started
func (*TestContextWithVault) VaultInstance ¶
func (v *TestContextWithVault) VaultInstance() *services.VaultInstance
VaultInstance returns the wrapper for the running instance of Vault that this test is using