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
13 changes: 13 additions & 0 deletions modules/nats/nats.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
genericContainerReq.Cmd = append(genericContainerReq.Cmd, []string{"--" + k, v}...)
}

// Pass a configuration file if provided
if settings.ConfigFile != nil {
genericContainerReq.Cmd = append(genericContainerReq.Cmd, "-config", "/etc/nats.conf")
genericContainerReq.Files = append(
genericContainerReq.Files,
testcontainers.ContainerFile{
Reader: settings.ConfigFile,
ContainerFilePath: "/etc/nats.conf",
FileMode: 0o644,
},
)
}
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved

container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
var c *NATSContainer
if container != nil {
Expand Down
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)
}
15 changes: 13 additions & 2 deletions modules/nats/options.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package nats

import (
"io"
"strings"

"github.com/testcontainers/testcontainers-go"
)

type options struct {
CmdArgs map[string]string
CmdArgs map[string]string
ConfigFile io.Reader
}

func defaultOptions() options {
return options{
CmdArgs: make(map[string]string, 0),
CmdArgs: make(map[string]string, 0),
ConfigFile: nil,
}
}

Expand Down Expand Up @@ -49,3 +52,11 @@ 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) CmdOption {
mdelapenya marked this conversation as resolved.
Show resolved Hide resolved
return func(o *options) {
o.ConfigFile = config
}
}