stream_route_test.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package stream_route_test
  18. import (
  19. "encoding/json"
  20. "io/ioutil"
  21. "net"
  22. "net/http"
  23. "time"
  24. . "github.com/onsi/ginkgo/v2"
  25. . "github.com/onsi/gomega"
  26. "github.com/apisix/manager-api/test/e2e/base"
  27. )
  28. var _ = Describe("Stream Route", func() {
  29. DescribeTable("test stream route data CURD",
  30. func(tc base.HttpTestCase) {
  31. base.RunTestCase(tc)
  32. },
  33. // base case
  34. Entry("create stream route", base.HttpTestCase{
  35. Object: base.ManagerApiExpect(),
  36. Method: http.MethodPost,
  37. Path: "/apisix/admin/stream_routes",
  38. Body: `{
  39. "id": "sr1",
  40. "remote_addr": "127.0.0.1",
  41. "server_addr": "127.0.0.1",
  42. "server_port": 10090,
  43. "sni": "test.com",
  44. "upstream": {
  45. "nodes": {
  46. "` + base.UpstreamIp + `:1980": 1
  47. },
  48. "type": "roundrobin"
  49. }
  50. }`,
  51. Headers: map[string]string{"Authorization": base.GetToken()},
  52. ExpectStatus: http.StatusOK,
  53. }),
  54. Entry("get stream route #1", base.HttpTestCase{
  55. Object: base.ManagerApiExpect(),
  56. Method: http.MethodGet,
  57. Path: "/apisix/admin/stream_routes/sr1",
  58. Headers: map[string]string{"Authorization": base.GetToken()},
  59. ExpectStatus: http.StatusOK,
  60. ExpectBody: `"server_port":10090`,
  61. }),
  62. Entry("update stream route", base.HttpTestCase{
  63. Object: base.ManagerApiExpect(),
  64. Method: http.MethodPut,
  65. Path: "/apisix/admin/stream_routes/sr1",
  66. Headers: map[string]string{"Authorization": base.GetToken()},
  67. Body: `{
  68. "id": "sr1",
  69. "server_port": 10091,
  70. "upstream": {
  71. "nodes": {
  72. "` + base.UpstreamIp + `:1980": 1
  73. },
  74. "type": "roundrobin"
  75. }
  76. }`,
  77. ExpectStatus: http.StatusOK,
  78. ExpectBody: `"server_port":10091`,
  79. }),
  80. Entry("get stream route #2", base.HttpTestCase{
  81. Object: base.ManagerApiExpect(),
  82. Method: http.MethodGet,
  83. Path: "/apisix/admin/stream_routes/sr1",
  84. Headers: map[string]string{"Authorization": base.GetToken()},
  85. ExpectStatus: http.StatusOK,
  86. ExpectBody: `"server_port":10091`,
  87. }),
  88. Entry("hit stream route", base.HttpTestCase{
  89. Object: base.APISIXStreamProxyExpect(10091, ""),
  90. Method: http.MethodGet,
  91. Path: "/hello",
  92. ExpectStatus: http.StatusOK,
  93. ExpectBody: "hello world",
  94. }),
  95. Entry("delete stream route", base.HttpTestCase{
  96. Object: base.ManagerApiExpect(),
  97. Method: http.MethodDelete,
  98. Path: "/apisix/admin/stream_routes/sr1",
  99. Headers: map[string]string{"Authorization": base.GetToken()},
  100. ExpectStatus: http.StatusOK,
  101. }),
  102. )
  103. DescribeTable("test stream route with HTTP upstream",
  104. func(tc base.HttpTestCase) {
  105. base.RunTestCase(tc)
  106. },
  107. Entry("create stream route", base.HttpTestCase{
  108. Object: base.ManagerApiExpect(),
  109. Method: http.MethodPost,
  110. Path: "/apisix/admin/stream_routes",
  111. Body: `{
  112. "id": "sr1",
  113. "server_port": 10090,
  114. "upstream": {
  115. "nodes": {
  116. "` + base.UpstreamIp + `:1980": 1
  117. },
  118. "type": "roundrobin"
  119. }
  120. }`,
  121. Headers: map[string]string{"Authorization": base.GetToken()},
  122. ExpectStatus: http.StatusOK,
  123. }),
  124. Entry("hit stream route", base.HttpTestCase{
  125. Object: base.APISIXStreamProxyExpect(10090, ""),
  126. Method: http.MethodGet,
  127. Path: "/hello",
  128. ExpectStatus: http.StatusOK,
  129. ExpectBody: "hello world",
  130. }),
  131. Entry("delete stream route", base.HttpTestCase{
  132. Object: base.ManagerApiExpect(),
  133. Method: http.MethodDelete,
  134. Path: "/apisix/admin/stream_routes/sr1",
  135. Headers: map[string]string{"Authorization": base.GetToken()},
  136. ExpectStatus: http.StatusOK,
  137. }),
  138. )
  139. // prepare ssl certificate
  140. apisixCert, err := ioutil.ReadFile("../../certs/apisix.crt")
  141. Expect(err).To(BeNil())
  142. apisixKey, err := ioutil.ReadFile("../../certs/apisix.key")
  143. Expect(err).To(BeNil())
  144. apisixSSLBody, err := json.Marshal(map[string]string{"cert": string(apisixCert), "key": string(apisixKey)})
  145. Expect(err).To(BeNil())
  146. DescribeTable("test stream route with HTTPS upstream",
  147. func(tc base.HttpTestCase) {
  148. base.RunTestCase(tc)
  149. },
  150. Entry("create ssl cert", base.HttpTestCase{
  151. Object: base.ManagerApiExpect(),
  152. Method: http.MethodPost,
  153. Path: "/apisix/admin/ssl",
  154. Body: string(apisixSSLBody),
  155. Headers: map[string]string{"Authorization": base.GetToken()},
  156. ExpectStatus: http.StatusOK,
  157. }),
  158. Entry("create stream route", base.HttpTestCase{
  159. Object: base.ManagerApiExpect(),
  160. Method: http.MethodPost,
  161. Path: "/apisix/admin/stream_routes",
  162. Body: `{
  163. "id": "sr1",
  164. "server_port": 10093,
  165. "sni": "test.com",
  166. "upstream": {
  167. "nodes": {
  168. "` + base.UpstreamIp + `:1980": 1
  169. },
  170. "type": "roundrobin"
  171. }
  172. }`,
  173. Headers: map[string]string{"Authorization": base.GetToken()},
  174. ExpectStatus: http.StatusOK,
  175. }),
  176. Entry("hit stream route through https", base.HttpTestCase{
  177. Object: base.APISIXStreamProxyExpect(10093, "test.com"),
  178. Method: http.MethodGet,
  179. Path: "/hello",
  180. ExpectStatus: http.StatusOK,
  181. ExpectBody: "hello world",
  182. }),
  183. )
  184. Describe("test stream route with TCP upstream", func() {
  185. It("create stream route", func() {
  186. base.RunTestCase(base.HttpTestCase{
  187. Object: base.ManagerApiExpect(),
  188. Method: http.MethodPost,
  189. Path: "/apisix/admin/stream_routes",
  190. Body: `{
  191. "id": "sr1tcp",
  192. "server_port": 10090,
  193. "upstream": {
  194. "nodes": {
  195. "` + base.UpstreamIp + `:1991": 1
  196. },
  197. "type": "roundrobin"
  198. }
  199. }`,
  200. Headers: map[string]string{"Authorization": base.GetToken()},
  201. ExpectStatus: http.StatusOK,
  202. })
  203. })
  204. It("hit stream route through tcp", func() {
  205. time.Sleep(base.SleepTime)
  206. conn, err := net.Dial("tcp", "127.0.0.1:1991")
  207. Expect(err).To(BeNil())
  208. _ = conn.SetDeadline(time.Now().Add(time.Second * 3))
  209. _, err = conn.Write([]byte("world"))
  210. Expect(err).To(BeNil())
  211. result := make([]byte, 11)
  212. n, err := conn.Read(result)
  213. Expect(n).Should(BeNumerically("==", 11))
  214. Expect(err).To(BeNil())
  215. Expect(string(result)).To(ContainSubstring("hello world"))
  216. err = conn.Close()
  217. Expect(err).To(BeNil())
  218. })
  219. })
  220. Describe("test stream route with UDP upstream", func() {
  221. It("create stream route", func() {
  222. base.RunTestCase(base.HttpTestCase{
  223. Object: base.ManagerApiExpect(),
  224. Method: http.MethodPost,
  225. Path: "/apisix/admin/stream_routes",
  226. Body: `{
  227. "id": "sr1udp",
  228. "server_port": 10095,
  229. "upstream": {
  230. "nodes": {
  231. "` + base.UpstreamIp + `:1992": 1
  232. },
  233. "type": "roundrobin"
  234. }
  235. }`,
  236. Headers: map[string]string{"Authorization": base.GetToken()},
  237. ExpectStatus: http.StatusOK,
  238. })
  239. })
  240. It("hit stream route through udp", func() {
  241. time.Sleep(base.SleepTime)
  242. conn, err := net.Dial("udp", "127.0.0.1:10095")
  243. Expect(err).To(BeNil())
  244. _ = conn.SetDeadline(time.Now().Add(time.Second * 3))
  245. _, err = conn.Write([]byte("world"))
  246. Expect(err).To(BeNil())
  247. result := make([]byte, 11)
  248. n, err := conn.Read(result)
  249. Expect(n).Should(BeNumerically("==", 11))
  250. Expect(err).To(BeNil())
  251. Expect(string(result)).To(ContainSubstring("hello world"))
  252. err = conn.Close()
  253. Expect(err).To(BeNil())
  254. })
  255. })
  256. DescribeTable("test stream route data CURD exception",
  257. func(tc base.HttpTestCase) {
  258. base.RunTestCase(tc)
  259. },
  260. Entry("create stream route with upstream id not found", base.HttpTestCase{
  261. Object: base.ManagerApiExpect(),
  262. Method: http.MethodPost,
  263. Path: "/apisix/admin/stream_routes",
  264. Body: `{
  265. "id": "sr1",
  266. "server_port": 10090,
  267. "upstream_id": "u1"
  268. }`,
  269. Headers: map[string]string{"Authorization": base.GetToken()},
  270. ExpectStatus: http.StatusBadRequest,
  271. }),
  272. )
  273. })