166 lines
3.5 KiB
Go
166 lines
3.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"net"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"frame"
|
|
"gocv.io/x/gocv"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
frame.SetAuthToken("test-token")
|
|
m.Run()
|
|
}
|
|
|
|
func startClipListener(t *testing.T) (string, chan frame.Clip) {
|
|
t.Helper()
|
|
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
|
if err != nil {
|
|
t.Fatalf("listen: %v", err)
|
|
}
|
|
ch := make(chan frame.Clip, 1)
|
|
go func() {
|
|
conn, err := ln.Accept()
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer conn.Close()
|
|
br := bufio.NewReader(conn)
|
|
if line, err := br.ReadString('\n'); err != nil || strings.TrimSpace(line) != "test-token" {
|
|
return
|
|
}
|
|
clp, err := frame.DecodeWireClip(br)
|
|
if err == nil {
|
|
ch <- clp
|
|
}
|
|
ln.Close()
|
|
}()
|
|
return ln.Addr().String(), ch
|
|
}
|
|
|
|
func makeTestClipBytes(t *testing.T, fill0, fill1 float64) frame.Clip {
|
|
t.Helper()
|
|
mat := gocv.NewMatWithSize(4, 4, gocv.MatTypeCV8UC1)
|
|
defer mat.Close()
|
|
|
|
mat.SetTo(gocv.NewScalar(fill0, 0, 0, 0))
|
|
bytes0 := mat.ToBytes()
|
|
|
|
mat.SetTo(gocv.NewScalar(fill1, 0, 0, 0))
|
|
bytes1 := mat.ToBytes()
|
|
|
|
return frame.Clip{
|
|
PixelMats: [][]byte{bytes0, bytes1},
|
|
Width: 4,
|
|
Height: 4,
|
|
Types: gocv.MatTypeCV8UC1,
|
|
Channels: 1,
|
|
Guids: [][]byte{{0xaa}, {0xbb}},
|
|
Timestamps: []uint64{100, 200},
|
|
}
|
|
}
|
|
|
|
func TestProcessClip_ForwardsToTerp(t *testing.T) {
|
|
clip := makeTestClipBytes(t, 0, 255)
|
|
addr, received := startClipListener(t)
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
processClip(clip, addr, 30, "")
|
|
}()
|
|
wg.Wait()
|
|
|
|
select {
|
|
case got := <-received:
|
|
if len(got.PixelMats) != 2 {
|
|
t.Errorf("got %d frames, want 2", len(got.PixelMats))
|
|
}
|
|
if len(got.Comparisons) != 1 {
|
|
t.Errorf("got %d comparisons, want 1", len(got.Comparisons))
|
|
}
|
|
if got.Comparisons[0].PixelsChanged == 0 {
|
|
t.Error("expected non-zero pixel change between different frames")
|
|
}
|
|
case <-time.After(3 * time.Second):
|
|
t.Fatal("timed out waiting for forwarded clip")
|
|
}
|
|
}
|
|
|
|
func TestProcessClip_DropsNoMotion(t *testing.T) {
|
|
clip := makeTestClipBytes(t, 100, 100)
|
|
addr, received := startClipListener(t)
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
processClip(clip, addr, 30, "")
|
|
}()
|
|
wg.Wait()
|
|
|
|
select {
|
|
case got := <-received:
|
|
t.Errorf("no-motion clip should have been dropped locally, got one with %d changed pixels",
|
|
got.Comparisons[0].PixelsChanged)
|
|
case <-time.After(500 * time.Millisecond):
|
|
}
|
|
}
|
|
|
|
func TestProcessClip_WithPassphrase(t *testing.T) {
|
|
clip := makeTestClipBytes(t, 0, 128)
|
|
|
|
frames := clip.Sublimate()
|
|
for i := range frames {
|
|
frames[i].PixelBytes = clip.PixelMats[i]
|
|
if err := frames[i].Encrypt("test-passphrase"); err != nil {
|
|
t.Fatalf("pre-encrypt frame %d: %v", i, err)
|
|
}
|
|
clip.PixelMats[i] = frames[i].PixelBytes
|
|
}
|
|
|
|
addr, received := startClipListener(t)
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
processClip(clip, addr, 30, "test-passphrase")
|
|
}()
|
|
wg.Wait()
|
|
|
|
select {
|
|
case got := <-received:
|
|
if err := got.Decrypt("test-passphrase"); err != nil {
|
|
t.Errorf("decrypt of forwarded clip failed: %v", err)
|
|
}
|
|
if len(got.Comparisons) != 1 {
|
|
t.Errorf("got %d comparisons, want 1", len(got.Comparisons))
|
|
}
|
|
case <-time.After(3 * time.Second):
|
|
t.Fatal("timed out waiting for encrypted clip")
|
|
}
|
|
}
|
|
|
|
func TestProcessClip_InvalidAddress(t *testing.T) {
|
|
clip := makeTestClipBytes(t, 0, 255)
|
|
|
|
done := make(chan struct{}, 1)
|
|
go func() {
|
|
processClip(clip, "127.0.0.1:1", 30, "")
|
|
close(done)
|
|
}()
|
|
|
|
select {
|
|
case <-done:
|
|
case <-time.After(10 * time.Second):
|
|
t.Fatal("processClip hung retrying an unreachable terp")
|
|
}
|
|
}
|