healthcheck.t 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916
  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. worker_connections(256);
  23. run_tests();
  24. __DATA__
  25. === TEST 1: set route(two healthy upstream nodes)
  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/routes/1',
  31. ngx.HTTP_PUT,
  32. [[{
  33. "uri": "/server_port",
  34. "upstream": {
  35. "type": "roundrobin",
  36. "nodes": {
  37. "127.0.0.1:1980": 1,
  38. "127.0.0.1:1981": 1
  39. },
  40. "checks": {
  41. "active": {
  42. "http_path": "/status",
  43. "host": "foo.com",
  44. "healthy": {
  45. "interval": 1,
  46. "successes": 1
  47. },
  48. "unhealthy": {
  49. "interval": 1,
  50. "http_failures": 2
  51. }
  52. }
  53. }
  54. }
  55. }]]
  56. )
  57. if code >= 300 then
  58. ngx.status = code
  59. end
  60. ngx.say(body)
  61. }
  62. }
  63. --- request
  64. GET /t
  65. --- response_body
  66. passed
  67. --- grep_error_log eval
  68. qr/^.*?\[error\](?!.*process exiting).*/
  69. --- grep_error_log_out
  70. === TEST 2: hit routes (two healthy nodes)
  71. --- config
  72. location /t {
  73. content_by_lua_block {
  74. ngx.sleep(3) -- wait for sync
  75. local http = require "resty.http"
  76. local httpc = http.new()
  77. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  78. .. "/server_port"
  79. -- hit route before start test loop
  80. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  81. if not res then
  82. ngx.say(err)
  83. return
  84. end
  85. local ports_count = {}
  86. for i = 1, 12 do
  87. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  88. if not res then
  89. ngx.say(err)
  90. return
  91. end
  92. ports_count[res.body] = (ports_count[res.body] or 0) + 1
  93. end
  94. local ports_arr = {}
  95. for port, count in pairs(ports_count) do
  96. table.insert(ports_arr, {port = port, count = count})
  97. end
  98. local function cmd(a, b)
  99. return a.port > b.port
  100. end
  101. table.sort(ports_arr, cmd)
  102. ngx.say(require("toolkit.json").encode(ports_arr))
  103. ngx.exit(200)
  104. }
  105. }
  106. --- request
  107. GET /t
  108. --- response_body
  109. [{"count":6,"port":"1981"},{"count":6,"port":"1980"}]
  110. --- grep_error_log eval
  111. qr/^.*?\[error\](?!.*process exiting).*/
  112. --- grep_error_log_out
  113. --- timeout: 10
  114. === TEST 3: set route(two upstream node: one healthy + one unhealthy)
  115. --- config
  116. location /t {
  117. content_by_lua_block {
  118. local t = require("lib.test_admin").test
  119. local code, body = t('/apisix/admin/routes/1',
  120. ngx.HTTP_PUT,
  121. [[{
  122. "uri": "/server_port",
  123. "upstream": {
  124. "type": "roundrobin",
  125. "nodes": {
  126. "127.0.0.1:1980": 1,
  127. "127.0.0.1:1970": 1
  128. },
  129. "checks": {
  130. "active": {
  131. "http_path": "/status",
  132. "host": "foo.com",
  133. "healthy": {
  134. "interval": 1,
  135. "successes": 1
  136. },
  137. "unhealthy": {
  138. "interval": 1,
  139. "http_failures": 2
  140. }
  141. }
  142. }
  143. }
  144. }]]
  145. )
  146. if code >= 300 then
  147. ngx.status = code
  148. end
  149. ngx.say(body)
  150. }
  151. }
  152. --- request
  153. GET /t
  154. --- response_body
  155. passed
  156. --- grep_error_log eval
  157. qr/^.*?\[error\](?!.*process exiting).*/
  158. --- grep_error_log_out
  159. === TEST 4: hit routes (two upstream node: one healthy + one unhealthy)
  160. --- config
  161. location /t {
  162. content_by_lua_block {
  163. local http = require "resty.http"
  164. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  165. .. "/server_port"
  166. do
  167. local httpc = http.new()
  168. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  169. end
  170. ngx.sleep(2.5)
  171. local ports_count = {}
  172. for i = 1, 12 do
  173. local httpc = http.new()
  174. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  175. if not res then
  176. ngx.say(err)
  177. return
  178. end
  179. ports_count[res.body] = (ports_count[res.body] or 0) + 1
  180. end
  181. local ports_arr = {}
  182. for port, count in pairs(ports_count) do
  183. table.insert(ports_arr, {port = port, count = count})
  184. end
  185. local function cmd(a, b)
  186. return a.port > b.port
  187. end
  188. table.sort(ports_arr, cmd)
  189. ngx.say(require("toolkit.json").encode(ports_arr))
  190. ngx.exit(200)
  191. }
  192. }
  193. --- request
  194. GET /t
  195. --- response_body
  196. [{"count":12,"port":"1980"}]
  197. --- grep_error_log eval
  198. qr/\([^)]+\) unhealthy .* for '.*'/
  199. --- grep_error_log_out
  200. (upstream#/apisix/routes/1) unhealthy TCP increment (1/2) for 'foo.com(127.0.0.1:1970)'
  201. (upstream#/apisix/routes/1) unhealthy TCP increment (2/2) for 'foo.com(127.0.0.1:1970)'
  202. --- timeout: 10
  203. === TEST 5: chash route (two healthy nodes)
  204. --- config
  205. location /t {
  206. content_by_lua_block {
  207. local t = require("lib.test_admin").test
  208. local code, body = t('/apisix/admin/routes/1',
  209. ngx.HTTP_PUT,
  210. [[{
  211. "uri": "/server_port",
  212. "upstream": {
  213. "type": "chash",
  214. "nodes": {
  215. "127.0.0.1:1981": 1,
  216. "127.0.0.1:1980": 1
  217. },
  218. "key": "remote_addr",
  219. "checks": {
  220. "active": {
  221. "http_path": "/status",
  222. "host": "foo.com",
  223. "healthy": {
  224. "interval": 1,
  225. "successes": 1
  226. },
  227. "unhealthy": {
  228. "interval": 1,
  229. "http_failures": 2
  230. }
  231. }
  232. }
  233. }
  234. }]]
  235. )
  236. if code >= 300 then
  237. ngx.status = code
  238. end
  239. ngx.say(body)
  240. }
  241. }
  242. --- request
  243. GET /t
  244. --- response_body
  245. passed
  246. --- grep_error_log eval
  247. qr/^.*?\[error\](?!.*process exiting).*/
  248. --- grep_error_log_out
  249. === TEST 6: hit routes (two healthy nodes)
  250. --- config
  251. location /t {
  252. content_by_lua_block {
  253. ngx.sleep(2) -- wait for sync
  254. local http = require "resty.http"
  255. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  256. .. "/server_port"
  257. local ports_count = {}
  258. for i = 1, 12 do
  259. local httpc = http.new()
  260. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  261. if not res then
  262. ngx.say(err)
  263. return
  264. end
  265. ports_count[res.body] = (ports_count[res.body] or 0) + 1
  266. end
  267. local ports_arr = {}
  268. for port, count in pairs(ports_count) do
  269. table.insert(ports_arr, {port = port, count = count})
  270. end
  271. local function cmd(a, b)
  272. return a.port > b.port
  273. end
  274. table.sort(ports_arr, cmd)
  275. ngx.say(require("toolkit.json").encode(ports_arr))
  276. ngx.exit(200)
  277. }
  278. }
  279. --- request
  280. GET /t
  281. --- response_body
  282. [{"count":12,"port":"1980"}]
  283. --- grep_error_log eval
  284. qr/^.*?\[error\](?!.*process exiting).*/
  285. --- grep_error_log_out
  286. --- timeout: 6
  287. === TEST 7: chash route (upstream nodes: 1 healthy + 8 unhealthy)
  288. --- config
  289. location /t {
  290. content_by_lua_block {
  291. local t = require("lib.test_admin").test
  292. local code, body = t('/apisix/admin/routes/1',
  293. ngx.HTTP_PUT,
  294. [[{
  295. "uri": "/server_port",
  296. "upstream": {
  297. "type": "chash",
  298. "nodes": {
  299. "127.0.0.1:1980": 1,
  300. "127.0.0.1:1970": 1,
  301. "127.0.0.1:1971": 1,
  302. "127.0.0.1:1972": 1,
  303. "127.0.0.1:1973": 1,
  304. "127.0.0.1:1974": 1,
  305. "127.0.0.1:1975": 1,
  306. "127.0.0.1:1976": 1,
  307. "127.0.0.1:1977": 1
  308. },
  309. "key": "remote_addr",
  310. "checks": {
  311. "active": {
  312. "http_path": "/status",
  313. "host": "foo.com",
  314. "healthy": {
  315. "interval": 1,
  316. "successes": 1
  317. },
  318. "unhealthy": {
  319. "interval": 1,
  320. "http_failures": 2
  321. }
  322. }
  323. }
  324. }
  325. }]]
  326. )
  327. if code >= 300 then
  328. ngx.status = code
  329. end
  330. ngx.say(body)
  331. }
  332. }
  333. --- request
  334. GET /t
  335. --- response_body
  336. passed
  337. --- grep_error_log eval
  338. qr/^.*?\[error\](?!.*process exiting).*/
  339. --- grep_error_log_out
  340. === TEST 8: hit routes (upstream nodes: 1 healthy + 8 unhealthy)
  341. --- config
  342. location /t {
  343. content_by_lua_block {
  344. local http = require "resty.http"
  345. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  346. .. "/server_port"
  347. do
  348. local httpc = http.new()
  349. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  350. end
  351. ngx.sleep(2.5)
  352. local ports_count = {}
  353. for i = 1, 12 do
  354. local httpc = http.new()
  355. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  356. if not res then
  357. ngx.say(err)
  358. return
  359. end
  360. ports_count[res.body] = (ports_count[res.body] or 0) + 1
  361. end
  362. local ports_arr = {}
  363. for port, count in pairs(ports_count) do
  364. table.insert(ports_arr, {port = port, count = count})
  365. end
  366. local function cmd(a, b)
  367. return a.port > b.port
  368. end
  369. table.sort(ports_arr, cmd)
  370. ngx.say(require("toolkit.json").encode(ports_arr))
  371. ngx.exit(200)
  372. }
  373. }
  374. --- request
  375. GET /t
  376. --- response_body
  377. [{"count":12,"port":"1980"}]
  378. --- grep_error_log eval
  379. qr/^.*?\[error\](?!.*process exiting).*/
  380. --- grep_error_log_out eval
  381. qr/Connection refused\) while connecting to upstream/
  382. --- timeout: 10
  383. === TEST 9: chash route (upstream nodes: 2 unhealthy)
  384. --- config
  385. location /t {
  386. content_by_lua_block {
  387. local t = require("lib.test_admin").test
  388. local code, body = t('/apisix/admin/routes/1',
  389. ngx.HTTP_PUT,
  390. [[{"uri":"/server_port","upstream":{"type":"chash","nodes":{"127.0.0.1:1960":1,"127.0.0.1:1961":1},"key":"remote_addr","retries":3,"checks":{"active":{"http_path":"/status","host":"foo.com","healthy":{"interval":999,"successes":3},"unhealthy":{"interval":999,"http_failures":3}},"passive":{"healthy":{"http_statuses":[200,201],"successes":3},"unhealthy":{"http_statuses":[500],"http_failures":3,"tcp_failures":3}}}}}]]
  391. )
  392. if code >= 300 then
  393. ngx.status = code
  394. end
  395. ngx.say(body)
  396. }
  397. }
  398. --- request
  399. GET /t
  400. --- response_body
  401. passed
  402. --- grep_error_log eval
  403. qr/^.*?\[error\](?!.*process exiting).*/
  404. --- grep_error_log_out
  405. === TEST 10: hit routes (passive + retries)
  406. --- config
  407. location /t {
  408. content_by_lua_block {
  409. local http = require "resty.http"
  410. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  411. .. "/server_port"
  412. local ports_count = {}
  413. for i = 1, 2 do
  414. local httpc = http.new()
  415. local res, err = httpc:request_uri(uri,
  416. {method = "GET", keepalive = false}
  417. )
  418. ngx.say("res: ", res.status, " err: ", err)
  419. end
  420. }
  421. }
  422. --- request
  423. GET /t
  424. --- response_body
  425. res: 502 err: nil
  426. res: 502 err: nil
  427. --- grep_error_log eval
  428. qr{\[error\].*while connecting to upstream.*}
  429. --- grep_error_log_out eval
  430. qr{.*http://127.0.0.1:1960/server_port.*
  431. .*http://127.0.0.1:1961/server_port.*
  432. .*http://127.0.0.1:1961/server_port.*
  433. .*http://127.0.0.1:1960/server_port.*
  434. .*http://127.0.0.1:1961/server_port.*
  435. .*http://127.0.0.1:1961/server_port.*}
  436. --- timeout: 10
  437. === TEST 11: add new routh with healthcheck attribute
  438. --- config
  439. location /t {
  440. content_by_lua_block {
  441. local t = require("lib.test_admin").test
  442. for i = 1, 3 do
  443. t('/apisix/admin/routes/' .. i,
  444. ngx.HTTP_PUT,
  445. [[{
  446. "uri": "/server_port",
  447. "upstream": {
  448. "type": "roundrobin",
  449. "nodes": {
  450. "127.0.0.1:1980": 1
  451. },
  452. "checks": {
  453. "active": {
  454. "http_path": "/status",
  455. "host": "foo.com",
  456. "healthy": {
  457. "interval": 1,
  458. "successes": 1
  459. },
  460. "unhealthy": {
  461. "interval": 1,
  462. "http_failures": 2
  463. }
  464. }
  465. }
  466. }
  467. }]]
  468. )
  469. ngx.sleep(0.1)
  470. local code, body = t('/server_port', ngx.HTTP_GET)
  471. ngx.say("code: ", code, " body: ", body)
  472. code, body = t('/apisix/admin/routes/' .. i, ngx.HTTP_DELETE)
  473. ngx.say("delete code: ", code)
  474. ngx.sleep(0.1)
  475. end
  476. }
  477. }
  478. --- request
  479. GET /t
  480. --- response_body
  481. code: 200 body: passed
  482. delete code: 200
  483. code: 200 body: passed
  484. delete code: 200
  485. code: 200 body: passed
  486. delete code: 200
  487. === TEST 12: add route (test health check config `host` valid)
  488. --- config
  489. location /t {
  490. content_by_lua_block {
  491. local t = require("lib.test_admin").test
  492. local code, body = t('/apisix/admin/routes/1',
  493. ngx.HTTP_PUT,
  494. [[{
  495. "uri": "/server_port",
  496. "upstream": {
  497. "type": "roundrobin",
  498. "nodes": {
  499. "127.0.0.1:1980": 1,
  500. "127.0.0.1:1988": 1
  501. },
  502. "checks": {
  503. "active": {
  504. "http_path": "/status",
  505. "host": "foo.com",
  506. "healthy": {
  507. "interval": 1,
  508. "successes": 1
  509. },
  510. "unhealthy": {
  511. "interval": 1,
  512. "http_failures": 2
  513. }
  514. }
  515. }
  516. }
  517. }]]
  518. )
  519. if code >= 300 then
  520. ngx.status = code
  521. end
  522. ngx.say(body)
  523. }
  524. }
  525. --- request
  526. GET /t
  527. --- response_body
  528. passed
  529. === TEST 13: test health check config `host` valid
  530. --- config
  531. location /t {
  532. content_by_lua_block {
  533. local http = require "resty.http"
  534. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  535. .. "/server_port"
  536. local httpc = http.new()
  537. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  538. ngx.sleep(2)
  539. ngx.say(res.status)
  540. }
  541. }
  542. --- request
  543. GET /t
  544. --- response_body
  545. 200
  546. --- grep_error_log eval
  547. qr/^.*?\[warn\].*/
  548. --- grep_error_log_out eval
  549. qr/unhealthy TCP increment.*foo.com/
  550. === TEST 14: add route (test health check customized `port`)
  551. --- config
  552. location /t {
  553. content_by_lua_block {
  554. local t = require("lib.test_admin").test
  555. local code, body = t('/apisix/admin/routes/1',
  556. ngx.HTTP_PUT,
  557. [[{
  558. "uri": "/server_port",
  559. "upstream": {
  560. "type": "roundrobin",
  561. "nodes": {
  562. "127.0.0.1:1980": 1,
  563. "127.0.0.1:1981": 1
  564. },
  565. "checks": {
  566. "active": {
  567. "http_path": "/status",
  568. "port": 1988,
  569. "host": "foo.com",
  570. "healthy": {
  571. "interval": 1,
  572. "successes": 1
  573. },
  574. "unhealthy": {
  575. "interval": 1,
  576. "http_failures": 2
  577. }
  578. }
  579. }
  580. }
  581. }]]
  582. )
  583. if code >= 300 then
  584. ngx.status = code
  585. end
  586. ngx.say(body)
  587. }
  588. }
  589. --- request
  590. GET /t
  591. --- response_body
  592. passed
  593. === TEST 15: test health check customized `port`
  594. --- config
  595. location /t {
  596. content_by_lua_block {
  597. local http = require "resty.http"
  598. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  599. .. "/server_port"
  600. local httpc = http.new()
  601. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  602. ngx.sleep(2)
  603. ngx.say(res.status)
  604. }
  605. }
  606. --- request
  607. GET /t
  608. --- response_body
  609. 200
  610. --- grep_error_log eval
  611. qr/^.*?\[warn\].*/
  612. --- grep_error_log_out eval
  613. qr/unhealthy TCP increment.*foo.com.*127.0.0.1:1988/
  614. --- timeout: 5
  615. === TEST 16: add route (test health check customized `port` out of minimum range)
  616. --- config
  617. location /t {
  618. content_by_lua_block {
  619. local t = require("lib.test_admin").test
  620. local code, body = t('/apisix/admin/routes/1',
  621. ngx.HTTP_PUT,
  622. [[{
  623. "uri": "/server_port",
  624. "upstream": {
  625. "type": "roundrobin",
  626. "nodes": {
  627. "127.0.0.1:1980": 1,
  628. "127.0.0.1:1981": 1
  629. },
  630. "checks": {
  631. "active": {
  632. "http_path": "/status",
  633. "port": 0,
  634. "host": "foo.com",
  635. "healthy": {
  636. "interval": 1,
  637. "successes": 1
  638. },
  639. "unhealthy": {
  640. "interval": 1,
  641. "http_failures": 2
  642. }
  643. }
  644. }
  645. }
  646. }]]
  647. )
  648. if code >= 300 then
  649. ngx.status = code
  650. end
  651. ngx.say(body)
  652. }
  653. }
  654. --- request
  655. GET /t
  656. --- response_body_like eval
  657. qr/expected 0 to be at least 1/
  658. --- error_code chomp
  659. 400
  660. === TEST 17: add route (test health check customized `port` out of maximum range)
  661. --- config
  662. location /t {
  663. content_by_lua_block {
  664. local t = require("lib.test_admin").test
  665. local code, body = t('/apisix/admin/routes/1',
  666. ngx.HTTP_PUT,
  667. [[{
  668. "uri": "/server_port",
  669. "upstream": {
  670. "type": "roundrobin",
  671. "nodes": {
  672. "127.0.0.1:1980": 1,
  673. "127.0.0.1:1981": 1
  674. },
  675. "checks": {
  676. "active": {
  677. "http_path": "/status",
  678. "port": 65536,
  679. "host": "foo.com",
  680. "healthy": {
  681. "interval": 1,
  682. "successes": 1
  683. },
  684. "unhealthy": {
  685. "interval": 1,
  686. "http_failures": 2
  687. }
  688. }
  689. }
  690. }
  691. }]]
  692. )
  693. if code >= 300 then
  694. ngx.status = code
  695. end
  696. ngx.say(body)
  697. }
  698. }
  699. --- request
  700. GET /t
  701. --- response_body_like eval
  702. qr/expected 65536 to be at most 65535/
  703. --- error_code chomp
  704. 400
  705. === TEST 18: set route + upstream (two upstream node: one healthy + one unhealthy)
  706. --- config
  707. location /t {
  708. content_by_lua_block {
  709. local t = require("lib.test_admin").test
  710. local code, body = t('/apisix/admin/upstreams/1',
  711. ngx.HTTP_PUT,
  712. [[{
  713. "type": "roundrobin",
  714. "nodes": {
  715. "127.0.0.1:1980": 1,
  716. "127.0.0.1:1970": 1
  717. },
  718. "checks": {
  719. "active": {
  720. "http_path": "/status",
  721. "host": "foo.com",
  722. "healthy": {
  723. "interval": 1,
  724. "successes": 1
  725. },
  726. "unhealthy": {
  727. "interval": 1,
  728. "http_failures": 2
  729. }
  730. }
  731. }
  732. }]]
  733. )
  734. if code >= 300 then
  735. ngx.status = code
  736. ngx.say(body)
  737. return
  738. end
  739. local code, body = t('/apisix/admin/routes/1',
  740. ngx.HTTP_PUT,
  741. [[{
  742. "uri": "/server_port",
  743. "upstream_id": 1
  744. }]]
  745. )
  746. if code >= 300 then
  747. ngx.status = code
  748. end
  749. ngx.say(body)
  750. }
  751. }
  752. --- request
  753. GET /t
  754. --- response_body
  755. passed
  756. --- grep_error_log eval
  757. qr/^.*?\[error\](?!.*process exiting).*/
  758. --- grep_error_log_out
  759. === TEST 19: hit routes, ensure the checker is bound to the upstream
  760. --- config
  761. location /t {
  762. content_by_lua_block {
  763. local http = require "resty.http"
  764. local uri = "http://127.0.0.1:" .. ngx.var.server_port
  765. .. "/server_port"
  766. do
  767. local httpc = http.new()
  768. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  769. end
  770. ngx.sleep(2.5)
  771. local ports_count = {}
  772. for i = 1, 12 do
  773. local httpc = http.new()
  774. local res, err = httpc:request_uri(uri, {method = "GET", keepalive = false})
  775. if not res then
  776. ngx.say(err)
  777. return
  778. end
  779. ports_count[res.body] = (ports_count[res.body] or 0) + 1
  780. end
  781. local ports_arr = {}
  782. for port, count in pairs(ports_count) do
  783. table.insert(ports_arr, {port = port, count = count})
  784. end
  785. local function cmd(a, b)
  786. return a.port > b.port
  787. end
  788. table.sort(ports_arr, cmd)
  789. ngx.say(require("toolkit.json").encode(ports_arr))
  790. ngx.exit(200)
  791. }
  792. }
  793. --- request
  794. GET /t
  795. --- response_body
  796. [{"count":12,"port":"1980"}]
  797. --- grep_error_log eval
  798. qr/\([^)]+\) unhealthy .* for '.*'/
  799. --- grep_error_log_out
  800. (upstream#/apisix/upstreams/1) unhealthy TCP increment (1/2) for 'foo.com(127.0.0.1:1970)'
  801. (upstream#/apisix/upstreams/1) unhealthy TCP increment (2/2) for 'foo.com(127.0.0.1:1970)'
  802. --- timeout: 10