174b5f9048
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
230 lines
5.9 KiB
Go
230 lines
5.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
func TestGenerateConfigCmd_Flags(t *testing.T) {
|
|
cmd := generateConfigCmd()
|
|
flags := cmd.Flags()
|
|
|
|
lang, err := flags.GetString("lang")
|
|
if err != nil {
|
|
t.Fatalf("failed to get --lang flag: %v", err)
|
|
}
|
|
if lang != "en" {
|
|
t.Errorf("--lang default = %q, want %q", lang, "en")
|
|
}
|
|
|
|
output, err := flags.GetString("output")
|
|
if err != nil {
|
|
t.Fatalf("failed to get --output flag: %v", err)
|
|
}
|
|
if output != "" {
|
|
t.Errorf("--output default = %q, want empty string", output)
|
|
}
|
|
}
|
|
|
|
func TestGenerateConfig_LangEn(t *testing.T) {
|
|
cmd := generateConfigCmd()
|
|
var buf bytes.Buffer
|
|
cmd.SetOut(&buf)
|
|
cmd.SetErr(&buf)
|
|
|
|
if err := cmd.Flags().Set("lang", "en"); err != nil {
|
|
t.Fatalf("Set flag failed: %v", err)
|
|
}
|
|
|
|
if err := cmd.Execute(); err != nil {
|
|
t.Fatalf("Execute failed: %v", err)
|
|
}
|
|
|
|
out := buf.String()
|
|
if !strings.Contains(out, "pg:") {
|
|
t.Errorf("output missing pg section")
|
|
}
|
|
if !strings.Contains(out, "host") {
|
|
t.Errorf("output missing host key")
|
|
}
|
|
if !strings.Contains(out, "PostgreSQL") {
|
|
t.Errorf("output missing English comment")
|
|
}
|
|
}
|
|
|
|
func TestGenerateConfig_LangRu(t *testing.T) {
|
|
cmd := generateConfigCmd()
|
|
var buf bytes.Buffer
|
|
cmd.SetOut(&buf)
|
|
cmd.SetErr(&buf)
|
|
|
|
if err := cmd.Flags().Set("lang", "ru"); err != nil {
|
|
t.Fatalf("Set flag failed: %v", err)
|
|
}
|
|
|
|
if err := cmd.Execute(); err != nil {
|
|
t.Fatalf("Execute failed: %v", err)
|
|
}
|
|
|
|
out := buf.String()
|
|
if !strings.Contains(out, "pg:") {
|
|
t.Errorf("output missing pg section")
|
|
}
|
|
if !strings.Contains(out, "хост") {
|
|
t.Errorf("output missing Russian comment (хост)")
|
|
}
|
|
}
|
|
|
|
func TestGenerateConfig_OutputFile(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
outputPath := filepath.Join(tempDir, "config.yaml")
|
|
|
|
cmd := generateConfigCmd()
|
|
var buf bytes.Buffer
|
|
cmd.SetOut(&buf)
|
|
cmd.SetErr(&buf)
|
|
|
|
if err := cmd.Flags().Set("output", outputPath); err != nil {
|
|
t.Fatalf("Set flag failed: %v", err)
|
|
}
|
|
|
|
if err := cmd.Execute(); err != nil {
|
|
t.Fatalf("Execute failed: %v", err)
|
|
}
|
|
|
|
data, err := os.ReadFile(outputPath)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output file: %v", err)
|
|
}
|
|
if len(data) == 0 {
|
|
t.Errorf("output file is empty")
|
|
}
|
|
|
|
if buf.Len() != 0 {
|
|
t.Errorf("stdout not empty when --output set: %q", buf.String())
|
|
}
|
|
}
|
|
|
|
func TestGenerateConfig_Stdout(t *testing.T) {
|
|
cmd := generateConfigCmd()
|
|
var buf bytes.Buffer
|
|
cmd.SetOut(&buf)
|
|
cmd.SetErr(&buf)
|
|
|
|
if err := cmd.Execute(); err != nil {
|
|
t.Fatalf("Execute failed: %v", err)
|
|
}
|
|
|
|
out := buf.String()
|
|
if out == "" {
|
|
t.Errorf("stdout empty when no --output")
|
|
}
|
|
if !strings.Contains(out, "pg:") {
|
|
t.Errorf("stdout missing pg section")
|
|
}
|
|
}
|
|
|
|
func TestGenerateConfig_AllKeys(t *testing.T) {
|
|
cmd := generateConfigCmd()
|
|
var buf bytes.Buffer
|
|
cmd.SetOut(&buf)
|
|
cmd.SetErr(&buf)
|
|
|
|
if err := cmd.Execute(); err != nil {
|
|
t.Fatalf("Execute failed: %v", err)
|
|
}
|
|
|
|
out := buf.String()
|
|
requiredKeys := make([]string, 0, 16)
|
|
requiredKeys = append(requiredKeys, "host", "port", "user", "password", "database", "sslmode", "exclude_tables", "dir", "retention_days", "cron", "pq_scheme", "classical_scheme", "pq_public_key_path", "classical_public_key_path", "healthz", "log")
|
|
|
|
for _, key := range requiredKeys {
|
|
if !strings.Contains(out, key) {
|
|
t.Errorf("output missing key %q", key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGenerateConfig_RoundTrip(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
outputPath := filepath.Join(tempDir, "config.yaml")
|
|
|
|
cmd := generateConfigCmd()
|
|
if err := cmd.Flags().Set("output", outputPath); err != nil {
|
|
t.Fatalf("Set flag failed: %v", err)
|
|
}
|
|
if err := cmd.Execute(); err != nil {
|
|
t.Fatalf("Execute failed: %v", err)
|
|
}
|
|
|
|
v := viper.New()
|
|
v.SetConfigFile(outputPath)
|
|
if err := v.ReadInConfig(); err != nil {
|
|
t.Fatalf("viper read generated config failed: %v", err)
|
|
}
|
|
|
|
var cfg struct {
|
|
PG struct {
|
|
Host string `mapstructure:"host"`
|
|
Port int `mapstructure:"port"`
|
|
User string `mapstructure:"user"`
|
|
Password string `mapstructure:"password"`
|
|
Database string `mapstructure:"database"`
|
|
SSLMode string `mapstructure:"sslmode"`
|
|
ExcludeTables []string `mapstructure:"exclude_tables"`
|
|
} `mapstructure:"pg"`
|
|
Backup struct {
|
|
Dir string `mapstructure:"dir"`
|
|
RetentionDays int `mapstructure:"retention_days"`
|
|
Cron string `mapstructure:"cron"`
|
|
} `mapstructure:"backup"`
|
|
PQScheme uint16 `mapstructure:"pq_scheme"`
|
|
ClassicalScheme uint16 `mapstructure:"classical_scheme"`
|
|
PQPublicKeyPath string `mapstructure:"pq_public_key_path"`
|
|
ClassicalPublicKeyPath string `mapstructure:"classical_public_key_path"`
|
|
Healthz struct {
|
|
Port int `mapstructure:"port"`
|
|
} `mapstructure:"healthz"`
|
|
Log struct {
|
|
Level string `mapstructure:"level"`
|
|
} `mapstructure:"log"`
|
|
}
|
|
|
|
if err := v.Unmarshal(&cfg); err != nil {
|
|
t.Fatalf("viper unmarshal generated config failed: %v", err)
|
|
}
|
|
|
|
if cfg.PG.Port != 5432 {
|
|
t.Errorf("PG.Port = %d, want 5432", cfg.PG.Port)
|
|
}
|
|
if cfg.PG.SSLMode != "prefer" {
|
|
t.Errorf("PG.SSLMode = %q, want prefer", cfg.PG.SSLMode)
|
|
}
|
|
if len(cfg.PG.ExcludeTables) != 1 || cfg.PG.ExcludeTables[0] != "e2e_one_time_keys_json" {
|
|
t.Errorf("PG.ExcludeTables = %v, want [e2e_one_time_keys_json]", cfg.PG.ExcludeTables)
|
|
}
|
|
if cfg.Backup.RetentionDays != 180 {
|
|
t.Errorf("Backup.RetentionDays = %d, want 180", cfg.Backup.RetentionDays)
|
|
}
|
|
if cfg.Backup.Cron != "0 0 3 * * *" {
|
|
t.Errorf("Backup.Cron = %q, want 0 0 3 * * *", cfg.Backup.Cron)
|
|
}
|
|
if cfg.PQScheme != 0x0006 {
|
|
t.Errorf("PQScheme = 0x%04x, want 0x%04x", cfg.PQScheme, 0x0006)
|
|
}
|
|
if cfg.ClassicalScheme != 0x0007 {
|
|
t.Errorf("ClassicalScheme = 0x%04x, want 0x%04x", cfg.ClassicalScheme, 0x0007)
|
|
}
|
|
if cfg.Healthz.Port != 8080 {
|
|
t.Errorf("Healthz.Port = %d, want 8080", cfg.Healthz.Port)
|
|
}
|
|
if cfg.Log.Level != "info" {
|
|
t.Errorf("Log.Level = %q, want info", cfg.Log.Level)
|
|
}
|
|
}
|