Skip to content

Commit

Permalink
Add tests for Caddyfile env vars and JSON env. substitutions
Browse files Browse the repository at this point in the history
  • Loading branch information
hslatman committed Jan 13, 2024
1 parent 3d6402c commit 28ef1be
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 75 deletions.
121 changes: 60 additions & 61 deletions crowdsec/caddyfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,139 +13,116 @@ import (
func TestUnmarshalCaddyfile(t *testing.T) {
tv := true
fv := false
type args struct {
d *caddyfile.Dispenser
}
tests := []struct {
name string
input string
env map[string]string
expected *CrowdSec
args args
wantParseErr bool
}{
{
name: "fail/missing tokens",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(``),
},
name: "fail/missing tokens",
expected: &CrowdSec{},
input: ``,
wantParseErr: true,
},
{
name: "fail/not-crowdsec",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`not-crowdsec`),
},
name: "fail/not-crowdsec",
expected: &CrowdSec{},
input: `not-crowdsec`,
wantParseErr: true,
},
{
name: "fail/invalid-duration",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key some_random_key
ticker_interval 30x
}`),
},
}`,
wantParseErr: true,
},
{
name: "fail/no-api-url",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
api_url
api_key some_random_key
ticker_interval 30x
}`),
},
input: `
crowdsec {
api_url
api_key some_random_key
ticker_interval 30x
}`,
wantParseErr: true,
},
{
name: "fail/invalid-api-url",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://\x00/
api_key some_random_key
ticker_interval 30x
}`),
},
}`,
wantParseErr: true,
},
{
name: "fail/invalid-api-url-no-scheme",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url example.com
api_key some_random_key
ticker_interval 30x
}`),
},
}`,
wantParseErr: true,
},
{
name: "fail/missing-api-key",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key
}`),
},
}`,
wantParseErr: true,
},
{
name: "fail/missing-ticker-interval",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key test-key
ticker_interval
}`),
},
}`,
wantParseErr: true,
},
{
name: "fail/invalid-streaming",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key test-key
ticker_interval 30s
disable_streaming absolutely
}`),
},
}`,
wantParseErr: true,
},
{
name: "fail/invalid-streaming",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key test-key
ticker_interval 30s
disable_streaming
enable_hard_fails yo
}`),
},
}`,
wantParseErr: true,
},
{
name: "fail/unknown-token",
expected: &CrowdSec{},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key some_random_key
unknown_token 42
}`),
},
}`,
wantParseErr: true,
},
{
Expand All @@ -157,12 +134,10 @@ func TestUnmarshalCaddyfile(t *testing.T) {
EnableStreaming: &tv,
EnableHardFails: &fv,
},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key some_random_key
}`),
},
}`,
wantParseErr: false,
},
{
Expand All @@ -174,25 +149,49 @@ func TestUnmarshalCaddyfile(t *testing.T) {
EnableStreaming: &fv,
EnableHardFails: &tv,
},
args: args{
d: caddyfile.NewTestDispenser(`crowdsec {
input: `crowdsec {
api_url http://127.0.0.1:8080
api_key some_random_key
ticker_interval 33s
disable_streaming
enable_hard_fails
}`),
}`,
wantParseErr: false,
},
{
name: "ok/env-vars",
expected: &CrowdSec{
APIUrl: "http://127.0.0.2:8080/",
APIKey: "env-test-key",
TickerInterval: "25s",
EnableStreaming: &tv,
EnableHardFails: &fv,
},
env: map[string]string{
"CROWDSEC_TEST_API_URL": "http://127.0.0.2:8080/",
"CROWDSEC_TEST_API_KEY": "env-test-key",
"CROWDSEC_TEST_TICKER_INTERVAL": "25s",
},
input: `crowdsec {
api_url {$CROWDSEC_TEST_API_URL}
api_key {$CROWDSEC_TEST_API_KEY}
ticker_interval {$CROWDSEC_TEST_TICKER_INTERVAL}
}`,
wantParseErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
jsonApp, err := parseCrowdSec(tt.args.d, nil)
for k, v := range tt.env {
t.Setenv(k, v)
}
dispenser := caddyfile.NewTestDispenser(tt.input)
jsonApp, err := parseCrowdSec(dispenser, nil)
if tt.wantParseErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)

app, ok := jsonApp.(httpcaddyfile.App)
require.True(t, ok)
Expand Down
24 changes: 24 additions & 0 deletions crowdsec/crowdsec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func TestCrowdSec_Provision(t *testing.T) {
tests := []struct {
name string
config string
env map[string]string
assertion func(tt assert.TestingT, c *CrowdSec)
wantErr bool
}{
Expand Down Expand Up @@ -68,13 +69,36 @@ func TestCrowdSec_Provision(t *testing.T) {
},
wantErr: false,
},
{
name: "json-env-vars",
config: `{
"api_url": "{env.CROWDSEC_TEST_API_URL}",
"api_key": "{env.CROWDSEC_TEST_API_KEY}",
"ticker_interval": "{env.CROWDSEC_TEST_TICKER_INTERVAL}"
}`,
env: map[string]string{
"CROWDSEC_TEST_API_URL": "http://127.0.0.2:8080/",
"CROWDSEC_TEST_API_KEY": "env-test-key",
"CROWDSEC_TEST_TICKER_INTERVAL": "25s",
},
assertion: func(tt assert.TestingT, c *CrowdSec) {
assert.Equal(tt, "http://127.0.0.2:8080/", c.APIUrl)
assert.Equal(tt, "env-test-key", c.APIKey)
assert.Equal(tt, "25s", c.TickerInterval)
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var c CrowdSec
err := json.Unmarshal([]byte(tt.config), &c)
require.NoError(t, err)

for k, v := range tt.env {
t.Setenv(k, v)
}

ctx, _ := caddy.NewContext(caddy.Context{Context: context.Background()})
err = c.Provision(ctx)
require.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/mholt/caddy-l4 v0.0.0-20231016112149-a362a1fbf652
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
go.uber.org/goleak v1.2.1
go.uber.org/zap v1.26.0
)

Expand Down Expand Up @@ -127,7 +128,6 @@ require (
go.step.sm/cli-utils v0.8.0 // indirect
go.step.sm/crypto v0.36.1 // indirect
go.step.sm/linkedca v0.20.1 // indirect
go.uber.org/goleak v1.2.1 // indirect
go.uber.org/mock v0.3.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
Expand Down
11 changes: 5 additions & 6 deletions internal/bouncer/bouncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,15 @@ func (b *Bouncer) Run() {
func (b *Bouncer) Shutdown() error {
b.startMu.Lock()
defer b.startMu.Unlock()
if !b.started || b.stopped {
return nil
}
b.logger.Info("stopping", b.zapField())
defer func() {
b.stopped = true
b.logger.Info("finished", b.zapField())
b.logger.Sync() // nolint
}()
if !b.started || b.stopped {
return nil
}

// the LiveBouncer has nothing to do on shutdown
if !b.useStreamingBouncer {
Expand All @@ -233,9 +235,6 @@ func (b *Bouncer) Shutdown() error {
b.cancel()
b.wg.Wait()

b.logger.Info("finished", b.zapField())
b.logger.Sync() // nolint

// TODO: clean shutdown of the streaming bouncer channel reading
//b.store = nil // TODO(hs): setting this to nil without reinstantiating it, leads to errors; do this properly.
return nil
Expand Down
Loading

0 comments on commit 28ef1be

Please sign in to comment.