Commit d11732d9 authored by Grigorii Demidov's avatar Grigorii Demidov

kresd dns64 module test was added

parent 902995b5
...@@ -43,6 +43,27 @@ Next keys can be used ...@@ -43,6 +43,27 @@ Next keys can be used
POSIX timestamp; the system time will be reported to binary under the test POSIX timestamp; the system time will be reported to binary under the test
- **features** : jinja2_var1=v1;jinja2_var2=v2;...;jinja2_varN=vN
semicolon-separated list of key=value pairs, all keys and values are strings;
contains user-defined jinja2 template variables which can be used for improving
flexibility of configuration generation process; when variable value is not needed,
it can be omitted as well as equal sign; **features** configuration key can be
repeated, so
::
**features** : jinja2_var1=v1;jinja2_var2=v2;...;jinja2_varN=vN
equal to
::
**features** : jinja2_var1=v1
**features** : jinja2_var2=v2
...
**features** : jinja2_varN=vN
Example Example
:: ::
...@@ -52,6 +73,8 @@ Example ...@@ -52,6 +73,8 @@ Example
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
trust-anchor: ". 3600 IN DS 17272 13 4 B87AD8C76DC2244E7AA57285057BF533F2E248CC8D7E1A071D8A3837A711A5EA705C4707E6E8911DA653BE1AE019927B" trust-anchor: ". 3600 IN DS 17272 13 4 B87AD8C76DC2244E7AA57285057BF533F2E248CC8D7E1A071D8A3837A711A5EA705C4707E6E8911DA653BE1AE019927B"
val-override-date: "1442323400" val-override-date: "1442323400"
features: dns64
features: dns64_prefix = fe80::21b:aabb:0:0
CONFIG_END CONFIG_END
**Scenario** **Scenario**
......
Subproject commit 96f9d58540f1ae6f219e85ce01a5818146bb49ee Subproject commit aa1a5faabd3f8daa448b92b8d3c958a7de084dad
...@@ -27,8 +27,10 @@ def del_files(path_to, delpath): ...@@ -27,8 +27,10 @@ def del_files(path_to, delpath):
for f in files: for f in files:
os.unlink(os.path.join(root, f)) os.unlink(os.path.join(root, f))
if delpath == True: if delpath == True:
os.rmdir(path_to); try:
os.rmdir(path_to);
except:
pass
VERBOSE = 0 VERBOSE = 0
DEFAULT_IFACE = 0 DEFAULT_IFACE = 0
...@@ -36,6 +38,8 @@ CHILD_IFACE = 0 ...@@ -36,6 +38,8 @@ CHILD_IFACE = 0
TMPDIR = "" TMPDIR = ""
OWN_TMPDIR = False OWN_TMPDIR = False
INSTALLDIR = os.path.dirname(os.path.abspath(__file__)) INSTALLDIR = os.path.dirname(os.path.abspath(__file__))
DEFAULT_FEATURE_LIST_DELIM = ';'
DEFAULT_FEATURE_PAIR_DELIM = '='
if "SOCKET_WRAPPER_DEFAULT_IFACE" in os.environ: if "SOCKET_WRAPPER_DEFAULT_IFACE" in os.environ:
DEFAULT_IFACE = int(os.environ["SOCKET_WRAPPER_DEFAULT_IFACE"]) DEFAULT_IFACE = int(os.environ["SOCKET_WRAPPER_DEFAULT_IFACE"])
...@@ -162,7 +166,7 @@ def parse_file(file_in): ...@@ -162,7 +166,7 @@ def parse_file(file_in):
line = line[0:line.index('#')] line = line[0:line.index('#')]
# Break to key-value pairs # Break to key-value pairs
# e.g.: ['minimization', 'on'] # e.g.: ['minimization', 'on']
kv = [x.strip() for x in line.split(':')] kv = [x.strip() for x in line.split(':',1)]
if len(kv) >= 2: if len(kv) >= 2:
config.append(kv) config.append(kv)
line = file_in.readline() line = file_in.readline()
...@@ -191,7 +195,7 @@ def write_timestamp_file(path, tst): ...@@ -191,7 +195,7 @@ def write_timestamp_file(path, tst):
time_file.flush() time_file.flush()
time_file.close() time_file.close()
def setup_env(child_env, config, config_name_list, j2template_list): def setup_env(scenario, child_env, config, config_name_list, j2template_list):
""" Set up test environment and config """ """ Set up test environment and config """
# Clear test directory # Clear test directory
del_files(TMPDIR, False) del_files(TMPDIR, False)
...@@ -207,6 +211,9 @@ def setup_env(child_env, config, config_name_list, j2template_list): ...@@ -207,6 +211,9 @@ def setup_env(child_env, config, config_name_list, j2template_list):
no_minimize = "true" no_minimize = "true"
trust_anchor_str = "" trust_anchor_str = ""
stub_addr = "" stub_addr = ""
features = {}
feature_list_delimiter = DEFAULT_FEATURE_LIST_DELIM
feature_pair_delimiter = DEFAULT_FEATURE_PAIR_DELIM
selfaddr = testserver.get_local_addr_str(socket.AF_INET, DEFAULT_IFACE) selfaddr = testserver.get_local_addr_str(socket.AF_INET, DEFAULT_IFACE)
for k,v in config: for k,v in config:
# Enable selectively for some tests # Enable selectively for some tests
...@@ -219,16 +226,35 @@ def setup_env(child_env, config, config_name_list, j2template_list): ...@@ -219,16 +226,35 @@ def setup_env(child_env, config, config_name_list, j2template_list):
write_timestamp_file(child_env["FAKETIME_TIMESTAMP_FILE"], int(override_date_str)) write_timestamp_file(child_env["FAKETIME_TIMESTAMP_FILE"], int(override_date_str))
elif k == 'stub-addr': elif k == 'stub-addr':
stub_addr = v.strip('"\'') stub_addr = v.strip('"\'')
elif k == 'features':
featurelist = v.split(feature_list_delimiter)
try :
for f_item in featurelist:
if f_item.find(feature_pair_delimiter) != -1:
f_key, f_value = [x.strip() for x in f_item.split(feature_pair_delimiter,1)]
else:
f_key = f_item.strip()
f_value = ""
features[f_key] = f_value
except Exception as e:
raise Exception ("can't parse features list in config section (%s)" % str(e));
elif k == 'force-ipv6' and v.upper() == 'TRUE':
scenario.force_ipv6 = True
self_sockfamily = socket.AF_INET
if scenario.force_ipv6 == True:
self_sockfamily = socket.AF_INET6
if stub_addr != "": if stub_addr != "":
selfaddr = stub_addr selfaddr = stub_addr
else: else:
selfaddr = testserver.get_local_addr_str(socket.AF_INET, DEFAULT_IFACE) selfaddr = testserver.get_local_addr_str(self_sockfamily, DEFAULT_IFACE)
childaddr = testserver.get_local_addr_str(socket.AF_INET, CHILD_IFACE) childaddr = testserver.get_local_addr_str(self_sockfamily, CHILD_IFACE)
# Prebind to sockets to create necessary files # Prebind to sockets to create necessary files
# @TODO: this is probably a workaround for socket_wrapper bug # @TODO: this is probably a workaround for socket_wrapper bug
for sock_type in (socket.SOCK_STREAM, socket.SOCK_DGRAM): for sock_type in (socket.SOCK_STREAM, socket.SOCK_DGRAM):
sock = socket.socket(socket.AF_INET, sock_type) sock = socket.socket(self_sockfamily, sock_type)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(self_sockfamily, socket.SO_REUSEADDR, 1)
sock.bind((childaddr, 53)) sock.bind((childaddr, 53))
if sock_type == socket.SOCK_STREAM: if sock_type == socket.SOCK_STREAM:
sock.listen(5) sock.listen(5)
...@@ -241,7 +267,8 @@ def setup_env(child_env, config, config_name_list, j2template_list): ...@@ -241,7 +267,8 @@ def setup_env(child_env, config, config_name_list, j2template_list):
"NO_MINIMIZE" : no_minimize, "NO_MINIMIZE" : no_minimize,
"TRUST_ANCHOR" : trust_anchor_str, "TRUST_ANCHOR" : trust_anchor_str,
"WORKING_DIR" : TMPDIR, "WORKING_DIR" : TMPDIR,
"INSTALL_DIR" : INSTALLDIR "INSTALL_DIR" : INSTALLDIR,
"FEATURES" : features
} }
for template_name, config_name in itertools.izip(j2template_list,config_name_list): for template_name, config_name in itertools.izip(j2template_list,config_name_list):
j2template = j2template_env.get_template(template_name) j2template = j2template_env.get_template(template_name)
...@@ -264,7 +291,7 @@ def play_object(path, binary_name, config_name, j2template, binary_additional_pa ...@@ -264,7 +291,7 @@ def play_object(path, binary_name, config_name, j2template, binary_additional_pa
# Setup daemon environment # Setup daemon environment
daemon_env = os.environ.copy() daemon_env = os.environ.copy()
setup_env(daemon_env, config, config_name, j2template) setup_env(scenario, daemon_env, config, config_name, j2template)
server = testserver.TestServer(scenario, config, DEFAULT_IFACE, CHILD_IFACE) server = testserver.TestServer(scenario, config, DEFAULT_IFACE, CHILD_IFACE)
server.start() server.start()
...@@ -279,14 +306,17 @@ def play_object(path, binary_name, config_name, j2template, binary_additional_pa ...@@ -279,14 +306,17 @@ def play_object(path, binary_name, config_name, j2template, binary_additional_pa
except Exception as e: except Exception as e:
raise Exception("Can't start '%s': %s" % (daemon_args, str(e))) raise Exception("Can't start '%s': %s" % (daemon_args, str(e)))
# Wait until the server accepts TCP clients # Wait until the server accepts TCP clients
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sockfamily = socket.AF_INET
if scenario.force_ipv6 == True:
sockfamily = socket.AF_INET6
sock = socket.socket(sockfamily, socket.SOCK_STREAM)
while True: while True:
time.sleep(0.1) time.sleep(0.1)
if daemon_proc.poll() != None: if daemon_proc.poll() != None:
print(open('%s/server.log' % TMPDIR).read()) print(open('%s/server.log' % TMPDIR).read())
raise Exception('process died "%s", logs in "%s"' % (os.path.basename(binary_name), TMPDIR)) raise Exception('process died "%s", logs in "%s"' % (os.path.basename(binary_name), TMPDIR))
try: try:
sock.connect((testserver.get_local_addr_str(socket.AF_INET, CHILD_IFACE), 53)) sock.connect((testserver.get_local_addr_str(sockfamily, CHILD_IFACE), 53))
except: continue except: continue
break break
sock.close() sock.close()
......
...@@ -353,7 +353,13 @@ class Step: ...@@ -353,7 +353,13 @@ class Step:
# Wait for a response for a reasonable time # Wait for a response for a reasonable time
answer = None answer = None
if not self.data[0].is_raw_data_entry: if not self.data[0].is_raw_data_entry:
answer, addr = ctx.child_sock.recvfrom(4096) while True:
try:
answer, addr = ctx.child_sock.recvfrom(4096)
break
except OSError, e:
if e.errno == errno.ENOBUFS:
time.sleep(0.1)
# Remember last answer for checking later # Remember last answer for checking later
self.raw_answer = answer self.raw_answer = answer
ctx.last_raw_answer = answer ctx.last_raw_answer = answer
...@@ -383,6 +389,7 @@ class Scenario: ...@@ -383,6 +389,7 @@ class Scenario:
self.steps = [] self.steps = []
self.current_step = None self.current_step = None
self.child_sock = None self.child_sock = None
self.force_ipv6 = False
def reply(self, query, address = None): def reply(self, query, address = None):
""" Attempt to find a range reply for a query. """ """ Attempt to find a range reply for a query. """
...@@ -415,9 +422,9 @@ class Scenario: ...@@ -415,9 +422,9 @@ class Scenario:
pass pass
return (None, True) return (None, True)
def play(self, saddr, paddr): def play(self, family, saddr, paddr):
""" Play given scenario. """ """ Play given scenario. """
self.child_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.child_sock = socket.socket(family, socket.SOCK_DGRAM)
self.child_sock.settimeout(3) self.child_sock.settimeout(3)
self.child_sock.connect((paddr, 53)) self.child_sock.connect((paddr, 53))
......
...@@ -256,9 +256,12 @@ class TestServer: ...@@ -256,9 +256,12 @@ class TestServer:
return sockname, proto return sockname, proto
def play(self): def play(self):
saddr = get_local_addr_str(socket.AF_INET,self.default_iface) sockfamily = socket.AF_INET
paddr = get_local_addr_str(socket.AF_INET,self.peer_iface) if self.scenario.force_ipv6 == True:
self.scenario.play(saddr,paddr) sockfamily = socket.AF_INET6
saddr = get_local_addr_str(sockfamily,self.default_iface)
paddr = get_local_addr_str(sockfamily,self.peer_iface)
self.scenario.play(sockfamily,saddr,paddr)
if __name__ == '__main__': if __name__ == '__main__':
# Self-test code # Self-test code
......
; config options
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
features: dns64
features: dns64_prefix = fe80::21b:aabb:0:0
CONFIG_END
SCENARIO_BEGIN Test dns64 features
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
cz. IN NS
SECTION AUTHORITY
cz. IN NS d.ns.nic.cz.
SECTION ADDITIONAL
d.ns.nic.cz. IN A 193.29.206.1
;d.ns.nic.cz. IN AAAA 2001:678:1::1
ENTRY_END
RANGE_END
RANGE_BEGIN 0 100
ADDRESS 193.29.206.1
ENTRY_BEGIN
MATCH opcode qname
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
www.example.cz. IN NS
SECTION AUTHORITY
example.cz. IN NS ns.example.cz.
SECTION ADDITIONAL
ns.example.cz. IN A 1.2.3.4
ENTRY_END
RANGE_END
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.cz. IN A
SECTION ANSWER
www.example.cz. IN A 1.2.3.5
SECTION AUTHORITY
example.cz. IN NS ns.example.cz.
SECTION ADDITIONAL
ns.example.cz. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.cz. IN AAAA
SECTION AUTHORITY
example.cz. 3600 IN SOA bla. bla. 1 2 3 4 5
SECTION ADDITIONAL
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.cz. IN AAAA
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.cz. IN AAAA
SECTION ANSWER
www.example.cz. IN AAAA fe80::21b:aabb:102:305
ENTRY_END
SCENARIO_END
...@@ -5,6 +5,12 @@ hints.root({['k.root-servers.net'] = '{{ROOT_ADDR}}'}) ...@@ -5,6 +5,12 @@ hints.root({['k.root-servers.net'] = '{{ROOT_ADDR}}'})
option('NO_MINIMIZE', {{NO_MINIMIZE}}) option('NO_MINIMIZE', {{NO_MINIMIZE}})
option('ALLOW_LOCAL', false) option('ALLOW_LOCAL', false)
trust_anchors.add('{{TRUST_ANCHOR}}') trust_anchors.add('{{TRUST_ANCHOR}}')
{% if FEATURES.dns64 is defined %}
modules.load( 'dns64')
{% if FEATURES.dns64_prefix is defined %}
dns64.config('{{FEATURES.dns64_prefix}}')
{% endif %}
{% endif %}
verbose(true) verbose(true)
-- Self-checks on globals -- Self-checks on globals
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment