mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-26 13:48:49 +08:00
196 lines
4.2 KiB
Go
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()
|
|
}
|