mirror of
https://github.com/juanfont/headscale.git
synced 2025-08-11 19:07:33 +00:00
db: add sqlite "source of truth" schema
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:

committed by
Kristoffer Dalby

parent
855c48aec2
commit
c6736dd6d6
211
hscontrol/db/sqliteconfig/config_test.go
Normal file
211
hscontrol/db/sqliteconfig/config_test.go
Normal file
@@ -0,0 +1,211 @@
|
||||
package sqliteconfig
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJournalMode(t *testing.T) {
|
||||
tests := []struct {
|
||||
mode JournalMode
|
||||
valid bool
|
||||
}{
|
||||
{JournalModeWAL, true},
|
||||
{JournalModeDelete, true},
|
||||
{JournalModeTruncate, true},
|
||||
{JournalModePersist, true},
|
||||
{JournalModeMemory, true},
|
||||
{JournalModeOff, true},
|
||||
{JournalMode("INVALID"), false},
|
||||
{JournalMode(""), false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(string(tt.mode), func(t *testing.T) {
|
||||
if got := tt.mode.IsValid(); got != tt.valid {
|
||||
t.Errorf("JournalMode(%q).IsValid() = %v, want %v", tt.mode, got, tt.valid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoVacuum(t *testing.T) {
|
||||
tests := []struct {
|
||||
mode AutoVacuum
|
||||
valid bool
|
||||
}{
|
||||
{AutoVacuumNone, true},
|
||||
{AutoVacuumFull, true},
|
||||
{AutoVacuumIncremental, true},
|
||||
{AutoVacuum("INVALID"), false},
|
||||
{AutoVacuum(""), false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(string(tt.mode), func(t *testing.T) {
|
||||
if got := tt.mode.IsValid(); got != tt.valid {
|
||||
t.Errorf("AutoVacuum(%q).IsValid() = %v, want %v", tt.mode, got, tt.valid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSynchronous(t *testing.T) {
|
||||
tests := []struct {
|
||||
mode Synchronous
|
||||
valid bool
|
||||
}{
|
||||
{SynchronousOff, true},
|
||||
{SynchronousNormal, true},
|
||||
{SynchronousFull, true},
|
||||
{SynchronousExtra, true},
|
||||
{Synchronous("INVALID"), false},
|
||||
{Synchronous(""), false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(string(tt.mode), func(t *testing.T) {
|
||||
if got := tt.mode.IsValid(); got != tt.valid {
|
||||
t.Errorf("Synchronous(%q).IsValid() = %v, want %v", tt.mode, got, tt.valid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigValidate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config *Config
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid default config",
|
||||
config: Default("/path/to/db.sqlite"),
|
||||
},
|
||||
{
|
||||
name: "empty path",
|
||||
config: &Config{
|
||||
Path: "",
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "negative busy timeout",
|
||||
config: &Config{
|
||||
Path: "/path/to/db.sqlite",
|
||||
BusyTimeout: -1,
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid journal mode",
|
||||
config: &Config{
|
||||
Path: "/path/to/db.sqlite",
|
||||
JournalMode: JournalMode("INVALID"),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := tt.config.Validate()
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("Config.Validate() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigToURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config *Config
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "default config",
|
||||
config: Default("/path/to/db.sqlite"),
|
||||
want: "file:/path/to/db.sqlite?_pragma=busy_timeout=10000&_pragma=journal_mode=WAL&_pragma=auto_vacuum=INCREMENTAL&_pragma=wal_autocheckpoint=1000&_pragma=synchronous=NORMAL&_pragma=foreign_keys=ON",
|
||||
},
|
||||
{
|
||||
name: "memory config",
|
||||
config: Memory(),
|
||||
want: ":memory:?_pragma=foreign_keys=ON",
|
||||
},
|
||||
{
|
||||
name: "minimal config",
|
||||
config: &Config{
|
||||
Path: "/simple/db.sqlite",
|
||||
WALAutocheckpoint: -1, // not set
|
||||
},
|
||||
want: "file:/simple/db.sqlite",
|
||||
},
|
||||
{
|
||||
name: "custom config",
|
||||
config: &Config{
|
||||
Path: "/custom/db.sqlite",
|
||||
BusyTimeout: 5000,
|
||||
JournalMode: JournalModeDelete,
|
||||
WALAutocheckpoint: -1, // not set
|
||||
Synchronous: SynchronousFull,
|
||||
ForeignKeys: true,
|
||||
},
|
||||
want: "file:/custom/db.sqlite?_pragma=busy_timeout=5000&_pragma=journal_mode=DELETE&_pragma=synchronous=FULL&_pragma=foreign_keys=ON",
|
||||
},
|
||||
{
|
||||
name: "memory with custom timeout",
|
||||
config: &Config{
|
||||
Path: ":memory:",
|
||||
BusyTimeout: 2000,
|
||||
WALAutocheckpoint: -1, // not set
|
||||
ForeignKeys: true,
|
||||
},
|
||||
want: ":memory:?_pragma=busy_timeout=2000&_pragma=foreign_keys=ON",
|
||||
},
|
||||
{
|
||||
name: "wal autocheckpoint zero",
|
||||
config: &Config{
|
||||
Path: "/test.db",
|
||||
WALAutocheckpoint: 0,
|
||||
},
|
||||
want: "file:/test.db?_pragma=wal_autocheckpoint=0",
|
||||
},
|
||||
{
|
||||
name: "all options",
|
||||
config: &Config{
|
||||
Path: "/full.db",
|
||||
BusyTimeout: 15000,
|
||||
JournalMode: JournalModeWAL,
|
||||
AutoVacuum: AutoVacuumFull,
|
||||
WALAutocheckpoint: 1000,
|
||||
Synchronous: SynchronousExtra,
|
||||
ForeignKeys: true,
|
||||
},
|
||||
want: "file:/full.db?_pragma=busy_timeout=15000&_pragma=journal_mode=WAL&_pragma=auto_vacuum=FULL&_pragma=wal_autocheckpoint=1000&_pragma=synchronous=EXTRA&_pragma=foreign_keys=ON",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tt.config.ToURL()
|
||||
if err != nil {
|
||||
t.Errorf("Config.ToURL() error = %v", err)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("Config.ToURL() = %q, want %q", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigToURLInvalid(t *testing.T) {
|
||||
config := &Config{
|
||||
Path: "",
|
||||
BusyTimeout: -1,
|
||||
}
|
||||
_, err := config.ToURL()
|
||||
if err == nil {
|
||||
t.Error("Config.ToURL() with invalid config should return error")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user