ecal-sock_test.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * EliasDB
  3. *
  4. * Copyright 2016 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the Mozilla Public
  7. * License, v. 2.0. If a copy of the MPL was not distributed with this
  8. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. */
  10. package v1
  11. import (
  12. "fmt"
  13. "strings"
  14. "sync"
  15. "testing"
  16. "time"
  17. "devt.de/krotik/common/errorutil"
  18. "devt.de/krotik/ecal/cli/tool"
  19. "devt.de/krotik/ecal/engine"
  20. "devt.de/krotik/ecal/util"
  21. "devt.de/krotik/eliasdb/api"
  22. "github.com/gorilla/websocket"
  23. )
  24. func TestECALSockConnectionErrors(t *testing.T) {
  25. queryURL := "http://localhost" + TESTPORT + EndpointECALSock
  26. _, _, res := sendTestRequest(queryURL+"foo?bar=123", "GET", nil)
  27. if res != `Bad Request
  28. websocket: the client is not using the websocket protocol: 'upgrade' token not found in 'Connection' header` {
  29. t.Error("Unexpected response:", res)
  30. return
  31. }
  32. oldSI := api.SI
  33. api.SI = nil
  34. defer func() {
  35. api.SI = oldSI
  36. }()
  37. _, _, res = sendTestRequest(queryURL+"foo?bar=123", "GET", nil)
  38. if res != `Resource was not found` {
  39. t.Error("Unexpected response:", res)
  40. return
  41. }
  42. }
  43. func TestECALSock(t *testing.T) {
  44. queryURL := "ws://localhost" + TESTPORT + EndpointECALSock + "foo?bar=123"
  45. lastUUID := ""
  46. var lastDataEvent *engine.Event
  47. resetSI()
  48. api.SI.Interpreter = tool.NewCLIInterpreter()
  49. testScriptDir := "testscripts"
  50. api.SI.Interpreter.Dir = &testScriptDir
  51. errorutil.AssertOk(api.SI.Interpreter.CreateRuntimeProvider("eliasdb-runtime"))
  52. logger := util.NewMemoryLogger(10)
  53. api.SI.Interpreter.RuntimeProvider.Logger = logger
  54. errorutil.AssertOk(api.SI.Interpreter.RuntimeProvider.Processor.AddRule(&engine.Rule{
  55. Name: "WebSocketRegister", // Name
  56. Desc: "Handles a websocket communication", // Description
  57. KindMatch: []string{"db.web.sock"}, // Kind match
  58. ScopeMatch: []string{},
  59. StateMatch: nil,
  60. Priority: 0,
  61. SuppressionList: nil,
  62. Action: func(p engine.Processor, m engine.Monitor, e *engine.Event, tid uint64) error {
  63. lastUUID = fmt.Sprint(e.State()["commID"])
  64. return nil
  65. },
  66. }))
  67. wg := &sync.WaitGroup{}
  68. errorutil.AssertOk(api.SI.Interpreter.RuntimeProvider.Processor.AddRule(&engine.Rule{
  69. Name: "WebSocketHandler", // Name
  70. Desc: "Handles a websocket communication", // Description
  71. KindMatch: []string{"db.web.sock.data"}, // Kind match
  72. ScopeMatch: []string{},
  73. StateMatch: nil,
  74. Priority: 0,
  75. SuppressionList: nil,
  76. Action: func(p engine.Processor, m engine.Monitor, e *engine.Event, tid uint64) error {
  77. lastDataEvent = e
  78. wg.Done()
  79. return nil
  80. },
  81. }))
  82. api.SI.Interpreter.RuntimeProvider.Processor.Start()
  83. defer api.SI.Interpreter.RuntimeProvider.Processor.Finish()
  84. // Now do the actual testing
  85. c, _, err := websocket.DefaultDialer.Dial(queryURL, nil)
  86. if err != nil {
  87. t.Error("Could not open websocket:", err)
  88. return
  89. }
  90. _, message, err := c.ReadMessage()
  91. if msg := formatJSONString(string(message)); err != nil || msg != `{
  92. "type": "init_success",
  93. "payload": {}
  94. }` {
  95. t.Error("Unexpected response:", msg, err)
  96. return
  97. }
  98. err = c.WriteMessage(websocket.TextMessage, []byte("buu"))
  99. if err != nil {
  100. t.Error("Could not send message:", err)
  101. return
  102. }
  103. _, message, err = c.ReadMessage()
  104. if msg := formatJSONString(string(message)); err != nil || msg != `{
  105. "commID": "`+lastUUID+`",
  106. "payload": {
  107. "error": "invalid character 'b' looking for beginning of value"
  108. },
  109. "type": "data"
  110. }` {
  111. t.Error("Unexpected response:", msg, err)
  112. return
  113. }
  114. wg.Add(1)
  115. err = c.WriteMessage(websocket.TextMessage, []byte(`{"foo":"bar"}`))
  116. if err != nil {
  117. t.Error("Could not send message:", err)
  118. return
  119. }
  120. wg.Wait()
  121. if data := lastDataEvent.State()["data"]; err != nil || fmt.Sprint(data) != `map[foo:bar]` {
  122. t.Error("Unexpected response:", data, err)
  123. return
  124. }
  125. err = c.WriteMessage(websocket.TextMessage, []byte(`{"close":true}`))
  126. if err != nil {
  127. t.Error("Could not send message:", err)
  128. return
  129. }
  130. // Reset the connection and provoke an error
  131. c, _, err = websocket.DefaultDialer.Dial(queryURL, nil)
  132. if err != nil {
  133. t.Error("Could not open websocket:", err)
  134. return
  135. }
  136. c.Close()
  137. for {
  138. if logger.Size() > 0 {
  139. break
  140. }
  141. time.Sleep(10 * time.Millisecond)
  142. }
  143. if !strings.Contains(logger.String(), "unexpected EOF") && !strings.Contains(logger.String(), "connection reset by peer") {
  144. t.Error("Unexpected log output:", logger.String())
  145. return
  146. }
  147. }