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