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