upstream-node-dns.t 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  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. no_root_location();
  21. no_shuffle();
  22. run_tests();
  23. __DATA__
  24. === TEST 1: route with one upstream node
  25. --- config
  26. location /t {
  27. content_by_lua_block {
  28. local t = require("lib.test_admin").test
  29. local code, body = t('/apisix/admin/routes/1',
  30. ngx.HTTP_PUT,
  31. [[{
  32. "upstream": {
  33. "nodes": {
  34. "test1.com:1980": 1
  35. },
  36. "type": "roundrobin"
  37. },
  38. "uri": "/hello"
  39. }]]
  40. )
  41. if code >= 300 then
  42. ngx.status = code
  43. end
  44. ngx.say(body)
  45. }
  46. }
  47. --- request
  48. GET /t
  49. --- response_body
  50. passed
  51. === TEST 2: hit route, resolve upstream node to "127.0.0.2" always
  52. --- init_by_lua_block
  53. require "resty.core"
  54. apisix = require("apisix")
  55. core = require("apisix.core")
  56. apisix.http_init()
  57. local utils = require("apisix.core.utils")
  58. utils.dns_parse = function (domain) -- mock: DNS parser
  59. if domain == "test1.com" then
  60. return {address = "127.0.0.2"}
  61. end
  62. error("unknown domain: " .. domain)
  63. end
  64. --- request
  65. GET /hello
  66. --- response_body
  67. hello world
  68. === TEST 3: hit route, resolve upstream node to different values
  69. --- init_by_lua_block
  70. require "resty.core"
  71. apisix = require("apisix")
  72. core = require("apisix.core")
  73. apisix.http_init()
  74. local utils = require("apisix.core.utils")
  75. local count = 0
  76. utils.dns_parse = function (domain) -- mock: DNS parser
  77. count = count + 1
  78. if domain == "test1.com" then
  79. return {address = "127.0.0." .. count}
  80. end
  81. error("unknown domain: " .. domain)
  82. end
  83. --- config
  84. location /t {
  85. content_by_lua_block {
  86. local t = require("lib.test_admin").test
  87. core.log.info("call /hello")
  88. local code, body = t('/hello', ngx.HTTP_GET)
  89. }
  90. }
  91. --- request
  92. GET /t
  93. --- grep_error_log eval
  94. qr/dns resolver domain: test1.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
  95. --- grep_error_log_out
  96. call /hello
  97. dns resolver domain: test1.com to 127.0.0.1
  98. proxy request to 127.0.0.1:1980
  99. === TEST 4: set route with two upstream nodes
  100. --- config
  101. location /t {
  102. content_by_lua_block {
  103. local t = require("lib.test_admin").test
  104. local code, body = t('/apisix/admin/routes/1',
  105. ngx.HTTP_PUT,
  106. [[{
  107. "upstream": {
  108. "nodes": {
  109. "test1.com:1980": 1,
  110. "test2.com:1980": 1
  111. },
  112. "type": "roundrobin"
  113. },
  114. "uri": "/hello"
  115. }]]
  116. )
  117. if code >= 300 then
  118. ngx.status = code
  119. end
  120. ngx.say(body)
  121. }
  122. }
  123. --- request
  124. GET /t
  125. --- response_body
  126. passed
  127. === TEST 5: hit route, resolve the upstream node to "127.0.0.2"
  128. --- init_by_lua_block
  129. require "resty.core"
  130. apisix = require("apisix")
  131. core = require("apisix.core")
  132. apisix.http_init()
  133. local utils = require("apisix.core.utils")
  134. utils.dns_parse = function (domain) -- mock: DNS parser
  135. if domain == "test1.com" or domain == "test2.com" then
  136. return {address = "127.0.0.2"}
  137. end
  138. error("unknown domain: " .. domain)
  139. end
  140. --- request
  141. GET /hello
  142. --- response_body
  143. hello world
  144. === TEST 6: hit route, resolve upstream node to different values
  145. --- init_by_lua_block
  146. require "resty.core"
  147. apisix = require("apisix")
  148. core = require("apisix.core")
  149. apisix.http_init()
  150. local utils = require("apisix.core.utils")
  151. local count = 0
  152. utils.dns_parse = function (domain) -- mock: DNS parser
  153. count = count + 1
  154. if domain == "test1.com" or domain == "test2.com" then
  155. return {address = "127.0.0." .. count}
  156. end
  157. error("unknown domain: " .. domain)
  158. end
  159. --- config
  160. location /t {
  161. content_by_lua_block {
  162. local t = require("lib.test_admin").test
  163. core.log.info("call /hello")
  164. local code, body = t('/hello', ngx.HTTP_GET)
  165. core.log.warn("code: ", code)
  166. }
  167. }
  168. --- request
  169. GET /t
  170. --- grep_error_log eval
  171. qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
  172. --- grep_error_log_out eval
  173. qr/call \/hello(
  174. dns resolver domain: test1.com to 127.0.0.1
  175. dns resolver domain: test2.com to 127.0.0.2|
  176. dns resolver domain: test2.com to 127.0.0.1
  177. dns resolver domain: test1.com to 127.0.0.2)
  178. proxy request to 127.0.0.[12]:1980
  179. /
  180. === TEST 7: upstream with one upstream node
  181. --- config
  182. location /t {
  183. content_by_lua_block {
  184. local t = require("lib.test_admin").test
  185. local code, body = t('/apisix/admin/upstreams/1',
  186. ngx.HTTP_PUT,
  187. [[{
  188. "nodes": {
  189. "test1.com:1980": 1
  190. },
  191. "type": "roundrobin",
  192. "desc": "new upstream"
  193. }]]
  194. )
  195. if code >= 300 then
  196. ngx.status = code
  197. end
  198. ngx.say(body)
  199. }
  200. }
  201. --- request
  202. GET /t
  203. --- response_body
  204. passed
  205. === TEST 8: set route with upstream_id 1
  206. --- config
  207. location /t {
  208. content_by_lua_block {
  209. local t = require("lib.test_admin").test
  210. local code, body = t('/apisix/admin/routes/1',
  211. ngx.HTTP_PUT,
  212. [[{
  213. "uri": "/hello",
  214. "upstream_id": "1"
  215. }]]
  216. )
  217. if code >= 300 then
  218. ngx.status = code
  219. end
  220. ngx.say(body)
  221. }
  222. }
  223. --- request
  224. GET /t
  225. --- response_body
  226. passed
  227. === TEST 9: hit route, resolve upstream node to different values
  228. --- init_by_lua_block
  229. require "resty.core"
  230. apisix = require("apisix")
  231. core = require("apisix.core")
  232. apisix.http_init()
  233. local utils = require("apisix.core.utils")
  234. local count = 0
  235. utils.dns_parse = function (domain) -- mock: DNS parser
  236. count = count + 1
  237. if domain == "test1.com" then
  238. return {address = "127.0.0." .. count}
  239. end
  240. error("unknown domain: " .. domain)
  241. end
  242. --- config
  243. location /t {
  244. content_by_lua_block {
  245. local t = require("lib.test_admin").test
  246. core.log.info("call /hello")
  247. local code, body = t('/hello', ngx.HTTP_GET)
  248. }
  249. }
  250. --- request
  251. GET /t
  252. --- grep_error_log eval
  253. qr/dns resolver domain: test1.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
  254. --- grep_error_log_out
  255. call /hello
  256. dns resolver domain: test1.com to 127.0.0.1
  257. proxy request to 127.0.0.1:1980
  258. === TEST 10: two upstream nodes in upstream object
  259. --- config
  260. location /t {
  261. content_by_lua_block {
  262. local t = require("lib.test_admin").test
  263. local code, body = t('/apisix/admin/upstreams/1',
  264. ngx.HTTP_PUT,
  265. [[{
  266. "nodes": {
  267. "test1.com:1980": 1,
  268. "test2.com:1980": 1
  269. },
  270. "type": "roundrobin",
  271. "desc": "new upstream"
  272. }]]
  273. )
  274. if code >= 300 then
  275. ngx.status = code
  276. end
  277. ngx.say(body)
  278. }
  279. }
  280. --- request
  281. GET /t
  282. --- response_body
  283. passed
  284. === TEST 11: hit route, resolve upstream node to different values
  285. --- init_by_lua_block
  286. require "resty.core"
  287. apisix = require("apisix")
  288. core = require("apisix.core")
  289. apisix.http_init()
  290. local utils = require("apisix.core.utils")
  291. local count = 0
  292. utils.dns_parse = function (domain) -- mock: DNS parser
  293. count = count + 1
  294. if domain == "test1.com" or domain == "test2.com" then
  295. return {address = "127.0.0." .. count}
  296. end
  297. error("unknown domain: " .. domain)
  298. end
  299. --- config
  300. location /t {
  301. content_by_lua_block {
  302. local t = require("lib.test_admin").test
  303. core.log.info("call /hello")
  304. local code, body = t('/hello', ngx.HTTP_GET)
  305. }
  306. }
  307. --- request
  308. GET /t
  309. --- grep_error_log eval
  310. qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
  311. --- grep_error_log_out eval
  312. qr/call \/hello(
  313. dns resolver domain: test1.com to 127.0.0.1
  314. dns resolver domain: test2.com to 127.0.0.2|
  315. dns resolver domain: test2.com to 127.0.0.1
  316. dns resolver domain: test1.com to 127.0.0.2)
  317. proxy request to 127.0.0.[12]:1980
  318. /
  319. === TEST 12: dns cached expired, resolve the domain always with same value
  320. --- init_by_lua_block
  321. require "resty.core"
  322. apisix = require("apisix")
  323. core = require("apisix.core")
  324. apisix.http_init()
  325. local utils = require("apisix.core.utils")
  326. local count = 1
  327. utils.dns_parse = function (domain) -- mock: DNS parser
  328. if domain == "test1.com" or domain == "test2.com" then
  329. return {address = "127.0.0.1"}
  330. end
  331. error("unknown domain: " .. domain)
  332. end
  333. --- config
  334. location /t {
  335. content_by_lua_block {
  336. local t = require("lib.test_admin").test
  337. core.log.info("call /hello")
  338. local code, body = t('/hello', ngx.HTTP_GET)
  339. }
  340. }
  341. --- request
  342. GET /t
  343. --- grep_error_log eval
  344. qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:1980/
  345. --- grep_error_log_out eval
  346. qr/call \/hello(
  347. dns resolver domain: test1.com to 127.0.0.1
  348. dns resolver domain: test2.com to 127.0.0.1|
  349. dns resolver domain: test2.com to 127.0.0.1
  350. dns resolver domain: test1.com to 127.0.0.1)
  351. proxy request to 127.0.0.1:1980
  352. /
  353. === TEST 13: two upstream nodes in upstream object (one host + one IP)
  354. --- config
  355. location /t {
  356. content_by_lua_block {
  357. local t = require("lib.test_admin").test
  358. local code, body = t('/apisix/admin/upstreams/1',
  359. ngx.HTTP_PUT,
  360. [[{
  361. "nodes": {
  362. "test1.com:1980": 1,
  363. "127.0.0.5:1981": 1
  364. },
  365. "type": "roundrobin",
  366. "desc": "new upstream"
  367. }]]
  368. )
  369. if code >= 300 then
  370. ngx.status = code
  371. end
  372. ngx.say(body)
  373. }
  374. }
  375. --- request
  376. GET /t
  377. --- response_body
  378. passed
  379. === TEST 14: dns cached expired, resolve the domain with different values
  380. --- init_by_lua_block
  381. require "resty.core"
  382. apisix = require("apisix")
  383. core = require("apisix.core")
  384. apisix.http_init()
  385. local utils = require("apisix.core.utils")
  386. local count = 0
  387. utils.dns_parse = function (domain) -- mock: DNS parser
  388. count = count + 1
  389. if domain == "test1.com" or domain == "test2.com" then
  390. return {address = "127.0.0." .. count}
  391. end
  392. error("unknown domain: " .. domain)
  393. end
  394. --- config
  395. location /t {
  396. content_by_lua_block {
  397. local t = require("lib.test_admin").test
  398. core.log.info("call /hello")
  399. local code, body = t('/hello', ngx.HTTP_GET)
  400. }
  401. }
  402. --- request
  403. GET /t
  404. --- grep_error_log eval
  405. qr/dns resolver domain: \w+.com to 127.0.0.\d|call \/hello|proxy request to 127.0.0.\d:198\d/
  406. --- grep_error_log_out eval
  407. qr/call \/hello
  408. dns resolver domain: test1.com to 127.0.0.1
  409. proxy request to 127.0.0.(1:1980|5:1981)
  410. /
  411. === TEST 15: route with upstream node, the domain's IP is changed
  412. --- config
  413. location /t {
  414. content_by_lua_block {
  415. local t = require("lib.test_admin").test
  416. local code, body = t('/apisix/admin/routes/1',
  417. ngx.HTTP_PUT,
  418. [[{
  419. "upstream": {
  420. "nodes": {
  421. "test1.com:1980": 1
  422. },
  423. "type": "roundrobin"
  424. },
  425. "uri": "/hello"
  426. }]]
  427. )
  428. if code >= 300 then
  429. ngx.status = code
  430. end
  431. ngx.say(body)
  432. }
  433. }
  434. --- request
  435. GET /t
  436. --- response_body
  437. passed
  438. === TEST 16: hit
  439. --- init_by_lua_block
  440. require "resty.core"
  441. apisix = require("apisix")
  442. core = require("apisix.core")
  443. apisix.http_init()
  444. local utils = require("apisix.core.utils")
  445. local count = 0
  446. utils.dns_parse = function (domain) -- mock: DNS parser
  447. count = count + 1
  448. if domain == "test1.com" then
  449. return {address = "127.0.0." .. count}
  450. end
  451. error("unknown domain: " .. domain)
  452. end
  453. --- config
  454. location /t {
  455. content_by_lua_block {
  456. local t = require("lib.test_admin").test
  457. t('/hello', ngx.HTTP_GET)
  458. -- avoid adding more "dns_value" into the route
  459. t('/hello', ngx.HTTP_GET)
  460. }
  461. }
  462. --- request
  463. GET /t
  464. --- grep_error_log eval
  465. qr/parse route which contain domain: .+("dns_value":.+){3}/
  466. --- grep_error_log_out