Skip to content

Commit

Permalink
test: check the service config with json schema after fetched it fo…
Browse files Browse the repository at this point in the history
…rm etcd. (#96)

* test: check the service config with `json schema` after fetched it form etcd.
* test: sleep one more seconds waiting for the etcd sync.
  • Loading branch information
membphis committed Jun 14, 2019
1 parent ba57698 commit f560316
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 54 deletions.
66 changes: 47 additions & 19 deletions lua/apisix/core/config_etcd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ local function short_key(self, str)
end


function _M.upgrade_version(self, new_ver)
local pre_index = self.prev_index
if not pre_index then
self.prev_index = new_ver
return
end

if new_ver <= pre_index then
return
end

self.prev_index = new_ver
return
end


function _M.fetch(self)
if not self.key then
return nil, "missing 'key' arguments"
Expand All @@ -106,27 +122,31 @@ function _M.fetch(self)

local changed = false
for _, item in ipairs(dir_res.nodes) do
local ok = true
if self.item_schema then
ok, err = check_schema(self.item_schema, item.value)
local key = short_key(self, item.key)
local data_valid = true
if type(item.value) ~= "table" then
data_valid = false
log.error("invalid item data of [", self.key .. "/" .. key,
"], val: ", tostring(item.value),
", it shoud be a object")
end

if not ok then
log.error("failed to check item data of [", self.key, "] err:",
err)
if data_valid and self.item_schema then
data_valid, err = check_schema(self.item_schema, item.value)
if not data_valid then
log.error("failed to check item data of [", self.key,
"] err:", err)
end
end

else
if data_valid then
changed = true
insert_tab(self.values, item)
local key = short_key(self, item.key)
self.values_hash[key] = #self.values
item.id = key
end

if not self.prev_index or
item.modifiedIndex > self.prev_index then
self.prev_index = item.modifiedIndex
end
self:upgrade_version(item.modifiedIndex)
end

if changed then
Expand All @@ -140,11 +160,22 @@ function _M.fetch(self)
return nil, err
end

if self.item_schema and res.value then
local key = short_key(self, res.key)
if res.value and type(res.value) ~= "table" then
self:upgrade_version(res.modifiedIndex)
log.error("invalid item data of [", self.key .. "/" .. key, "], val: ",
tostring(res.value),
", it shoud be a object")
return self.values
end

if res.value and self.item_schema then
local ok, err = check_schema(self.item_schema, res.value)
if not ok then
log.error("failed to check item data of [", self.key, "] err:", err)
return nil, err
self:upgrade_version(res.modifiedIndex)

log.warn("failed to check item data of [", self.key, "] err:", err)
return self.values
end
end

Expand All @@ -155,11 +186,8 @@ function _M.fetch(self)
end
-- log.warn("waitdir: ", encode_json(res))

if not self.prev_index or res.modifiedIndex > self.prev_index then
self.prev_index = res.modifiedIndex
end
self:upgrade_version(res.modifiedIndex)

local key = short_key(self, res.key)
res.id = key
local pre_index = self.values_hash[key]
if pre_index then
Expand Down
51 changes: 36 additions & 15 deletions lua/apisix/core/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,29 @@ function _M.check(schema, json)
end


local plugins_schema = [[
"plugins": {
"type": "object"
}
]]


local upstream_schema = [[
"upstream": {
"type": "object",
"properties": {
"nodes": {
"type": "object"
},
"type": {
"type": "string"
}
},
"required": ["nodes", "type"]
}
]]


_M.route = [[{
"type": "object",
"properties": {
Expand All @@ -42,23 +65,11 @@ _M.route = [[{
"items": {
"type": "string",
"enum": ["GET", "PUT", "POST", "DELETE"]
"uniqueItems" = true,
}
},
"plugins": {
"type": "object"
},
"upstream": {
"type": "object",
"properties": {
"nodes": {
"type": "object"
},
"type": {
"type": "string"
}
},
"required": ["nodes", "type"]
},
]] .. plugins_schema .. [[,
]] .. upstream_schema .. [[,
"uri": {
"type": "string"
}
Expand All @@ -67,4 +78,14 @@ _M.route = [[{
}]]


_M.service = [[{
"type": "object",
"properties": {
]] .. plugins_schema .. [[,
]] .. upstream_schema .. [[
},
"required": ["upstream"]
}]]


return _M
6 changes: 5 additions & 1 deletion lua/apisix/service.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ end

function _M.init_worker()
local err
services, err = core.config.new("/services", {automatic = true})
services, err = core.config.new("/services",
{
automatic = true,
item_schema = core.schema.service
})
if not services then
error("failed to create etcd instance to fetch upstream: " .. err)
return
Expand Down
4 changes: 2 additions & 2 deletions t/admin/routes.t
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ passed
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
code, message = t('/apisix/admin/routes/1',
local code, message = t('/apisix/admin/routes/1',
ngx.HTTP_DELETE,
nil,
[[{
Expand All @@ -133,7 +133,7 @@ GET /t
location /t {
content_by_lua_block {
local t = require("lib.test_admin").test
code = t('/apisix/admin/routes/not_found',
local code = t('/apisix/admin/routes/not_found',
ngx.HTTP_DELETE,
nil,
[[{
Expand Down
35 changes: 25 additions & 10 deletions t/node/invalid-route.t
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ __DATA__
--- request
GET /t
--- error_log
failed to check item data of [/apisix/routes] err:invalid
invalid item data of [/apisix/routes/1], val: mexxxxxxxxxxxxxxx, it shoud be a object
--- response_body_like eval
qr/"value":"mexxxxxxxxxxxxxxx"/
Expand All @@ -41,25 +41,40 @@ GET /not_found
--- response_body_like eval
qr/404 Not Found/
--- error_log
failed to check item data of [/apisix/routes] err:invalid
invalid item data of [/apisix/routes/1], val: mexxxxxxxxxxxxxxx, it shoud be a object
=== TEST 3: delete invalid route(id: 1)
=== TEST 3: set valid route(id: 1)
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local res, err = core.etcd.delete("/routes/1")
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
ngx.HTTP_PUT,
[[{
"methods": ["GET"],
"plugins": {},
"id":1,
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
},
"uri": "/hello"
}]]
)
if res.status >= 300 then
res.status = code
if code >= 300 then
ngx.status = code
end
ngx.say("done")
ngx.say(body)
}
}
--- request
GET /t
--- response_body
done
passed
--- error_log
invalid item data of [/apisix/routes/1], val: mexxxxxxxxxxxxxxx, it shoud be a object
75 changes: 75 additions & 0 deletions t/node/invalid-service.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use t::APISix 'no_plan';

repeat_each(1);
log_level('info');
no_long_string();
no_root_location();
no_shuffle();

run_tests();

__DATA__
=== TEST 1: set invalid service(id: 1)
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local res, err = core.etcd.set("/services/1", [[mexxxxxxxxxxxxxxx]])
if res.status >= 300 then
res.status = code
end
ngx.print(core.json.encode(res.body))
ngx.sleep(1)
}
}
--- request
GET /t
--- error_log
invalid item data of [/apisix/services/1], val: mexxxxxxxxxxxxxxx, it shoud be a object
--- response_body_like eval
qr/"value":"mexxxxxxxxxxxxxxx"/
=== TEST 2: /not_found
--- request
GET /not_found
--- error_code: 404
--- response_body_like eval
qr/404 Not Found/
--- error_log
invalid item data of [/apisix/services/1], val: mexxxxxxxxxxxxxxx, it shoud be a object
=== TEST 3: set valid service(id: 1)
--- config
location /t {
content_by_lua_block {
local core = require("apisix.core")
local res, err = core.etcd.set("/services/1", core.json.decode([[{
"plugins": {},
"upstream": {
"nodes": {
"127.0.0.1:1980": 1
},
"type": "roundrobin"
}
}]]))
if res.status >= 300 then
res.status = code
end
ngx.print(core.json.encode(res.body))
}
}
--- request
GET /t
--- response_body_like eval
qr/"nodes":\{"127.0.0.1:1980":1\}/
--- error_log
invalid item data of [/apisix/services/1], val: mexxxxxxxxxxxxxxx, it shoud be a object
35 changes: 28 additions & 7 deletions t/node/sanity.t
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,37 @@ passed
=== TEST 2: /not_found
--- config
location /t {
content_by_lua_block {
ngx.sleep(1)
ngx.say("done")
}
}
--- request
GET /not_found
--- error_code: 404
--- response_body_like eval
qr/404 Not Found/
--- error_code eval
[200, 404]
--- pipelined_requests eval
["GET /t\n",
"GET /not_found\n"]
--- response_body eval
["done\n",
qr/404 Not Found/]
=== TEST 3: hit routes
--- request
GET /hello
--- response_body
hello world
--- config
location /t {
content_by_lua_block {
ngx.sleep(1)
ngx.say("done")
}
}
--- pipelined_requests eval
["GET /t\n",
"GET /hello\n"]
--- response_body eval
["done\n",
"hello world\n"]

0 comments on commit f560316

Please sign in to comment.