*.gcno
*.gcda
*.gcov
+*.info
+luacov.*.out
.dirstamp
.libs
.deps
[submodule "modules/policy/lua-aho-corasick"]
path = modules/policy/lua-aho-corasick
url = git://github.com/cloudflare/lua-aho-corasick.git
+[submodule "tests/config/tapered"]
+ path = tests/config/tapered
+ url = https://github.com/telemachus/tapered.git
-- Ignore test files
exclude_files = {
'modules/policy/lua-aho-corasick', -- Vendored
+ 'tests/config/tapered',
}
-- Ignore some pedantic checks
-- Tests and scripts can use global variables
files['scripts'].ignore = {'111', '112', '113'}
files['tests'].ignore = {'111', '112', '113'}
-files['tests/config/test_utils.lua'].ignore = {'121'}
\ No newline at end of file
+files['modules/*/*_test.lua'].ignore = {'111', '112', '113'}
\ No newline at end of file
--- /dev/null
+local utils = require('test_utils')
+
+-- setup resolver
+modules = { 'hints' }
+
+-- test for default configuration
+local function test_default()
+ -- get loaded root hints and change names to lowercase
+ hints_data = utils.table_keys_to_lower(hints.root())
+
+ -- root hints loaded from default location
+ -- check correct ip address of a.root-server.net
+ utils.contains(hints_data['a.root-servers.net.'], '198.41.0.4', 'has IP address for a.root-servers.net.')
+end
+
+-- test loading from config file
+local function test_custom()
+ -- load custom root hints file with fake ip address for a.root-server.net
+ err_msg = hints.root_file(TEST_DIR .. 'hints_test.zone')
+ same(err_msg, '', 'load root hints from file')
+
+ -- get loaded root hints and change names to lowercase
+ hints_data = utils.table_keys_to_lower(hints.root())
+ isnt(hints_data['a.root-servers.net.'], nil, 'can retrieve root hints')
+
+ -- check loaded ip address of a.root-server.net
+ utils.not_contains(hints_data['a.root-servers.net.'], '198.41.0.4', 'real IP address for a.root-servers.net. is replaced')
+ utils.contains(hints_data['a.root-servers.net.'], '10.0.0.1', 'real IP address for a.root-servers.net. is correct')
+end
+
+return {
+ test_default,
+ test_custom
+}
\ No newline at end of file
-dofile('./test_utils.lua') -- load test utilities
-
-- setup resolver
modules = { 'predict' }
-- mock global functions
local resolve_count = 0
+local current_epoch = 0
+
worker.resolve = function ()
resolve_count = resolve_count + 1
end
+
stats.frequent = function ()
return {
{name = 'example.com', type = 'TYPE65535'},
{name = 'example.com', type = 'SOA'},
}
end
-local current_epoch = 0
+
predict.epoch = function ()
return current_epoch % predict.period + 1
end
-- test if draining of prefetch queue works
-function test_predict_drain()
+local function test_predict_drain()
predict.queue_len = 2
predict.queue['TYPE65535 example.com'] = 1
predict.queue['SOA example.com'] = 1
predict.drain()
-- test that it attempted to prefetch
- assert.same(2, resolve_count)
- assert.same(0, predict.queue_len)
+ same(resolve_count, 2, 'attempted to prefetch on drain')
+ same(predict.queue_len, 0, 'prefetch queue empty after drain')
end
-- test if prediction process works
-function test_predict_process()
+local function test_predict_process()
-- start new epoch
predict.process()
- assert.same(0, predict.queue_len)
+ same(predict.queue_len, 0, 'first epoch, empty prefetch queue')
-- next epoch, still no period for frequent queries
current_epoch = current_epoch + 1
predict.process()
- assert.same(0, predict.queue_len)
+ same(predict.queue_len, 0, 'second epoch, empty prefetch queue')
-- next epoch, found period
current_epoch = current_epoch + 1
predict.process()
- assert.same(2, predict.queue_len)
+ same(predict.queue_len, 2, 'third epoch, prefetching')
-- drain works with scheduled prefetches (two batches)
resolve_count = 0
predict.drain()
predict.drain()
- assert.same(2, resolve_count)
- assert.same(0, predict.queue_len)
+ same(resolve_count, 2, 'attempted to resolve queries in queue')
+ same(predict.queue_len, 0, 'prefetch queue is empty')
end
--- run test after processed config file
--- default config will be used and we can test it.
-event.after(0, function (ev)
- test(test_predict_drain)
- test(test_predict_process)
- quit()
-end)
+-- return test set
+return {
+ test_predict_drain,
+ test_predict_process
+}
\ No newline at end of file
+++ /dev/null
-dofile('./test_utils.lua') -- load test utilities
-
--- test if constants work properly
-function test_constants()
- assert.same(1, kres.class.IN)
- assert.same(1, kres.class['IN'])
- assert.same(2, kres.type.NS)
- assert.same(2, kres.type.TYPE2)
- assert.same(nil, kres.type.BADTYPE)
- assert.same(2, kres.rcode.SERVFAIL)
-end
-
--- test if rrsets interfaces work
-function test_rrsets()
- local rr = {owner = '\3com', ttl = 1, type = kres.type.TXT, rdata = '\5hello'}
- local rr_text = tostring(kres.rr2str(rr))
- assert.same('com. 1 TXT "hello"', rr_text:gsub('%s+', ' '))
-end
-
--- run test after processed config file
--- default config will be used and we can test it.
-event.after(0, function (ev)
- test(test_constants)
- test(test_rrsets)
- quit()
-end)
--- /dev/null
+-- test if constants work properly
+local function test_constants()
+ same(kres.class.IN, 1, 'class constants work')
+ same(kres.type.NS, 2, 'record type constants work')
+ same(kres.type.TYPE2, 2, 'unnamed record type constants work')
+ same(kres.type.BADTYPE, nil, 'non-existent type constants are checked')
+ same(kres.rcode.SERVFAIL, 2, 'rcode constants work')
+end
+
+-- test globals
+local function test_globals()
+ ok(mode('strict'), 'changing strictness mode')
+ boom(mode, {'badmode'}, 'changing to non-existent strictness mode')
+ same(reorder_RR(true), true, 'answer section reordering')
+ same(option('REORDER_RR', false), false, 'generic option call')
+ boom(option, {'REORDER_RR', 'potato'}, 'generic option call argument check')
+ boom(option, {'MARS_VACATION', false}, 'generic option check name')
+ same(table_print('crabdiary'), 'crabdiary\n', 'table print works')
+ same(table_print({fakepizza=1}), '[fakepizza] => 1\n', 'table print works on tables')
+end
+
+-- test if dns library functions work
+local function test_kres_functions()
+ local rr = {owner = '\3com', ttl = 1, type = kres.type.TXT, rdata = '\5hello'}
+ local rr_text = tostring(kres.rr2str(rr))
+ same(rr_text:gsub('%s+', ' '), 'com. 1 TXT "hello"', 'rrset to text works')
+ same(kres.dname2str(todname('com.')), 'com.', 'domain name conversion works')
+end
+
+return {
+ test_constants,
+ test_globals,
+ test_kres_functions,
+}
\ No newline at end of file
+++ /dev/null
-dofile('./test_utils.lua') -- load test utilities
-
--- setup resolver
-modules = { 'hints' }
-
--- test for default configuration
-function test_default()
- -- get loaded root hints and change names to lowercase
- hints_data = table_keys_to_lower(hints.root())
-
- -- root hints loaded from default location
- -- check correct ip address of a.root-server.net
- if not contains(hints_data['a.root-servers.net.'], '198.41.0.4') then
- fail("Real IP address for a.root-servers.net. not found.")
- end
-end
-
--- test loading from config file
-function test_custom()
- -- load custom root hints file with fake ip address for a.root-server.net
- err_msg = hints.root_file('hints.zone')
- if err_msg ~= '' then
- fail("hints.root_file error: %s", err_msg)
- end
-
- -- get loaded root hints and change names to lowercase
- hints_data = table_keys_to_lower(hints.root())
-
- -- check loaded ip address of a.root-server.net
- if contains(hints_data['a.root-servers.net.'], '198.41.0.4') then
- fail("Real IP address for a.root-servers.net. not removed")
- end
- if not contains(hints_data['a.root-servers.net.'], '10.0.0.1') then
- fail("Fake IP address for a.root-servers.net. not found.")
- end
-end
-
--- run test after processed config file
--- default config will be used and we can test it.
-ev = event.after(0, function (ev)
- test_default()
- test_custom()
- quit()
-end)
#!/bin/bash -e
+export SOURCE_PATH=$(cd "$(dirname "$0")" && pwd -P)
+export TEST_FILE=${2}
export TMP_RUNDIR="$(mktemp -d)"
+export KRESD_NO_LISTEN=1
function finish {
- rm -rf "${TMP_RUNDIR}"
+ rm -rf "${TMP_RUNDIR}"
}
trap finish EXIT
-echo "config-test: ${2}"
-cp "tests/config/${2}/"* "${TMP_RUNDIR}/"
-cp tests/config/test_utils.lua "${TMP_RUNDIR}/"
-KRESD_NO_LISTEN=1 ${DEBUGGER} ${1} -f 1 -c test.cfg "${TMP_RUNDIR}"
+echo "# $(basename ${TEST_FILE})"
+${DEBUGGER} ${1} -f 1 -c ${SOURCE_PATH}/test.cfg "${TMP_RUNDIR}"
\ No newline at end of file
--- /dev/null
+Subproject commit be84b64d18293a29ca0acdf0431b0345084afe33
--- /dev/null
+package.path = package.path .. ';' .. env.SOURCE_PATH .. '/?.lua'
+TEST_DIR = env.TEST_FILE:match('(.*/)')
+
+-- optional code coverage
+local ok, runner = pcall(require, 'luacov.runner')
+if ok then
+ runner.init({
+ savestepsize = 2,
+ statsfile = TEST_DIR .. '/luacov.stats.out',
+ exclude = {'test', 'tapered'},
+ })
+ jit.off()
+end
+
+-- export testing module in globals
+local tapered = require('tapered.src.tapered')
+for k, v in pairs(tapered) do
+ _G[k] = v
+end
+
+-- load test
+local tests = dofile(env.TEST_FILE) or {}
+
+-- run test after processed config file
+-- default config will be used and we can test it.
+local runtest = require('test_utils').test
+event.after(0, function ()
+ for _, t in ipairs(tests) do
+ runtest(t)
+ end
+ done()
+end)
# Check return code of kresd. Passed test have to call quit().
tests_config := \
- basic \
- hints \
- predict
+ $(wildcard modules/*/*_test.lua) \
+ $(wildcard tests/config/*_test.lua)
define make_config_test
-test-config-$(1): tests/config/$(1)/test.cfg check-install-precond
- @$(preload_syms) ./tests/config/runtest.sh $(abspath $(SBINDIR)/kresd) $(1)
-.PHONY: test-$(1)
+$(1): check-install-precond
+ @$(preload_syms) ./tests/config/runtest.sh $(abspath $(SBINDIR)/kresd) $(abspath $(1))
+$(1)-clean:
+ @$(RM) $(dir $(1))/luacov.stats.out
+.PHONY: $(1)
endef
$(foreach test,$(tests_config),$(eval $(call make_config_test,$(test))))
-check-config: $(foreach test,$(tests_config),test-config-$(test))
-
+check-config: $(tests_config)
+check-config-clean: $(foreach test,$(tests_config),$(test)-clean)
.PHONY: check-config
-function fail(fmt, ...)
- io.stderr:write(string.format(fmt..'\n', ...))
- os.exit(2)
-end
+local M = {}
-function test(f, ...)
+function M.test(f, ...)
local res, exception = pcall(f, ...)
if not res then
local trace = debug.getinfo(2)
- fail('%s:%d %s', trace.source, trace.currentline, exception)
+ io.stderr:write(string.format('%s:%d %s\n', trace.source, trace.currentline, exception))
+ os.exit(2)
end
return res
end
-function table_keys_to_lower(table)
+function M.table_keys_to_lower(table)
local res = {}
for k, v in pairs(table) do
res[k:lower()] = v
return res
end
-function contains(table, value)
+local function contains(pass, fail, table, value, message)
+ message = message or string.format('table contains "%s"', value)
for _, v in pairs(table) do
if v == value then
- return true
+ pass(message)
+ return
end
end
- return false
+ fail(message)
+ return
+end
+
+function M.contains(table, value, message)
+ return contains(pass, fail, table, value, message)
+end
+
+function M.not_contains(table, value, message)
+ return contains(fail, pass, table, value, message)
end
--- Emulate busted testing interface
-local assert_builtin = assert
-assert = setmetatable({}, {
- __call = function (_, ...)
- return assert_builtin(...)
- end,
- __index = {
- truthy = function (expr)
- assert_builtin(expr)
- end,
- falsy = function (expr)
- assert_builtin(not expr)
- end,
- same = function (a, b)
- if a ~= b then
- assert_builtin(false, string.format('expected: %s got: %s', a, b))
- end
- end,
- }
-})
\ No newline at end of file
+return M
\ No newline at end of file
# installcheck requires kresd to be installed in its final destination
# (DESTDIR is not supported right now because module path gets hardcoded)
installcheck: check-config
-tests-clean: $(foreach test,$(tests_BIN),$(test)-clean) mock_cmodule-clean $(CLEAN_DNSTAP)
+tests-clean: $(foreach test,$(tests_BIN),$(test)-clean) mock_cmodule-clean $(CLEAN_DNSTAP) check-config-clean
.PHONY: check-integration deckard installcheck tests tests-clean