feat(v2): add safe runtime configuration
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const testSHA256 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||
|
||||
func TestLoadResolvesOnlyNamedEnvironmentURL(t *testing.T) {
|
||||
t.Setenv("SILVER_POSE_RTSP_URL", "rtsp://operator:secret@192.0.2.9/Streaming/Channels/101")
|
||||
|
||||
cfg, err := Load(writeConfig(t, validConfigJSON()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if cfg.Source.URL != "rtsp://operator:secret@192.0.2.9/Streaming/Channels/101" {
|
||||
t.Fatalf("resolved source URL = %q", cfg.Source.URL)
|
||||
}
|
||||
if !strings.HasPrefix(cfg.RuntimeConfigVersion, "cfg-") {
|
||||
t.Fatalf("runtime config version = %q", cfg.RuntimeConfigVersion)
|
||||
}
|
||||
if strings.Contains(cfg.RuntimeConfigVersion, "secret") {
|
||||
t.Fatalf("runtime config version leaked a credential: %q", cfg.RuntimeConfigVersion)
|
||||
}
|
||||
if !filepath.IsAbs(cfg.Model.ONNXPath) || !filepath.IsAbs(cfg.Tools.FFmpegPath) {
|
||||
t.Fatalf("relative paths were not resolved: %#v", cfg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRejectsEmbeddedRTSPURL(t *testing.T) {
|
||||
t.Setenv("SILVER_POSE_RTSP_URL", "rtsp://operator:secret@192.0.2.9/Streaming/Channels/101")
|
||||
configJSON := strings.Replace(validConfigJSON(), `"rtsp_url_env": "SILVER_POSE_RTSP_URL"`, `"rtsp_url_env": "SILVER_POSE_RTSP_URL", "url": "rtsp://secret"`, 1)
|
||||
|
||||
_, err := Load(writeConfig(t, configJSON))
|
||||
if err == nil || !strings.Contains(err.Error(), "rtsp_url_env") {
|
||||
t.Fatalf("embedded URL error = %v", err)
|
||||
}
|
||||
if strings.Contains(err.Error(), "secret") {
|
||||
t.Fatalf("embedded URL error leaked a credential: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRejectsMissingSourceEnvironment(t *testing.T) {
|
||||
os.Unsetenv("SILVER_POSE_RTSP_URL")
|
||||
|
||||
_, err := Load(writeConfig(t, validConfigJSON()))
|
||||
if err == nil || !strings.Contains(err.Error(), "SILVER_POSE_RTSP_URL") {
|
||||
t.Fatalf("missing environment error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadRejectsInvalidModelHash(t *testing.T) {
|
||||
t.Setenv("SILVER_POSE_RTSP_URL", "rtsp://operator:secret@192.0.2.9/Streaming/Channels/101")
|
||||
|
||||
_, err := Load(writeConfig(t, strings.Replace(validConfigJSON(), testSHA256, "invalid", 1)))
|
||||
if err == nil || !strings.Contains(err.Error(), "model.sha256") {
|
||||
t.Fatalf("invalid hash error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func writeConfig(t *testing.T, content string) string {
|
||||
t.Helper()
|
||||
path := filepath.Join(t.TempDir(), "config.json")
|
||||
if err := os.WriteFile(path, []byte(content), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func validConfigJSON() string {
|
||||
return `{
|
||||
"source": {
|
||||
"id": "lobby-camera-01",
|
||||
"rtsp_url_env": "SILVER_POSE_RTSP_URL",
|
||||
"transport": "tcp",
|
||||
"timeout_seconds": 5,
|
||||
"low_latency": true
|
||||
},
|
||||
"model": {
|
||||
"onnx": "assets/best.onnx",
|
||||
"sha256": "` + testSHA256 + `",
|
||||
"ort_dll": "runtime/onnxruntime.dll",
|
||||
"confidence_threshold": 0.25
|
||||
},
|
||||
"tools": {
|
||||
"ffmpeg": "runtime/ffmpeg.exe",
|
||||
"ffprobe": "runtime/ffprobe.exe"
|
||||
},
|
||||
"event": {
|
||||
"keypoint_confidence_threshold": 0.4,
|
||||
"suspect_window_seconds": 0.5,
|
||||
"confirm_window_seconds": 1.8,
|
||||
"recovery_window_seconds": 2,
|
||||
"cooldown_seconds": 10,
|
||||
"require_rapid_drop": false,
|
||||
"require_lower_body": false,
|
||||
"horizontal_angle_threshold_degrees": 45
|
||||
},
|
||||
"artifacts": { "event_dir": "../artifacts/events" }
|
||||
}`
|
||||
}
|
||||
Reference in New Issue
Block a user