-
-
Notifications
You must be signed in to change notification settings - Fork 511
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* main: feat: support databend module (#2779) chore: golangci-lint 1.61.0 (#2787) fix(mssql): bump Docker image version (#2786) fix: handle 127 error code for podman compatibility (#2778) fix: do not override ImageBuildOptions.Labels when building from a Dockerfile (#2775) feat(mongodb): Wait for mongodb module with a replicaset to finish (#2777) fix(postgres): Apply default snapshot name if no name specified (#2783)
- Loading branch information
Showing
28 changed files
with
973 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Databend | ||
|
||
Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a> | ||
|
||
## Introduction | ||
|
||
The Testcontainers module for Databend. | ||
|
||
## Adding this module to your project dependencies | ||
|
||
Please run the following command to add the Databend module to your Go dependencies: | ||
|
||
``` | ||
go get github.com/testcontainers/testcontainers-go/modules/databend | ||
``` | ||
|
||
## Usage example | ||
|
||
<!--codeinclude--> | ||
[Creating a Databend container](../../modules/databend/examples_test.go) inside_block:runDatabendContainer | ||
<!--/codeinclude--> | ||
|
||
## Module Reference | ||
|
||
### Run function | ||
|
||
- Not available until the next release of testcontainers-go <a href="https://github.com/testcontainers/testcontainers-go"><span class="tc-version">:material-tag: main</span></a> | ||
|
||
The Databend module exposes one entrypoint function to create the Databend container, and this function receives three parameters: | ||
|
||
```golang | ||
func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (*DatabendContainer, error) | ||
``` | ||
|
||
- `context.Context`, the Go context. | ||
- `string`, the Docker image to use. | ||
- `testcontainers.ContainerCustomizer`, a variadic argument for passing options. | ||
|
||
### Container Options | ||
|
||
When starting the Databend container, you can pass options in a variadic way to configure it. | ||
|
||
#### Image | ||
|
||
If you need to set a different Databend Docker image, you can set a valid Docker image as the second argument in the `Run` function. | ||
E.g. `Run(context.Background(), "datafuselabs/databend:v1.2.615")`. | ||
|
||
{% include "../features/common_functional_options.md" %} | ||
|
||
#### Set username, password | ||
|
||
If you need to set a different user/password/database, you can use `WithUsername`, `WithPassword` options. | ||
|
||
!!!info | ||
The default values for the username is `databend`, for password is `databend` and for the default database name is `default`. | ||
|
||
### Container Methods | ||
|
||
The Databend container exposes the following methods: | ||
|
||
#### ConnectionString | ||
|
||
This method returns the connection string to connect to the Databend container, using the default `8000` port. | ||
It's possible to pass extra parameters to the connection string, e.g. `sslmode=disable`. | ||
<!--codeinclude--> | ||
[Get connection string](../../modules/databend/databend_test.go) inside_block:connectionString | ||
<!--/codeinclude--> | ||
#### MustGetConnectionString | ||
`MustConnectionString` panics if the address cannot be determined. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package core | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestMergeCustomLabels(t *testing.T) { | ||
t.Run("success", func(t *testing.T) { | ||
dst := map[string]string{"A": "1", "B": "2"} | ||
src := map[string]string{"B": "X", "C": "3"} | ||
|
||
err := MergeCustomLabels(dst, src) | ||
require.NoError(t, err) | ||
require.Equal(t, map[string]string{"A": "1", "B": "X", "C": "3"}, dst) | ||
}) | ||
|
||
t.Run("invalid-prefix", func(t *testing.T) { | ||
dst := map[string]string{"A": "1", "B": "2"} | ||
src := map[string]string{"B": "X", LabelLang: "go"} | ||
|
||
err := MergeCustomLabels(dst, src) | ||
|
||
require.EqualError(t, err, `key "org.testcontainers.lang" has "org.testcontainers" prefix`) | ||
require.Equal(t, map[string]string{"A": "1", "B": "X"}, dst) | ||
}) | ||
|
||
t.Run("nil-destination", func(t *testing.T) { | ||
src := map[string]string{"A": "1"} | ||
err := MergeCustomLabels(nil, src) | ||
require.Error(t, err) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
include ../../commons-test.mk | ||
|
||
.PHONY: test | ||
test: | ||
$(MAKE) test-databend |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package databend | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/testcontainers/testcontainers-go" | ||
"github.com/testcontainers/testcontainers-go/wait" | ||
) | ||
|
||
const ( | ||
databendUser = "databend" | ||
defaultUser = "databend" | ||
defaultPassword = "databend" | ||
defaultDatabaseName = "default" | ||
) | ||
|
||
// Container represents the Databend container type used in the module | ||
type Container struct { | ||
*testcontainers.DockerContainer | ||
username string | ||
password string | ||
database string | ||
} | ||
|
||
var _ testcontainers.RequestCustomizer = (*DatabendOption)(nil) | ||
|
||
// DatabendOption is an option for the Databend container. | ||
type DatabendOption func(*Container) | ||
|
||
// Customize is a NOOP. It's defined to satisfy the testcontainers.ContainerCustomizer interface. | ||
func (o DatabendOption) Customize(*testcontainers.Request) error { | ||
// NOOP to satisfy interface. | ||
return nil | ||
} | ||
|
||
// Run creates an instance of the Databend container type | ||
func Run(ctx context.Context, img string, opts ...testcontainers.RequestCustomizer) (*Container, error) { | ||
req := testcontainers.Request{ | ||
Image: img, | ||
ExposedPorts: []string{"8000/tcp"}, | ||
Env: map[string]string{ | ||
"QUERY_DEFAULT_USER": defaultUser, | ||
"QUERY_DEFAULT_PASSWORD": defaultPassword, | ||
}, | ||
WaitingFor: wait.ForListeningPort("8000/tcp"), | ||
Started: true, | ||
} | ||
|
||
for _, opt := range opts { | ||
if err := opt.Customize(&req); err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
username := req.Env["QUERY_DEFAULT_USER"] | ||
password := req.Env["QUERY_DEFAULT_PASSWORD"] | ||
if password == "" && username == "" { | ||
return nil, errors.New("empty password and user") | ||
} | ||
|
||
container, err := testcontainers.Run(ctx, req) | ||
var c *Container | ||
if container != nil { | ||
c = &Container{ | ||
DockerContainer: container, | ||
password: password, | ||
username: username, | ||
database: defaultDatabaseName, | ||
} | ||
} | ||
|
||
if err != nil { | ||
return c, fmt.Errorf("generic container: %w", err) | ||
} | ||
|
||
return c, nil | ||
} | ||
|
||
// MustConnectionString panics if the address cannot be determined. | ||
func (c *Container) MustConnectionString(ctx context.Context, args ...string) string { | ||
addr, err := c.ConnectionString(ctx, args...) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return addr | ||
} | ||
|
||
func (c *Container) ConnectionString(ctx context.Context, args ...string) (string, error) { | ||
containerPort, err := c.MappedPort(ctx, "8000/tcp") | ||
if err != nil { | ||
return "", fmt.Errorf("mapped port: %w", err) | ||
} | ||
|
||
host, err := c.Host(ctx) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
extraArgs := "" | ||
if len(args) > 0 { | ||
extraArgs = "?" + strings.Join(args, "&") | ||
} | ||
if c.database == "" { | ||
return "", errors.New("database name is empty") | ||
} | ||
|
||
// databend://databend:databend@localhost:8000/default?sslmode=disable | ||
connectionString := fmt.Sprintf("databend://%s:%s@%s:%s/%s%s", c.username, c.password, host, containerPort.Port(), c.database, extraArgs) | ||
return connectionString, nil | ||
} | ||
|
||
// WithUsername sets the username for the Databend container. | ||
// WithUsername is [Run] option that configures the default query user by setting | ||
// the `QUERY_DEFAULT_USER` container environment variable. | ||
func WithUsername(username string) testcontainers.CustomizeRequestOption { | ||
return func(req *testcontainers.Request) error { | ||
req.Env["QUERY_DEFAULT_USER"] = username | ||
return nil | ||
} | ||
} | ||
|
||
// WithPassword sets the password for the Databend container. | ||
func WithPassword(password string) testcontainers.CustomizeRequestOption { | ||
return func(req *testcontainers.Request) error { | ||
req.Env["QUERY_DEFAULT_PASSWORD"] = password | ||
return nil | ||
} | ||
} |
Oops, something went wrong.