func BenchmarkServer(b *testing.B) { runtime.GOMAXPROCS(runtime.NumCPU()) port := 9001 a := dmx.NewDebugAdaptor() ctx, cancelF := context.WithCancel(context.Background()) err := MakeStateServer(ctx, port, a) if err != nil { log.Panicln("error in create server", err) } url := fmt.Sprintf("ws://localhost:%v/", port) d := websocket.Dialer{} conn, _, err := d.Dial(url, http.Header{}) if err != nil { log.Panicln("error in dial", err) } conn.ReadMessage() toggleSendOneDimmer := true var message []byte b.ResetTimer() for i := 0; i < b.N; i++ { b.StopTimer() prevLength := len(a.GetLastOutput()) if toggleSendOneDimmer { message = parse.OneSystemStateBytes } else { message = parse.InitialBytes } toggleSendOneDimmer = !toggleSendOneDimmer b.StartTimer() conn.WriteMessage(websocket.TextMessage, message) for { time.Sleep(time.Nanosecond) if len(a.GetLastOutput()) != prevLength { break } } } b.StopTimer() shouldCloseConnection(conn) cancelF() time.Sleep(time.Nanosecond) }
func MakeCliApp(ctx context.Context) *cli.App { app := cli.NewApp() app.Name = "subicul" app.Usage = "lighting server" app.Flags = []cli.Flag{ cli.IntFlag{ Name: "port", Value: 8080, Usage: "TCP port to listen on", EnvVar: "SUBICUL_PORT", }, cli.StringFlag{ Name: "path", Usage: "serial path for the enttec USB pro device", EnvVar: "SUBICUL_PATH", }, } app.Action = func(c *cli.Context) { var a dmx.Adaptor if c.String("path") == "" { a = dmx.NewDebugAdaptor() } else { a = dmx.NewUSBEnttecProAdaptor( "dmx", c.String("path"), ) } // od := lige.DummyDMXAdaptor{} err := MakeStateServer(ctx, c.Int("port"), a) if err != nil { log.Fatalln(err) } <-ctx.Done() } return app }
func TestServer(t *testing.T) { Convey("when i start the server", t, func() { port := 9002 a := dmx.NewDebugAdaptor() ctx, cancelF := context.WithCancel(context.Background()) err := MakeStateServer(ctx, port, a) So(err, ShouldBeNil) url := fmt.Sprintf("ws://localhost:%v/", port) d := websocket.Dialer{} Convey("and connect", func() { conn, _, err := d.Dial(url, http.Header{}) So(err, ShouldBeNil) Convey("it should return a default state", func() { shouldGet(conn, parse.InitialBytes) Convey("it shouldnt crash on an invalid state", func() { shouldSend(conn, []byte{}) }) Convey("it should take an updated state", func() { newState := parse.OneSystemStateBytes shouldSend(conn, newState) Convey("and it should output the new state", func() { time.Sleep(time.Second / 2) So(a.GetLastOutput(), ShouldResemble, map[int]byte{1: 255}) }) Convey("and reconnect", func() { shouldCloseConnection(conn) conn, _, err = d.Dial(url, http.Header{}) So(err, ShouldBeNil) Convey("it should return the same state", func() { shouldGet(conn, newState) }) }) Convey("and connect with another client", func() { conn2, _, err := d.Dial(url, http.Header{}) So(err, ShouldBeNil) Convey("it should initally recieve the state set by the first", func() { shouldGet(conn2, newState) Convey("and then when the first changes the state, it should get it", func() { secondNewState := parse.TwoSystemStateBytes shouldSend(conn, secondNewState) shouldGet(conn2, secondNewState) Convey("and vice versa", func() { thirdNewState := parse.ThreeSystemStateBytes shouldSend(conn2, thirdNewState) shouldGet(conn, thirdNewState) }) }) conn.WriteMessage(websocket.TextMessage, newState) }) Reset(func() { So(conn2.Close(), ShouldBeNil) }) }) }) }) Convey("output should be blank", func() { So(a.GetLastOutput(), ShouldResemble, map[int]byte{}) }) Reset(func() { shouldCloseConnection(conn) }) }) Reset(func() { cancelF() time.Sleep(time.Millisecond) So("subicul", testutils.ShouldNotBeRunningGoroutines) }) }) }