mirror of
https://github.com/TronoSfera/backupy-agent.git
synced 2026-05-18 10:03:30 +03:00
Source ports from the TronoSfera/backupy-cloud monorepo:
- apps/agent/ — Go agent (WSS client, persistent queue, Docker
discovery, 5 DB drivers: PG/MySQL/Mongo/Redis/SQLite,
pre/post hooks, Prometheus metrics)
- apps/backupy-decrypt/ — standalone CLI for client-side decryption
- packages/proto/ — protobuf wire format (generated .pb.go committed
so the repo builds without protoc)
- docs/ — agent spec + wire-protocol contract
Apache-2.0 license. Image published to ghcr.io/tronosfera/backupy-agent
on every v* tag via .github/workflows/release.yml (multi-arch amd64+arm64).
107 lines
2.8 KiB
Go
107 lines
2.8 KiB
Go
package config
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const validKey = "bkpy_live_abcdefghijklmnopqrstuvwxyz012345"
|
|
|
|
func TestValidate_Happy(t *testing.T) {
|
|
dir := t.TempDir()
|
|
cfg := &Config{
|
|
ServerURL: "https://api.backupy.ru",
|
|
AgentKey: validKey,
|
|
StateDir: dir,
|
|
LogLevel: "info",
|
|
}
|
|
require.NoError(t, cfg.Validate())
|
|
require.Equal(t, filepath.Join(dir, "state.db"), cfg.StateDBPath())
|
|
}
|
|
|
|
func TestValidate_ServerURL(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
url string
|
|
insec bool
|
|
errSub string
|
|
}{
|
|
{"https ok", "https://api.backupy.ru", false, ""},
|
|
{"http rejected by default", "http://localhost:8080", false, "must use https"},
|
|
{"http allowed with dev flag", "http://localhost:8080", true, ""},
|
|
{"ftp rejected", "ftp://example.com", false, "unsupported scheme"},
|
|
{"missing host", "https://", false, "missing host"},
|
|
{"unparsable", "://broken", false, "valid URL"},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := validateServerURL(tc.url, tc.insec)
|
|
if tc.errSub == "" {
|
|
require.NoError(t, err)
|
|
return
|
|
}
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), tc.errSub)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidate_AgentKey(t *testing.T) {
|
|
dir := t.TempDir()
|
|
cases := []struct {
|
|
name string
|
|
key string
|
|
ok bool
|
|
}{
|
|
{"live key", "bkpy_live_abcdefghijklmnopqrstuvwxyz012345", true},
|
|
{"test key", "bkpy_test_abcdefghijklmnopqrstuvwxyz012345", true},
|
|
{"wrong prefix", "bkpy_dev_abcdefghijklmnopqrstuvwxyz012345", false},
|
|
{"too short", "bkpy_live_abc", false},
|
|
{"too long", "bkpy_live_abcdefghijklmnopqrstuvwxyz0123456", false},
|
|
{"invalid char", "bkpy_live_abcdefghijklmnopqrstuvwxyz01234!", false},
|
|
{"empty", "", false},
|
|
{"missing underscore", "bkpylive_abcdefghijklmnopqrstuvwxyz012345", false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
cfg := &Config{
|
|
ServerURL: "https://api.backupy.ru",
|
|
AgentKey: tc.key,
|
|
StateDir: dir,
|
|
}
|
|
err := cfg.Validate()
|
|
if tc.ok {
|
|
require.NoError(t, err)
|
|
} else {
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "BACKUP_AGENT_KEY")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidate_StateDir(t *testing.T) {
|
|
t.Run("empty rejected", func(t *testing.T) {
|
|
err := validateStateDirWritable("")
|
|
require.Error(t, err)
|
|
})
|
|
t.Run("creates missing dir", func(t *testing.T) {
|
|
root := t.TempDir()
|
|
nested := filepath.Join(root, "nested", "state")
|
|
require.NoError(t, validateStateDirWritable(nested))
|
|
})
|
|
t.Run("redaction in errors", func(t *testing.T) {
|
|
// Sanity check: error text never mentions the agent key.
|
|
cfg := &Config{
|
|
ServerURL: "https://api.backupy.ru",
|
|
AgentKey: validKey,
|
|
StateDir: "", // invalid
|
|
}
|
|
err := cfg.Validate()
|
|
require.Error(t, err)
|
|
require.False(t, strings.Contains(err.Error(), validKey))
|
|
})
|
|
}
|