host_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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 route_test
  18. import (
  19. "net/http"
  20. . "github.com/onsi/ginkgo/v2"
  21. "github.com/apisix/manager-api/test/e2e/base"
  22. )
  23. var _ = Describe("Route", func() {
  24. DescribeTable("test route with host",
  25. func(tc base.HttpTestCase) {
  26. base.RunTestCase(tc)
  27. },
  28. Entry("invalid host", base.HttpTestCase{
  29. Object: base.ManagerApiExpect(),
  30. Path: "/apisix/admin/routes/r1",
  31. Method: http.MethodPut,
  32. Body: `{
  33. "name": "route1",
  34. "uri": "/hello_",
  35. "host": "$%$foo.com",
  36. "upstream": {
  37. "nodes": {
  38. "` + base.UpstreamIp + `:1980": 1
  39. },
  40. "type": "roundrobin"
  41. }
  42. }`,
  43. Headers: map[string]string{"Authorization": base.GetToken()},
  44. ExpectStatus: http.StatusBadRequest,
  45. }),
  46. Entry("invalid hosts", base.HttpTestCase{
  47. Object: base.ManagerApiExpect(),
  48. Method: http.MethodPut,
  49. Path: "/apisix/admin/routes/r1",
  50. Body: `{
  51. "name": "route1",
  52. "uri": "/hello_",
  53. "hosts": ["$%$foo.com", "*.bar.com"],
  54. "upstream": {
  55. "nodes": {
  56. "` + base.UpstreamIp + `:1980": 1
  57. },
  58. "type": "roundrobin"
  59. }
  60. }`,
  61. Headers: map[string]string{"Authorization": base.GetToken()},
  62. ExpectStatus: http.StatusBadRequest,
  63. }),
  64. Entry("create route with host and hosts together at the same time", base.HttpTestCase{
  65. Object: base.ManagerApiExpect(),
  66. Method: http.MethodPut,
  67. Path: "/apisix/admin/routes/r1",
  68. Body: `{
  69. "name": "route1",
  70. "uri": "/hello_",
  71. "host": "github.com",
  72. "hosts": ["foo.com", "*.bar.com"],
  73. "upstream": {
  74. "nodes": {
  75. "` + base.UpstreamIp + `:1980": 1
  76. },
  77. "type": "roundrobin"
  78. }
  79. }`,
  80. Headers: map[string]string{"Authorization": base.GetToken()},
  81. ExpectStatus: http.StatusBadRequest,
  82. }),
  83. Entry("hit route not created", base.HttpTestCase{
  84. Object: base.APISIXExpect(),
  85. Method: http.MethodGet,
  86. Path: "/hello_",
  87. Headers: map[string]string{"Host": "foo.com"},
  88. ExpectStatus: http.StatusNotFound,
  89. ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n",
  90. }),
  91. Entry("hit route not created", base.HttpTestCase{
  92. Object: base.APISIXExpect(),
  93. Method: http.MethodGet,
  94. Path: "/hello_",
  95. Headers: map[string]string{"Host": "$%$foo.com"},
  96. ExpectStatus: http.StatusNotFound,
  97. ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n",
  98. }),
  99. )
  100. DescribeTable("test route with hosts",
  101. func(tc base.HttpTestCase) {
  102. base.RunTestCase(tc)
  103. },
  104. Entry("make sure route not created", base.HttpTestCase{
  105. Object: base.APISIXExpect(),
  106. Method: http.MethodGet,
  107. Path: "/hello_",
  108. Headers: map[string]string{"Host": "foo.com"},
  109. ExpectStatus: http.StatusNotFound,
  110. ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n",
  111. }),
  112. Entry("create route", base.HttpTestCase{
  113. Object: base.ManagerApiExpect(),
  114. Method: http.MethodPut,
  115. Path: "/apisix/admin/routes/r1",
  116. Body: `{
  117. "name": "route1",
  118. "uri": "/hello_",
  119. "hosts": ["foo.com", "*.bar.com"],
  120. "upstream": {
  121. "nodes": {
  122. "` + base.UpstreamIp + `:1980": 1
  123. },
  124. "type": "roundrobin"
  125. }
  126. }`,
  127. Headers: map[string]string{"Authorization": base.GetToken()},
  128. ExpectStatus: http.StatusOK,
  129. }),
  130. Entry("create route with int uri", base.HttpTestCase{
  131. Object: base.ManagerApiExpect(),
  132. Method: http.MethodPut,
  133. Path: "/apisix/admin/routes/r1",
  134. Body: `{
  135. "name": "route2",
  136. "uri": 123456
  137. }`,
  138. Headers: map[string]string{"Authorization": base.GetToken()},
  139. ExpectStatus: http.StatusBadRequest,
  140. }),
  141. Entry("hit the route just created - wildcard domain name", base.HttpTestCase{
  142. Object: base.APISIXExpect(),
  143. Method: http.MethodGet,
  144. Path: "/hello_",
  145. Headers: map[string]string{"Host": "test.bar.com"},
  146. ExpectStatus: http.StatusOK,
  147. ExpectBody: "hello world\n",
  148. Sleep: base.SleepTime,
  149. }),
  150. Entry("hit the route just created", base.HttpTestCase{
  151. Object: base.APISIXExpect(),
  152. Method: http.MethodGet,
  153. Path: "/hello_",
  154. Headers: map[string]string{"Host": "foo.com"},
  155. ExpectStatus: http.StatusOK,
  156. ExpectBody: "hello world\n",
  157. }),
  158. Entry("hit the route not exists", base.HttpTestCase{
  159. Object: base.APISIXExpect(),
  160. Method: http.MethodGet,
  161. Path: "/hello_111",
  162. Headers: map[string]string{"Host": "foo.com"},
  163. ExpectStatus: http.StatusNotFound,
  164. ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n",
  165. }),
  166. Entry("delete the route just created", base.HttpTestCase{
  167. Object: base.ManagerApiExpect(),
  168. Method: http.MethodDelete,
  169. Path: "/apisix/admin/routes/r1",
  170. Headers: map[string]string{"Authorization": base.GetToken()},
  171. ExpectStatus: http.StatusOK,
  172. }),
  173. Entry("hit the route just deleted", base.HttpTestCase{
  174. Object: base.APISIXExpect(),
  175. Method: http.MethodGet,
  176. Path: "/hello_",
  177. Headers: map[string]string{"Host": "bar.com"},
  178. ExpectStatus: http.StatusNotFound,
  179. ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n",
  180. Sleep: base.SleepTime,
  181. }),
  182. )
  183. DescribeTable("update routes with hosts",
  184. func(tc base.HttpTestCase) {
  185. base.RunTestCase(tc)
  186. },
  187. Entry("hit route that not exist", base.HttpTestCase{
  188. Object: base.APISIXExpect(),
  189. Method: http.MethodGet,
  190. Path: "/hello",
  191. Headers: map[string]string{"Host": "foo.com"},
  192. ExpectStatus: http.StatusNotFound,
  193. ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n",
  194. }),
  195. Entry("create route with host foo.com", base.HttpTestCase{
  196. Object: base.ManagerApiExpect(),
  197. Method: http.MethodPut,
  198. Path: "/apisix/admin/routes/r1",
  199. Body: `{
  200. "name": "route1",
  201. "uri": "/hello",
  202. "methods": ["GET"],
  203. "hosts": ["foo.com"],
  204. "upstream": {
  205. "type": "roundrobin",
  206. "nodes": [{
  207. "host": "` + base.UpstreamIp + `",
  208. "port": 1980,
  209. "weight": 1
  210. }]
  211. }
  212. }`,
  213. Headers: map[string]string{"Authorization": base.GetToken()},
  214. ExpectStatus: http.StatusOK,
  215. ExpectBody: []string{"\"id\":\"r1\"", "\"hosts\":[\"foo.com\"]"},
  216. }),
  217. Entry("hit the route just create", base.HttpTestCase{
  218. Object: base.APISIXExpect(),
  219. Method: http.MethodGet,
  220. Path: "/hello",
  221. Headers: map[string]string{"Host": "foo.com"},
  222. ExpectStatus: http.StatusOK,
  223. Sleep: base.SleepTime,
  224. }),
  225. Entry("update route with host bar.com", base.HttpTestCase{
  226. Object: base.ManagerApiExpect(),
  227. Method: http.MethodPut,
  228. Path: "/apisix/admin/routes/r1",
  229. Body: `{
  230. "name": "route1",
  231. "uri": "/hello",
  232. "hosts": ["bar.com"],
  233. "upstream": {
  234. "nodes": {
  235. "` + base.UpstreamIp + `:1980": 1
  236. },
  237. "type": "roundrobin"
  238. }
  239. }`,
  240. Headers: map[string]string{"Authorization": base.GetToken()},
  241. ExpectStatus: http.StatusOK,
  242. ExpectBody: []string{"\"id\":\"r1\"", "\"hosts\":[\"bar.com\"]"},
  243. }),
  244. Entry("hit the route with host foo.com", base.HttpTestCase{
  245. Object: base.APISIXExpect(),
  246. Method: http.MethodGet,
  247. Path: "/hello",
  248. Headers: map[string]string{"Host": "foo.com"},
  249. ExpectStatus: http.StatusNotFound,
  250. Sleep: base.SleepTime,
  251. }),
  252. Entry("hit the route just updated", base.HttpTestCase{
  253. Object: base.APISIXExpect(),
  254. Method: http.MethodGet,
  255. Path: "/hello",
  256. Headers: map[string]string{"Host": "bar.com"},
  257. ExpectStatus: http.StatusOK,
  258. ExpectBody: "hello world\n",
  259. }),
  260. Entry("delete route", base.HttpTestCase{
  261. Object: base.ManagerApiExpect(),
  262. Method: http.MethodDelete,
  263. Path: "/apisix/admin/routes/r1",
  264. Headers: map[string]string{"Authorization": base.GetToken()},
  265. ExpectStatus: http.StatusOK,
  266. }),
  267. Entry("hit the route just deleted", base.HttpTestCase{
  268. Object: base.APISIXExpect(),
  269. Method: http.MethodGet,
  270. Path: "/hello",
  271. Headers: map[string]string{"Host": "bar.com"},
  272. ExpectStatus: http.StatusNotFound,
  273. ExpectBody: "{\"error_msg\":\"404 Route Not Found\"}\n",
  274. Sleep: base.SleepTime,
  275. }),
  276. )
  277. DescribeTable("test route with empty array",
  278. func(tc base.HttpTestCase) {
  279. base.RunTestCase(tc)
  280. },
  281. Entry("create route with empty hosts and host", base.HttpTestCase{
  282. Object: base.ManagerApiExpect(),
  283. Path: "/apisix/admin/routes/r1",
  284. Method: http.MethodPut,
  285. Body: `{
  286. "name": "route1",
  287. "uri": "/hello",
  288. "hosts": [],
  289. "host": "test.com",
  290. "upstream": {
  291. "nodes": {
  292. "` + base.UpstreamIp + `:1980": 1
  293. },
  294. "type": "roundrobin"
  295. }
  296. }`,
  297. Headers: map[string]string{"Authorization": base.GetToken()},
  298. ExpectStatus: http.StatusBadRequest,
  299. ExpectBody: `{"code":10000,"message":"schema validate failed: (root): Must validate one and only one schema (oneOf)\n(root): Must validate all the schemas (allOf)\nhosts: Array must have at least 1 items"}`,
  300. }),
  301. Entry("make sure the route not created", base.HttpTestCase{
  302. Object: base.APISIXExpect(),
  303. Method: http.MethodGet,
  304. Path: "/hello",
  305. Headers: map[string]string{"Host": "test.com"},
  306. ExpectStatus: http.StatusNotFound,
  307. ExpectBody: `{"error_msg":"404 Route Not Found"}`,
  308. }),
  309. Entry("create route with empty hosts", base.HttpTestCase{
  310. Object: base.ManagerApiExpect(),
  311. Path: "/apisix/admin/routes/r1",
  312. Method: http.MethodPut,
  313. Body: `{
  314. "name": "route2",
  315. "uri": "/hello",
  316. "hosts": [],
  317. "upstream": {
  318. "nodes": {
  319. "` + base.UpstreamIp + `:1980": 1
  320. },
  321. "type": "roundrobin"
  322. }
  323. }`,
  324. Headers: map[string]string{"Authorization": base.GetToken()},
  325. ExpectStatus: http.StatusBadRequest,
  326. ExpectBody: `{"code":10000,"message":"schema validate failed: hosts: Array must have at least 1 items"}`,
  327. }),
  328. Entry("make sure the route not created", base.HttpTestCase{
  329. Object: base.APISIXExpect(),
  330. Method: http.MethodGet,
  331. Path: "/hello",
  332. ExpectStatus: http.StatusNotFound,
  333. ExpectBody: `{"error_msg":"404 Route Not Found"}`,
  334. }),
  335. Entry("create route with empty uris and uri", base.HttpTestCase{
  336. Object: base.ManagerApiExpect(),
  337. Path: "/apisix/admin/routes/r1",
  338. Method: http.MethodPut,
  339. Body: `{
  340. "name": "route2",
  341. "uri": "/hello",
  342. "uris": [],
  343. "upstream": {
  344. "nodes": {
  345. "` + base.UpstreamIp + `:1980": 1
  346. },
  347. "type": "roundrobin"
  348. }
  349. }`,
  350. Headers: map[string]string{"Authorization": base.GetToken()},
  351. ExpectStatus: http.StatusBadRequest,
  352. ExpectBody: `{"code":10000,"message":"schema validate failed: (root): Must validate one and only one schema (oneOf)\n(root): Must validate all the schemas (allOf)\nuris: Array must have at least 1 items"}`,
  353. }),
  354. Entry("create route with empty remote_addrs and remote_addr", base.HttpTestCase{
  355. Object: base.ManagerApiExpect(),
  356. Path: "/apisix/admin/routes/r1",
  357. Method: http.MethodPut,
  358. Body: `{
  359. "name": "route2",
  360. "uri": "/hello",
  361. "remote_addrs": [],
  362. "remote_addr": "0.0.0.0",
  363. "upstream": {
  364. "nodes": {
  365. "` + base.UpstreamIp + `:1980": 1
  366. },
  367. "type": "roundrobin"
  368. }
  369. }`,
  370. Headers: map[string]string{"Authorization": base.GetToken()},
  371. ExpectStatus: http.StatusBadRequest,
  372. ExpectBody: `{"code":10000,"message":"schema validate failed: (root): Must validate one and only one schema (oneOf)\n(root): Must validate all the schemas (allOf)\nremote_addrs: Array must have at least 1 items"}`,
  373. }),
  374. Entry("make sure the route not created", base.HttpTestCase{
  375. Object: base.APISIXExpect(),
  376. Method: http.MethodGet,
  377. Path: "/hello",
  378. ExpectStatus: http.StatusNotFound,
  379. ExpectBody: `{"error_msg":"404 Route Not Found"}`,
  380. }),
  381. )
  382. })