Files

86 lines
3.6 KiB
Go

package admission_test
import (
"context"
"crypto/rand"
"encoding/base64"
"os"
"testing"
coreService "github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"git.ilapage.cn/ila/yovision/Sense/server/app/sense/admission"
"git.ilapage.cn/ila/yovision/Sense/server/app/sense/credential"
deviceModels "git.ilapage.cn/ila/yovision/Sense/server/app/sense/device/models"
"git.ilapage.cn/ila/yovision/Sense/server/app/sense/onvif"
"git.ilapage.cn/ila/yovision/Sense/server/app/sense/rtsp"
)
type onvifFixture struct{}
func (onvifFixture) Profiles(context.Context, string, onvif.Credential) ([]onvif.Profile, error) {
return []onvif.Profile{{Token: "main", Name: "主码流", Width: 1920, Height: 1080, Encoding: "H264", StreamURI: "rtsp://192.0.2.10/main"}, {Token: "sub", Name: "子码流", Width: 640, Height: 360, Encoding: "H264", StreamURI: "rtsp://192.0.2.10/sub"}}, nil
}
type rtspFixture struct{}
func (rtspFixture) Verify(context.Context, string, rtsp.Credential) (rtsp.Result, error) {
return rtsp.Result{Status: "ready", Detail: "合成 RTSP 可用"}, nil
}
func TestProfilesSurvivePostgreSQLReopen(t *testing.T) {
dsn := os.Getenv("SENSE_ADMISSION_TEST_DATABASE_URL")
if dsn == "" {
t.Skip("set SENSE_ADMISSION_TEST_DATABASE_URL to an isolated PostgreSQL database")
}
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
if err = db.AutoMigrate(&deviceModels.Device{}, &credential.DeviceCredential{}, &admission.Result{}, &admission.Profile{}); err != nil {
t.Fatal(err)
}
deviceID := "issue66-postgres-device"
db.Where("device_id = ?", deviceID).Delete(&admission.Profile{})
db.Where("device_id = ?", deviceID).Delete(&admission.Result{})
db.Where("device_id = ?", deviceID).Delete(&credential.DeviceCredential{})
db.Where("id = ?", deviceID).Delete(&deviceModels.Device{})
t.Cleanup(func() {
db.Where("device_id = ?", deviceID).Delete(&admission.Profile{})
db.Where("device_id = ?", deviceID).Delete(&admission.Result{})
db.Where("device_id = ?", deviceID).Delete(&credential.DeviceCredential{})
db.Where("id = ?", deviceID).Delete(&deviceModels.Device{})
})
key := make([]byte, 32)
if _, err = rand.Read(key); err != nil {
t.Fatal(err)
}
t.Setenv(credential.EnvironmentKey, base64.StdEncoding.EncodeToString(key))
vault, _ := credential.NewVault(key)
device := deviceModels.Device{ID: deviceID, Name: "重启持久化摄像机", Modality: deviceModels.ModalityVideo, Status: deviceModels.StatusPending, AdapterStatus: deviceModels.AdapterReady, Version: 1}
if err = db.Create(&device).Error; err != nil {
t.Fatal(err)
}
for _, purpose := range []string{credential.PurposeONVIF, credential.PurposeRTSP} {
cipher, _ := vault.Encrypt(deviceID, purpose, "synthetic-user", "synthetic-password")
if err = db.Create(&credential.DeviceCredential{DeviceID: deviceID, Purpose: purpose, Ciphertext: cipher, KeyVersion: credential.Version()}).Error; err != nil {
t.Fatal(err)
}
}
service := admission.Service{Service: coreService.Service{Orm: db}, ONVIF: onvifFixture{}, RTSP: rtspFixture{}}
if _, err = service.Probe(context.Background(), admission.ProbeRequest{DeviceID: deviceID, Address: "http://192.0.2.10/onvif", Version: 1}); err != nil {
t.Fatal(err)
}
reopened, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
t.Fatal(err)
}
restarted := admission.Service{Service: coreService.Service{Orm: reopened}}
saved, err := restarted.Get(deviceID)
if err != nil || saved.Status != "ready" || len(saved.Profiles) != 2 {
t.Fatalf("saved=%#v err=%v", saved, err)
}
}