Files

87 lines
2.9 KiB
Go

package callruntime
import (
"bytes"
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"os"
"path/filepath"
"testing"
"git.ipao.vip/rogee/go-sip/internal/callflow"
)
func TestConversationRecordingFactsMatchFiles(t *testing.T) {
directory := t.TempDir()
incoming := [][]byte{{1, 0, 2, 0}, make([]byte, 32000)}
outgoing := [][]byte{{4, 0}, {5, 0, 6, 0}}
in, out, err := persistConversationRecordings(directory, "channel/with:separators", callflow.Result{InboundTurns: incoming, OutboundTurns: outgoing})
if err != nil {
t.Fatal(err)
}
if len(in) != 2 || len(out) != 2 {
t.Fatal("lost recording segments")
}
for side, facts := range [][]RecordingFact{in, out} {
expected := [][][]byte{incoming, outgoing}[side]
for index, fact := range facts {
if filepath.Dir(fact.Path) != directory {
t.Fatal("recording escaped directory")
}
raw, err := os.ReadFile(fact.Path)
if err != nil {
t.Fatal(err)
}
sum := sha256.Sum256(raw)
if fact.SHA256 != hex.EncodeToString(sum[:]) || fact.Bytes != len(raw) || fact.DurationMS != int64(len(expected[index]))*1000/32000 {
t.Fatal("recording fact does not match content")
}
if string(raw[:4]) != "RIFF" || string(raw[8:12]) != "WAVE" || string(raw[36:40]) != "data" {
t.Fatal("invalid WAV header")
}
if binary.LittleEndian.Uint32(raw[24:28]) != 16000 || binary.LittleEndian.Uint32(raw[40:44]) != uint32(len(expected[index])) || !bytes.Equal(raw[44:], expected[index]) {
t.Fatal("incorrect WAV format or payload")
}
info, err := os.Stat(fact.Path)
if err != nil {
t.Fatal(err)
}
if info.Mode().Perm() != 0600 {
t.Fatal("recording is not restricted")
}
}
}
if in[0].Segment != "inbound_turn_01" || out[0].Segment != "outbound_segment_00" {
t.Fatal("segment identities changed")
}
}
func TestRecordingFailuresAreExplicit(t *testing.T) {
directory := t.TempDir()
if err := writeWAV(filepath.Join(directory, "odd.wav"), []byte{1}, 16000); err == nil {
t.Fatal("odd PCM accepted")
}
blocker := filepath.Join(directory, "file")
if err := os.WriteFile(blocker, []byte("blocked"), 0600); err != nil {
t.Fatal(err)
}
if _, _, err := persistConversationRecordings(filepath.Join(blocker, "child"), "channel", callflow.Result{InboundTurns: [][]byte{{0, 0}}}); err == nil {
t.Fatal("directory creation error hidden")
}
for _, flow := range []callflow.Result{{InboundTurns: [][]byte{{1}}}, {OutboundTurns: [][]byte{{1}}}} {
if _, _, err := persistConversationRecordings(directory, "channel", flow); err == nil {
t.Fatal("invalid segment accepted")
}
}
for _, dir := range []string{"", directory} {
in, out, err := persistConversationRecordings(dir, "empty", callflow.Result{})
if err != nil || len(in) != 0 || len(out) != 0 {
t.Fatal("empty recording produced facts")
}
}
if _, _, err := fileDigestAndSize(filepath.Join(directory, "missing.wav")); err == nil {
t.Fatal("missing recording silently returned a checksum")
}
}