upstream.t 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  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. use t::APISIX 'no_plan';
  18. repeat_each(1);
  19. log_level('info');
  20. worker_connections(256);
  21. no_root_location();
  22. no_shuffle();
  23. run_tests();
  24. __DATA__
  25. === TEST 1: set upstream(id: 1) invalid parameters
  26. --- config
  27. location /t {
  28. content_by_lua_block {
  29. local t = require("lib.test_admin").test
  30. local code, body = t('/apisix/admin/upstreams/1',
  31. ngx.HTTP_PUT,
  32. [[{
  33. "type": "roundrobin",
  34. "desc": "new upstream"
  35. }]]
  36. )
  37. if code >= 300 then
  38. ngx.status = code
  39. end
  40. ngx.say(body)
  41. }
  42. }
  43. --- request
  44. GET /t
  45. --- error_code: 400
  46. === TEST 2: set upstream(id: 1) nodes
  47. --- config
  48. location /t {
  49. content_by_lua_block {
  50. local t = require("lib.test_admin").test
  51. local code, body = t('/apisix/admin/upstreams/1',
  52. ngx.HTTP_PUT,
  53. [[{
  54. "nodes": {
  55. "127.0.0.1:1980": 1
  56. },
  57. "type": "roundrobin",
  58. "desc": "new upstream"
  59. }]]
  60. )
  61. if code >= 300 then
  62. ngx.status = code
  63. end
  64. ngx.say(body)
  65. }
  66. }
  67. --- request
  68. GET /t
  69. --- response_body
  70. passed
  71. === TEST 3: set route(id: 1)
  72. --- config
  73. location /t {
  74. content_by_lua_block {
  75. local t = require("lib.test_admin").test
  76. local code, body = t('/apisix/admin/routes/1',
  77. ngx.HTTP_PUT,
  78. [[{
  79. "uri": "/hello",
  80. "upstream_id": "1"
  81. }]]
  82. )
  83. if code >= 300 then
  84. ngx.status = code
  85. end
  86. ngx.say(body)
  87. }
  88. }
  89. --- request
  90. GET /t
  91. --- response_body
  92. passed
  93. === TEST 4: /not_found
  94. --- request
  95. GET /not_found
  96. --- error_code: 404
  97. --- response_body
  98. {"error_msg":"404 Route Not Found"}
  99. === TEST 5: hit routes
  100. --- request
  101. GET /hello
  102. --- response_body
  103. hello world
  104. === TEST 6: delete upstream(id: 1)
  105. --- config
  106. location /t {
  107. content_by_lua_block {
  108. ngx.sleep(0.5)
  109. local t = require("lib.test_admin").test
  110. local code, message = t('/apisix/admin/upstreams/1',
  111. ngx.HTTP_DELETE
  112. )
  113. ngx.print("[delete] code: ", code, " message: ", message)
  114. }
  115. }
  116. --- request
  117. GET /t
  118. --- response_body
  119. [delete] code: 400 message: {"error_msg":"can not delete this upstream, route [1] is still using it now"}
  120. === TEST 7: delete route(id: 1)
  121. --- config
  122. location /t {
  123. content_by_lua_block {
  124. local t = require("lib.test_admin").test
  125. local code, message = t('/apisix/admin/routes/1',
  126. ngx.HTTP_DELETE
  127. )
  128. ngx.say("[delete] code: ", code, " message: ", message)
  129. }
  130. }
  131. --- request
  132. GET /t
  133. --- response_body
  134. [delete] code: 200 message: passed
  135. === TEST 8: delete upstream(id: 1)
  136. --- config
  137. location /t {
  138. content_by_lua_block {
  139. local t = require("lib.test_admin").test
  140. local code, message = t('/apisix/admin/upstreams/1',
  141. ngx.HTTP_DELETE
  142. )
  143. ngx.say("[delete] code: ", code, " message: ", message)
  144. }
  145. }
  146. --- request
  147. GET /t
  148. --- response_body
  149. [delete] code: 200 message: passed
  150. === TEST 9: delete upstream again(id: 1)
  151. --- config
  152. location /t {
  153. content_by_lua_block {
  154. local t = require("lib.test_admin").test
  155. local code, message = t('/apisix/admin/upstreams/1',
  156. ngx.HTTP_DELETE
  157. )
  158. ngx.say("[delete] code: ", code)
  159. }
  160. }
  161. --- request
  162. GET /t
  163. --- response_body
  164. [delete] code: 404
  165. === TEST 10: set upstream(id: 1, using `node` mode to pass upstream host)
  166. --- config
  167. location /t {
  168. content_by_lua_block {
  169. local t = require("lib.test_admin").test
  170. local code, body = t('/apisix/admin/upstreams/1',
  171. ngx.HTTP_PUT,
  172. [[{
  173. "nodes": {
  174. "test.com:1980": 1
  175. },
  176. "type": "roundrobin",
  177. "desc": "new upstream",
  178. "pass_host": "node"
  179. }]]
  180. )
  181. if code >= 300 then
  182. ngx.status = code
  183. end
  184. ngx.say(body)
  185. }
  186. }
  187. --- request
  188. GET /t
  189. --- response_body
  190. passed
  191. === TEST 11: set route(id: 1, using `node` mode to pass upstream host)
  192. --- config
  193. location /t {
  194. content_by_lua_block {
  195. local t = require("lib.test_admin").test
  196. local code, body = t('/apisix/admin/routes/1',
  197. ngx.HTTP_PUT,
  198. [[{
  199. "uri": "/echo",
  200. "upstream_id": "1"
  201. }]]
  202. )
  203. if code >= 300 then
  204. ngx.status = code
  205. end
  206. ngx.say(body)
  207. }
  208. }
  209. --- request
  210. GET /t
  211. --- response_body
  212. passed
  213. === TEST 12: hit route
  214. --- request
  215. GET /echo
  216. --- response_headers
  217. host: test.com:1980
  218. === TEST 13: set upstream(using `rewrite` mode to pass upstream host)
  219. --- config
  220. location /t {
  221. content_by_lua_block {
  222. local t = require("lib.test_admin").test
  223. local code, body = t('/apisix/admin/upstreams/1',
  224. ngx.HTTP_PUT,
  225. [[{
  226. "nodes": {
  227. "127.0.0.1:1980": 1
  228. },
  229. "type": "roundrobin",
  230. "desc": "new upstream",
  231. "pass_host": "rewrite",
  232. "upstream_host": "test.com"
  233. }]]
  234. )
  235. if code >= 300 then
  236. ngx.status = code
  237. end
  238. ngx.say(body)
  239. }
  240. }
  241. --- request
  242. GET /t
  243. --- response_body
  244. passed
  245. === TEST 14: set route(using `rewrite` mode to pass upstream host)
  246. --- config
  247. location /t {
  248. content_by_lua_block {
  249. local t = require("lib.test_admin").test
  250. local code, body = t('/apisix/admin/routes/1',
  251. ngx.HTTP_PUT,
  252. [[{
  253. "uri": "/echo",
  254. "upstream_id": "1"
  255. }]]
  256. )
  257. if code >= 300 then
  258. ngx.status = code
  259. end
  260. ngx.say(body)
  261. }
  262. }
  263. --- request
  264. GET /t
  265. --- response_body
  266. passed
  267. === TEST 15: hit route
  268. --- request
  269. GET /echo
  270. --- response_headers
  271. host: test.com
  272. === TEST 16: delete upstream in used
  273. --- config
  274. location /t {
  275. content_by_lua_block {
  276. local t = require("lib.test_admin").test
  277. ngx.sleep(0.5) -- wait for data synced
  278. local code, body = t('/apisix/admin/upstreams/1',
  279. ngx.HTTP_DELETE
  280. )
  281. if code >= 300 then
  282. ngx.status = code
  283. end
  284. ngx.print(body)
  285. }
  286. }
  287. --- request
  288. GET /t
  289. --- error_code: 400
  290. --- response_body
  291. {"error_msg":"can not delete this upstream, route [1] is still using it now"}
  292. === TEST 17: multi nodes with `node` mode to pass host
  293. --- config
  294. location /t {
  295. content_by_lua_block {
  296. local t = require("lib.test_admin").test
  297. local code, body = t('/apisix/admin/upstreams/1',
  298. ngx.HTTP_PUT,
  299. [[{
  300. "nodes": {
  301. "localhost:1979": 1000,
  302. "127.0.0.1:1980": 1
  303. },
  304. "type": "roundrobin",
  305. "pass_host": "node"
  306. }]]
  307. )
  308. if code >= 300 then
  309. ngx.status = code
  310. ngx.say(body)
  311. return
  312. end
  313. local code, body = t('/apisix/admin/routes/1',
  314. ngx.HTTP_PUT,
  315. [[{
  316. "uri": "/uri",
  317. "upstream_id": "1"
  318. }]]
  319. )
  320. if code >= 300 then
  321. ngx.status = code
  322. end
  323. ngx.say(body)
  324. }
  325. }
  326. --- request
  327. GET /t
  328. --- response_body
  329. passed
  330. === TEST 18: hit route
  331. --- request
  332. GET /uri
  333. --- response_body eval
  334. qr/host: 127.0.0.1/
  335. --- error_log
  336. proxy request to 127.0.0.1:1980
  337. === TEST 19: multi nodes with `node` mode to pass host, the second node has domain
  338. --- config
  339. location /t {
  340. content_by_lua_block {
  341. local t = require("lib.test_admin").test
  342. local code, body = t('/apisix/admin/upstreams/1',
  343. ngx.HTTP_PUT,
  344. [[{
  345. "nodes": {
  346. "127.0.0.1:1979": 1000,
  347. "localhost:1980": 1
  348. },
  349. "type": "roundrobin",
  350. "pass_host": "node"
  351. }]]
  352. )
  353. if code >= 300 then
  354. ngx.status = code
  355. ngx.say(body)
  356. return
  357. end
  358. local code, body = t('/apisix/admin/routes/1',
  359. ngx.HTTP_PUT,
  360. [[{
  361. "uri": "/uri",
  362. "upstream_id": "1"
  363. }]]
  364. )
  365. if code >= 300 then
  366. ngx.status = code
  367. end
  368. ngx.say(body)
  369. }
  370. }
  371. --- request
  372. GET /t
  373. --- response_body
  374. passed
  375. === TEST 20: hit route
  376. --- request
  377. GET /uri
  378. --- response_body eval
  379. qr/host: localhost/
  380. --- error_log
  381. proxy request to 127.0.0.1:1980
  382. === TEST 21: check that including port in host header is supported when pass_host = node and port is not standard
  383. --- config
  384. location /t {
  385. content_by_lua_block {
  386. local t = require("lib.test_admin").test
  387. local code, body = t('/apisix/admin/upstreams/1',
  388. ngx.HTTP_PUT,
  389. [[{
  390. "nodes": {
  391. "localhost:1980": 1000
  392. },
  393. "type": "roundrobin",
  394. "pass_host": "node"
  395. }]]
  396. )
  397. if code >= 300 then
  398. ngx.status = code
  399. ngx.say(body)
  400. return
  401. end
  402. local code, body = t('/apisix/admin/routes/1',
  403. ngx.HTTP_PUT,
  404. [[{
  405. "methods": ["GET"],
  406. "upstream_id": "1",
  407. "uri": "/uri"
  408. }]]
  409. )
  410. if code >= 300 then
  411. ngx.status = code
  412. end
  413. ngx.say(body)
  414. }
  415. }
  416. --- request
  417. GET /t
  418. --- response_body
  419. passed
  420. === TEST 22: hit route
  421. --- request
  422. GET /uri
  423. --- response_body eval
  424. qr/host: localhost:1980/
  425. === TEST 23: check that including port in host header is supported when retrying and pass_host = node and port is not standard
  426. --- config
  427. location /t {
  428. content_by_lua_block {
  429. local t = require("lib.test_admin").test
  430. local code, body = t('/apisix/admin/upstreams/1',
  431. ngx.HTTP_PUT,
  432. [[{
  433. "nodes": {
  434. "127.0.0.1:1979": 1000,
  435. "localhost:1980": 1
  436. },
  437. "type": "roundrobin",
  438. "pass_host": "node"
  439. }]]
  440. )
  441. if code >= 300 then
  442. ngx.status = code
  443. ngx.say(body)
  444. return
  445. end
  446. local code, body = t('/apisix/admin/routes/1',
  447. ngx.HTTP_PUT,
  448. [[{
  449. "methods": ["GET"],
  450. "upstream_id": "1",
  451. "uri": "/uri"
  452. }]]
  453. )
  454. if code >= 300 then
  455. ngx.status = code
  456. end
  457. ngx.say(body)
  458. }
  459. }
  460. --- request
  461. GET /t
  462. --- response_body
  463. passed
  464. === TEST 24: hit route
  465. --- log_level: debug
  466. --- request
  467. GET /uri
  468. --- error_log
  469. Host: 127.0.0.1:1979
  470. === TEST 25: distinguish different upstreams even they have the same addr
  471. --- config
  472. location /t {
  473. content_by_lua_block {
  474. local t = require("lib.test_admin").test
  475. local code, body = t('/apisix/admin/upstreams/1',
  476. ngx.HTTP_PUT,
  477. {
  478. nodes = {["localhost:1980"] = 1},
  479. type = "roundrobin"
  480. }
  481. )
  482. assert(code < 300)
  483. local code, body = t('/apisix/admin/routes/1',
  484. ngx.HTTP_PUT,
  485. [[{
  486. "upstream_id": "1",
  487. "uri": "/server_port"
  488. }]]
  489. )
  490. assert(code < 300)
  491. local http = require "resty.http"
  492. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  493. .. "/server_port"
  494. local ports_count = {}
  495. for i = 1, 24 do
  496. local httpc = http.new()
  497. local res, err = httpc:request_uri(uri)
  498. if not res then
  499. ngx.say(err)
  500. return
  501. end
  502. ports_count[res.body] = (ports_count[res.body] or 0) + 1
  503. local code, body = t('/apisix/admin/upstreams/1',
  504. ngx.HTTP_PUT,
  505. {
  506. nodes = {["localhost:" .. (1980 + i % 3)] = 1},
  507. type = "roundrobin"
  508. }
  509. )
  510. assert(code < 300)
  511. end
  512. local ports_arr = {}
  513. for port, count in pairs(ports_count) do
  514. table.insert(ports_arr, {port = port, count = count})
  515. end
  516. local function cmd(a, b)
  517. return a.port > b.port
  518. end
  519. table.sort(ports_arr, cmd)
  520. ngx.say(require("toolkit.json").encode(ports_arr))
  521. }
  522. }
  523. --- request
  524. GET /t
  525. --- timeout: 5
  526. --- response_body
  527. [{"count":8,"port":"1982"},{"count":8,"port":"1981"},{"count":8,"port":"1980"}]