This is an automated email from the ASF dual-hosted git repository. membphis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push: new 3306a3e feature: support percentage for fault injection (#2516) 3306a3e is described below commit 3306a3ed3ca58ad319a280e484b700fc20dc221b Author: Alex Zhang <zchao1...@gmail.com> AuthorDate: Tue Oct 27 14:10:44 2020 +0800 feature: support percentage for fault injection (#2516) --- apisix/plugins/fault-injection.lua | 27 +++++++-- doc/plugins/fault-injection.md | 2 + doc/zh-cn/plugins/fault-injection.md | 2 + t/plugin/fault-injection.t | 112 +++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 4 deletions(-) diff --git a/apisix/plugins/fault-injection.lua b/apisix/plugins/fault-injection.lua index 8cf8b8d..aace3e2 100644 --- a/apisix/plugins/fault-injection.lua +++ b/apisix/plugins/fault-injection.lua @@ -14,8 +14,10 @@ -- See the License for the specific language governing permissions and -- limitations under the License. -- -local core = require("apisix.core") -local sleep = core.sleep +local core = require("apisix.core") + +local sleep = core.sleep +local random = math.random local plugin_name = "fault-injection" @@ -28,6 +30,7 @@ local schema = { properties = { http_status = {type = "integer", minimum = 200}, body = {type = "string", minLength = 0}, + percentage = {type = "integer", minimum = 0, maximum = 100} }, minProperties = 1, }, @@ -35,6 +38,7 @@ local schema = { type = "object", properties = { duration = {type = "number", minimum = 0}, + percentage = {type = "integer", minimum = 0, maximum = 100} }, minProperties = 1, } @@ -51,6 +55,15 @@ local _M = { } +local function sample_hit(percentage) + if not percentage then + return true + end + + return random(0, 100) <= percentage +end + + function _M.check_schema(conf) local ok, err = core.schema.check(schema, conf) if not ok then @@ -64,11 +77,17 @@ end function _M.rewrite(conf, ctx) core.log.info("plugin rewrite phase, conf: ", core.json.delay_encode(conf)) - if conf.delay and conf.delay.duration ~= nil then + if conf.delay + and conf.delay.duration ~= nil + and sample_hit(conf.delay.percentage) + then sleep(conf.delay.duration) end - if conf.abort and conf.abort.http_status ~= nil then + if conf.abort + and conf.abort.http_status ~= nil + and sample_hit(conf.abort.percentage) + then return conf.abort.http_status, conf.abort.body end end diff --git a/doc/plugins/fault-injection.md b/doc/plugins/fault-injection.md index 7209018..ff09cfc 100644 --- a/doc/plugins/fault-injection.md +++ b/doc/plugins/fault-injection.md @@ -29,7 +29,9 @@ Fault injection plugin, this plugin can be used with other plugins and will be e | ----------------- | ------- | ----------- | ------- | ---------- | ------------------------------------------------ | | abort.http_status | integer | optional | | [200, ...] | user-specified http code returned to the client. | | abort.body | string | optional | | | response data returned to the client. | +| abort.percentage | integer | optional | | [0, 100] | percentage of requests to be aborted. | | delay.duration | number | optional | | | delay time (can be decimal). | +| delay.percentage | integer | optional | | [0, 100] | percentage of requests to be delayed. | Note: One of `abort` and `delay` must be specified. diff --git a/doc/zh-cn/plugins/fault-injection.md b/doc/zh-cn/plugins/fault-injection.md index eb50de8..ad40492 100644 --- a/doc/zh-cn/plugins/fault-injection.md +++ b/doc/zh-cn/plugins/fault-injection.md @@ -29,7 +29,9 @@ | ----------------- | ------- | ------ | ------ | ---------- | -------------------------- | | abort.http_status | integer | 可选 | | [200, ...] | 返回给客户端的 http 状态码 | | abort.body | string | 可选 | | | 返回给客户端的响应数据 | +| abort.percentage | integer | 可选 | | [0, 100] | 将被中断的请求占比 | | delay.duration | number | 可选 | | | 延迟时间,可以指定小数 | +| delay.percentage | integer | 可选 | | [0, 100] | 将被延迟的请求占比 | 注:参数 abort 和 delay 至少要存在一个。 diff --git a/t/plugin/fault-injection.t b/t/plugin/fault-injection.t index 9a44745..c427714 100644 --- a/t/plugin/fault-injection.t +++ b/t/plugin/fault-injection.t @@ -523,3 +523,115 @@ GET /hello HTTP/1.1 Fault Injection! --- no_error_log [error] + + + +=== TEST 16: set route (abort injection but with zero percentage) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "fault-injection": { + "abort": { + "http_status": 200, + "body": "Fault Injection!\n", + "percentage": 0 + } + }, + "redirect": { + "uri": "/hello/world", + "ret_code": 302 + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- error_code: 200 +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 17: hit route (redirect) +--- request +GET /hello HTTP/1.1 +--- error_code: 302 +--- no_error_log +[error] + + + +=== TEST 18: set route (delay injection but with zero percentage) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "fault-injection": { + "delay": { + "duration": 1, + "percentage": 0 + } + }, + "proxy-rewrite": { + "uri": "/hello1" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- error_code: 200 +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 19: hit route (no wait and return hello1 world) +--- request +GET /hello HTTP/1.1 +--- error_code: 200 +--- response_body +hello1 world +--- no_error_log +[error]