From 62b2277a56aadb6c40f0626aa746b05b5c1f8f2c Mon Sep 17 00:00:00 2001 From: Harry Felton Date: Wed, 6 Mar 2024 21:05:20 +1300 Subject: [PATCH] test: top-level helpers API for service provisioning --- tests/helpers/service_pool.go | 117 ++++++++++++++++++--------------- tests/integration/auth_test.go | 24 ++----- 2 files changed, 69 insertions(+), 72 deletions(-) diff --git a/tests/helpers/service_pool.go b/tests/helpers/service_pool.go index 5b5caa5..b484deb 100644 --- a/tests/helpers/service_pool.go +++ b/tests/helpers/service_pool.go @@ -6,57 +6,6 @@ import ( "testing" ) -// TheaServiceRequest encapsulates information required to -// spawn a Thea service inside of a docker container. -type TheaServiceRequest struct { - // databaseName defines the name of the PostgreSQL database - // which this Thea container is expected to connect to. Provisioning - // of this database will be handled automatically if needed. - databaseName string - - // ingestDirectory defines an optional directory on the - // host file system which will be mapped in to the /ingests - // path inside of the container. - ingestDirectory string - - // environmentVariables can optionally be provided to - // the request to augment the mandatory API_HOST_ADDR and DB_NAME - // values that are provided. Note that overriding these values - // inside of the environmentVariables will have no effect. - environmentVariables map[string]string -} - -func NewTheaContainerRequest() TheaServiceRequest { - return TheaServiceRequest{ - databaseName: MasterDBName, - ingestDirectory: "", - environmentVariables: make(map[string]string, 0), - } -} - -func (req TheaServiceRequest) Key() string { - return fmt.Sprintf("thea-%s-%s", req.databaseName, req.ingestDirectory) -} - -func (req TheaServiceRequest) String() string { - return fmt.Sprintf("Request{db=%s ingestDir=%s}", req.databaseName, req.ingestDirectory) -} - -func (req TheaServiceRequest) WithDatabaseName(databaseName string) TheaServiceRequest { - req.databaseName = databaseName - return req -} - -func (req TheaServiceRequest) WithIngestDirectory(ingestPath string) TheaServiceRequest { - req.ingestDirectory = ingestPath - return req -} - -func (req TheaServiceRequest) WithEnvironmentVariable(key, value string) TheaServiceRequest { - req.environmentVariables[key] = value - return req -} - type TestServicePool struct { *sync.Mutex databaseManager *databaseManager @@ -73,7 +22,18 @@ func newTestServicePool() *TestServicePool { } } -var ServicePool *TestServicePool = newTestServicePool() +var ( + servicePool *TestServicePool = newTestServicePool() + defaultServiceRequest = NewTheaContainerRequest().WithDatabaseName("integration_test") +) + +func RequireDefaultThea(t *testing.T) *TestService { + return servicePool.requireThea(t, defaultServiceRequest) +} + +func RequireThea(t *testing.T, request TheaServiceRequest) *TestService { + return servicePool.requireThea(t, request) +} // RequireThea will return a TestService back to the caller based on the request provided. // If the request matches a previously seen request (note that the environment variables inside @@ -81,7 +41,7 @@ var ServicePool *TestServicePool = newTestServicePool() // may be returned to the caller. If no existing service can satisfy the request, then a new instance // of Thea will be started inside of a Docker container, pointing to a new database (if specified), and // running on a unique port number. Cleanup of services is automatic via the testing.T Cleanup functionality. -func (pool *TestServicePool) RequireThea(t *testing.T, request TheaServiceRequest) *TestService { +func (pool *TestServicePool) requireThea(t *testing.T, request TheaServiceRequest) *TestService { pool.Lock() defer pool.Unlock() @@ -135,3 +95,54 @@ func (pool *TestServicePool) getOrCreate(t *testing.T, request TheaServiceReques pool.databaseManager.provisionDB(t, request.databaseName) return spawnThea(t, request) } + +// TheaServiceRequest encapsulates information required to +// spawn a Thea service inside of a docker container. +type TheaServiceRequest struct { + // databaseName defines the name of the PostgreSQL database + // which this Thea container is expected to connect to. Provisioning + // of this database will be handled automatically if needed. + databaseName string + + // ingestDirectory defines an optional directory on the + // host file system which will be mapped in to the /ingests + // path inside of the container. + ingestDirectory string + + // environmentVariables can optionally be provided to + // the request to augment the mandatory API_HOST_ADDR and DB_NAME + // values that are provided. Note that overriding these values + // inside of the environmentVariables will have no effect. + environmentVariables map[string]string +} + +func NewTheaContainerRequest() TheaServiceRequest { + return TheaServiceRequest{ + databaseName: MasterDBName, + ingestDirectory: "", + environmentVariables: make(map[string]string, 0), + } +} + +func (req TheaServiceRequest) Key() string { + return fmt.Sprintf("thea-%s-%s", req.databaseName, req.ingestDirectory) +} + +func (req TheaServiceRequest) String() string { + return fmt.Sprintf("Request{db=%s ingestDir=%s}", req.databaseName, req.ingestDirectory) +} + +func (req TheaServiceRequest) WithDatabaseName(databaseName string) TheaServiceRequest { + req.databaseName = databaseName + return req +} + +func (req TheaServiceRequest) WithIngestDirectory(ingestPath string) TheaServiceRequest { + req.ingestDirectory = ingestPath + return req +} + +func (req TheaServiceRequest) WithEnvironmentVariable(key, value string) TheaServiceRequest { + req.environmentVariables[key] = value + return req +} diff --git a/tests/integration/auth_test.go b/tests/integration/auth_test.go index deaf189..bfda35d 100644 --- a/tests/integration/auth_test.go +++ b/tests/integration/auth_test.go @@ -10,21 +10,7 @@ import ( "github.com/stretchr/testify/assert" ) -var ( - ctx = context.Background() - defaultContainerRequest = helpers.NewTheaContainerRequest().WithDatabaseName("integration_test") -) - -// requireSharedThea requests a Thea service from the service -// pool using the same DB name each time, meaning that the -// pool will provide the same service instance back to the -// test, only cleaning it up once all are compelted -// NOTE: It is important that any t.Parallel calls come -// AFTER a requireSharedThea call, as otherwise -// the pool may mistakenly consider a service finished with. -func requireSharedThea(t *testing.T) *helpers.TestService { - return helpers.ServicePool.RequireThea(t, defaultContainerRequest) -} +var ctx = context.Background() // This package performs HTTP REST API testing against // this controller. It requires that an instance of @@ -32,7 +18,7 @@ func requireSharedThea(t *testing.T) *helpers.TestService { // URL provided. func TestLogin_InvalidCredentials(t *testing.T) { - srv := requireSharedThea(t) + srv := helpers.RequireDefaultThea(t) t.Parallel() resp, err := srv.NewClient(t).LoginWithResponse(ctx, @@ -50,7 +36,7 @@ func TestLogin_InvalidCredentials(t *testing.T) { // Ensure that a successful login returns valid tokens // which can be used in a subsequent request to fetch the user. func TestLogin_ValidCredentials(t *testing.T) { - srv := requireSharedThea(t) + srv := helpers.RequireDefaultThea(t) t.Parallel() testUser, authedClient := srv.NewClientWithRandomUser(t) @@ -82,7 +68,7 @@ func TestLogin_ValidCredentials(t *testing.T) { // of the response clearing the cookies, they should not work for // secured endpoints. func TestLogout_BlacklistsTokens(t *testing.T) { - srv := requireSharedThea(t) + srv := helpers.RequireDefaultThea(t) t.Parallel() _, authedClient := srv.NewClientWithRandomUser(t) @@ -107,7 +93,7 @@ func TestLogout_BlacklistsTokens(t *testing.T) { // when 'LogoutAll' is called. Other users active on Thea should // not be impacted by this. func TestLogoutAll_BlacklistsAllTokens(t *testing.T) { - srv := requireSharedThea(t) + srv := helpers.RequireDefaultThea(t) t.Parallel() assertClientState := func(t *testing.T, client *gen.ClientWithResponses, expectedUser *helpers.TestUser) {