test(config): upload and transcription settings (red)
Off by default until the image has ffmpeg; 200 MB / 90 min (the longest length measured); iguana primary, berget fallback that an explicit empty value disables; zero or negative limits are refused rather than silently rejecting every upload. Red: the Config fields do not exist. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// clearUploadEnv unsets every upload knob so a test observes the default, not the
|
||||
// host environment.
|
||||
func clearUploadEnv(t *testing.T) {
|
||||
t.Helper()
|
||||
for _, k := range []string{
|
||||
"TAPIR_UPLOADS_ENABLED", "TAPIR_UPLOAD_MAX_MB", "TAPIR_UPLOAD_MAX_MINUTES",
|
||||
"TAPIR_TRANSCRIBE_MODEL", "TAPIR_TRANSCRIBE_FALLBACK_MODEL", "TAPIR_TRANSCRIBE_TIMEOUT",
|
||||
"TAPIR_UPLOAD_TMP_DIR", "TAPIR_FFMPEG_BIN", "TAPIR_FFPROBE_BIN",
|
||||
"TAPIR_MAX_UPLOADED_TRANSCRIPT_CHARS",
|
||||
} {
|
||||
unset(t, k)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoad_UploadDefaults(t *testing.T) {
|
||||
clearUploadEnv(t)
|
||||
|
||||
c, err := Load()
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
|
||||
if c.UploadsEnabled {
|
||||
t.Error("uploads must be OFF by default: the runtime image needs ffmpeg first (ADR-033)")
|
||||
}
|
||||
if c.UploadMaxBytes != 200<<20 {
|
||||
t.Errorf("UploadMaxBytes = %d, want 200 MB", c.UploadMaxBytes)
|
||||
}
|
||||
if c.UploadMaxDuration != 90*time.Minute {
|
||||
t.Errorf("UploadMaxDuration = %v, want 90m (the longest length measured, not a found ceiling)", c.UploadMaxDuration)
|
||||
}
|
||||
if c.TranscribeModel != "iguana/kb-whisper" {
|
||||
t.Errorf("TranscribeModel = %q", c.TranscribeModel)
|
||||
}
|
||||
if c.TranscribeFallbackModel != "berget/kb-whisper" {
|
||||
t.Errorf("TranscribeFallbackModel = %q", c.TranscribeFallbackModel)
|
||||
}
|
||||
if c.TranscribeTimeout != 30*time.Minute {
|
||||
t.Errorf("TranscribeTimeout = %v, want 30m (a 90 min recording took ~7.5 min)", c.TranscribeTimeout)
|
||||
}
|
||||
if c.UploadTmpDir != os.TempDir() {
|
||||
t.Errorf("UploadTmpDir = %q, want os.TempDir()", c.UploadTmpDir)
|
||||
}
|
||||
if c.FFmpegBin != "ffmpeg" || c.FFprobeBin != "ffprobe" {
|
||||
t.Errorf("bins = %q, %q", c.FFmpegBin, c.FFprobeBin)
|
||||
}
|
||||
if c.MaxUploadedTranscriptChars != 120000 {
|
||||
t.Errorf("MaxUploadedTranscriptChars = %d, want 120000", c.MaxUploadedTranscriptChars)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoad_UploadValuesAreParsed(t *testing.T) {
|
||||
clearUploadEnv(t)
|
||||
setEnv(t, map[string]string{
|
||||
"TAPIR_UPLOADS_ENABLED": "true",
|
||||
"TAPIR_UPLOAD_MAX_MB": "50",
|
||||
"TAPIR_UPLOAD_MAX_MINUTES": "30",
|
||||
"TAPIR_TRANSCRIBE_MODEL": "koala/whisper",
|
||||
"TAPIR_TRANSCRIBE_TIMEOUT": "10m",
|
||||
"TAPIR_UPLOAD_TMP_DIR": "/var/spool/tapir",
|
||||
"TAPIR_FFMPEG_BIN": "/opt/ffmpeg",
|
||||
"TAPIR_FFPROBE_BIN": "/opt/ffprobe",
|
||||
"TAPIR_MAX_UPLOADED_TRANSCRIPT_CHARS": "60000",
|
||||
})
|
||||
|
||||
c, err := Load()
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
|
||||
if !c.UploadsEnabled || c.UploadMaxBytes != 50<<20 || c.UploadMaxDuration != 30*time.Minute ||
|
||||
c.TranscribeModel != "koala/whisper" || c.TranscribeTimeout != 10*time.Minute ||
|
||||
c.UploadTmpDir != "/var/spool/tapir" || c.FFmpegBin != "/opt/ffmpeg" ||
|
||||
c.FFprobeBin != "/opt/ffprobe" || c.MaxUploadedTranscriptChars != 60000 {
|
||||
t.Errorf("values not applied: %+v", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoad_EmptyTranscribeFallbackDisablesIt(t *testing.T) {
|
||||
clearUploadEnv(t)
|
||||
t.Setenv("TAPIR_TRANSCRIBE_FALLBACK_MODEL", "")
|
||||
|
||||
c, err := Load()
|
||||
if err != nil {
|
||||
t.Fatalf("Load: %v", err)
|
||||
}
|
||||
|
||||
if c.TranscribeFallbackModel != "" {
|
||||
t.Errorf("TranscribeFallbackModel = %q: an explicit empty value must disable the cloud fallback, "+
|
||||
"so private audio can be kept on the homelab", c.TranscribeFallbackModel)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoad_UploadRejectsInvalidValues(t *testing.T) {
|
||||
tests := []struct{ key, val string }{
|
||||
{"TAPIR_UPLOADS_ENABLED", "maybe"},
|
||||
{"TAPIR_UPLOAD_MAX_MB", "lots"},
|
||||
{"TAPIR_UPLOAD_MAX_MB", "0"},
|
||||
{"TAPIR_UPLOAD_MAX_MB", "-5"},
|
||||
{"TAPIR_UPLOAD_MAX_MINUTES", "0"},
|
||||
{"TAPIR_UPLOAD_MAX_MINUTES", "forever"},
|
||||
{"TAPIR_TRANSCRIBE_TIMEOUT", "soon"},
|
||||
{"TAPIR_TRANSCRIBE_TIMEOUT", "0s"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.key+"="+tt.val, func(t *testing.T) {
|
||||
clearUploadEnv(t)
|
||||
t.Setenv(tt.key, tt.val)
|
||||
|
||||
if _, err := Load(); err == nil {
|
||||
t.Errorf("Load accepted %s=%q; a zero or negative limit would reject every upload", tt.key, tt.val)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user