APISIX外掛如何編寫單元測試

跡_Jason發表於2021-11-19

參考文件:

example.lua

local core = require("apisix.core")
local pairs = pairs
local type = type
local ngx = ngx
local buffers = {}
local schema = {
    type = "object",
    properties = {
        message = {
            description = "需要列印的日誌",
            type = "string"
        }
    },
    required = { "message" },
    minProperties = 1,
}

local plugin_name = "example"

local _M = {
    version = 0.1,
    priority = 412,
    name = plugin_name,
    schema = schema,
}

function _M.check_schema(conf)
    local ok, err = core.schema.check(schema, conf)
    if not ok then
        return false, err
    end
    core.log.info("xxxxxxxx: ", "gjx")
    return true
end

function _M.log(conf, ctx)
    buffers.message = conf.message
    core.log.debug("metadata:",core.json.encode(buffers,true))
end

return _M

Example.t

use t::APISIX 'no_plan';

repeat_each(1); -- 重複次數
no_long_string(); -- 預設地,失敗的字串匹配測試將會使用 Test::LongString 模組產生一個錯誤資訊,在 run_tests 之前呼叫這個函式將會關閉它
no_root_location();
no_shuffle(); -- 在no_shuffle()呼叫的情況下,測試塊的執行順序與它們在測試檔案中出現的順序完全一致
log_level('debug'); -- 日誌級別
run_tests; -- 這個放在最後

__DATA__

=== TEST 1: sanity  -- 用例名稱
--- config   -- 用於配置Nginx conf 資訊
    location /t {
        content_by_lua_block {
            local plugin = require("apisix.plugins.example")
             local ctx ={
                headers={
                }
            }
            local ok, err = plugin.check_schema({message="gejiax"})
            if not ok then
                ngx.say(err)
            end
            plugin.log({message="gejiax"},ctx)
            ngx.say("done")  -- 列印結果
        }
    }
--- request  -- 呼叫請求,校驗結果
GET /t
--- more_headers -- 頭部資訊
Authorization: Bearer eyJhbGc
--- response_headers  -- 響應返回頭部資訊
in: out
--- error_code: 401 -- 狀態碼
--- response_body  -- 請求結果
done
--- no_error_log  -- 表示會對 nginx 的 error.log 檢查,必須沒有 EORROR 級別的記錄
[error]
--- response_body_like eval  --返回值正規表示式校驗
qr/"Access Denied"/
--- error_log eval   --錯誤日誌正規表示式
qr/conf_version: \d+#1,/

content_by_lua_block 說明

=== TEST 12: Add https endpoint with ssl_verify false
--- config
    location /t {
        content_by_lua_block {
            local t = require("lib.test_admin").test  -- 呼叫apisix介面的實現,?就是如何去呼叫API介面的示例
            local code, body = t('/apisix/admin/routes/1',
                 ngx.HTTP_PUT,
                 [[{
                        "plugins": {
                            "authz-keycloak": {
                                "token_endpoint": "https://127.0.0.1:8443/auth/realms/University/protocol/openid-connect/token",
                                "permissions": ["course_resource#delete"],
                                "client_id": "course_management",
                                "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
                                "timeout": 3000,
                                "ssl_verify": false
                            }
                        },
                        "upstream": {
                            "nodes": {
                                "127.0.0.1:1982": 1
                            },
                            "type": "roundrobin"
                        },
                        "uri": "/hello1"
                }]],
                [[{
                    "node": {
                        "value": {
                            "plugins": {
                                "authz-keycloak": {
                                    "token_endpoint": "https://127.0.0.1:8443/auth/realms/University/protocol/openid-connect/token",
                                    "permissions": ["course_resource#delete"],
                                    "client_id": "course_management",
                                    "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
                                    "timeout": 3000,
                                    "ssl_verify": false
                                }
                            },
                            "upstream": {
                                "nodes": {
                                    "127.0.0.1:1982": 1
                                },
                                "type": "roundrobin"
                            },
                            "uri": "/hello1"
                        },
                        "key": "/apisix/routes/1"
                    },
                    "action": "set"
                }]]
                )

            if code >= 300 then
                ngx.status = code
            end
            ngx.say(body)
        }
    }
--- request
GET /t
--- response_body
passed
--- no_error_log
[error]

HTTP 請求

location /t {
        content_by_lua_block {
            local json_decode = require("toolkit.json").decode  -- json 工具類
            local http = require "resty.http"
            local httpc = http.new()
            local uri = "http://127.0.0.1:8090/auth/realms/University/protocol/openid-connect/token"
            local res, err = httpc:request_uri(uri, {
                    method = "POST",
                    body = "grant_type=password&client_id=course_management&client_secret=d1ec69e9-55d2-4109-a3ea-befa071579d5&username=teacher@gmail.com&password=123456",
                    headers = {
                        ["Content-Type"] = "application/x-www-form-urlencoded"
                    }
                })

            if res.status == 200 then
                local body = json_decode(res.body)
                local accessToken = body["access_token"]


                uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello1"
                local res, err = httpc:request_uri(uri, {
                    method = "GET",
                    headers = {
                        ["Authorization"] = "Bearer " .. accessToken,
                    }
                 })

                if res.status == 200 then
                    ngx.say(true)
                else
                    ngx.say(false)
                end
            else
                ngx.say(false)
            end
        }
    }

多個location

=== TEST 6: first request timeout
--- config
    location = /aggregate {
        content_by_lua_block {
            local core = require("apisix.core")
            local t = require("lib.test_admin").test
            local code, body = t('/apisix/batch-requests',
                ngx.HTTP_POST,
                [=[{
                    "timeout": 100,
                    "pipeline":[
                    {
                        "path": "/b",
                        "headers": {
                            "Header1": "hello",
                            "Header2": "world"
                        }
                    },{
                        "path": "/c",
                        "method": "PUT"
                    },{
                        "path": "/d"
                    }]
                }]=],
                [=[[
                {
                    "status": 504,
                    "reason": "upstream timeout"
                }
                ]]=]
                )

            ngx.status = code
            ngx.say(body)
        }
    }

    location = /b {
        content_by_lua_block {
            ngx.sleep(1)
            ngx.status = 200
        }
    }
    location = /c {
        content_by_lua_block {
            ngx.status = 201
        }
    }
    location = /d {
        content_by_lua_block {
            ngx.status = 202
        }
    }
--- request
GET /aggregate
--- response_body
passed
--- error_log
timeout

相關文章