Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nats): WithConfigFile - pass a configuration file to nats server #2905

Merged
merged 13 commits into from
Dec 5, 2024
9 changes: 8 additions & 1 deletion docs/modules/nats.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ These arguments are passed to the NATS server when it starts, as part of the com
[Passing arguments](../../modules/nats/examples_test.go) inside_block:withArguments
<!--/codeinclude-->

#### Custom configuration file

vyskocilm marked this conversation as resolved.
Show resolved Hide resolved
It's possible to pass a custom config file to NATS container using `nats.WithConfigFile(strings.NewReader(config))`. The `io.Reader` is passed as a `-config /etc/nats.conf` arguments to an entrypoint.
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved

!!! note
Changing a connectivity (listen address or ports) can break the container setup. So configuration must be done with a care.
vyskocilm marked this conversation as resolved.
Show resolved Hide resolved

### Container Methods

The NATS container exposes the following methods:
Expand Down Expand Up @@ -102,4 +109,4 @@ Exactly like `ConnectionString`, but it panics if an error occurs, returning jus

<!--codeinclude-->
[NATS Cluster](../../modules/nats/examples_test.go) inside_block:cluster
<!--/codeinclude-->
<!--/codeinclude-->
51 changes: 51 additions & 0 deletions modules/nats/nats_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package nats_test

import (
"bufio"
"context"
"strings"
"testing"

"github.com/nats-io/nats.go"
Expand Down Expand Up @@ -57,3 +59,52 @@ func TestNATS(t *testing.T) {

require.Equal(t, "hello", string(msg.Data))
}

func TestNATSWithConfigFile(t *testing.T) {
const natsConf = `
listen: 0.0.0.0:4222
authorization {
token: "s3cr3t"
}
`
ctx := context.Background()

// createNATSContainer {
ctr, err := tcnats.Run(ctx, "nats:2.9", tcnats.WithConfigFile(strings.NewReader(natsConf)))
// }
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved
testcontainers.CleanupContainer(t, ctr)
require.NoError(t, err)

// connectionString {
uri, err := ctr.ConnectionString(ctx)
// }
require.NoError(t, err)

// connect without token {
mallory, err := nats.Connect(uri, nats.Name("Mallory"), nats.Token("secret"))
// }
require.Error(t, err)
require.ErrorIs(t, err, nats.ErrAuthorization)
t.Cleanup(mallory.Close)
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved

// connect via token {
nc, err := nats.Connect(uri, nats.Name("API Token Test"), nats.Token("s3cr3t"))
// }
require.NoError(t, err)
t.Cleanup(nc.Close)

// validate /etc/nats.conf mentioned in logs {
const expected = "Using configuration file: /etc/nats.conf"
logs, err := ctr.Logs(ctx)
require.NoError(t, err)
sc := bufio.NewScanner(logs)
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved
found := false
for sc.Scan() {
if strings.Contains(sc.Text(), expected) {
found = true
break
}
}
// }
require.Truef(t, found, "expected log line not found: %s", expected)
}
22 changes: 21 additions & 1 deletion modules/nats/options.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package nats

import (
"io"
"strings"

"github.com/testcontainers/testcontainers-go"
Expand All @@ -16,7 +17,7 @@ func defaultOptions() options {
}
}

// Compiler check to ensure that Option implements the testcontainers.ContainerCustomizer interface.
// Compiler check to ensure that CmdOption implements the testcontainers.ContainerCustomizer interface.
var _ testcontainers.ContainerCustomizer = (*CmdOption)(nil)

// CmdOption is an option for the NATS container.
Expand Down Expand Up @@ -49,3 +50,22 @@ func WithArgument(flag string, value string) CmdOption {
o.CmdArgs[flag] = value
}
}

// WithConfigFile pass io.Reader to the NATS container as /etc/nats.conf
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved
// Changes of a connectivity (listen address, or ports) may break a testcontainer
vyskocilm marked this conversation as resolved.
Show resolved Hide resolved
func WithConfigFile(config io.Reader) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) error {
if config != nil {
req.Cmd = append(req.Cmd, "-config", "/etc/nats.conf")
req.Files = append(
req.Files,
testcontainers.ContainerFile{
Reader: config,
ContainerFilePath: "/etc/nats.conf",
FileMode: 0o644,
},
)
}
return nil
}
}