2019-12-18 23:08:07 +00:00
|
|
|
package camera
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2019-12-31 16:14:05 +00:00
|
|
|
"github.com/cyrilix/robocar-protobuf/go/events"
|
|
|
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
|
|
|
"github.com/golang/protobuf/proto"
|
2021-10-12 16:26:57 +00:00
|
|
|
"go.uber.org/zap"
|
2019-12-18 23:08:07 +00:00
|
|
|
"gocv.io/x/gocv"
|
|
|
|
"image/jpeg"
|
2019-12-31 16:14:05 +00:00
|
|
|
"sync"
|
2019-12-18 23:08:07 +00:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
type fakeVideoSource struct {
|
2019-12-31 16:14:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f fakeVideoSource) Close() error {
|
|
|
|
return nil
|
2019-12-18 23:08:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f fakeVideoSource) Read(dest *gocv.Mat) bool {
|
|
|
|
img := gocv.IMRead("testdata/img.jpg", gocv.IMReadUnchanged)
|
|
|
|
if img.Total() == 0 {
|
2021-10-12 16:26:57 +00:00
|
|
|
zap.S().Info("image read is empty")
|
2019-12-18 23:08:07 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
img.CopyTo(dest)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestOpencvCameraPart(t *testing.T) {
|
2019-12-31 16:14:05 +00:00
|
|
|
var muPubEvents sync.Mutex
|
|
|
|
publishedEvents := make(map[string]*[]byte)
|
|
|
|
oldPublish := publish
|
|
|
|
defer func() {
|
2020-01-28 22:30:38 +00:00
|
|
|
publish = oldPublish
|
|
|
|
}()
|
2021-09-09 21:19:39 +00:00
|
|
|
waitEvent := sync.WaitGroup{}
|
2021-11-01 10:59:22 +00:00
|
|
|
waitEvent.Add(2)
|
2020-01-28 22:30:38 +00:00
|
|
|
publish = func(_ mqtt.Client, topic string, payload *[]byte) {
|
2019-12-31 16:14:05 +00:00
|
|
|
muPubEvents.Lock()
|
|
|
|
defer muPubEvents.Unlock()
|
|
|
|
publishedEvents[topic] = payload
|
2021-09-09 21:19:39 +00:00
|
|
|
waitEvent.Done()
|
2019-12-31 16:14:05 +00:00
|
|
|
}
|
|
|
|
|
2019-12-18 23:08:07 +00:00
|
|
|
const topic = "topic/test/camera"
|
2021-11-01 10:59:22 +00:00
|
|
|
const topicRoi = "topic/test/camera-roi"
|
2019-12-18 23:08:07 +00:00
|
|
|
imgBuffer := gocv.NewMat()
|
|
|
|
|
|
|
|
part := OpencvCameraPart{
|
2020-01-28 22:30:38 +00:00
|
|
|
client: nil,
|
2019-12-18 23:08:07 +00:00
|
|
|
vc: fakeVideoSource{},
|
|
|
|
topic: topic,
|
2021-11-01 10:59:22 +00:00
|
|
|
topicRoi: topicRoi,
|
2021-09-09 21:19:39 +00:00
|
|
|
publishFrequency: 2, // Send 2 img/s for tests
|
2019-12-18 23:08:07 +00:00
|
|
|
imgBuffered: &imgBuffer,
|
2021-11-01 10:59:22 +00:00
|
|
|
horizon: 30,
|
2019-12-18 23:08:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
go part.Start()
|
2021-09-09 21:19:39 +00:00
|
|
|
waitEvent.Wait()
|
2019-12-18 23:08:07 +00:00
|
|
|
|
2021-11-01 10:59:22 +00:00
|
|
|
for _, tpc := range []string{topic, topicRoi} {
|
2019-12-31 16:14:05 +00:00
|
|
|
|
2021-11-01 10:59:22 +00:00
|
|
|
var frameMsg events.FrameMessage
|
|
|
|
muPubEvents.Lock()
|
|
|
|
err := proto.Unmarshal(*(publishedEvents[tpc]), &frameMsg)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("unable to unmarshal published frame to topic %v", tpc)
|
|
|
|
}
|
|
|
|
muPubEvents.Unlock()
|
2020-01-03 16:41:42 +00:00
|
|
|
|
2021-11-01 10:59:22 +00:00
|
|
|
if frameMsg.GetId().GetName() != "camera" {
|
|
|
|
t.Errorf("bad name frame: %v, wants %v", frameMsg.GetId().GetName(), "camera")
|
|
|
|
}
|
|
|
|
if len(frameMsg.GetId().GetId()) != 13 {
|
|
|
|
t.Errorf("bad id length: %v, wants %v", len(frameMsg.GetId().GetId()), 13)
|
|
|
|
}
|
|
|
|
|
|
|
|
if frameMsg.GetId().GetCreatedAt() == nil {
|
|
|
|
t.Errorf("missin CreatedAt field")
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = jpeg.Decode(bytes.NewReader(frameMsg.GetFrame()))
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("image published can't be decoded: %v", err)
|
|
|
|
}
|
2019-12-18 23:08:07 +00:00
|
|
|
|
2021-11-01 10:59:22 +00:00
|
|
|
// Uncomment to debug image cropping
|
|
|
|
/*
|
|
|
|
dir, f := path.Split(fmt.Sprintf("/tmp/%s.jpg", tpc))
|
|
|
|
os.MkdirAll(dir, os.FileMode(0755))
|
|
|
|
err = ioutil.WriteFile(path.Join(dir, f), frameMsg.GetFrame(), os.FileMode(0644) )
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("unable to write image for topic %s: %v", tpc, err)
|
|
|
|
}
|
|
|
|
*/
|
2019-12-18 23:08:07 +00:00
|
|
|
}
|
|
|
|
}
|