git mv Ingress ingress

This commit is contained in:
Prashanth Balasubramanian 2016-02-21 16:13:08 -08:00
parent 34b949c134
commit 3da4e74e5a
2185 changed files with 754743 additions and 0 deletions

View file

@ -0,0 +1,233 @@
use Test::Nginx::Socket;
use Cwd qw(cwd);
plan tests => repeat_each() * 24;
my $pwd = cwd();
our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;;";
};
no_long_string();
run_tests();
__DATA__
=== TEST 1: Load module without errors.
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
';
}
--- config
location /sanity {
echo "OK";
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
OK
=== TEST 2: Can init cache - defaults
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /sanity {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
ngx.say(DNS_Cache.initted())
';
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
true
=== TEST 3: Can init cache - user config
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache(300)
';
}
--- config
location /sanity {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
ngx.say(DNS_Cache.initted())
';
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
true
=== TEST 4: Can init new instance - defaults
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache(300)
';
}
--- config
location /sanity {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new()
if dns then
ngx.say("OK")
else
ngx.say(err)
end
';
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
OK
=== TEST 5: Can init new instance - user config
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache(300)
';
}
--- config
location /sanity {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
negative_ttl = 10,
resolver = { nameservers = {"10.10.10.10"} }
})
if dns then
ngx.say("OK")
else
ngx.say(err)
end
';
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
OK
=== TEST 6: Resty DNS errors are passed through
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache(300)
';
}
--- config
location /sanity {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
resolver = { }
})
if dns then
ngx.say("OK")
else
ngx.say(err)
end
';
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
no nameservers specified
=== TEST 7: Can create instance with shared dict
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /sanity {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
ngx.say(DNS_Cache.initted())
local dns, err = DNS_Cache.new({
dict = "dns_cache"
})
if dns then
ngx.say("OK")
else
ngx.say(err)
end
';
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
true
OK
=== TEST 8: Can create instance with shared dict and no lru_cache
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
}
--- config
location /sanity {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
ngx.say(DNS_Cache.initted())
local dns, err = DNS_Cache.new({
dict = "dns_cache"
})
if dns then
ngx.say("OK")
else
ngx.say(err)
end
';
}
--- request
GET /sanity
--- no_error_log
[error]
--- response_body
false
OK

View file

@ -0,0 +1,195 @@
use lib 't';
use TestDNS;
use Cwd qw(cwd);
plan tests => repeat_each() * 12;
my $pwd = cwd();
our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;;";
};
no_long_string();
run_tests();
__DATA__
=== TEST 1: Can resolve with lru + dict
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {
nameservers = { {"127.0.0.1", "1953"} }
}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 }],
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456}]
=== TEST 2: Can resolve with lru only
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
resolver = {
nameservers = { {"127.0.0.1", "1953"} }
}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 }],
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456}]
=== TEST 3: Can resolve with dict only
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {
nameservers = { {"127.0.0.1", "1953"} }
}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 }],
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456}]
=== TEST 4: Can resolve with no cache, error thrown
--- http_config eval
"$::HttpConfig"
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
resolver = {
nameservers = { {"127.0.0.1", "1953"} }
}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 }],
}
--- request
GET /t
--- error_log
No cache defined
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456}]

View file

@ -0,0 +1,873 @@
use lib 't';
use TestDNS;
use Cwd qw(cwd);
plan tests => repeat_each() * 47;
my $pwd = cwd();
our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;;";
lua_socket_log_errors off;
};
no_long_string();
run_tests();
__DATA__
=== TEST 1: Response comes from cache on second hit
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 }],
}
--- request
GET /t
--- error_log
lru_cache HIT
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456}]
=== TEST 2: Response comes from dict on miss
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache() -- reset cache
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 }],
}
--- request
GET /t
--- error_log
lru_cache MISS
shared_dict HIT
lru_cache SET
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456}]
=== TEST 3: Stale response from lru served if resolver down
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_sleep 2;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1954"}}, retrans = 1, timeout = 100}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if stale then
answer = stale
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- error_log
lru_cache MISS
lru_cache STALE
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":-1}]
=== TEST 4: Stale response from dict served if resolver down
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_sleep 2;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1954"}}, retrans = 1, timeout = 100}
})
DNS_Cache.init_cache() -- reset cache
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if stale then
answer = stale
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- error_log
lru_cache MISS
shared_dict STALE
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":-1}]
=== TEST 5: Stale response from lru served if resolver down, no dict
--- http_config eval
"$::HttpConfig"
. q{
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_sleep 2;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1954"}}, retrans = 1, timeout = 100}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if stale then
answer = stale
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- error_log
lru_cache MISS
lru_cache STALE
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":-1}]
=== TEST 6: Stale response from dict served if resolver down, no lru
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
}
--- config
location /t {
echo_location /_t;
echo_sleep 2;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1954"}}, retrans = 1, timeout = 100}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if stale then
answer = stale
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- error_log
shared_dict STALE
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":-1}]
=== TEST 7: TTLs are reduced
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_sleep 2;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}, retrans = 1, timeout = 100}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(answer)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 10 }],
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":8}]
=== TEST 8: TTL reduction can be disabled
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_sleep 2;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
normalise_ttl = false,
resolver = {nameservers = {{"127.0.0.1", "1953"}}, retrans = 1, timeout = 100}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(answer)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 10 }],
}
--- request
GET /t
--- no_error_log
[error]
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":10}]
=== TEST 9: Negative responses are not cached by default
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns._debug(true)
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
rcode => 3,
opcode => 0,
qname => 'www.google.com',
}
--- request
GET /t
--- no_error_log
SET
--- response_body
{"errcode":3,"errstr":"name error"}
=== TEST 10: Negative responses can be cached
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
negative_ttl = 10,
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
negative_ttl = 10,
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
rcode => 3,
opcode => 0,
qname => 'www.google.com',
}
--- request
GET /t
--- error_log
lru_cache HIT
--- response_body
{"errcode":3,"errstr":"name error"}
=== TEST 11: Cached negative responses are not returned by default
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
echo_location /_t;
echo_location /_t2;
}
location /_t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
negative_ttl = 10,
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns._debug(true)
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
';
}
location /_t2 {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1954"}, retrans = 1, timeout = 100}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
rcode => 3,
opcode => 0,
qname => 'www.google.com',
}
--- request
GET /t
--- error_log
lru_cache SET
lru_cache HIT
--- response_body
null
=== TEST 12: Cache TTL can be minimised
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
minimise_ttl = true,
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [
{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 },
{ name => "l.www.google.com", ipv6 => "::1", ttl => 10 },
],
}
--- request
GET /t
--- error_log
lru_cache SET: www.google.com|1 10
shared_dict SET: www.google.com|1 10
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456},{"address":"0:0:0:0:0:0:0:1","type":28,"class":1,"name":"l.www.google.com","ttl":10}]
=== TEST 13: Cache TTLs not minimised by default
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}}
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [
{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 123456 },
{ name => "l.www.google.com", ipv6 => "::1", ttl => 10 },
],
}
--- request
GET /t
--- error_log
lru_cache SET: www.google.com|1 123456
shared_dict SET: www.google.com|1 123456
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":123456},{"address":"0:0:0:0:0:0:0:1","type":28,"class":1,"name":"l.www.google.com","ttl":10}]

View file

@ -0,0 +1,275 @@
use lib 't';
use TestDNS;
use Cwd qw(cwd);
plan tests => repeat_each() * 17;
my $pwd = cwd();
our $HttpConfig = qq{
lua_package_path "$pwd/lib/?.lua;;";
lua_socket_log_errors off;
};
no_long_string();
run_tests();
__DATA__
=== TEST 1: Query is triggered when cache is expired
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}},
max_stale = 10
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
dns._debug(true)
-- Sleep beyond response TTL
ngx.sleep(1.1)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
if stale then
answer = stale
else
ngx.say(err)
end
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
ngx.sleep(0.1)
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- error_log
Returning STALE
Attempting to repopulate 'www.google.com'
Repopulating 'www.google.com'
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":1}]
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":0}]
=== TEST 2: Query is not triggered when cache expires and max_stale is disabled
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}, retrans = 1, timeout = 50 },
max_stale = 0
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
dns._debug(true)
-- Sleep beyond response TTL
ngx.sleep(1.1)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
if stale then
answer = stale
else
ngx.say(err)
end
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
ngx.sleep(0.1)
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- no_error_log
Attempting to repopulate 'www.google.com'
Repopulating 'www.google.com'
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":0}]
=== TEST 3: Repopulate ignores max_stale
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}, retrans = 1, timeout = 50 },
max_stale = 10,
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
-- Sleep beyond response TTL
ngx.sleep(1.1)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
if stale then
answer = stale
else
ngx.say(err)
end
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
ngx.sleep(0.1)
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- error_log
Repopulating 'www.google.com'
Querying: www.google.com
Resolver error
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":0}]
=== TEST 4: Multiple queries only trigger 1 repopulate timer
--- http_config eval
"$::HttpConfig"
. q{
lua_shared_dict dns_cache 1m;
init_by_lua '
local DNS_Cache = require("resty.dns.cache")
DNS_Cache.init_cache()
';
}
--- config
location /t {
content_by_lua '
local DNS_Cache = require("resty.dns.cache")
local dns, err = DNS_Cache.new({
dict = "dns_cache",
resolver = {nameservers = {{"127.0.0.1", "1953"}}, retrans = 1, timeout = 50 },
repopulate = true,
})
if not dns then
ngx.say(err)
end
dns.resolver._id = 125
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
dns._debug(true)
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local answer, err, stale = dns:query("www.google.com", { qtype = dns.TYPE_A })
if not answer then
ngx.say(err)
end
local cjson = require"cjson"
ngx.say(cjson.encode(answer))
';
}
--- udp_listen: 1953
--- udp_reply dns
{
id => 125,
opcode => 0,
qname => 'www.google.com',
answer => [{ name => "www.google.com", ipv4 => "127.0.0.1", ttl => 1 }],
}
--- request
GET /t
--- no_error_log
Attempting to repopulate www.google.com
--- response_body
[{"address":"127.0.0.1","type":1,"class":1,"name":"www.google.com","ttl":1}]

View file

@ -0,0 +1,271 @@
package TestDNS;
use strict;
use warnings;
use 5.010001;
use Test::Nginx::Socket::Lua -Base;
#use JSON::XS;
use constant {
TYPE_A => 1,
TYPE_TXT => 16,
TYPE_CNAME => 5,
TYPE_AAAA => 28,
CLASS_INTERNET => 1,
};
sub encode_name ($);
sub encode_ipv4 ($);
sub encode_ipv6 ($);
sub gen_dns_reply ($$);
sub Test::Base::Filter::dns {
my ($self, $code) = @_;
my $args = $self->current_arguments;
#warn "args: $args";
if (defined $args && $args ne 'tcp' && $args ne 'udp') {
die "Invalid argument to the \"dns\" filter: $args\n";
}
my $mode = $args // 'udp';
my $block = $self->current_block;
my $pointer_spec = $block->dns_pointers;
my @pointers;
if (defined $pointer_spec) {
my @loops = split /\s*,\s*/, $pointer_spec;
for my $loop (@loops) {
my @nodes = split /\s*=>\s*/, $loop;
my $prev;
for my $n (@nodes) {
if ($n !~ /^\d+$/ || $n == 0) {
die "bad name ID in the --- dns_pointers: $n\n";
}
if (!defined $prev) {
$prev = $n;
next;
}
$pointers[$prev] = $n;
}
}
}
my $input = eval $code;
if ($@) {
die "failed to evaluate code $code: $@\n";
}
if (!ref $input) {
return $input;
}
if (ref $input eq 'ARRAY') {
my @replies;
for my $t (@$input) {
push @replies, gen_dns_reply($t, $mode);
}
return \@replies;
}
if (ref $input eq 'HASH') {
return gen_dns_reply($input, $mode);
}
return $input;
}
sub gen_dns_reply ($$) {
my ($t, $mode) = @_;
my @raw_names;
push @raw_names, \($t->{qname});
my $answers = $t->{answer} // [];
if (!ref $answers) {
$answers = [$answers];
}
for my $ans (@$answers) {
push @raw_names, \($ans->{name});
if (defined $ans->{cname}) {
push @raw_names, \($ans->{cname});
}
}
for my $rname (@raw_names) {
$$rname = encode_name($$rname // "");
}
my $qname = $t->{qname};
my $s = '';
my $id = $t->{id} // 0;
$s .= pack("n", $id);
#warn "id: ", length($s), " ", encode_json([$s]);
my $qr = $t->{qr} // 1;
my $opcode = $t->{opcode} // 0;
my $aa = $t->{aa} // 0;
my $tc = $t->{tc} // 0;
my $rd = $t->{rd} // 1;
my $ra = $t->{ra} // 1;
my $rcode = $t->{rcode} // 0;
my $flags = ($qr << 15) + ($opcode << 11) + ($aa << 10) + ($tc << 9) + ($rd << 8) + ($ra << 7) + $rcode;
#warn sprintf("flags: %b", $flags);
$flags = pack("n", $flags);
$s .= $flags;
#warn "flags: ", length($flags), " ", encode_json([$flags]);
my $qdcount = $t->{qdcount} // 1;
my $ancount = $t->{ancount} // scalar @$answers;
my $nscount = 0;
my $arcount = 0;
$s .= pack("nnnn", $qdcount, $ancount, $nscount, $arcount);
#warn "qname: ", length($qname), " ", encode_json([$qname]);
$s .= $qname;
my $qs_type = $t->{qtype} // TYPE_A;
my $qs_class = $t->{qclass} // CLASS_INTERNET;
$s .= pack("nn", $qs_type, $qs_class);
for my $ans (@$answers) {
my $name = $ans->{name};
my $type = $ans->{type};
my $class = $ans->{class};
my $ttl = $ans->{ttl};
my $rdlength = $ans->{rdlength};
my $rddata = $ans->{rddata};
my $ipv4 = $ans->{ipv4};
if (defined $ipv4) {
my ($data, $len) = encode_ipv4($ipv4);
$rddata //= $data;
$rdlength //= $len;
$type //= TYPE_A;
$class //= CLASS_INTERNET;
}
my $ipv6 = $ans->{ipv6};
if (defined $ipv6) {
my ($data, $len) = encode_ipv6($ipv6);
$rddata //= $data;
$rdlength //= $len;
$type //= TYPE_AAAA;
$class //= CLASS_INTERNET;
}
my $cname = $ans->{cname};
if (defined $cname) {
$rddata //= $cname;
$rdlength //= length $rddata;
$type //= TYPE_CNAME;
$class //= CLASS_INTERNET;
}
my $txt = $ans->{txt};
if (defined $txt) {
$rddata //= $txt;
$rdlength //= length $rddata;
$type //= TYPE_TXT;
$class //= CLASS_INTERNET;
}
$type //= 0;
$class //= 0;
$ttl //= 0;
#warn "rdlength: $rdlength, rddata: ", encode_json([$rddata]), "\n";
$s .= $name . pack("nnNn", $type, $class, $ttl, $rdlength) . $rddata;
}
if ($mode eq 'tcp') {
return pack("n", length($s)) . $s;
}
return $s;
}
sub encode_ipv4 ($) {
my $txt = shift;
my @bytes = split /\./, $txt;
return pack("CCCC", @bytes), 4;
}
sub encode_ipv6 ($) {
my $txt = shift;
my @groups = split /:/, $txt;
my $nils = 0;
my $nonnils = 0;
for my $g (@groups) {
if ($g eq '') {
$nils++;
} else {
$nonnils++;
$g = hex($g);
}
}
my $total = $nils + $nonnils;
if ($total > 8 ) {
die "Invalid IPv6 address: too many groups: $total: $txt";
}
if ($nils) {
my $found = 0;
my @new_groups;
for my $g (@groups) {
if ($g eq '') {
if ($found) {
next;
}
for (1 .. 8 - $nonnils) {
push @new_groups, 0;
}
$found = 1;
} else {
push @new_groups, $g;
}
}
@groups = @new_groups;
}
if (@groups != 8) {
die "Invalid IPv6 address: $txt: @groups\n";
}
#warn "IPv6 groups: @groups";
return pack("nnnnnnnn", @groups), 16;
}
sub encode_name ($) {
my $name = shift;
$name =~ s/([^.]+)\.?/chr(length($1)) . $1/ge;
$name .= "\0";
return $name;
}
1