You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by me...@apache.org on 2020/10/27 06:10:54 UTC
[apisix] branch master updated: feature: support percentage for
fault injection (#2516)
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 <zc...@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]