-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUtil.pm
196 lines (163 loc) · 6.26 KB
/
Util.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package t::Util;
use strict;
use warnings;
use Cwd qw(cwd);
our $cwd = cwd();
our $LuaPackagePath = "lua_package_path \'$cwd/?.lua;$cwd/?/init.lua;;\';";
our $JitLogConfig = <<_EOC_;
local verbose = false
-- local verbose = true
local outfile = "$Test::Nginx::Util::ErrLogFile"
if verbose then
local dump = require "jit.dump"
dump.on(nil, outfile)
else
local v = require "jit.v"
v.on(outfile)
end
_EOC_
our $InitByLuaBlockConfig = <<_EOC_;
local log = ngx.log
local ERR = ngx.ERR
if os.getenv("PDK_PHASE_CHECKS_LUACOV") == "1" then
require("luacov.runner")("t/phase_checks.luacov")
jit.off()
elseif os.getenv("PDK_LUACOV") == "1" then
require("luacov.runner")("t/pdk.luacov")
jit.off()
end
local private_phases = require("kong.pdk.private.phases")
local phases = private_phases.phases
-- This function executes 1 or more pdk methods twice: the first time with phase
-- checking deactivated, and the second time with phase checking activated.
-- Params:
-- * phase: the phase we want to test, i.e. "access"
-- * skip_fnlist controls a check: by default, this method
-- will check that the provided list of methods is "complete" - that
-- all the methods inside the `mod` (see below) are covered. Setting
-- `skip_fnlist` to `true` will skip that test (so the `mod` can have
-- methods that go untested)
--
-- This method also reads from 2 globals:
-- * phase_check_module is just a string used to determine the "module"
-- For example, if `phase_check_module` is "kong.response", then `mod` is "response"
-- * phase_check_data is an array of tables with this format:
-- {
-- method = "exit", -- the method inside mod, `kong.response.exit` for example
-- args = { 200 }, -- passed to the method
-- init_worker = false, -- expected to always throw an error on init_worker phase
-- certificate = "pending", -- ignored phase
-- rewrite = true, -- expected to work with and without the phase checker
-- access = true,
-- header_filter = "forced false", -- exit will only error with the phase_checks active
-- body_filter = false,
-- log = false,
-- admin_api = true,
-- }
--
function phase_check_functions(phase, skip_fnlist)
-- mock balancer structure
ngx.ctx.balancer_data = {}
local mod
do
local PDK = require "kong.pdk"
local pdk = PDK.new({ enabled_headers = { ["Server"] = true } })
mod = pdk
for part in phase_check_module:gmatch("[^.]+") do
mod = mod[part]
end
end
local entries = {}
for _, entry in ipairs(phase_check_data) do
entries[entry.method] = true
end
if not skip_fnlist then
for fname, fn in pairs(mod) do
if type(fn) == "function" and not entries[fname] then
log(ERR, "function " .. fname .. " has no phase checking data")
end
end
end
for _, fdata in ipairs(phase_check_data) do
local fname = fdata.method
local fn = mod[fname]
if type(fn) ~= "function" then
log(ERR, "function " .. fname .. " does not exist in module")
goto continue
end
local msg = "in " .. phases[phase] .. ", " ..
fname .. " expected "
-- Run function with phase checked disabled
if kong then
kong.ctx = nil
end
-- kong = nil
ngx.ctx.KONG_PHASE = nil
local expected = fdata[phases[phase]]
if expected == "pending" then
goto continue
end
local forced_false = expected == "forced false"
if forced_false then
expected = true
end
local ok1, err1 = pcall(fn, unpack(fdata.args or {}))
if ok1 ~= expected then
local errmsg = ""
if type(err1) == "string" then
errmsg = "; error: " .. err1:gsub(",", ";")
end
log(ERR, msg, tostring(expected),
" when phase check is disabled", errmsg)
ok1 = not ok1
end
if not forced_false
and ok1 == false
and err1
and not err1:match("attempt to index field ")
and not err1:match("API disabled in the ")
and not err1:match("headers have already been sent") then
log(ERR, msg, "an OpenResty error but got ", (err1:gsub(",", ";")))
end
-- Re-enable phase checking and compare results
if not kong then
kong = {}
end
kong.ctx = { core = { } }
ngx.ctx.KONG_PHASE = phase
if forced_false then
ok1, err1 = false, ""
expected = false
end
---[[
local ok2, err2 = pcall(fn, unpack(fdata.args or {}))
if ok1 then
-- succeeded without phase checking,
-- phase checking should not block it.
if not ok2 then
log(ERR, msg, "true when phase check is enabled; got: ", (err2:gsub(",", ";")))
end
else
if ok2 then
log(ERR, msg, "false when phase check is enabled")
end
-- if failed with OpenResty phase error
if err1 and err1:match("API disabled in the ") then
-- should replace with a Kong error
if not err2:match("function cannot be called") then
log(ERR, msg, "a Kong-generated error; got: ", (err2:gsub(",", ";")))
end
end
end
--]]
::continue::
end
end
_EOC_
our $HttpConfig = <<_EOC_;
$LuaPackagePath
init_by_lua_block {
$InitByLuaBlockConfig
}
_EOC_
1;