1
0
mirror of https://github.com/hybridgroup/gobot.git synced 2025-04-26 13:48:49 +08:00

196 lines
4.2 KiB
Go

package tello
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"sync"
"testing"
"time"
"gobot.io/x/gobot"
"gobot.io/x/gobot/gobottest"
)
var _ gobot.Driver = (*Driver)(nil)
type WriteCloserDoNothing struct{}
func (w *WriteCloserDoNothing) Write(p []byte) (n int, err error) {
return 0, nil
}
func (w *WriteCloserDoNothing) Close() error {
return nil
}
func TestTelloDriver(t *testing.T) {
d := NewDriver("8888")
gobottest.Assert(t, d.respPort, "8888")
}
func statusMessage(msgType uint16, msgAfter7 ...byte) []byte {
msg := make([]byte, 7, len(msgAfter7)+7)
msg[0] = messageStart
binary.LittleEndian.PutUint16(msg[5:7], msgType)
msg = append(msg, msgAfter7...)
return msg
}
func TestHandleResponse(t *testing.T) {
cc := []struct {
name string
msg io.Reader
events []gobot.Event
err error
}{
{
name: "[empty messsage]",
msg: bytes.NewReader(nil),
err: io.EOF,
},
{
name: "wifiMessage",
msg: bytes.NewReader(statusMessage(wifiMessage)),
events: []gobot.Event{{Name: WifiDataEvent}},
},
{
name: "lightMessage",
msg: bytes.NewReader(statusMessage(lightMessage)),
events: []gobot.Event{{Name: LightStrengthEvent}},
},
{
name: "logMessage",
msg: bytes.NewReader(statusMessage(logMessage)),
events: []gobot.Event{{Name: LogEvent}},
},
{
name: "timeCommand",
msg: bytes.NewReader(statusMessage(timeCommand)),
events: []gobot.Event{{Name: TimeEvent}},
},
{
name: "bounceCommand",
msg: bytes.NewReader(statusMessage(bounceCommand)),
events: []gobot.Event{{Name: BounceEvent}},
},
{
name: "takeoffCommand",
msg: bytes.NewReader(statusMessage(takeoffCommand)),
events: []gobot.Event{{Name: TakeoffEvent}},
},
{
name: "landCommand",
msg: bytes.NewReader(statusMessage(landCommand)),
events: []gobot.Event{{Name: LandingEvent}},
},
{
name: "palmLandCommand",
msg: bytes.NewReader(statusMessage(palmLandCommand)),
events: []gobot.Event{{Name: PalmLandingEvent}},
},
{
name: "flipCommand",
msg: bytes.NewReader(statusMessage(flipCommand)),
events: []gobot.Event{{Name: FlipEvent}},
},
{
name: "flightMessage",
msg: bytes.NewReader(statusMessage(flightMessage)),
events: []gobot.Event{{Name: FlightDataEvent}},
},
{
name: "exposureCommand",
msg: bytes.NewReader(statusMessage(exposureCommand)),
events: []gobot.Event{{Name: SetExposureEvent}},
},
{
name: "videoEncoderRateCommand",
msg: bytes.NewReader(statusMessage(videoEncoderRateCommand)),
events: []gobot.Event{{Name: SetVideoEncoderRateEvent}},
},
{
name: "ConnectedEvent",
msg: bytes.NewReader([]byte{0x63, 0x6f, 0x6e}),
events: []gobot.Event{{Name: ConnectedEvent}},
},
}
for _, c := range cc {
t.Run(c.name, func(t *testing.T) {
d := NewDriver("8888")
events := d.Subscribe()
err := d.handleResponse(c.msg)
if c.err != err {
t.Errorf("expected '%v' error, got: %v", c.err, err)
}
for i, cev := range c.events {
t.Run(fmt.Sprintf("event %d", i), func(t *testing.T) {
t.Logf("expect: %#v", cev)
select {
case ev, ok := <-events:
if !ok {
t.Error("subscription channel is closed")
}
if ev.Name != cev.Name {
t.Errorf("got: %s", ev.Name)
}
case <-time.After(time.Millisecond):
t.Error("subscription channel seems empty")
}
})
}
})
}
}
func TestHaltShouldTerminateAllTheRelatedGoroutines(t *testing.T) {
d := NewDriver("8888")
d.cmdConn = &WriteCloserDoNothing{}
var wg sync.WaitGroup
wg.Add(3)
d.addDoneChReaderCount(1)
go func() {
defer d.addDoneChReaderCount(-1)
<-d.doneCh
wg.Done()
fmt.Println("Done routine 1.")
}()
d.addDoneChReaderCount(1)
go func() {
defer d.addDoneChReaderCount(-1)
<-d.doneCh
wg.Done()
fmt.Println("Done routine 2.")
}()
d.addDoneChReaderCount(1)
go func() {
defer d.addDoneChReaderCount(-1)
<-d.doneCh
wg.Done()
fmt.Println("Done routine 3.")
}()
d.Halt()
wg.Wait()
gobottest.Assert(t, d.doneChReaderCount, int32(0))
}
func TestHaltNotWaitForeverWhenCalledMultipleTimes(t *testing.T) {
d := NewDriver("8888")
d.cmdConn = &WriteCloserDoNothing{}
d.Halt()
d.Halt()
d.Halt()
}