gobot.io/x/gobot/v2@v2.1.0/platforms/dji/tello/driver_test.go (about) 1 package tello 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "io" 8 "sync" 9 "testing" 10 "time" 11 12 "gobot.io/x/gobot/v2" 13 "gobot.io/x/gobot/v2/gobottest" 14 ) 15 16 var _ gobot.Driver = (*Driver)(nil) 17 18 type WriteCloserDoNothing struct{} 19 20 func (w *WriteCloserDoNothing) Write(p []byte) (n int, err error) { 21 return 0, nil 22 } 23 func (w *WriteCloserDoNothing) Close() error { 24 return nil 25 } 26 27 func TestTelloDriver(t *testing.T) { 28 d := NewDriver("8888") 29 30 gobottest.Assert(t, d.respPort, "8888") 31 } 32 33 func statusMessage(msgType uint16, msgAfter7 ...byte) []byte { 34 msg := make([]byte, 7, len(msgAfter7)+7) 35 msg[0] = messageStart 36 binary.LittleEndian.PutUint16(msg[5:7], msgType) 37 msg = append(msg, msgAfter7...) 38 return msg 39 } 40 41 func TestHandleResponse(t *testing.T) { 42 cc := []struct { 43 name string 44 msg io.Reader 45 events []gobot.Event 46 err error 47 }{ 48 { 49 name: "[empty messsage]", 50 msg: bytes.NewReader(nil), 51 err: io.EOF, 52 }, 53 { 54 name: "wifiMessage", 55 msg: bytes.NewReader(statusMessage(wifiMessage)), 56 events: []gobot.Event{{Name: WifiDataEvent}}, 57 }, 58 { 59 name: "lightMessage", 60 msg: bytes.NewReader(statusMessage(lightMessage)), 61 events: []gobot.Event{{Name: LightStrengthEvent}}, 62 }, 63 { 64 name: "logMessage", 65 msg: bytes.NewReader(statusMessage(logMessage)), 66 events: []gobot.Event{{Name: LogEvent}}, 67 }, 68 { 69 name: "timeCommand", 70 msg: bytes.NewReader(statusMessage(timeCommand)), 71 events: []gobot.Event{{Name: TimeEvent}}, 72 }, 73 { 74 name: "bounceCommand", 75 msg: bytes.NewReader(statusMessage(bounceCommand)), 76 events: []gobot.Event{{Name: BounceEvent}}, 77 }, 78 { 79 name: "takeoffCommand", 80 msg: bytes.NewReader(statusMessage(takeoffCommand)), 81 events: []gobot.Event{{Name: TakeoffEvent}}, 82 }, 83 { 84 name: "landCommand", 85 msg: bytes.NewReader(statusMessage(landCommand)), 86 events: []gobot.Event{{Name: LandingEvent}}, 87 }, 88 { 89 name: "palmLandCommand", 90 msg: bytes.NewReader(statusMessage(palmLandCommand)), 91 events: []gobot.Event{{Name: PalmLandingEvent}}, 92 }, 93 { 94 name: "flipCommand", 95 msg: bytes.NewReader(statusMessage(flipCommand)), 96 events: []gobot.Event{{Name: FlipEvent}}, 97 }, 98 { 99 name: "flightMessage", 100 msg: bytes.NewReader(statusMessage(flightMessage)), 101 events: []gobot.Event{{Name: FlightDataEvent}}, 102 }, 103 { 104 name: "exposureCommand", 105 msg: bytes.NewReader(statusMessage(exposureCommand)), 106 events: []gobot.Event{{Name: SetExposureEvent}}, 107 }, 108 { 109 name: "videoEncoderRateCommand", 110 msg: bytes.NewReader(statusMessage(videoEncoderRateCommand)), 111 events: []gobot.Event{{Name: SetVideoEncoderRateEvent}}, 112 }, 113 { 114 name: "ConnectedEvent", 115 msg: bytes.NewReader([]byte{0x63, 0x6f, 0x6e}), 116 events: []gobot.Event{{Name: ConnectedEvent}}, 117 }, 118 } 119 120 for _, c := range cc { 121 t.Run(c.name, func(t *testing.T) { 122 d := NewDriver("8888") 123 events := d.Subscribe() 124 err := d.handleResponse(c.msg) 125 if c.err != err { 126 t.Errorf("expected '%v' error, got: %v", c.err, err) 127 } 128 for i, cev := range c.events { 129 t.Run(fmt.Sprintf("event %d", i), func(t *testing.T) { 130 t.Logf("expect: %#v", cev) 131 select { 132 case ev, ok := <-events: 133 if !ok { 134 t.Error("subscription channel is closed") 135 } 136 if ev.Name != cev.Name { 137 t.Errorf("got: %s", ev.Name) 138 } 139 case <-time.After(time.Millisecond): 140 t.Error("subscription channel seems empty") 141 } 142 }) 143 } 144 }) 145 } 146 } 147 148 func TestHaltShouldTerminateAllTheRelatedGoroutines(t *testing.T) { 149 d := NewDriver("8888") 150 d.cmdConn = &WriteCloserDoNothing{} 151 152 var wg sync.WaitGroup 153 wg.Add(3) 154 155 d.addDoneChReaderCount(1) 156 go func() { 157 <-d.doneCh 158 d.addDoneChReaderCount(-1) 159 wg.Done() 160 fmt.Println("Done routine 1.") 161 }() 162 163 d.addDoneChReaderCount(1) 164 go func() { 165 <-d.doneCh 166 d.addDoneChReaderCount(-1) 167 wg.Done() 168 fmt.Println("Done routine 2.") 169 }() 170 171 d.addDoneChReaderCount(1) 172 go func() { 173 <-d.doneCh 174 d.addDoneChReaderCount(-1) 175 wg.Done() 176 fmt.Println("Done routine 3.") 177 }() 178 179 d.Halt() 180 wg.Wait() 181 182 gobottest.Assert(t, d.doneChReaderCount, int32(0)) 183 } 184 185 func TestHaltNotWaitForeverWhenCalledMultipleTimes(t *testing.T) { 186 d := NewDriver("8888") 187 d.cmdConn = &WriteCloserDoNothing{} 188 189 d.Halt() 190 d.Halt() 191 d.Halt() 192 }