Merged in feature/s3integration (pull request #47)
Set Up S3 integration * cfginterfaceandfirsts3funcs * addlocalstack * generallypassesfullsuite * addedmultipleattemptedpings * cleanup * stabiliseplusskip
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/database/migrations"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/database"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -17,8 +19,9 @@ func TestRunMigrations(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
@@ -32,14 +35,17 @@ func TestRunMigrations(t *testing.T) {
|
||||
func TestRunMigrationsNoDB(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg.DBUser = "invalid_user"
|
||||
cfg.DBSecret = "invalid_pass"
|
||||
cfg.DBHost = "invalid_host"
|
||||
cfg.DBPort = 5432
|
||||
cfg.DBName = "invalid_name"
|
||||
cfg.DBNoSSL = true
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
cfg.SetDBConfig(&database.DBConfig{
|
||||
DBUser: "invalid_user",
|
||||
DBSecret: "invalid_pass",
|
||||
DBHost: "invalid_host",
|
||||
DBPort: 5432,
|
||||
DBName: "invalid_name",
|
||||
DBNoSSL: true,
|
||||
})
|
||||
|
||||
err := migrations.Run(ctx, cfg)
|
||||
assert.Error(t, err)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -14,15 +15,16 @@ import (
|
||||
func TestClient(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
id, err := queries.CreateClient(ctx, "example_client")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"path"
|
||||
"queryorchestration/internal/database"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -17,15 +18,16 @@ import (
|
||||
func TestCollector(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
contextId, err := queries.CreateQuery(ctx, repository.QuerytypeContextFull)
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -14,15 +15,16 @@ import (
|
||||
func TestDocument(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
clientId, err := queries.CreateClient(ctx, "example_client")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -14,15 +15,16 @@ import (
|
||||
func TestJob(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
clientId, err := queries.CreateClient(ctx, "example_client")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"path"
|
||||
"queryorchestration/internal/database"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -17,15 +18,16 @@ import (
|
||||
func TestQueries(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
contextQueryID, err := queries.CreateQuery(ctx, repository.Querytype(repository.QuerytypeContextFull))
|
||||
assert.NoError(t, err)
|
||||
@@ -164,15 +166,16 @@ func TestQueries(t *testing.T) {
|
||||
func TestQueryDependencyTree(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
contextQueryID, err := queries.CreateQuery(ctx, repository.Querytype(repository.QuerytypeContextFull))
|
||||
assert.NoError(t, err)
|
||||
@@ -234,15 +237,16 @@ func TestQueryDependencyTree(t *testing.T) {
|
||||
func TestQueriesList(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
contextQueryID, err := queries.CreateQuery(ctx, repository.Querytype(repository.QuerytypeContextFull))
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -15,15 +16,16 @@ import (
|
||||
func TestResults(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
jsonQueryID, err := queries.CreateQuery(ctx, repository.Querytype(repository.QuerytypeJsonExtractor))
|
||||
assert.NoError(t, err)
|
||||
@@ -73,15 +75,16 @@ func TestResults(t *testing.T) {
|
||||
func TestResultValues(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
jsonQueryID, err := queries.CreateQuery(ctx, repository.Querytype(repository.QuerytypeJsonExtractor))
|
||||
assert.NoError(t, err)
|
||||
@@ -170,15 +173,16 @@ func TestResultValues(t *testing.T) {
|
||||
func TestUnsyncedQueries(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
queries := cfg.DBQueries
|
||||
queries := cfg.GetDBQueries()
|
||||
|
||||
clientId, err := queries.CreateClient(ctx, "example_client")
|
||||
assert.NoError(t, err)
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/server"
|
||||
"queryorchestration/internal/test"
|
||||
queuemock "queryorchestration/mocks/queue"
|
||||
runnermock "queryorchestration/mocks/runner"
|
||||
@@ -21,17 +20,16 @@ func TestNew(t *testing.T) {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
sccfg := test.CreateBaseConfig()
|
||||
sccfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &BaseConfig{
|
||||
BaseConfig: server.BaseConfig{
|
||||
BaseConfig: *sccfg,
|
||||
},
|
||||
}
|
||||
qcleanup := test.CreateQueueClient(t, ctx, &test.CreateQueueConfig{
|
||||
Cfg: &cfg.BaseConfig.BaseConfig,
|
||||
cfg := &BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
|
||||
_, acleanup := test.CreateAWSContainer(t, ctx, &test.CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer qcleanup()
|
||||
defer acleanup()
|
||||
err := cfg.SetQueueClient(ctx)
|
||||
assert.NoError(t, err)
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
@@ -43,7 +41,7 @@ func TestNew(t *testing.T) {
|
||||
cfg.ControllerFunc = func() Controller {
|
||||
return runnermock.NewMockController(t)
|
||||
}
|
||||
cfg.QueueURL = test.CreateQueue(t, ctx, &cfg.BaseConfig.BaseConfig, "queueName")
|
||||
cfg.QueueURL = test.CreateQueue(t, ctx, cfg, "queueName")
|
||||
|
||||
srvPtr, err := New(ctx, cfg)
|
||||
assert.NotNil(t, srvPtr)
|
||||
|
||||
@@ -18,11 +18,9 @@ func TestNew(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
sccfg := test.CreateBaseConfig()
|
||||
sccfg.BasePath = path.Join(os.Getenv("PWD"), "../..")
|
||||
cfg := &server.BaseConfig{
|
||||
BaseConfig: *sccfg,
|
||||
}
|
||||
cfg := &server.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../.."))
|
||||
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
|
||||
@@ -4,8 +4,6 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/server"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
@@ -21,13 +19,9 @@ func TestNew(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
sccfg := test.CreateBaseConfig()
|
||||
sccfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &BaseConfig{
|
||||
BaseConfig: server.BaseConfig{
|
||||
BaseConfig: *sccfg,
|
||||
},
|
||||
}
|
||||
cfg := &BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
@@ -37,11 +31,9 @@ func TestNew(t *testing.T) {
|
||||
return nil, nil
|
||||
}
|
||||
cfg.RegisterHandlersFunc = registerHandlers
|
||||
errInitializingConfig := serviceconfig.InitializeConfig(cfg)
|
||||
assert.NoError(t, errInitializingConfig)
|
||||
|
||||
serverInstance, errCreatingServer := New(ctx, cfg)
|
||||
assert.NoError(t, errCreatingServer)
|
||||
serverInstance, err := New(ctx, cfg)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 8080, serverInstance.port)
|
||||
assert.Equal(t, "0.0.0.0", serverInstance.host)
|
||||
assert.Equal(t, "0.0.0.0:8080", serverInstance.address)
|
||||
|
||||
@@ -1,10 +1,43 @@
|
||||
package aws
|
||||
|
||||
type AWSConfig struct {
|
||||
AWSKeyID string `env:"AWS_ACCESS_KEY_ID,required,notEmpty"`
|
||||
AWSSecretKey string `env:"AWS_SECRET_ACCESS_KEY,required,notEmpty"`
|
||||
AWSRegion string `env:"AWS_REGION,required,notEmpty"`
|
||||
AWSSessionToken string `env:"AWS_SESSION_TOKEN"`
|
||||
AWSKeyID string `env:"AWS_ACCESS_KEY_ID,required,notEmpty"`
|
||||
AWSSecretKey string `env:"AWS_SECRET_ACCESS_KEY,required,notEmpty"`
|
||||
AWSRegion string `env:"AWS_REGION,required,notEmpty"`
|
||||
AWSDefaultRegion string `env:"AWS_DEFAULT_REGION"`
|
||||
AWSSessionToken string `env:"AWS_SESSION_TOKEN"`
|
||||
AWSEndpointUrl string `env:"AWS_ENDPOINT_URL"`
|
||||
}
|
||||
|
||||
type ConfigProvider interface{}
|
||||
type ConfigProvider interface {
|
||||
GetAWSKeyID() string
|
||||
GetAWSSecretKey() string
|
||||
GetAWSRegion() string
|
||||
GetAWSSessionToken() string
|
||||
GetAWSEndpoint() string
|
||||
SetAWSEndpoint(string)
|
||||
}
|
||||
|
||||
func (c *AWSConfig) SetAWSEndpoint(e string) {
|
||||
c.AWSEndpointUrl = e
|
||||
}
|
||||
|
||||
func (c *AWSConfig) GetAWSEndpoint() string {
|
||||
return c.AWSEndpointUrl
|
||||
}
|
||||
|
||||
func (c *AWSConfig) GetAWSKeyID() string {
|
||||
return c.AWSKeyID
|
||||
}
|
||||
|
||||
func (c *AWSConfig) GetAWSSecretKey() string {
|
||||
return c.AWSSecretKey
|
||||
}
|
||||
|
||||
func (c *AWSConfig) GetAWSSessionToken() string {
|
||||
return c.AWSSessionToken
|
||||
}
|
||||
|
||||
func (c *AWSConfig) GetAWSRegion() string {
|
||||
return c.AWSRegion
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package aws_test
|
||||
|
||||
import (
|
||||
"queryorchestration/internal/serviceconfig/aws"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetAWSKeyID(t *testing.T) {
|
||||
cfg := aws.AWSConfig{}
|
||||
|
||||
name := cfg.GetAWSKeyID()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.AWSKeyID = "name"
|
||||
name = cfg.GetAWSKeyID()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.AWSKeyID, name)
|
||||
}
|
||||
|
||||
func TestGetAWSSecretKey(t *testing.T) {
|
||||
cfg := aws.AWSConfig{}
|
||||
|
||||
name := cfg.GetAWSSecretKey()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.AWSSecretKey = "name"
|
||||
name = cfg.GetAWSSecretKey()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.AWSSecretKey, name)
|
||||
}
|
||||
|
||||
func TestGetAWSRegion(t *testing.T) {
|
||||
cfg := aws.AWSConfig{}
|
||||
|
||||
name := cfg.GetAWSRegion()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.AWSRegion = "name"
|
||||
name = cfg.GetAWSRegion()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.AWSRegion, name)
|
||||
}
|
||||
|
||||
func TestGetAWSSessionToken(t *testing.T) {
|
||||
cfg := aws.AWSConfig{}
|
||||
|
||||
name := cfg.GetAWSSessionToken()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.AWSSessionToken = "name"
|
||||
name = cfg.GetAWSSessionToken()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.AWSSessionToken, name)
|
||||
}
|
||||
|
||||
func TestGetAWSEndpoint(t *testing.T) {
|
||||
cfg := aws.AWSConfig{}
|
||||
|
||||
name := cfg.GetAWSEndpoint()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.AWSEndpointUrl = "name"
|
||||
name = cfg.GetAWSEndpoint()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.AWSEndpointUrl, name)
|
||||
}
|
||||
|
||||
func TestSetAWSEndpoint(t *testing.T) {
|
||||
cfg := aws.AWSConfig{}
|
||||
|
||||
assert.Equal(t, "", cfg.AWSEndpointUrl)
|
||||
url := "/i/am/here"
|
||||
cfg.SetAWSEndpoint(url)
|
||||
assert.Equal(t, url, cfg.AWSEndpointUrl)
|
||||
}
|
||||
@@ -48,7 +48,9 @@ type ConfigProvider interface {
|
||||
aws.ConfigProvider
|
||||
queue.ConfigProvider
|
||||
GetBasePath() string
|
||||
SetBasePath(string)
|
||||
SetDBConfig(*database.DBConfig)
|
||||
SetAWSConfig(*aws.AWSConfig)
|
||||
}
|
||||
|
||||
// Configuration Methods
|
||||
@@ -123,6 +125,14 @@ func (b *BaseConfig) GetBasePath() string {
|
||||
return b.Pwd
|
||||
}
|
||||
|
||||
func (b *BaseConfig) SetBasePath(p string) {
|
||||
b.BasePath = p
|
||||
}
|
||||
|
||||
func (b *BaseConfig) SetDBConfig(cfg *database.DBConfig) {
|
||||
b.DBConfig = *cfg
|
||||
}
|
||||
|
||||
func (b *BaseConfig) SetAWSConfig(cfg *aws.AWSConfig) {
|
||||
b.AWSConfig = *cfg
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package serviceconfig
|
||||
|
||||
import (
|
||||
"os"
|
||||
"queryorchestration/internal/serviceconfig/aws"
|
||||
"queryorchestration/internal/serviceconfig/database"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -146,10 +147,16 @@ func TestGetBasePath(t *testing.T) {
|
||||
Pwd: "pwd_path",
|
||||
}
|
||||
assert.Equal(t, "pwd_path", cfg.GetBasePath())
|
||||
cfg.BasePath = "base_path"
|
||||
cfg.SetBasePath("base_path")
|
||||
assert.Equal(t, "base_path", cfg.GetBasePath())
|
||||
}
|
||||
|
||||
func TestSetBasePath(t *testing.T) {
|
||||
cfg := &BaseConfig{}
|
||||
cfg.SetBasePath("/i/am/here")
|
||||
assert.Equal(t, "/i/am/here", cfg.BasePath)
|
||||
}
|
||||
|
||||
func TestSetDBConfig(t *testing.T) {
|
||||
cfg := &BaseConfig{}
|
||||
dbcfg := database.DBConfig{
|
||||
@@ -158,3 +165,12 @@ func TestSetDBConfig(t *testing.T) {
|
||||
cfg.SetDBConfig(&dbcfg)
|
||||
assert.Equal(t, dbcfg, cfg.DBConfig)
|
||||
}
|
||||
|
||||
func TestSetAWSConfig(t *testing.T) {
|
||||
cfg := &BaseConfig{}
|
||||
acfg := aws.AWSConfig{
|
||||
AWSRegion: "user",
|
||||
}
|
||||
cfg.SetAWSConfig(&acfg)
|
||||
assert.Equal(t, acfg, cfg.AWSConfig)
|
||||
}
|
||||
|
||||
@@ -26,12 +26,18 @@ type ConfigProvider interface {
|
||||
GetDBURI() string
|
||||
GetDBOpts() map[string]string
|
||||
GetDBOptsString() string
|
||||
GetDBHost() string
|
||||
GetDBPort() int
|
||||
GetDBUser() string
|
||||
GetDBSecret() string
|
||||
IsDBNoSSL() bool
|
||||
GetDBName() string
|
||||
GetDBDriver() string
|
||||
SetDBPoolConfig() error
|
||||
SetDBPool(ctx context.Context) error
|
||||
GetDBQueries() *repository.Queries
|
||||
GetDBPool() Pool
|
||||
DBPing(context.Context) error
|
||||
ExecuteDBTransaction(context.Context, func(context.Context, *repository.Queries) error) error
|
||||
}
|
||||
|
||||
@@ -69,10 +75,30 @@ func (b *DBConfig) GetDBBaseURI() string {
|
||||
return fmt.Sprintf("%s://%s:%s@%s:%d/", b.GetDBDriver(), b.DBUser, b.DBSecret, b.DBHost, b.DBPort)
|
||||
}
|
||||
|
||||
func (b *DBConfig) GetDBName() string {
|
||||
return b.DBName
|
||||
}
|
||||
|
||||
func (b *DBConfig) GetDBURI() string {
|
||||
return fmt.Sprintf("%s%s?%s", b.GetDBBaseURI(), b.DBName, b.GetDBOptsString())
|
||||
}
|
||||
|
||||
func (b *DBConfig) GetDBHost() string {
|
||||
return b.DBHost
|
||||
}
|
||||
|
||||
func (b *DBConfig) GetDBPort() int {
|
||||
return b.DBPort
|
||||
}
|
||||
|
||||
func (b *DBConfig) GetDBUser() string {
|
||||
return b.DBUser
|
||||
}
|
||||
|
||||
func (b *DBConfig) GetDBSecret() string {
|
||||
return b.DBSecret
|
||||
}
|
||||
|
||||
func (b *DBConfig) IsDBNoSSL() bool {
|
||||
return b.DBNoSSL
|
||||
}
|
||||
|
||||
func (b *DBConfig) GetDBName() string {
|
||||
return b.DBName
|
||||
}
|
||||
|
||||
@@ -66,6 +66,66 @@ func TestGetDBURI(t *testing.T) {
|
||||
assert.Equal(t, "postgres://user:pass@host:123/name?sslmode=disable", uri)
|
||||
}
|
||||
|
||||
func TestGetDBHost(t *testing.T) {
|
||||
cfg := database.DBConfig{}
|
||||
|
||||
name := cfg.GetDBHost()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.DBHost = "name"
|
||||
name = cfg.GetDBHost()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.DBHost, name)
|
||||
}
|
||||
|
||||
func TestGetDBPort(t *testing.T) {
|
||||
cfg := database.DBConfig{}
|
||||
|
||||
name := cfg.GetDBPort()
|
||||
assert.Equal(t, 0, name)
|
||||
|
||||
cfg.DBPort = 8080
|
||||
name = cfg.GetDBPort()
|
||||
assert.Equal(t, 8080, name)
|
||||
assert.Equal(t, cfg.DBPort, name)
|
||||
}
|
||||
|
||||
func TestGetDBUser(t *testing.T) {
|
||||
cfg := database.DBConfig{}
|
||||
|
||||
name := cfg.GetDBUser()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.DBUser = "name"
|
||||
name = cfg.GetDBUser()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.DBUser, name)
|
||||
}
|
||||
|
||||
func TestGetDBSecret(t *testing.T) {
|
||||
cfg := database.DBConfig{}
|
||||
|
||||
name := cfg.GetDBSecret()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.DBSecret = "name"
|
||||
name = cfg.GetDBSecret()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.DBSecret, name)
|
||||
}
|
||||
|
||||
func TestIsDBNoSSL(t *testing.T) {
|
||||
cfg := database.DBConfig{}
|
||||
|
||||
name := cfg.IsDBNoSSL()
|
||||
assert.False(t, name)
|
||||
|
||||
cfg.DBNoSSL = true
|
||||
name = cfg.IsDBNoSSL()
|
||||
assert.True(t, name)
|
||||
assert.Equal(t, cfg.DBNoSSL, name)
|
||||
}
|
||||
|
||||
func TestGetDBName(t *testing.T) {
|
||||
cfg := database.DBConfig{}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
@@ -61,13 +62,35 @@ func (b *DBConfig) SetDBPool(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = pool.Ping(ctx)
|
||||
if err != nil {
|
||||
return errors.New("unable to ping database")
|
||||
}
|
||||
|
||||
b.DBPool = pool
|
||||
b.DBQueries = repository.New(b.DBPool)
|
||||
|
||||
err = b.DBPing(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *DBConfig) DBPing(ctx context.Context) error {
|
||||
timeout := time.After(30 * time.Second)
|
||||
tick := time.NewTicker(2 * time.Second)
|
||||
defer tick.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
return fmt.Errorf("unable to ping database")
|
||||
case <-tick.C:
|
||||
err := b.DBPool.Ping(ctx)
|
||||
if err == nil {
|
||||
slog.Info("Successful database ping")
|
||||
return nil
|
||||
}
|
||||
slog.Info("Attempted database ping")
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/database/repository"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/database"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
@@ -19,8 +20,9 @@ func TestSetDBPool(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../../.."))
|
||||
_, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
RunMigrations: true,
|
||||
@@ -29,7 +31,7 @@ func TestSetDBPool(t *testing.T) {
|
||||
|
||||
err := cfg.SetDBPool(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, cfg.DBPool)
|
||||
assert.NotNil(t, cfg.GetDBPool())
|
||||
}
|
||||
|
||||
func TestGetDBPoolConfig(t *testing.T) {
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package objectstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
)
|
||||
|
||||
// S3Client defines the interface for interacting with S3
|
||||
type S3Client interface {
|
||||
// Bucket Operations
|
||||
CreateBucket(ctx context.Context, params *s3.CreateBucketInput, opts ...func(*s3.Options)) (*s3.CreateBucketOutput, error)
|
||||
DeleteBucket(ctx context.Context, params *s3.DeleteBucketInput, opts ...func(*s3.Options)) (*s3.DeleteBucketOutput, error)
|
||||
HeadBucket(ctx context.Context, params *s3.HeadBucketInput, opts ...func(*s3.Options)) (*s3.HeadBucketOutput, error)
|
||||
ListBuckets(ctx context.Context, params *s3.ListBucketsInput, opts ...func(*s3.Options)) (*s3.ListBucketsOutput, error)
|
||||
|
||||
// Object Operations
|
||||
PutObject(ctx context.Context, params *s3.PutObjectInput, opts ...func(*s3.Options)) (*s3.PutObjectOutput, error)
|
||||
GetObject(ctx context.Context, params *s3.GetObjectInput, opts ...func(*s3.Options)) (*s3.GetObjectOutput, error)
|
||||
DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, opts ...func(*s3.Options)) (*s3.DeleteObjectOutput, error)
|
||||
DeleteObjects(ctx context.Context, params *s3.DeleteObjectsInput, opts ...func(*s3.Options)) (*s3.DeleteObjectsOutput, error)
|
||||
CopyObject(ctx context.Context, params *s3.CopyObjectInput, opts ...func(*s3.Options)) (*s3.CopyObjectOutput, error)
|
||||
HeadObject(ctx context.Context, params *s3.HeadObjectInput, opts ...func(*s3.Options)) (*s3.HeadObjectOutput, error)
|
||||
ListObjects(ctx context.Context, params *s3.ListObjectsInput, opts ...func(*s3.Options)) (*s3.ListObjectsOutput, error)
|
||||
ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, opts ...func(*s3.Options)) (*s3.ListObjectsV2Output, error)
|
||||
|
||||
// Multipart Upload Operations
|
||||
CreateMultipartUpload(ctx context.Context, params *s3.CreateMultipartUploadInput, opts ...func(*s3.Options)) (*s3.CreateMultipartUploadOutput, error)
|
||||
UploadPart(ctx context.Context, params *s3.UploadPartInput, opts ...func(*s3.Options)) (*s3.UploadPartOutput, error)
|
||||
CompleteMultipartUpload(ctx context.Context, params *s3.CompleteMultipartUploadInput, opts ...func(*s3.Options)) (*s3.CompleteMultipartUploadOutput, error)
|
||||
AbortMultipartUpload(ctx context.Context, params *s3.AbortMultipartUploadInput, opts ...func(*s3.Options)) (*s3.AbortMultipartUploadOutput, error)
|
||||
ListMultipartUploads(ctx context.Context, params *s3.ListMultipartUploadsInput, opts ...func(*s3.Options)) (*s3.ListMultipartUploadsOutput, error)
|
||||
ListParts(ctx context.Context, params *s3.ListPartsInput, opts ...func(*s3.Options)) (*s3.ListPartsOutput, error)
|
||||
|
||||
// Tagging Operations
|
||||
GetObjectTagging(ctx context.Context, params *s3.GetObjectTaggingInput, opts ...func(*s3.Options)) (*s3.GetObjectTaggingOutput, error)
|
||||
PutObjectTagging(ctx context.Context, params *s3.PutObjectTaggingInput, opts ...func(*s3.Options)) (*s3.PutObjectTaggingOutput, error)
|
||||
DeleteObjectTagging(ctx context.Context, params *s3.DeleteObjectTaggingInput, opts ...func(*s3.Options)) (*s3.DeleteObjectTaggingOutput, error)
|
||||
|
||||
// ACL Operations
|
||||
GetObjectAcl(ctx context.Context, params *s3.GetObjectAclInput, opts ...func(*s3.Options)) (*s3.GetObjectAclOutput, error)
|
||||
PutObjectAcl(ctx context.Context, params *s3.PutObjectAclInput, opts ...func(*s3.Options)) (*s3.PutObjectAclOutput, error)
|
||||
GetBucketAcl(ctx context.Context, params *s3.GetBucketAclInput, opts ...func(*s3.Options)) (*s3.GetBucketAclOutput, error)
|
||||
PutBucketAcl(ctx context.Context, params *s3.PutBucketAclInput, opts ...func(*s3.Options)) (*s3.PutBucketAclOutput, error)
|
||||
|
||||
// Lifecycle Operations
|
||||
GetBucketLifecycleConfiguration(ctx context.Context, params *s3.GetBucketLifecycleConfigurationInput, opts ...func(*s3.Options)) (*s3.GetBucketLifecycleConfigurationOutput, error)
|
||||
PutBucketLifecycleConfiguration(ctx context.Context, params *s3.PutBucketLifecycleConfigurationInput, opts ...func(*s3.Options)) (*s3.PutBucketLifecycleConfigurationOutput, error)
|
||||
DeleteBucketLifecycle(ctx context.Context, params *s3.DeleteBucketLifecycleInput, opts ...func(*s3.Options)) (*s3.DeleteBucketLifecycleOutput, error)
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package objectstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
awsc "queryorchestration/internal/serviceconfig/aws"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
)
|
||||
|
||||
type ObjectStoreConfig struct {
|
||||
BucketName string `env:"BUCKET_NAME,required,notEmpty"`
|
||||
AWSEndpointUrlS3 string `env:"AWS_ENDPOINT_URL_S3"`
|
||||
AWSS3UsePathStyle bool `env:"AWS_S3_USE_PATH_STYLE" envDefault:"false"`
|
||||
StoreClient S3Client
|
||||
}
|
||||
|
||||
type ConfigProvider interface {
|
||||
awsc.ConfigProvider
|
||||
SetStoreClient(context.Context) error
|
||||
SetStoreClientAndPingByName(context.Context, string) error
|
||||
GetStoreClient() S3Client
|
||||
PingStoreByName(context.Context, string) error
|
||||
SetS3Endpoint(string)
|
||||
GetS3Endpoint() string
|
||||
SetS3UsePathStyle(bool)
|
||||
}
|
||||
|
||||
func (c *ObjectStoreConfig) SetStoreClientAndPingByName(ctx context.Context, name string) error {
|
||||
err := c.SetStoreClient(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.PingStoreByName(ctx, name)
|
||||
}
|
||||
|
||||
func (c *ObjectStoreConfig) SetStoreClient(ctx context.Context) error {
|
||||
cfg, err := config.LoadDefaultConfig(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load SDK config: %v", err)
|
||||
}
|
||||
|
||||
c.StoreClient = s3.NewFromConfig(cfg, func(o *s3.Options) {
|
||||
o.UsePathStyle = c.AWSS3UsePathStyle
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ObjectStoreConfig) GetStoreClient() S3Client {
|
||||
return c.StoreClient
|
||||
}
|
||||
|
||||
func (c *ObjectStoreConfig) PingStoreByName(ctx context.Context, name string) error {
|
||||
timeout := time.After(30 * time.Second)
|
||||
tick := time.NewTicker(2 * time.Second)
|
||||
defer tick.Stop()
|
||||
|
||||
input := &s3.HeadBucketInput{
|
||||
Bucket: &name,
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
return fmt.Errorf("unable to ping bucket by name: %s", name)
|
||||
case <-tick.C:
|
||||
_, err := c.StoreClient.HeadBucket(ctx, input)
|
||||
if err == nil {
|
||||
slog.Info("Successful bucket ping", "name", name)
|
||||
return nil
|
||||
}
|
||||
slog.Info("Attempted bucket ping", "name", name)
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ObjectStoreConfig) GetS3Endpoint() string {
|
||||
return c.AWSEndpointUrlS3
|
||||
}
|
||||
|
||||
func (c *ObjectStoreConfig) SetS3Endpoint(e string) {
|
||||
c.AWSEndpointUrlS3 = e
|
||||
}
|
||||
|
||||
func (c *ObjectStoreConfig) SetS3UsePathStyle(e bool) {
|
||||
c.AWSS3UsePathStyle = e
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package objectstore_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
objectstore "queryorchestration/internal/serviceconfig/objectstore"
|
||||
objectstoremock "queryorchestration/mocks/objectstore"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func TestGetStoreClient(t *testing.T) {
|
||||
c := objectstore.ObjectStoreConfig{}
|
||||
assert.Nil(t, c.GetStoreClient())
|
||||
c.StoreClient = &s3.Client{}
|
||||
assert.Equal(t, &s3.Client{}, c.GetStoreClient())
|
||||
}
|
||||
|
||||
func TestStoreClient(t *testing.T) {
|
||||
os.Clearenv()
|
||||
ctx := context.Background()
|
||||
c := objectstore.ObjectStoreConfig{}
|
||||
err := c.SetStoreClient(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, c.StoreClient)
|
||||
}
|
||||
|
||||
func TestPingStoreByName(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mocks3 := objectstoremock.NewMockS3Client(t)
|
||||
c := objectstore.ObjectStoreConfig{
|
||||
StoreClient: mocks3,
|
||||
}
|
||||
name := "bucket-name"
|
||||
|
||||
mocks3.EXPECT().
|
||||
HeadBucket(
|
||||
mock.Anything,
|
||||
mock.MatchedBy(func(in *s3.HeadBucketInput) bool {
|
||||
return *in.Bucket == name
|
||||
}),
|
||||
mock.Anything,
|
||||
).
|
||||
Return(&s3.HeadBucketOutput{}, nil)
|
||||
|
||||
err := c.PingStoreByName(ctx, name)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
@@ -3,52 +3,79 @@ package queue
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"queryorchestration/internal/serviceconfig/aws"
|
||||
"log/slog"
|
||||
awsc "queryorchestration/internal/serviceconfig/aws"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sqs"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
||||
)
|
||||
|
||||
type QueueConfig struct {
|
||||
aws.AWSConfig
|
||||
EnableOtel bool `env:"ENABLE_OTEL" envDefault:"false"`
|
||||
AWSEndpointUrlSQS string `env:"AWS_ENDPOINT_URL_SQS"`
|
||||
QueueClient SQSClient
|
||||
}
|
||||
|
||||
type ConfigProvider interface {
|
||||
aws.ConfigProvider
|
||||
awsc.ConfigProvider
|
||||
SetQueueClient(context.Context) error
|
||||
GetQueueClient() SQSClient
|
||||
PingQueueByURL(context.Context, string) error
|
||||
SendToQueue(context.Context, *SendParams) error
|
||||
ReceiveFromQueue(context.Context, *ReceiveParams) (*sqs.ReceiveMessageOutput, error)
|
||||
DeleteFromQueue(context.Context, *DeleteParams) error
|
||||
SetSQSEndpoint(string)
|
||||
GetSQSEndpoint() string
|
||||
}
|
||||
|
||||
func (c *QueueConfig) GetQueueClient() SQSClient {
|
||||
return c.QueueClient
|
||||
}
|
||||
|
||||
func (c *QueueConfig) GetSQSEndpoint() string {
|
||||
return c.AWSEndpointUrlSQS
|
||||
}
|
||||
|
||||
func (c *QueueConfig) PingQueueByURL(ctx context.Context, url string) error {
|
||||
_, err := c.QueueClient.GetQueueAttributes(ctx, &sqs.GetQueueAttributesInput{
|
||||
QueueUrl: &url,
|
||||
timeout := time.After(30 * time.Second)
|
||||
tick := time.NewTicker(2 * time.Second)
|
||||
defer tick.Stop()
|
||||
|
||||
input := &sqs.GetQueueAttributesInput{
|
||||
QueueUrl: aws.String(url),
|
||||
AttributeNames: []types.QueueAttributeName{types.QueueAttributeNameApproximateNumberOfMessages},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load ping queue by url (%s): %v", url, err)
|
||||
}
|
||||
return err
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
return fmt.Errorf("unable to ping queue by url: %s", url)
|
||||
case <-tick.C:
|
||||
r, err := c.QueueClient.GetQueueAttributes(ctx, input)
|
||||
if err == nil {
|
||||
slog.Info("Successful queue ping", "url", url, "approx_msgs", r.Attributes[string(types.QueueAttributeNameApproximateNumberOfMessages)])
|
||||
return nil
|
||||
}
|
||||
slog.Info("Attempted queue ping", "url", url)
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *QueueConfig) SetQueueClient(ctx context.Context) error {
|
||||
qcfg, err := config.LoadDefaultConfig(ctx)
|
||||
cfg, err := config.LoadDefaultConfig(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to load SDK config: %v", err)
|
||||
}
|
||||
|
||||
c.QueueClient = sqs.NewFromConfig(qcfg)
|
||||
c.QueueClient = sqs.NewFromConfig(cfg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *QueueConfig) SetSQSEndpoint(e string) {
|
||||
c.AWSEndpointUrlSQS = e
|
||||
}
|
||||
|
||||
@@ -49,3 +49,23 @@ func TestPingQueueByURL(t *testing.T) {
|
||||
err := c.PingQueueByURL(ctx, url)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
func TestGetSQSEndpoint(t *testing.T) {
|
||||
cfg := queue.QueueConfig{}
|
||||
|
||||
name := cfg.GetSQSEndpoint()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.AWSEndpointUrlSQS = "name"
|
||||
name = cfg.GetSQSEndpoint()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.AWSEndpointUrlSQS, name)
|
||||
}
|
||||
|
||||
func TestSetSQSEndpoint(t *testing.T) {
|
||||
cfg := queue.QueueConfig{}
|
||||
|
||||
assert.Equal(t, "", cfg.AWSEndpointUrlSQS)
|
||||
url := "/i/am/here"
|
||||
cfg.SetSQSEndpoint(url)
|
||||
assert.Equal(t, url, cfg.AWSEndpointUrlSQS)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package documentclean_test
|
||||
|
||||
import (
|
||||
"queryorchestration/internal/serviceconfig/queue/documentclean"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetDocumentCleanURL(t *testing.T) {
|
||||
cfg := documentclean.DocCleanConfig{}
|
||||
|
||||
name := cfg.GetDocumentCleanURL()
|
||||
assert.Equal(t, "", name)
|
||||
|
||||
cfg.DocumentCleanURL = "name"
|
||||
name = cfg.GetDocumentCleanURL()
|
||||
assert.Equal(t, "name", name)
|
||||
assert.Equal(t, cfg.DocumentCleanURL, name)
|
||||
}
|
||||
@@ -15,8 +15,8 @@ func (c *QueueConfig) ReceiveFromQueue(ctx context.Context, params *ReceiveParam
|
||||
return c.QueueClient.ReceiveMessage(ctx, &sqs.ReceiveMessageInput{
|
||||
QueueUrl: ¶ms.QueueURL,
|
||||
MaxNumberOfMessages: 1,
|
||||
WaitTimeSeconds: 2,
|
||||
VisibilityTimeout: 2,
|
||||
WaitTimeSeconds: 20,
|
||||
VisibilityTimeout: 30,
|
||||
MessageAttributeNames: params.Attributes,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
type AWSContainerConfig struct {
|
||||
Container testcontainers.Container
|
||||
ExternalEndpoint string
|
||||
NetworkEndpoint string
|
||||
}
|
||||
|
||||
type CreateAWSConfig struct {
|
||||
Network *testcontainers.DockerNetwork
|
||||
Cfg serviceconfig.ConfigProvider
|
||||
}
|
||||
|
||||
func CreateAWSContainer(t *testing.T, ctx context.Context, cfg *CreateAWSConfig) (*AWSContainerConfig, func()) {
|
||||
alias := "localstack"
|
||||
|
||||
port, err := nat.NewPort("tcp", "4566")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create port: %v", err)
|
||||
}
|
||||
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: "localstack/localstack:4.1.0",
|
||||
Env: map[string]string{
|
||||
"AWS_ACCESS_KEY_ID": cfg.Cfg.GetAWSKeyID(),
|
||||
"AWS_SECRET_ACCESS_KEY": cfg.Cfg.GetAWSSecretKey(),
|
||||
"AWS_SESSION_TOKEN": cfg.Cfg.GetAWSSessionToken(),
|
||||
"AWS_REGION": cfg.Cfg.GetAWSRegion(),
|
||||
"SERVICES": "s3,sqs",
|
||||
"SKIP_SSL_CERT_DOWNLOAD": "1",
|
||||
"LOCALSTACK_HOST": alias,
|
||||
"SQS_ENDPOINT_STRATEGY": "path",
|
||||
"EAGER_SERVICE_LOADING": "1",
|
||||
},
|
||||
ExposedPorts: []string{port.Port()},
|
||||
WaitingFor: wait.ForAll(
|
||||
// wait.ForExposedPort(),
|
||||
wait.ForListeningPort(port),
|
||||
wait.ForLog("Ready."),
|
||||
),
|
||||
}
|
||||
|
||||
if cfg.Network != nil {
|
||||
req.Networks = []string{cfg.Network.Name}
|
||||
req.NetworkAliases = map[string][]string{
|
||||
cfg.Network.Name: {alias},
|
||||
}
|
||||
}
|
||||
|
||||
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to start container: %v", err)
|
||||
}
|
||||
|
||||
host, err := container.Host(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to extract host: %v", err)
|
||||
}
|
||||
mappedPort, err := container.MappedPort(ctx, port)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to extract port: %v", err)
|
||||
}
|
||||
|
||||
extEndpoint := fmt.Sprintf("http://%s:%s", host, mappedPort.Port())
|
||||
t.Setenv("AWS_ENDPOINT_URL", extEndpoint)
|
||||
t.Setenv("AWS_ENDPOINT_URL_SQS", extEndpoint)
|
||||
t.Setenv("AWS_ENDPOINT_URL_S3", extEndpoint)
|
||||
cfg.Cfg.SetAWSEndpoint(extEndpoint)
|
||||
|
||||
var endpoint string
|
||||
if cfg.Network != nil {
|
||||
endpoint = fmt.Sprintf("http://%s:%s", alias, port.Port())
|
||||
cfg.Cfg.SetAWSEndpoint(endpoint)
|
||||
}
|
||||
|
||||
return &AWSContainerConfig{
|
||||
Container: container,
|
||||
ExternalEndpoint: extEndpoint,
|
||||
NetworkEndpoint: endpoint,
|
||||
}, func() {
|
||||
err := container.Terminate(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreateQueueContainer(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
qcfg, cleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
assert.NotNil(t, qcfg)
|
||||
assert.NotNil(t, cleanup)
|
||||
|
||||
cleanup()
|
||||
}
|
||||
+14
-11
@@ -21,7 +21,7 @@ type Container struct {
|
||||
|
||||
type containerConfig struct {
|
||||
Name string
|
||||
Cfg *serviceconfig.BaseConfig
|
||||
Cfg serviceconfig.ConfigProvider
|
||||
Network *testcontainers.DockerNetwork
|
||||
Env map[string]string
|
||||
WaitForMsg string
|
||||
@@ -30,16 +30,19 @@ type containerConfig struct {
|
||||
|
||||
func createContainer(t *testing.T, ctx context.Context, cfg *containerConfig) (testcontainers.Container, func()) {
|
||||
env := map[string]string{
|
||||
"DB_USER": cfg.Cfg.DBUser,
|
||||
"DB_PASS": cfg.Cfg.DBSecret,
|
||||
"DB_HOST": cfg.Cfg.DBHost,
|
||||
"DB_NAME": cfg.Cfg.DBName,
|
||||
"DB_PORT": strconv.Itoa(cfg.Cfg.DBPort),
|
||||
"DB_NOSSL": "true",
|
||||
"AWS_ACCESS_KEY_ID": cfg.Cfg.AWSKeyID,
|
||||
"AWS_SECRET_ACCESS_KEY": cfg.Cfg.AWSRegion,
|
||||
"AWS_REGION": cfg.Cfg.AWSSecretKey,
|
||||
"AWS_ENDPOINT_URL_SQS": cfg.Cfg.AWSEndpointUrlSQS,
|
||||
"DB_USER": cfg.Cfg.GetDBUser(),
|
||||
"DB_PASS": cfg.Cfg.GetDBSecret(),
|
||||
"DB_HOST": cfg.Cfg.GetDBHost(),
|
||||
"DB_NAME": cfg.Cfg.GetDBName(),
|
||||
"DB_PORT": strconv.Itoa(cfg.Cfg.GetDBPort()),
|
||||
"DB_NOSSL": strconv.FormatBool(cfg.Cfg.IsDBNoSSL()),
|
||||
"AWS_ACCESS_KEY_ID": cfg.Cfg.GetAWSKeyID(),
|
||||
"AWS_SECRET_ACCESS_KEY": cfg.Cfg.GetAWSSecretKey(),
|
||||
"AWS_REGION": cfg.Cfg.GetAWSRegion(),
|
||||
"AWS_ENDPOINT_URL": cfg.Cfg.GetAWSEndpoint(),
|
||||
"AWS_ENDPOINT_URL_SQS": cfg.Cfg.GetAWSEndpoint(),
|
||||
"AWS_ENDPOINT_URL_S3": cfg.Cfg.GetAWSEndpoint(),
|
||||
"AWS_S3_USE_PATH_STYLE": strconv.FormatBool(true),
|
||||
}
|
||||
if cfg.Env != nil {
|
||||
for k, v := range cfg.Env {
|
||||
|
||||
@@ -2,6 +2,7 @@ package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -16,7 +17,8 @@ func TestCreateContainer(t *testing.T) {
|
||||
ncfg, ncleanup := CreateNetwork(t, ctx)
|
||||
defer ncleanup()
|
||||
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
_, dbcleanup := CreateDB(t, ctx, &CreateDatabaseConfig{
|
||||
Network: ncfg,
|
||||
|
||||
+15
-14
@@ -86,26 +86,27 @@ func CreateDB(t *testing.T, ctx context.Context, cfg *CreateDatabaseConfig) (tes
|
||||
t.Setenv("DB_HOST", dbcfg.DBHost)
|
||||
t.Setenv("DB_PORT", fmt.Sprint(dbcfg.DBPort))
|
||||
|
||||
if cfg.Cfg != nil {
|
||||
if cfg.RunMigrations {
|
||||
cfg.Cfg.SetDBConfig(dbcfg)
|
||||
if cfg.Cfg == nil {
|
||||
SetCfgProvider(t, cfg.Cfg)
|
||||
}
|
||||
|
||||
err := migrations.Run(ctx, cfg.Cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cfg.Cfg.SetDBConfig(dbcfg)
|
||||
|
||||
err = dbcfg.SetDBPool(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.RunMigrations {
|
||||
err := migrations.Run(ctx, cfg.Cfg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if cfg.Network != nil {
|
||||
dbcfg.DBHost = alias
|
||||
dbcfg.DBPort = port.Int()
|
||||
err = cfg.Cfg.SetDBPool(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.Network != nil {
|
||||
dbcfg.DBHost = alias
|
||||
dbcfg.DBPort = port.Int()
|
||||
cfg.Cfg.SetDBConfig(dbcfg)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -16,12 +17,13 @@ func TestCreateDB(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../.."))
|
||||
|
||||
dbcfg, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{Cfg: cfg})
|
||||
assert.NotNil(t, dbcfg)
|
||||
assert.Nil(t, cfg.DBPool)
|
||||
assert.Nil(t, cfg.GetDBPool())
|
||||
assert.NotNil(t, cleanup)
|
||||
|
||||
cleanup()
|
||||
@@ -33,8 +35,9 @@ func TestCreateDBWithMigrations(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../.."))
|
||||
|
||||
dbcfg, cleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Cfg: cfg,
|
||||
@@ -43,6 +46,6 @@ func TestCreateDBWithMigrations(t *testing.T) {
|
||||
defer cleanup()
|
||||
|
||||
assert.NotNil(t, dbcfg)
|
||||
assert.NotNil(t, cfg.DBPool)
|
||||
assert.NotNil(t, cfg.GetDBPool())
|
||||
assert.NotNil(t, cleanup)
|
||||
}
|
||||
|
||||
+52
-35
@@ -3,6 +3,8 @@ package test
|
||||
import (
|
||||
"context"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/aws"
|
||||
"queryorchestration/internal/serviceconfig/database"
|
||||
"testing"
|
||||
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
@@ -11,21 +13,18 @@ import (
|
||||
type EcosystemConfig struct {
|
||||
Services map[Service]*Container
|
||||
Runners map[Runner]*Container
|
||||
Cfg *serviceconfig.BaseConfig
|
||||
Cfg serviceconfig.ConfigProvider
|
||||
}
|
||||
|
||||
type EcosystemNetworkConfig struct {
|
||||
Runners []*RunnerNetworkConfig
|
||||
Services []*ServiceNetworkConfig
|
||||
Cfg *serviceconfig.BaseConfig
|
||||
Network *testcontainers.DockerNetwork
|
||||
Runners []*RunnerNetworkConfig
|
||||
Services []*ServiceNetworkConfig
|
||||
Cfg serviceconfig.ConfigProvider
|
||||
Network *testcontainers.DockerNetwork
|
||||
AWSContainer *AWSContainerConfig
|
||||
}
|
||||
|
||||
func CreateRunnersAndServicesNetwork(t *testing.T, ctx context.Context, ncfg *EcosystemNetworkConfig) (*EcosystemConfig, func()) {
|
||||
if ncfg.Cfg == nil {
|
||||
ncfg.Cfg = CreateBaseConfig()
|
||||
}
|
||||
|
||||
network := ncfg.Network
|
||||
var ncleanup func()
|
||||
if network == nil {
|
||||
@@ -52,13 +51,20 @@ func CreateRunnersAndServicesNetwork(t *testing.T, ctx context.Context, ncfg *Ec
|
||||
}
|
||||
|
||||
var qcleanup func()
|
||||
if ncfg.Cfg.QueueClient == nil {
|
||||
qcleanup = CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
if ncfg.AWSContainer == nil {
|
||||
_, qcleanup = CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Network: network,
|
||||
Cfg: ncfg.Cfg,
|
||||
})
|
||||
}
|
||||
|
||||
if ncfg.Cfg.GetQueueClient() == nil {
|
||||
err := ncfg.Cfg.SetQueueClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
qs := make(map[string]*Container, len(ncfg.Runners))
|
||||
qclean := make([]func(), len(ncfg.Runners))
|
||||
for i, r := range ncfg.Runners {
|
||||
@@ -96,20 +102,26 @@ func CreateRunnersAndServicesNetwork(t *testing.T, ctx context.Context, ncfg *Ec
|
||||
}
|
||||
}
|
||||
|
||||
func CreateBaseConfig() *serviceconfig.BaseConfig {
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
func SetCfgProvider(t *testing.T, cfg serviceconfig.ConfigProvider) {
|
||||
cfg.SetAWSConfig(&aws.AWSConfig{
|
||||
AWSKeyID: "test",
|
||||
AWSSecretKey: "test",
|
||||
AWSRegion: "us-east-1",
|
||||
})
|
||||
t.Setenv("AWS_ACCESS_KEY_ID", cfg.GetAWSKeyID())
|
||||
t.Setenv("AWS_SECRET_ACCESS_KEY", cfg.GetAWSSecretKey())
|
||||
t.Setenv("AWS_SESSION_TOKEN", cfg.GetAWSSessionToken())
|
||||
t.Setenv("AWS_REGION", cfg.GetAWSRegion())
|
||||
t.Setenv("AWS_DEFAULT_REGION", cfg.GetAWSRegion())
|
||||
|
||||
cfg.AWSKeyID = "test"
|
||||
cfg.AWSSecretKey = "test"
|
||||
cfg.AWSRegion = "us-east-1"
|
||||
cfg.DBUser = "invalid_user"
|
||||
cfg.DBSecret = "invalid_pass"
|
||||
cfg.DBHost = "invalid_host"
|
||||
cfg.DBPort = 5432
|
||||
cfg.DBName = "invalid_name"
|
||||
cfg.DBNoSSL = true
|
||||
|
||||
return cfg
|
||||
cfg.SetDBConfig(&database.DBConfig{
|
||||
DBUser: "invalid_user",
|
||||
DBSecret: "invalid_pass",
|
||||
DBHost: "invalid_host",
|
||||
DBPort: 5432,
|
||||
DBName: "invalid_name",
|
||||
DBNoSSL: true,
|
||||
})
|
||||
}
|
||||
|
||||
type ServiceNetworkConfig struct {
|
||||
@@ -118,7 +130,8 @@ type ServiceNetworkConfig struct {
|
||||
}
|
||||
|
||||
func CreateServiceNetwork(t *testing.T, ctx context.Context, scfg *ServiceNetworkConfig) (*Container, func()) {
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
network, ncleanup := CreateNetwork(t, ctx)
|
||||
|
||||
@@ -142,17 +155,14 @@ func CreateServiceNetwork(t *testing.T, ctx context.Context, scfg *ServiceNetwor
|
||||
}
|
||||
|
||||
type RunnerNetworkConfig struct {
|
||||
Network *testcontainers.DockerNetwork
|
||||
Cfg *serviceconfig.BaseConfig
|
||||
Name Runner
|
||||
Env map[string]string
|
||||
Network *testcontainers.DockerNetwork
|
||||
AWSContainer *AWSContainerConfig
|
||||
Cfg serviceconfig.ConfigProvider
|
||||
Name Runner
|
||||
Env map[string]string
|
||||
}
|
||||
|
||||
func CreateRunnerNetwork(t *testing.T, ctx context.Context, rcfg *RunnerNetworkConfig) (*Container, func()) {
|
||||
if rcfg.Cfg == nil {
|
||||
rcfg.Cfg = CreateBaseConfig()
|
||||
}
|
||||
|
||||
network := rcfg.Network
|
||||
var ncleanup func()
|
||||
if network == nil {
|
||||
@@ -160,13 +170,20 @@ func CreateRunnerNetwork(t *testing.T, ctx context.Context, rcfg *RunnerNetworkC
|
||||
}
|
||||
|
||||
var qcleanup func()
|
||||
if rcfg.Cfg.QueueClient == nil {
|
||||
qcleanup = CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
if rcfg.AWSContainer == nil {
|
||||
_, qcleanup = CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Network: network,
|
||||
Cfg: rcfg.Cfg,
|
||||
})
|
||||
}
|
||||
|
||||
if rcfg.Cfg.GetQueueClient() == nil {
|
||||
err := rcfg.Cfg.SetQueueClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
url := CreateQueue(t, ctx, rcfg.Cfg, rcfg.Name)
|
||||
|
||||
_, dbcleanup := CreateDB(t, ctx, &CreateDatabaseConfig{
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -15,7 +16,10 @@ func TestCreateRunnerNetwork(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
conn, cleanup := CreateRunnerNetwork(t, ctx, &RunnerNetworkConfig{
|
||||
Cfg: cfg,
|
||||
Name: QueryRunner,
|
||||
})
|
||||
|
||||
@@ -46,8 +50,9 @@ func TestCreateRunnersAndServicesNetwork(t *testing.T) {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
cfg := CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../.."))
|
||||
|
||||
conn, cleanup := CreateRunnersAndServicesNetwork(t, ctx, &EcosystemNetworkConfig{
|
||||
Cfg: cfg,
|
||||
@@ -66,7 +71,8 @@ func TestCreateRunnersAndServicesNetwork(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateBaseConfig(t *testing.T) {
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
assert.Equal(t, "test", cfg.AWSKeyID)
|
||||
assert.Equal(t, "test", cfg.AWSSecretKey)
|
||||
assert.Equal(t, "us-east-1", cfg.AWSRegion)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
objectstore "queryorchestration/internal/serviceconfig/objectstore"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
)
|
||||
|
||||
func CreateBucket(t *testing.T, ctx context.Context, cfg objectstore.ConfigProvider, name string) {
|
||||
_, err := cfg.GetStoreClient().CreateBucket(ctx, &s3.CreateBucketInput{
|
||||
Bucket: aws.String(name),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = cfg.PingStoreByName(ctx, name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func CreateStoreClient(t *testing.T, ctx context.Context, cfg objectstore.ConfigProvider, endpoint string) {
|
||||
cfg.SetS3Endpoint(endpoint)
|
||||
cfg.SetS3UsePathStyle(true)
|
||||
err := cfg.SetStoreClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
objectstore "queryorchestration/internal/serviceconfig/objectstore"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type StoreConfig struct {
|
||||
serviceconfig.BaseConfig
|
||||
objectstore.ObjectStoreConfig
|
||||
}
|
||||
|
||||
func TestCreateBucket(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := &StoreConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
acfg, cleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
CreateStoreClient(t, ctx, cfg, acfg.ExternalEndpoint)
|
||||
|
||||
CreateBucket(t, ctx, cfg, "myname")
|
||||
}
|
||||
|
||||
func TestCreateStoreClient(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := &StoreConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
acfg, cleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
CreateStoreClient(t, ctx, cfg, acfg.ExternalEndpoint)
|
||||
assert.NotNil(t, cfg.GetStoreClient())
|
||||
}
|
||||
+9
-114
@@ -2,128 +2,25 @@ package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/queue"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sqs"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
type queueContainerConfig struct {
|
||||
Container testcontainers.Container
|
||||
ExternalEndpoint string
|
||||
NetworkEndpoint string
|
||||
}
|
||||
|
||||
type CreateQueueConfig struct {
|
||||
Network *testcontainers.DockerNetwork
|
||||
Cfg *serviceconfig.BaseConfig
|
||||
}
|
||||
|
||||
func createQueueContainer(t *testing.T, ctx context.Context, cfg *CreateQueueConfig) (*queueContainerConfig, func()) {
|
||||
alias := "localstack"
|
||||
provider := credentials.NewStaticCredentialsProvider(cfg.Cfg.AWSKeyID, cfg.Cfg.AWSSecretKey, cfg.Cfg.AWSSessionToken)
|
||||
|
||||
port, err := nat.NewPort("tcp", "4566")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create port: %v", err)
|
||||
}
|
||||
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: "localstack/localstack:4.0.3",
|
||||
Env: map[string]string{
|
||||
"AWS_ACCESS_KEY_ID": provider.Value.AccessKeyID,
|
||||
"AWS_SECRET_ACCESS_KEY": provider.Value.SecretAccessKey,
|
||||
"AWS_SESSION_TOKEN": provider.Value.SessionToken,
|
||||
"AWS_REGION": cfg.Cfg.AWSRegion,
|
||||
"SERVICES": "sqs",
|
||||
"SKIP_SSL_CERT_DOWNLOAD": "1",
|
||||
"LOCALSTACK_HOST": alias,
|
||||
"SQS_ENDPOINT_STRATEGY": "path",
|
||||
},
|
||||
ExposedPorts: []string{port.Port()},
|
||||
WaitingFor: wait.ForAll(
|
||||
// wait.ForExposedPort(),
|
||||
wait.ForListeningPort(port),
|
||||
wait.ForLog("Ready."),
|
||||
),
|
||||
}
|
||||
|
||||
if cfg.Network != nil {
|
||||
req.Networks = []string{cfg.Network.Name}
|
||||
req.NetworkAliases = map[string][]string{
|
||||
cfg.Network.Name: {alias},
|
||||
}
|
||||
}
|
||||
|
||||
container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
func CreateQueue(t *testing.T, ctx context.Context, cfg serviceconfig.ConfigProvider, name string) string {
|
||||
queueM, err := cfg.GetQueueClient().CreateQueue(ctx, &sqs.CreateQueueInput{
|
||||
QueueName: aws.String(name),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to start container: %v", err)
|
||||
}
|
||||
|
||||
host, err := container.Host(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to extract host: %v", err)
|
||||
}
|
||||
mappedPort, err := container.MappedPort(ctx, port)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to extract port: %v", err)
|
||||
}
|
||||
|
||||
extEndpoint := fmt.Sprintf("http://%s:%s", host, mappedPort.Port())
|
||||
t.Setenv("AWS_ENDPOINT_URL_SQS", extEndpoint)
|
||||
cfg.Cfg.AWSEndpointUrlSQS = extEndpoint
|
||||
|
||||
var endpoint string
|
||||
if cfg.Network != nil {
|
||||
endpoint = fmt.Sprintf("http://%s:%s", alias, port.Port())
|
||||
cfg.Cfg.AWSEndpointUrlSQS = endpoint
|
||||
}
|
||||
|
||||
return &queueContainerConfig{
|
||||
Container: container,
|
||||
ExternalEndpoint: extEndpoint,
|
||||
NetworkEndpoint: endpoint,
|
||||
}, func() {
|
||||
err := container.Terminate(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func CreateQueueClient(t *testing.T, ctx context.Context, cfg *CreateQueueConfig) func() {
|
||||
qcfg, clean := createQueueContainer(t, ctx, cfg)
|
||||
|
||||
provider := credentials.NewStaticCredentialsProvider(cfg.Cfg.AWSKeyID, cfg.Cfg.AWSSecretKey, cfg.Cfg.AWSSessionToken)
|
||||
|
||||
sqsCfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(cfg.Cfg.AWSRegion), config.WithCredentialsProvider(provider), config.WithBaseEndpoint(qcfg.ExternalEndpoint))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cfg.Cfg.QueueClient = sqs.NewFromConfig(sqsCfg)
|
||||
|
||||
return clean
|
||||
}
|
||||
|
||||
func CreateQueue(t *testing.T, ctx context.Context, cfg *serviceconfig.BaseConfig, name string) string {
|
||||
queueM, err := cfg.QueueClient.CreateQueue(ctx, &sqs.CreateQueueInput{
|
||||
QueueName: aws.String(name),
|
||||
})
|
||||
err = cfg.PingQueueByURL(ctx, *queueM.QueueUrl)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -131,9 +28,7 @@ func CreateQueue(t *testing.T, ctx context.Context, cfg *serviceconfig.BaseConfi
|
||||
return *queueM.QueueUrl
|
||||
}
|
||||
|
||||
func AssertMessageWait(t *testing.T, ctx context.Context, cfg serviceconfig.ConfigProvider, params *queue.ReceiveParams) types.Message {
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
func AssertMessage(t *testing.T, ctx context.Context, cfg serviceconfig.ConfigProvider, params *queue.ReceiveParams) types.Message {
|
||||
result, err := cfg.ReceiveFromQueue(ctx, params)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result.Messages)
|
||||
@@ -143,16 +38,16 @@ func AssertMessageWait(t *testing.T, ctx context.Context, cfg serviceconfig.Conf
|
||||
return result.Messages[0]
|
||||
}
|
||||
|
||||
func AssertMessageBodyWait(t *testing.T, ctx context.Context, cfg serviceconfig.ConfigProvider, url string, body string) {
|
||||
message := AssertMessageWait(t, ctx, cfg, &queue.ReceiveParams{
|
||||
func AssertMessageBody(t *testing.T, ctx context.Context, cfg serviceconfig.ConfigProvider, url string, body string) {
|
||||
message := AssertMessage(t, ctx, cfg, &queue.ReceiveParams{
|
||||
QueueURL: url,
|
||||
})
|
||||
|
||||
assert.Equal(t, body, *message.Body)
|
||||
}
|
||||
|
||||
func AssertMessageAttrWait(t *testing.T, ctx context.Context, cfg serviceconfig.ConfigProvider, url string, name string, value string) {
|
||||
message := AssertMessageWait(t, ctx, cfg, &queue.ReceiveParams{
|
||||
func AssertMessageAttr(t *testing.T, ctx context.Context, cfg serviceconfig.ConfigProvider, url string, name string, value string) {
|
||||
message := AssertMessage(t, ctx, cfg, &queue.ReceiveParams{
|
||||
QueueURL: url,
|
||||
Attributes: []string{name},
|
||||
})
|
||||
|
||||
+28
-46
@@ -2,6 +2,7 @@ package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/serviceconfig/queue"
|
||||
"testing"
|
||||
|
||||
@@ -10,51 +11,23 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCreateQueueContainer(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
cfg := CreateBaseConfig()
|
||||
|
||||
qcfg, cleanup := createQueueContainer(t, ctx, &CreateQueueConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
assert.NotNil(t, qcfg)
|
||||
assert.NotNil(t, cleanup)
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
func TestCreateQueueClient(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
cfg := CreateBaseConfig()
|
||||
|
||||
cleanup := CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
assert.NotNil(t, cfg.QueueClient)
|
||||
assert.NotNil(t, cleanup)
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
func TestCreateQueue(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping long test in short mode")
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
cleanup := CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
_, cleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer cleanup()
|
||||
|
||||
err := cfg.SetQueueClient(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
url := CreateQueue(t, ctx, cfg, "myname")
|
||||
assert.Equal(t, "http://localstack:4566/queue/us-east-1/000000000000/myname", url)
|
||||
}
|
||||
@@ -65,21 +38,24 @@ func TestAssertMessageWait(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
cleanup := CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
_, cleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer cleanup()
|
||||
err := cfg.SetQueueClient(ctx)
|
||||
assert.NoError(t, err)
|
||||
url := CreateQueue(t, ctx, cfg, "myname")
|
||||
|
||||
err := cfg.SendToQueue(ctx, &queue.SendParams{
|
||||
err = cfg.SendToQueue(ctx, &queue.SendParams{
|
||||
QueueURL: url,
|
||||
Body: "body",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
msg := AssertMessageWait(t, ctx, cfg, &queue.ReceiveParams{
|
||||
msg := AssertMessage(t, ctx, cfg, &queue.ReceiveParams{
|
||||
QueueURL: url,
|
||||
})
|
||||
assert.NotNil(t, msg)
|
||||
@@ -91,21 +67,24 @@ func TestAssertMessageBodyWait(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
cleanup := CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
_, cleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer cleanup()
|
||||
err := cfg.SetQueueClient(ctx)
|
||||
assert.NoError(t, err)
|
||||
url := CreateQueue(t, ctx, cfg, "myname")
|
||||
|
||||
err := cfg.SendToQueue(ctx, &queue.SendParams{
|
||||
err = cfg.SendToQueue(ctx, &queue.SendParams{
|
||||
QueueURL: url,
|
||||
Body: "body",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
AssertMessageBodyWait(t, ctx, cfg, url, "\"body\"")
|
||||
AssertMessageBody(t, ctx, cfg, url, "\"body\"")
|
||||
}
|
||||
|
||||
func TestAssertMessageAttrWait(t *testing.T) {
|
||||
@@ -114,18 +93,21 @@ func TestAssertMessageAttrWait(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
cleanup := CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
_, cleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer cleanup()
|
||||
err := cfg.SetQueueClient(ctx)
|
||||
assert.NoError(t, err)
|
||||
url := CreateQueue(t, ctx, cfg, "myname")
|
||||
|
||||
name := "name"
|
||||
value := "value"
|
||||
|
||||
err := cfg.SendToQueue(ctx, &queue.SendParams{
|
||||
err = cfg.SendToQueue(ctx, &queue.SendParams{
|
||||
QueueURL: url,
|
||||
Body: "body",
|
||||
Attributes: map[string]types.MessageAttributeValue{
|
||||
@@ -137,5 +119,5 @@ func TestAssertMessageAttrWait(t *testing.T) {
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
AssertMessageAttrWait(t, ctx, cfg, url, name, value)
|
||||
AssertMessageAttr(t, ctx, cfg, url, name, value)
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ const (
|
||||
type RunnerConfig struct {
|
||||
Name Runner
|
||||
QueueURL string
|
||||
Cfg *serviceconfig.BaseConfig
|
||||
Cfg serviceconfig.ConfigProvider
|
||||
Network *testcontainers.DockerNetwork
|
||||
Env map[string]string
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -16,13 +17,16 @@ func TestCreateRunner(t *testing.T) {
|
||||
ncfg, ncleanup := CreateNetwork(t, ctx)
|
||||
defer ncleanup()
|
||||
|
||||
cfg := CreateBaseConfig()
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
SetCfgProvider(t, cfg)
|
||||
|
||||
qcleanup := CreateQueueClient(t, ctx, &CreateQueueConfig{
|
||||
_, qcleanup := CreateAWSContainer(t, ctx, &CreateAWSConfig{
|
||||
Network: ncfg,
|
||||
Cfg: cfg,
|
||||
})
|
||||
defer qcleanup()
|
||||
err := cfg.SetQueueClient(ctx)
|
||||
assert.NoError(t, err)
|
||||
url := CreateQueue(t, ctx, cfg, "myname")
|
||||
|
||||
_, dbcleanup := CreateDB(t, ctx, &CreateDatabaseConfig{
|
||||
|
||||
@@ -19,7 +19,7 @@ const (
|
||||
|
||||
type ServiceConfig struct {
|
||||
Name Service
|
||||
Cfg *serviceconfig.BaseConfig
|
||||
Cfg serviceconfig.ConfigProvider
|
||||
Network *testcontainers.DockerNetwork
|
||||
Env map[string]string
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"queryorchestration/internal/serviceconfig"
|
||||
"queryorchestration/internal/test"
|
||||
"testing"
|
||||
|
||||
@@ -19,8 +20,9 @@ func TestCreateService(t *testing.T) {
|
||||
ncfg, ncleanup := test.CreateNetwork(t, ctx)
|
||||
defer ncleanup()
|
||||
|
||||
cfg := test.CreateBaseConfig()
|
||||
cfg.BasePath = path.Join(os.Getenv("PWD"), "../..")
|
||||
cfg := &serviceconfig.BaseConfig{}
|
||||
test.SetCfgProvider(t, cfg)
|
||||
cfg.SetBasePath(path.Join(os.Getenv("PWD"), "../.."))
|
||||
_, dbcleanup := test.CreateDB(t, ctx, &test.CreateDatabaseConfig{
|
||||
Network: ncfg,
|
||||
Cfg: cfg,
|
||||
|
||||
Reference in New Issue
Block a user