1
0
Fork 0
mirror of https://github.com/pomerium/pomerium.git synced 2025-07-14 15:28:28 +02:00
pomerium/config/config_source_test.go
Joe Kralicky fe31799eb5
Fix many instances of contexts and loggers not being propagated ()
This also replaces instances where we manually write "return ctx.Err()"
with "return context.Cause(ctx)" which is functionally identical, but
will also correctly propagate cause errors if present.
2024-10-25 14:50:56 -04:00

204 lines
5.2 KiB
Go

package config
import (
"context"
"fmt"
"os"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFileWatcherSource(t *testing.T) {
tmpdir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1}, 0o600)
if !assert.NoError(t, err) {
return
}
err = os.WriteFile(filepath.Join(tmpdir, "kubernetes-example.txt"), []byte{2}, 0o600)
if !assert.NoError(t, err) {
return
}
newTest := func(enabled bool) func(*testing.T) {
return func(t *testing.T) {
ssrc := NewStaticSource(&Config{
Options: &Options{
CAFile: filepath.Join(tmpdir, "example.txt"),
Policies: []Policy{{
KubernetesServiceAccountTokenFile: filepath.Join(tmpdir, "kubernetes-example.txt"),
}},
RuntimeFlags: map[RuntimeFlag]bool{
RuntimeFlagConfigHotReload: enabled,
},
},
})
src := NewFileWatcherSource(context.Background(), ssrc)
ch := make(chan struct{}, 10)
src.OnConfigChange(context.Background(), func(_ context.Context, _ *Config) {
ch <- struct{}{}
})
err := os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1, 2}, 0o600)
if !assert.NoError(t, err) {
return
}
select {
case <-ch:
if !enabled {
t.Error("expected OnConfigChange not to be fired after modifying a file")
}
case <-time.After(time.Second):
if enabled {
t.Error("expected OnConfigChange to be fired after modifying a file")
}
}
require.Empty(t, ch, "expected exactly one OnConfigChange event")
err = os.WriteFile(filepath.Join(tmpdir, "kubernetes-example.txt"), []byte{2, 3}, 0o600)
if !assert.NoError(t, err) {
return
}
select {
case <-ch:
if !enabled {
t.Error("expected OnConfigChange not to be fired after modifying a file")
}
case <-time.After(time.Second):
if enabled {
t.Error("expected OnConfigChange to be fired after modifying a policy file")
}
}
require.Empty(t, ch, "expected exactly one OnConfigChange event")
ssrc.SetConfig(context.Background(), &Config{
Options: &Options{
CAFile: filepath.Join(tmpdir, "example.txt"),
},
})
select {
case <-ch:
case <-time.After(time.Second):
if enabled {
t.Error("expected OnConfigChange to be fired after triggering a change to the underlying source")
}
}
require.Empty(t, ch, "expected exactly one OnConfigChange event")
}
}
t.Run("Hot Reload Enabled", newTest(true))
t.Run("Hot Reload Disabled", newTest(false))
}
func TestFileOrEnvironmentSource(t *testing.T) {
tmpdir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1}, 0o600)
if !assert.NoError(t, err) {
return
}
err = os.WriteFile(filepath.Join(tmpdir, "kubernetes-example.txt"), []byte{2}, 0o600)
if !assert.NoError(t, err) {
return
}
newTest := func(enabled bool) func(*testing.T) {
return func(t *testing.T) {
initialConfigYaml := fmt.Sprintf(`
certificate_authority_file: %s
policy:
- from: https://foo
to: https://bar
kubernetes_service_account_token_file: %s
codec_type: auto
runtime_flags:
config_hot_reload: %t
`,
filepath.Join(tmpdir, "example.txt"),
filepath.Join(tmpdir, "kubernetes-example.txt"),
enabled,
)
configFilePath := filepath.Join(tmpdir, "config.yaml")
err := os.WriteFile(configFilePath, []byte(initialConfigYaml), 0o600)
require.NoError(t, err)
var src Source
src, err = NewFileOrEnvironmentSource(context.Background(), configFilePath, "")
require.NoError(t, err)
src = NewFileWatcherSource(context.Background(), src)
ch := make(chan struct{}, 10)
src.OnConfigChange(context.Background(), func(_ context.Context, _ *Config) {
ch <- struct{}{}
})
err = os.WriteFile(filepath.Join(tmpdir, "example.txt"), []byte{1, 2}, 0o600)
require.NoError(t, err)
select {
case <-ch:
if !enabled {
t.Error("expected OnConfigChange not to be fired after modifying a file")
}
case <-time.After(time.Second):
if enabled {
t.Error("expected OnConfigChange to be fired after modifying a file")
}
}
require.Empty(t, ch, "expected exactly one OnConfigChange event")
err = os.WriteFile(filepath.Join(tmpdir, "kubernetes-example.txt"), []byte{2, 3}, 0o600)
if !assert.NoError(t, err) {
return
}
select {
case <-ch:
if !enabled {
t.Error("expected OnConfigChange not to be fired after modifying a file")
}
case <-time.After(time.Second):
if enabled {
t.Error("expected OnConfigChange to be fired after modifying a policy file")
}
}
require.Empty(t, ch, "expected exactly one OnConfigChange event")
// the file watcher checks modification time, not contents
err = os.Chtimes(configFilePath, time.Now(), time.Now())
require.NoError(t, err)
select {
case <-ch:
if !enabled {
t.Error("expected OnConfigChange not to be fired after triggering a change to the underlying source")
}
case <-time.After(time.Second):
if enabled {
t.Error("expected OnConfigChange to be fired after triggering a change to the underlying source")
}
}
require.Empty(t, ch, "expected exactly one OnConfigChange event")
}
}
t.Run("Hot Reload Enabled", newTest(true))
t.Run("Hot Reload Disabled", newTest(false))
}