Skip to content
Merged
39 changes: 27 additions & 12 deletions modules/azure/azurite/azurite.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,35 +72,50 @@ func (c *Container) serviceURL(ctx context.Context, srv service) (string, error)

// Run creates an instance of the Azurite container type
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error) {
moduleCmd := []string{}

moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithEntrypoint("azurite"),
testcontainers.WithExposedPorts(BlobPort, QueuePort, TablePort),
}

// 1. Gather all config options (defaults and then apply provided options)
settings := defaultOptions()
for _, opt := range opts {
if o, ok := opt.(Option); ok {
if err := o(&settings); err != nil {
return nil, fmt.Errorf("azurite option: %w", err)
}
}
}

entrypoint := "azurite"
if len(settings.EnabledServices) == 1 && settings.EnabledServices[0] != tableService {
// Use azurite-table in future once it matures. Graceful shutdown is currently very slow.
entrypoint = fmt.Sprintf("%s-%s", entrypoint, settings.EnabledServices[0])
}
moduleOpts := []testcontainers.ContainerCustomizer{testcontainers.WithEntrypoint(entrypoint)}

// 2. evaluate the enabled services to apply the right wait strategy and Cmd options
if len(settings.EnabledServices) > 0 {
cmd := make([]string, 0, len(settings.EnabledServices))
exposedPorts := make([]string, 0, len(settings.EnabledServices))
waitingFor := make([]wait.Strategy, 0, len(settings.EnabledServices))
for _, srv := range settings.EnabledServices {
switch srv {
case BlobService:
moduleCmd = append(moduleCmd, "--blobHost", "0.0.0.0")
cmd = append(cmd, "--blobHost", "0.0.0.0", "--blobPort", BlobPort)
exposedPorts = append(exposedPorts, BlobPort)
waitingFor = append(waitingFor, wait.ForListeningPort(BlobPort))
case QueueService:
moduleCmd = append(moduleCmd, "--queueHost", "0.0.0.0")
cmd = append(cmd, "--queueHost", "0.0.0.0", "--queuePort", QueuePort)
exposedPorts = append(exposedPorts, QueuePort)
waitingFor = append(waitingFor, wait.ForListeningPort(QueuePort))
case TableService:
moduleCmd = append(moduleCmd, "--tableHost", "0.0.0.0")
cmd = append(cmd, "--tableHost", "0.0.0.0", "--tablePort", TablePort)
exposedPorts = append(exposedPorts, TablePort)
waitingFor = append(waitingFor, wait.ForListeningPort(TablePort))
}
}

moduleOpts = append(moduleOpts, testcontainers.WithCmd(moduleCmd...))
moduleOpts = append(moduleOpts, testcontainers.WithWaitStrategy(waitingFor...))
moduleOpts = append(moduleOpts,
testcontainers.WithCmd(cmd...),
testcontainers.WithExposedPorts(exposedPorts...),
testcontainers.WithWaitStrategy(waitingFor...),
)
}

moduleOpts = append(moduleOpts, opts...)
Expand Down
27 changes: 27 additions & 0 deletions modules/azure/azurite/azurite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,33 @@ func TestAzurite_inMemoryPersistence(t *testing.T) {
})
}

func TestAzurite_enabledServices(t *testing.T) {
ctx := context.Background()

invalidService := azurite.Service("invalid")
services := []azurite.Service{azurite.BlobService, azurite.QueueService, azurite.TableService, invalidService}
for _, service := range services {
t.Run(string(service), func(t *testing.T) {
ctr, err := azurite.Run(ctx, "mcr.microsoft.com/azure-storage/azurite:3.33.0", azurite.WithInMemoryPersistence(0), azurite.WithEnabledServices(service))
testcontainers.CleanupContainer(t, ctr)
if service == invalidService {
require.Error(t, err)
return
}
require.NoError(t, err)

for _, s := range services {
_, err = ctr.ServiceURL(ctx, s)
if s == service {
require.NoError(t, err)
} else {
require.Error(t, err)
}
}
})
}
}

func TestAzurite_serviceURL(t *testing.T) {
ctx := context.Background()

Expand Down
3 changes: 3 additions & 0 deletions modules/azure/azurite/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func ExampleRun_blobOperations() {
ctx,
"mcr.microsoft.com/azure-storage/azurite:3.33.0",
azurite.WithInMemoryPersistence(64),
azurite.WithEnabledServices(azurite.BlobService),
)
defer func() {
if err := testcontainers.TerminateContainer(azuriteContainer); err != nil {
Expand Down Expand Up @@ -198,6 +199,7 @@ func ExampleRun_queueOperations() {
ctx,
"mcr.microsoft.com/azure-storage/azurite:3.28.0",
azurite.WithInMemoryPersistence(64),
azurite.WithEnabledServices(azurite.QueueService),
)
defer func() {
if err := testcontainers.TerminateContainer(azuriteContainer); err != nil {
Expand Down Expand Up @@ -292,6 +294,7 @@ func ExampleRun_tableOperations() {
ctx,
"mcr.microsoft.com/azure-storage/azurite:3.28.0",
azurite.WithInMemoryPersistence(64),
azurite.WithEnabledServices(azurite.TableService),
)
defer func() {
if err := testcontainers.TerminateContainer(azuriteContainer); err != nil {
Expand Down
32 changes: 32 additions & 0 deletions modules/azure/azurite/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,38 @@ func defaultOptions() options {
}
}

// Satisfy the testcontainers.CustomizeRequestOption interface
var _ testcontainers.ContainerCustomizer = (Option)(nil)

// Option is an option for the Azurite container.
type Option func(*options) error

// Customize is a NOOP. It's defined to satisfy the testcontainers.ContainerCustomizer interface.
func (o Option) Customize(*testcontainers.GenericContainerRequest) error {
// NOOP to satisfy interface.
return nil
}

// WithEnabledServices is a custom option to specify which services should be enabled.
func WithEnabledServices(services ...service) Option {
return func(o *options) error {
if len(services) == 0 {
services = []service{blobService, queueService, tableService}
} else {
for _, s := range services {
switch s {
case blobService, queueService, tableService:
default:
return fmt.Errorf("unknown service: %s", s)
}
}
}

o.EnabledServices = services
return nil
}
}

// WithInMemoryPersistence is a custom option to enable in-memory persistence for Azurite.
// This option is only available for Azurite v3.28.0 and later.
func WithInMemoryPersistence(megabytes float64) testcontainers.CustomizeRequestOption {
Expand Down
Loading