]> git.ipfire.org Git - thirdparty/pdns.git/blob - regression-tests.api/runtests.py
rec: Add a new max-udp-queries-per-round setting
[thirdparty/pdns.git] / regression-tests.api / runtests.py
1 #!/usr/bin/env python
2 #
3 # Shell-script style.
4
5 import os
6 import requests
7 import shutil
8 import subprocess
9 import sys
10 import tempfile
11 import time
12
13 SQLITE_DB = 'pdns.sqlite3'
14 WEBPORT = '5556'
15 DNSPORT = 5555
16 APIKEY = '1234567890abcdefghijklmnopq-key'
17 PDNSUTIL_CMD = ["../pdns/pdnsutil", "--config-dir=."]
18
19 NAMED_CONF_TPL = """
20 # Generated by runtests.py
21 options { directory "../regression-tests/zones/"; };
22 zone "example.com" { type master; file "example.com"; };
23 zone "powerdnssec.org" { type master; file "powerdnssec.org"; };
24 zone "cryptokeys.org" { type master; file "cryptokeys.org"; };
25 """
26
27 AUTH_CONF_TPL = """
28 # Generated by runtests.py
29 launch=gsqlite3,bind
30 gsqlite3-dnssec=on
31 gsqlite3-database="""+SQLITE_DB+"""
32 module-dir=../regression-tests/modules
33 bind-config=bindbackend.conf
34 """
35
36 BINDBACKEND_CONF_TPL = """
37 # Generated by runtests.py
38 """
39
40 ACL_LIST_TPL = """
41 # Generated by runtests.py
42 # local host
43 127.0.0.1
44 ::1
45 """
46
47 REC_EXAMPLE_COM_CONF_TPL = """
48 # Generated by runtests.py
49 auth-zones+=example.com=../regression-tests/zones/example.com
50 """
51
52 REC_CONF_TPL = """
53 # Generated by runtests.py
54 auth-zones=
55 forward-zones=
56 forward-zones-recurse=
57 api-config-dir=%(conf_dir)s
58 include-dir=%(conf_dir)s
59 """
60
61
62 def ensure_empty_dir(name):
63 if os.path.exists(name):
64 shutil.rmtree(name)
65 os.mkdir(name)
66
67 def format_call_args(cmd):
68 return "$ '%s'" % ("' '".join(cmd))
69
70 def run_check_call(cmd, *args, **kwargs):
71 print format_call_args(cmd)
72 subprocess.check_call(cmd, *args, **kwargs)
73
74 wait = ('--wait' in sys.argv)
75 if wait:
76 sys.argv.remove('--wait')
77
78 tests = [opt for opt in sys.argv if opt.startswith('--tests=')]
79 if tests:
80 for opt in tests:
81 sys.argv.remove(opt)
82 tests = [opt.split('=', 1)[1] for opt in tests]
83
84 daemon = (len(sys.argv) == 2) and sys.argv[1] or None
85 if daemon not in ('authoritative', 'recursor'):
86 print "Usage: ./runtests (authoritative|recursor)"
87 sys.exit(2)
88
89 daemon = sys.argv[1]
90
91 pdns_recursor = os.environ.get("PDNSRECURSOR", "../pdns/recursordist/pdns_recursor")
92
93 # Take sdig if it exists (recursor in travis), otherwise build it from Authoritative source.
94 sdig = os.environ.get("SDIG", "")
95 if sdig:
96 sdig = os.path.abspath(sdig)
97 if not sdig or not os.path.exists(sdig):
98 run_check_call(["make", "-C", "../pdns", "sdig"])
99 sdig = "../pdns/sdig"
100
101 if daemon == 'authoritative':
102
103 # Prepare sqlite DB with some zones.
104 subprocess.check_call(["rm", "-f", SQLITE_DB])
105 subprocess.check_call(["make", "-C", "../pdns", "zone2sql"])
106
107 with open('../modules/gsqlite3backend/schema.sqlite3.sql', 'r') as schema_file:
108 subprocess.check_call(["sqlite3", SQLITE_DB], stdin=schema_file)
109
110 with open('named.conf', 'w') as named_conf:
111 named_conf.write(NAMED_CONF_TPL)
112 with tempfile.TemporaryFile() as tf:
113 p = subprocess.Popen(["../pdns/zone2sql", "--transactions", "--gsqlite", "--named-conf=named.conf"], stdout=tf)
114 p.communicate()
115 if p.returncode != 0:
116 raise Exception("zone2sql failed")
117 tf.seek(0, os.SEEK_SET) # rewind
118 subprocess.check_call(["sqlite3", SQLITE_DB], stdin=tf)
119
120 with open('bindbackend.conf', 'w') as bindbackend_conf:
121 bindbackend_conf.write(BINDBACKEND_CONF_TPL)
122
123 with open('pdns.conf', 'w') as pdns_conf:
124 pdns_conf.write(AUTH_CONF_TPL)
125
126 subprocess.check_call(PDNSUTIL_CMD + ["secure-zone", "powerdnssec.org"])
127 pdnscmd = ("../pdns/pdns_server --daemon=no --local-address=127.0.0.1 --local-ipv6= --local-port=5300 --socket-dir=./ --no-shuffle --dnsupdate=yes --cache-ttl=0 --config-dir=. --api=yes --webserver-port="+WEBPORT+" --webserver-address=127.0.0.1 --api-key="+APIKEY).split()
128
129 else:
130 conf_dir = 'rec-conf.d'
131 ensure_empty_dir(conf_dir)
132 with open('acl.list', 'w') as acl_list:
133 acl_list.write(ACL_LIST_TPL)
134 with open('recursor.conf', 'w') as recursor_conf:
135 recursor_conf.write(REC_CONF_TPL % locals())
136 with open(conf_dir+'/example.com..conf', 'w') as conf_file:
137 conf_file.write(REC_EXAMPLE_COM_CONF_TPL)
138
139 pdnscmd = (pdns_recursor + " --daemon=no --socket-dir=. --config-dir=. --allow-from-file=acl.list --local-address=127.0.0.1 --local-port=5555 --webserver=yes --webserver-port="+WEBPORT+" --webserver-address=127.0.0.1 --webserver-password=something --api-key="+APIKEY).split()
140
141
142 # Now run pdns and the tests.
143 print "Launching pdns..."
144 print ' '.join(pdnscmd)
145 pdns = subprocess.Popen(pdnscmd, close_fds=True)
146
147 print "Waiting for webserver port to become available..."
148 available = False
149 for try_number in range(0, 10):
150 try:
151 res = requests.get('http://127.0.0.1:%s/' % WEBPORT)
152 available = True
153 break
154 except:
155 time.sleep(0.5)
156
157 if not available:
158 print "Webserver port not reachable after 10 tries, giving up."
159 pdns.terminate()
160 pdns.wait()
161 sys.exit(2)
162
163 print "Running tests..."
164 rc = 0
165 test_env = {}
166 test_env.update(os.environ)
167 test_env.update({
168 'WEBPORT': WEBPORT,
169 'APIKEY': APIKEY,
170 'DAEMON': daemon,
171 'SQLITE_DB': SQLITE_DB,
172 'PDNSUTIL_CMD': ' '.join(PDNSUTIL_CMD),
173 'SDIG': sdig,
174 'DNSPORT': str(DNSPORT)
175 })
176
177 try:
178 print ""
179 p = subprocess.check_call(["nosetests", "--with-xunit"] + tests, env=test_env)
180 except subprocess.CalledProcessError as ex:
181 rc = ex.returncode
182 finally:
183 if wait:
184 print "Waiting as requested, press ENTER to stop."
185 raw_input()
186 pdns.terminate()
187 pdns.wait()
188
189 sys.exit(rc)