mirror of
https://github.com/hybridgroup/gobot.git
synced 2025-04-24 13:48:49 +08:00
Add SSE test coverage
Add a Stream type that handle the request to /events/:event and write tests for event stream Add a test for the events/:event endpoint that actually tests the endpoint response Using <-time.After in a 'select' creates one channel every time, let's use a time.Timer instead so that we reuse the same channel
This commit is contained in:
parent
bc8bb36f8f
commit
1f09fb021b
11
api/api.go
11
api/api.go
@ -224,15 +224,12 @@ func (a *API) robotDevice(res http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// robotDeviceEvent returns device event route handler.
|
||||
// Creates an event stream connection
|
||||
// and queries event data to be written when received
|
||||
func (a *API) robotDeviceEvent(res http.ResponseWriter, req *http.Request) {
|
||||
f, _ := res.(http.Flusher)
|
||||
c, _ := res.(http.CloseNotifier)
|
||||
|
||||
dataChan := make(chan string)
|
||||
closer := c.CloseNotify()
|
||||
msg := make(chan string)
|
||||
|
||||
res.Header().Set("Content-Type", "text/event-stream")
|
||||
res.Header().Set("Cache-Control", "no-cache")
|
||||
@ -243,12 +240,12 @@ func (a *API) robotDeviceEvent(res http.ResponseWriter, req *http.Request) {
|
||||
Event(req.URL.Query().Get(":event")); event != nil {
|
||||
gobot.On(event, func(data interface{}) {
|
||||
d, _ := json.Marshal(data)
|
||||
msg <- string(d)
|
||||
dataChan <- string(d)
|
||||
})
|
||||
|
||||
for {
|
||||
select {
|
||||
case data := <-msg:
|
||||
case data := <-dataChan:
|
||||
fmt.Fprintf(res, "data: %v\n\n", data)
|
||||
f.Flush()
|
||||
case <-closer:
|
||||
@ -258,7 +255,7 @@ func (a *API) robotDeviceEvent(res http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
} else {
|
||||
a.writeJSON(map[string]interface{}{
|
||||
"error": errors.New("No Event found with the name " + req.URL.Query().Get(":event")),
|
||||
"error": "No Event found with the name " + req.URL.Query().Get(":event"),
|
||||
}, res)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -8,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hybridgroup/gobot"
|
||||
)
|
||||
@ -363,6 +365,55 @@ func TestRobotConnection(t *testing.T) {
|
||||
gobot.Assert(t, body["error"], "No Connection found with the name UnknownConnection1")
|
||||
}
|
||||
|
||||
func TestRobotDeviceEvent(t *testing.T) {
|
||||
a := initTestAPI()
|
||||
server := httptest.NewServer(a)
|
||||
defer server.Close()
|
||||
|
||||
eventsUrl := "/api/robots/Robot1/devices/Device1/events/"
|
||||
|
||||
// known event
|
||||
respc := make(chan *http.Response, 1)
|
||||
go func() {
|
||||
resp, _ := http.Get(server.URL + eventsUrl + "TestEvent")
|
||||
respc <- resp
|
||||
}()
|
||||
|
||||
event := a.gobot.Robot("Robot1").
|
||||
Device("Device1").(gobot.Eventer).
|
||||
Event("TestEvent")
|
||||
|
||||
go func() {
|
||||
time.Sleep(time.Millisecond * 5)
|
||||
gobot.Publish(event, "event-data")
|
||||
}()
|
||||
|
||||
done := false
|
||||
timer := time.NewTimer(time.Millisecond * 10)
|
||||
|
||||
for !done {
|
||||
select {
|
||||
case resp := <-respc:
|
||||
reader := bufio.NewReader(resp.Body)
|
||||
data, _ := reader.ReadString('\n')
|
||||
gobot.Assert(t, data, "data: \"event-data\"\n")
|
||||
done = true
|
||||
case <-timer.C:
|
||||
t.Error("Not receiving data")
|
||||
done = true
|
||||
}
|
||||
}
|
||||
|
||||
server.CloseClientConnections()
|
||||
|
||||
// unknown event
|
||||
response, _ := http.Get(server.URL + eventsUrl + "UnknownEvent")
|
||||
|
||||
var body map[string]interface{}
|
||||
json.NewDecoder(response.Body).Decode(&body)
|
||||
gobot.Assert(t, body["error"], "No Event found with the name UnknownEvent")
|
||||
}
|
||||
|
||||
func TestAPIRouter(t *testing.T) {
|
||||
a := initTestAPI()
|
||||
|
||||
|
@ -25,6 +25,7 @@ type testDriver struct {
|
||||
pin string
|
||||
connection gobot.Connection
|
||||
gobot.Commander
|
||||
gobot.Eventer
|
||||
}
|
||||
|
||||
func (t *testDriver) Start() (errs []error) { return }
|
||||
@ -38,9 +39,12 @@ func newTestDriver(adaptor *testAdaptor, name string, pin string) *testDriver {
|
||||
name: name,
|
||||
connection: adaptor,
|
||||
pin: pin,
|
||||
Eventer: gobot.NewEventer(),
|
||||
Commander: gobot.NewCommander(),
|
||||
}
|
||||
|
||||
t.AddEvent("TestEvent")
|
||||
|
||||
t.AddCommand("TestDriverCommand", func(params map[string]interface{}) interface{} {
|
||||
name := params["name"].(string)
|
||||
return fmt.Sprintf("hello %v", name)
|
||||
|
@ -18,7 +18,6 @@ type testDriver struct {
|
||||
name string
|
||||
pin string
|
||||
connection Connection
|
||||
Eventer
|
||||
Commander
|
||||
}
|
||||
|
||||
@ -36,24 +35,14 @@ func newTestDriver(adaptor *testAdaptor, name string, pin string) *testDriver {
|
||||
name: name,
|
||||
connection: adaptor,
|
||||
pin: pin,
|
||||
Eventer: NewEventer(),
|
||||
Commander: NewCommander(),
|
||||
}
|
||||
|
||||
t.AddEvent("DriverCommand")
|
||||
|
||||
t.AddCommand("DriverCommand", func(params map[string]interface{}) interface{} {
|
||||
return t.DriverCommand()
|
||||
})
|
||||
t.AddCommand("DriverCommand", func(params map[string]interface{}) interface{} { return nil })
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *testDriver) DriverCommand() string {
|
||||
Publish(t.Event("DriverCommand"), "DriverCommand")
|
||||
return "DriverCommand"
|
||||
}
|
||||
|
||||
type testAdaptor struct {
|
||||
name string
|
||||
port string
|
||||
|
Loading…
x
Reference in New Issue
Block a user