1package app
2
3import (
4 "os"
5 "path/filepath"
6 "testing"
7
8 "github.com/bnema/vev/internal/adapters/brokerconfig"
9 "github.com/bnema/vev/internal/adapters/daemonmux"
10 "github.com/bnema/vev/internal/adapters/ipc"
11 "github.com/stretchr/testify/require"
12)
13
14func TestEnsureProductionBrokerConfigCreatesPrivateEmptyBootstrapWithoutReplacingExisting(t *testing.T) {
15 configHome := t.TempDir()
16 t.Setenv("XDG_CONFIG_HOME", configHome)
17
18 require.NoError(t, ensureProductionBrokerConfig())
19 path := productionBrokerConfigPath()
20 raw, err := os.ReadFile(path)
21 require.NoError(t, err)
22 require.JSONEq(t, `{"marker":"vev.broker.offline/v1","registrations":[]}`, string(raw))
23 info, err := os.Stat(path)
24 require.NoError(t, err)
25 require.Equal(t, os.FileMode(0o600), info.Mode().Perm())
26 dirInfo, err := os.Stat(filepath.Dir(path))
27 require.NoError(t, err)
28 require.Equal(t, os.FileMode(0o700), dirInfo.Mode().Perm())
29
30 layout := productionBrokerLayout()
31 _, err = brokerconfig.LoadProduction(layout, path, "", localDaemonPolicy(), daemonmux.SocketPath(ipc.SocketDir()))
32 require.NoError(t, err)
33
34 require.NoError(t, os.WriteFile(path, []byte("operator-owned"), 0o600))
35 require.NoError(t, ensureProductionBrokerConfig())
36 raw, err = os.ReadFile(path)
37 require.NoError(t, err)
38 require.Equal(t, "operator-owned", string(raw))
39}
40
41func TestEnsureProductionBrokerConfigSupportsConcurrentFirstUse(t *testing.T) {
42 t.Setenv("XDG_CONFIG_HOME", t.TempDir())
43
44 errs := make(chan error, 16)
45 for range cap(errs) {
46 go func() { errs <- ensureProductionBrokerConfig() }()
47 }
48 for range cap(errs) {
49 require.NoError(t, <-errs)
50 }
51 raw, err := os.ReadFile(productionBrokerConfigPath())
52 require.NoError(t, err)
53 require.JSONEq(t, `{"marker":"vev.broker.offline/v1","registrations":[]}`, string(raw))
54}
55
56func TestProductionBrokerLayoutUsesDedicatedRuntimeStateAndConfig(t *testing.T) {
57 t.Setenv("XDG_RUNTIME_DIR", t.TempDir())
58 t.Setenv("XDG_STATE_HOME", t.TempDir())
59 t.Setenv("XDG_CONFIG_HOME", t.TempDir())
60
61 layout := productionBrokerLayout()
62 require.Equal(t, filepath.Join(layout.Root, "state"), layout.State)
63 require.Equal(t, filepath.Join(layout.Runtime, "spawn"), layout.Spawn)
64 require.Equal(t, "broker", filepath.Base(layout.Root))
65 require.Equal(t, "broker", filepath.Base(layout.Runtime))
66 require.Equal(t, "broker.json", filepath.Base(productionBrokerConfigPath()))
67 require.NotEqual(t, layout.Root, layout.Runtime)
68}