Skip to content
24 changes: 11 additions & 13 deletions modules/gcloud/bigquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,32 @@ func RunBigQueryContainer(ctx context.Context, opts ...testcontainers.ContainerC
// RunBigQuery creates an instance of the GCloud container type for BigQuery.
// The URI uses http:// as the protocol.
func RunBigQuery(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*GCloudContainer, error) {
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{"9050/tcp", "9060/tcp"},
WaitingFor: wait.ForHTTP("/discovery/v1/apis/bigquery/v2/rest").WithPort("9050/tcp").WithStartupTimeout(time.Second * 5),
},
Started: true,
moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithExposedPorts("9050/tcp", "9060/tcp"),
testcontainers.WithWaitStrategy(wait.ForHTTP("/discovery/v1/apis/bigquery/v2/rest").WithPort("9050/tcp").WithStartupTimeout(time.Second * 5)),
}

settings, err := applyOptions(&req, opts)
moduleOpts = append(moduleOpts, opts...)

settings, err := applyOptions(opts)
if err != nil {
return nil, err
}

req.Cmd = append(req.Cmd, "--project", settings.ProjectID)
moduleOpts = append(moduleOpts, testcontainers.WithCmdArgs("--project", settings.ProjectID))

// Process data yaml file only for the BigQuery container.
if settings.bigQueryDataYaml != nil {
containerPath := "/testcontainers-data.yaml"

req.Cmd = append(req.Cmd, "--data-from-yaml", containerPath)
moduleOpts = append(moduleOpts, testcontainers.WithCmdArgs("--data-from-yaml", containerPath))

req.Files = append(req.Files, testcontainers.ContainerFile{
moduleOpts = append(moduleOpts, testcontainers.WithFiles(testcontainers.ContainerFile{
Reader: settings.bigQueryDataYaml,
ContainerFilePath: containerPath,
FileMode: 0o644,
})
}))
}

return newGCloudContainer(ctx, req, 9050, settings, "http")
return newGCloudContainer(ctx, img, 9050, settings, "http", moduleOpts...)
}
44 changes: 22 additions & 22 deletions modules/gcloud/bigquery/bigquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ const (

// bigQueryDataYamlPath is the path to the data yaml file in the container.
bigQueryDataYamlPath = "/testcontainers-data.yaml"

defaultPortNumber9050 = "9050"
defaultPortNumber9060 = "9060"
defaultPort9050 = defaultPortNumber9050 + "/tcp"
defaultPort9060 = defaultPortNumber9060 + "/tcp"
)

// Container represents the BigQuery container type used in the module
Expand All @@ -36,44 +41,39 @@ func (c *Container) URI() string {
// Run creates an instance of the BigQuery GCloud container type.
// The URI uses http:// as the protocol.
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error) {
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{"9050/tcp", "9060/tcp"},
WaitingFor: wait.ForAll(
wait.ForListeningPort("9050/tcp"),
wait.ForHTTP("/discovery/v1/apis/bigquery/v2/rest").WithPort("9050/tcp").WithStatusCodeMatcher(func(status int) bool {
return status == 200
}).WithStartupTimeout(time.Second*5),
),
},
Started: true,
moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithExposedPorts(defaultPort9050, defaultPort9060),
testcontainers.WithWaitStrategy(wait.ForAll(
wait.ForListeningPort(defaultPort9050),
wait.ForHTTP("/discovery/v1/apis/bigquery/v2/rest").WithPort(defaultPort9050).WithStatusCodeMatcher(func(status int) bool {
return status == 200
}).WithStartupTimeout(time.Second*5),
)),
}

settings := defaultOptions()
for _, opt := range opts {
if apply, ok := opt.(Option); ok {
if err := apply(&settings); err != nil {
return nil, err
return nil, fmt.Errorf("apply option: %w", err)
}
}
if err := opt.Customize(&req); err != nil {
return nil, err
}
}

req.Cmd = append(req.Cmd, "--project", settings.ProjectID)
moduleOpts = append(moduleOpts, testcontainers.WithCmdArgs("--project", settings.ProjectID))

moduleOpts = append(moduleOpts, opts...)

container, err := testcontainers.GenericContainer(ctx, req)
ctr, err := testcontainers.Run(ctx, img, moduleOpts...)
var c *Container
if container != nil {
c = &Container{Container: container, settings: settings}
if ctr != nil {
c = &Container{Container: ctr, settings: settings}
}
if err != nil {
return c, fmt.Errorf("generic container: %w", err)
return c, fmt.Errorf("run bigquery: %w", err)
}

portEndpoint, err := c.PortEndpoint(ctx, "9050/tcp", "http")
portEndpoint, err := c.PortEndpoint(ctx, defaultPort9050, "http")
if err != nil {
return c, fmt.Errorf("port endpoint: %w", err)
}
Expand Down
9 changes: 3 additions & 6 deletions modules/gcloud/bigquery/bigquery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,12 @@ func TestBigQueryWithDataYAML(t *testing.T) {
tcbigquery.WithDataYAML(bytes.NewReader(dataYaml)),
)
testcontainers.CleanupContainer(t, bigQueryContainer)
require.EqualError(t, err, `data yaml already exists`)
require.ErrorContains(t, err, `data yaml already exists`)
})

t.Run("multi-value-not-set", func(t *testing.T) {
noValueOption := func() testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) error {
req.Cmd = append(req.Cmd, "--data-from-yaml")
return nil
}
noValueOption := func() testcontainers.ContainerCustomizer {
return testcontainers.WithCmdArgs("--data-from-yaml")
}

bigQueryContainer, err := tcbigquery.Run(
Expand Down
10 changes: 5 additions & 5 deletions modules/gcloud/bigquery/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ func WithDataYAML(r io.Reader) testcontainers.CustomizeRequestOption {
return errors.New("data yaml already exists")
}

req.Cmd = append(req.Cmd, "--data-from-yaml", bigQueryDataYamlPath)
if err := testcontainers.WithCmdArgs("--data-from-yaml", bigQueryDataYamlPath)(req); err != nil {
return err
}

req.Files = append(req.Files, testcontainers.ContainerFile{
return testcontainers.WithFiles(testcontainers.ContainerFile{
Reader: r,
ContainerFilePath: bigQueryDataYamlPath,
FileMode: 0o644,
})

return nil
})(req)
}
}
25 changes: 13 additions & 12 deletions modules/gcloud/bigtable.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,26 @@ func RunBigTableContainer(ctx context.Context, opts ...testcontainers.ContainerC
// Deprecated: use [bigtable.Run] instead
// RunBigTable creates an instance of the GCloud container type for BigTable.
func RunBigTable(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*GCloudContainer, error) {
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{"9000/tcp"},
WaitingFor: wait.ForLog("running"),
},
Started: true,
moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithExposedPorts("9000/tcp"),
testcontainers.WithWaitStrategy(wait.ForAll(
wait.ForListeningPort("9000/tcp"),
wait.ForLog("running")),
),
}

settings, err := applyOptions(&req, opts)
moduleOpts = append(moduleOpts, opts...)

settings, err := applyOptions(opts)
if err != nil {
return nil, err
}

req.Cmd = []string{
moduleOpts = append(moduleOpts, testcontainers.WithCmd(
"/bin/sh",
"-c",
"gcloud beta emulators bigtable start --host-port 0.0.0.0:9000 --project=" + settings.ProjectID,
}
"gcloud beta emulators bigtable start --host-port 0.0.0.0:9000 --project="+settings.ProjectID,
))

return newGCloudContainer(ctx, req, 9000, settings, "")
return newGCloudContainer(ctx, img, 9000, settings, "", moduleOpts...)
}
41 changes: 19 additions & 22 deletions modules/gcloud/bigtable/bigtable.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

const (
// DefaultProjectID is the default project ID for the BigTable container.
DefaultProjectID = "test-project"
DefaultProjectID = "test-project"
defaultPortNumber = "9000"
defaultPort = defaultPortNumber + "/tcp"
)

// Container represents the BigTable container type used in the module
Expand All @@ -32,16 +34,12 @@ func (c *Container) URI() string {
// Run creates an instance of the BigTable GCloud container type.
// The URI uses the empty string as the protocol.
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error) {
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{"9000/tcp"},
WaitingFor: wait.ForAll(
wait.ForListeningPort("9000/tcp"),
wait.ForLog("running"),
),
},
Started: true,
moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithExposedPorts(defaultPort),
testcontainers.WithWaitStrategy(wait.ForAll(
wait.ForListeningPort(defaultPort),
wait.ForLog("running"),
)),
}

settings := defaultOptions()
Expand All @@ -51,27 +49,26 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
return nil, err
}
}
if err := opt.Customize(&req); err != nil {
return nil, err
}
}

req.Cmd = []string{
moduleOpts = append(moduleOpts, testcontainers.WithCmd(
"/bin/sh",
"-c",
"gcloud beta emulators bigtable start --host-port 0.0.0.0:9000 --project=" + settings.ProjectID,
}
"gcloud beta emulators bigtable start --host-port 0.0.0.0:"+defaultPortNumber+" --project="+settings.ProjectID,
))

moduleOpts = append(moduleOpts, opts...)

container, err := testcontainers.GenericContainer(ctx, req)
ctr, err := testcontainers.Run(ctx, img, moduleOpts...)
var c *Container
if container != nil {
c = &Container{Container: container, settings: settings}
if ctr != nil {
c = &Container{Container: ctr, settings: settings}
}
if err != nil {
return c, fmt.Errorf("generic container: %w", err)
return c, fmt.Errorf("run bigtable: %w", err)
}

portEndpoint, err := c.PortEndpoint(ctx, "9000/tcp", "")
portEndpoint, err := c.PortEndpoint(ctx, defaultPort, "")
if err != nil {
return c, fmt.Errorf("port endpoint: %w", err)
}
Expand Down
22 changes: 10 additions & 12 deletions modules/gcloud/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,23 @@ func RunDatastoreContainer(ctx context.Context, opts ...testcontainers.Container
// Deprecated: use [datastore.Run] instead
// RunDatastore creates an instance of the GCloud container type for Datastore.
func RunDatastore(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*GCloudContainer, error) {
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{"8081/tcp"},
WaitingFor: wait.ForHTTP("/").WithPort("8081/tcp"),
},
Started: true,
moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithExposedPorts("8081/tcp"),
testcontainers.WithWaitStrategy(wait.ForHTTP("/").WithPort("8081/tcp")),
}

settings, err := applyOptions(&req, opts)
moduleOpts = append(moduleOpts, opts...)

settings, err := applyOptions(opts)
if err != nil {
return nil, err
}

req.Cmd = []string{
moduleOpts = append(moduleOpts, testcontainers.WithCmd(
"/bin/sh",
"-c",
"gcloud beta emulators datastore start --host-port 0.0.0.0:8081 --project=" + settings.ProjectID,
}
"gcloud beta emulators datastore start --host-port 0.0.0.0:8081 --project="+settings.ProjectID,
))

return newGCloudContainer(ctx, req, 8081, settings, "")
return newGCloudContainer(ctx, img, 8081, settings, "", moduleOpts...)
}
41 changes: 19 additions & 22 deletions modules/gcloud/datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

const (
// DefaultProjectID is the default project ID for the Datastore container.
DefaultProjectID = "test-project"
DefaultProjectID = "test-project"
defaultPortNumber = "8081"
defaultPort = defaultPortNumber + "/tcp"
)

// Container represents the Datastore container type used in the module
Expand All @@ -32,16 +34,12 @@ func (c *Container) URI() string {
// Run creates an instance of the Datastore GCloud container type.
// The URI uses the empty string as the protocol.
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*Container, error) {
req := testcontainers.GenericContainerRequest{
ContainerRequest: testcontainers.ContainerRequest{
Image: img,
ExposedPorts: []string{"8081/tcp"},
WaitingFor: wait.ForAll(
wait.ForListeningPort("8081/tcp"),
wait.ForHTTP("/").WithPort("8081/tcp"),
),
},
Started: true,
moduleOpts := []testcontainers.ContainerCustomizer{
testcontainers.WithExposedPorts(defaultPort),
testcontainers.WithWaitStrategy(wait.ForAll(
wait.ForListeningPort(defaultPort),
wait.ForHTTP("/").WithPort(defaultPort),
)),
}

settings := defaultOptions()
Expand All @@ -51,27 +49,26 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
return nil, err
}
}
if err := opt.Customize(&req); err != nil {
return nil, err
}
}

req.Cmd = []string{
moduleOpts = append(moduleOpts, testcontainers.WithCmd(
"/bin/sh",
"-c",
"gcloud beta emulators datastore start --host-port 0.0.0.0:8081 --project=" + settings.ProjectID,
}
"gcloud beta emulators datastore start --host-port 0.0.0.0:"+defaultPortNumber+" --project="+settings.ProjectID,
))

moduleOpts = append(moduleOpts, opts...)

container, err := testcontainers.GenericContainer(ctx, req)
ctr, err := testcontainers.Run(ctx, img, moduleOpts...)
var c *Container
if container != nil {
c = &Container{Container: container, settings: settings}
if ctr != nil {
c = &Container{Container: ctr, settings: settings}
}
if err != nil {
return c, fmt.Errorf("generic container: %w", err)
return c, fmt.Errorf("run datastore: %w", err)
}

portEndpoint, err := c.PortEndpoint(ctx, "8081/tcp", "")
portEndpoint, err := c.PortEndpoint(ctx, defaultPort, "")
if err != nil {
return c, fmt.Errorf("port endpoint: %w", err)
}
Expand Down
Loading
Loading