Commit 0ee41b14 authored by Ivana Krumlova's avatar Ivana Krumlova Committed by Petr Špaček

Deckard: Python 3 support

The main problem was that socket.type from Python standard library is
not an integer anymore. It is EnumInt object which is used instead of
bit field. To make the code compatible with both versions of Python we
had to replace all exact value comparisons with bitwise masking.
parent 7d99e3c7
......@@ -4,7 +4,7 @@ DAEMON ?= kresd
TEMPLATE ?= template/kresd.j2
CONFIG ?= config
PYTHON := python2
PYTHON := python3
LIBEXT := .so
PLATFORM := $(shell uname -s)
ifeq ($(PLATFORM),Darwin)
......
#!/usr/bin/env python2
#!/usr/bin/env python3
from __future__ import print_function
import sys
import os
import fileinput
......@@ -175,7 +177,7 @@ def setup_env(scenario, child_env, config, config_name_list, j2template_list):
sock = socket.socket(self_sockfamily, sock_type)
sock.setsockopt(self_sockfamily, socket.SO_REUSEADDR, 1)
sock.bind((childaddr, 53))
if sock_type == socket.SOCK_STREAM:
if sock_type & socket.SOCK_STREAM:
sock.listen(5)
# Generate configuration files
j2template_loader = jinja2.FileSystemLoader(searchpath=os.path.dirname(os.path.abspath(__file__)))
......@@ -189,7 +191,7 @@ def setup_env(scenario, child_env, config, config_name_list, j2template_list):
"INSTALL_DIR" : INSTALLDIR,
"FEATURES" : features
}
for template_name, config_name in itertools.izip(j2template_list,config_name_list):
for template_name, config_name in zip(j2template_list,config_name_list):
j2template = j2template_env.get_template(template_name)
cfg_rendered = j2template.render(j2template_ctx)
f = open(os.path.join(TMPDIR,config_name), 'w')
......@@ -255,11 +257,13 @@ def play_object(path, binary_name, config_name, j2template, binary_additional_pa
server.start_srv((rd.address, 53), socket.AF_INET6)
# Play test scenario
ex = None
try:
server.play(CHILD_IFACE)
except Exception as ex:
except Exception as exc:
ex = exc
raise
else:
ex = None
finally:
server.stop()
daemon_proc.terminate()
......@@ -279,12 +283,12 @@ def test_platform(*args):
if __name__ == '__main__':
if len(sys.argv) < 5:
print "Usage: test_integration.py <scenario> <binary> <template> <config name> [<additional>]"
print "\t<scenario> - path to scenario"
print "\t<binary> - executable to test"
print "\t<template> - colon-separated list of jinja2 template files"
print "\t<config name> - colon-separated list of files to be generated"
print "\t<additional> - additional parameters for <binary>"
print("Usage: test_integration.py <scenario> <binary> <template> <config name> [<additional>]")
print("\t<scenario> - path to scenario")
print("\t<binary> - executable to test")
print("\t<template> - colon-separated list of jinja2 template files")
print("\t<config name> - colon-separated list of files to be generated")
print("\t<additional> - additional parameters for <binary>")
sys.exit(0)
test_platform()
......@@ -300,8 +304,8 @@ if __name__ == '__main__':
template_name_list = sys.argv[3].split(':')
config_name_list = sys.argv[4].split(':')
if len(template_name_list) != len (config_name_list):
print "ERROR: Number of j2 template files not equal to number of file names to be generated"
print "i.e. len(<template>) != len(<config name>), see usage"
print("ERROR: Number of j2 template files not equal to number of file names to be generated")
print("i.e. len(<template>) != len(<config name>), see usage")
sys.exit(0)
if len(sys.argv) > 5:
......
from __future__ import print_function
import os
import threading
......@@ -7,6 +9,6 @@ def dprint(tag, msg):
""" Verbose logging (if enabled). """
if 'VERBOSE' in os.environ:
dprint_lock.acquire()
print tag, msg
print(tag, msg)
dprint_lock.release()
from __future__ import absolute_import
import dns.message
import dns.rrset
import dns.rcode
import dns.dnssec
......@@ -8,8 +11,8 @@ import os, sys, errno
import itertools, random, string
import time
from datetime import datetime
from dprint import dprint
from testserver import recvfrom_msg, sendto_msg
from pydnstest.dprint import dprint
from pydnstest.testserver import recvfrom_msg, sendto_msg
# Global statistics
......@@ -349,7 +352,7 @@ class Entry:
self.message.use_tsig(keyring=keyring, keyname=tsig_keyname)
def __rr_add(self, section, rr):
""" Merge record to existing RRSet, or append to given section. """
"""Append to given section."""
section.append(rr)
def set_mandatory(self):
......@@ -541,7 +544,7 @@ class Step:
# Don't use a message copy as the EDNS data portion is not copied.
data_to_wire = self.data[0].message.to_wire()
if choice is None or len(choice) == 0:
choice = ctx.client.keys()[0]
choice = list(ctx.client.keys())[0]
if choice not in ctx.client:
raise Exception('step %03d invalid QUERY target: %s' % (self.id, choice))
# Create socket to test subject
......@@ -554,7 +557,7 @@ class Step:
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
sock.settimeout(3)
if source:
sock.bind((source, 0))
sock.bind((source, 0))
sock.connect(destination)
# Send query to client and wait for response
tstart = datetime.now()
......@@ -562,7 +565,7 @@ class Step:
try:
sendto_msg(sock, data_to_wire)
break
except OSError, e:
except OSError as e:
# ENOBUFS, throttle sending
if e.errno == errno.ENOBUFS:
time.sleep(0.1)
......@@ -573,7 +576,7 @@ class Step:
try:
answer, _ = recvfrom_msg(sock, True)
break
except OSError, e:
except OSError as e:
if e.errno == errno.ENOBUFS:
time.sleep(0.1)
# Track RTT
......
#!/usr/bin/env python
import os
import traceback
import time
class Test:
""" Small library to imitate CMocka output. """
......
from __future__ import absolute_import
from __future__ import print_function
import threading
import select
import socket
......@@ -8,7 +11,7 @@ import dns.rdatatype
import itertools
import struct
import binascii
from dprint import dprint
from pydnstest.dprint import dprint
def recvfrom_msg(stream, raw = False):
"""
......@@ -18,14 +21,14 @@ def recvfrom_msg(stream, raw = False):
if raw == False: (DNS message object, peer address)
if raw == True: (blob, peer address)
"""
if stream.type == socket.SOCK_DGRAM:
if stream.type & socket.SOCK_DGRAM:
data, addr = stream.recvfrom(4096)
elif stream.type == socket.SOCK_STREAM:
elif stream.type & socket.SOCK_STREAM:
data = stream.recv(2)
if len(data) == 0:
return None, None
msg_len = struct.unpack_from("!H",data)[0]
data = ""
data = b""
received = 0
while received < msg_len:
next_chunk = stream.recv(4096)
......@@ -35,7 +38,7 @@ def recvfrom_msg(stream, raw = False):
received += len(next_chunk)
addr = stream.getpeername()[0]
else:
raise Exception("[recvfrom_msg]: unknown socket type '%i'" % stream.type)
raise NotImplementedError("[recvfrom_msg]: unknown socket type '%i'" % stream.type)
if not raw:
data = dns.message.from_wire(data, one_rr_per_rrset=True)
return data, addr
......@@ -44,16 +47,16 @@ def recvfrom_msg(stream, raw = False):
def sendto_msg(stream, message, addr=None):
""" Send DNS/UDP/TCP message. """
try:
if stream.type == socket.SOCK_DGRAM:
if stream.type & socket.SOCK_DGRAM:
if addr is None:
stream.send(message)
else:
stream.sendto(message, addr)
elif stream.type == socket.SOCK_STREAM:
elif stream.type & socket.SOCK_STREAM:
data = struct.pack("!H",len(message)) + message
stream.send(data)
else:
raise Exception ("[recvfrom_msg]: unknown socket type '%i'" % stream.type)
assert False, "[sendto_msg]: unknown socket type '%i'" % stream.type
except: # Failure to respond is OK, resolver should recover
pass
......@@ -64,7 +67,7 @@ def get_local_addr_str(family, iface):
elif family == socket.AF_INET6:
addr_local_pattern = "fd00::5357:5f{:02X}"
else:
raise Exception("[get_local_addr_str] family not supported '%i'" % family)
raise NotImplementedError("[get_local_addr_str] family not supported '%i'" % family)
return addr_local_pattern.format(iface)
class AddrMapInfo:
......@@ -228,7 +231,8 @@ class TestServer:
address = (get_local_addr_str(family, self.default_iface), 53)
elif family == socket.AF_INET6:
if socket.has_ipv6 is not True:
raise Exception("[start_srv] IPV6 is not supported")
raise NotImplementedError("[start_srv] IPv6 is not supported by socket {0}"
.format(socket))
if address[0] is None:
address = (get_local_addr_str(family, self.default_iface), 53)
else:
......@@ -241,7 +245,7 @@ class TestServer:
elif proto == socket.IPPROTO_UDP:
socktype = socket.SOCK_DGRAM
else:
raise Exception("[start_srv] unsupported protocol {protocol}".format(protocol=proto))
raise NotImplementedError("[start_srv] unsupported protocol {0}".format(proto))
if (self.thread is None):
self.thread = threading.Thread(target=self.query_io)
......@@ -269,6 +273,7 @@ class TestServer:
if __name__ == '__main__':
# Self-test code
# Usage: $PYTHON -m pydnstest.testserver
DEFAULT_IFACE = 0
CHILD_IFACE = 0
if "SOCKET_WRAPPER_DEFAULT_IFACE" in os.environ:
......@@ -279,11 +284,11 @@ if __name__ == '__main__':
# Mirror server
server = TestServer(None,None,DEFAULT_IFACE)
server.start()
print "[==========] Mirror server running at", server.address()
print("[==========] Mirror server running at", server.address())
try:
while True:
time.sleep(0.5)
time.sleep(0.5)
except KeyboardInterrupt:
print "[==========] Shutdown."
print("[==========] Shutdown.")
pass
server.stop()
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