diff options
Diffstat (limited to 'src/integration-tests/gnunet_testing.py.in')
-rw-r--r-- | src/integration-tests/gnunet_testing.py.in | 225 |
1 files changed, 125 insertions, 100 deletions
diff --git a/src/integration-tests/gnunet_testing.py.in b/src/integration-tests/gnunet_testing.py.in index cc3e18b06..fa43c6838 100644 --- a/src/integration-tests/gnunet_testing.py.in +++ b/src/integration-tests/gnunet_testing.py.in | |||
@@ -1,21 +1,19 @@ | |||
1 | #!@PYTHON@ | 1 | #!@PYTHON@ |
2 | # This file is part of GNUnet. | 2 | # This file is part of GNUnet. |
3 | # (C) 2010, 2017 Christian Grothoff (and other contributing authors) | 3 | # (C) 2010, 2017, 2018 Christian Grothoff (and other contributing authors) |
4 | # | 4 | # |
5 | # GNUnet is free software; you can redistribute it and/or modify | 5 | # GNUnet is free software: you can redistribute it and/or modify it |
6 | # it under the terms of the GNU General Public License as published | 6 | # under the terms of the GNU Affero General Public License as published |
7 | # by the Free Software Foundation; either version 2, or (at your | 7 | # by the Free Software Foundation, either version 3 of the License, |
8 | # option) any later version. | 8 | # or (at your option) any later version. |
9 | # | 9 | # |
10 | # GNUnet is distributed in the hope that it will be useful, but | 10 | # GNUnet is distributed in the hope that it will be useful, but |
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | # General Public License for more details. | 13 | # Affero General Public License for more details. |
14 | # | 14 | # |
15 | # You should have received a copy of the GNU General Public License | 15 | # You should have received a copy of the GNU Affero General Public License |
16 | # along with GNUnet; see the file COPYING. If not, write to the | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | # Boston, MA 02110-1301, USA. | ||
19 | # | 17 | # |
20 | # Functions for integration testing | 18 | # Functions for integration testing |
21 | import os | 19 | import os |
@@ -25,86 +23,99 @@ import shutil | |||
25 | import time | 23 | import time |
26 | from gnunet_pyexpect import pexpect | 24 | from gnunet_pyexpect import pexpect |
27 | 25 | ||
26 | |||
28 | class Check: | 27 | class Check: |
29 | def __init__(self, test): | 28 | def __init__(self, test): |
30 | self.fulfilled = False | 29 | self.fulfilled = False |
31 | self.conditions = list() | 30 | self.conditions = list() |
32 | self.test = test | 31 | self.test = test |
33 | def add (self, condition): | 32 | |
33 | def add(self, condition): | ||
34 | self.conditions.append(condition) | 34 | self.conditions.append(condition) |
35 | def run (self): | 35 | |
36 | def run(self): | ||
36 | fulfilled = True | 37 | fulfilled = True |
37 | pos = 0 | 38 | pos = 0 |
38 | neg = 0 | 39 | neg = 0 |
39 | for c in self.conditions: | 40 | for c in self.conditions: |
40 | if (False == c.check ()): | 41 | if (False == c.check()): |
41 | fulfilled = False | 42 | fulfilled = False |
42 | neg += 1 | 43 | neg += 1 |
43 | else: | 44 | else: |
44 | pos += 1 | 45 | pos += 1 |
45 | return fulfilled | 46 | return fulfilled |
46 | def run_blocking (self, timeout, pos_cont, neg_cont): | 47 | |
47 | execs = 0; | 48 | def run_blocking(self, timeout, pos_cont, neg_cont): |
49 | execs = 0 | ||
48 | res = False | 50 | res = False |
49 | while ((False == res) and (execs < timeout)): | 51 | while ((False == res) and (execs < timeout)): |
50 | res = self.run() | 52 | res = self.run() |
51 | time.sleep(1) | 53 | time.sleep(1) |
52 | execs += 1 | 54 | execs += 1 |
53 | if ((False == res) and (execs >= timeout)): | 55 | if ((False == res) and (execs >= timeout)): |
54 | print(('Check had timeout after ' +str(timeout)+ ' seconds')) | 56 | print(('Check had timeout after ' + str(timeout) + ' seconds')) |
55 | neg_cont (self) | 57 | neg_cont(self) |
56 | elif ((False == res) and (execs < timeout)): | 58 | elif ((False == res) and (execs < timeout)): |
57 | if (None != neg_cont): | 59 | if (None != neg_cont): |
58 | neg_cont (self) | 60 | neg_cont(self) |
59 | else: | 61 | else: |
60 | if (None != pos_cont): | 62 | if (None != pos_cont): |
61 | pos_cont (self) | 63 | pos_cont(self) |
62 | return res | 64 | return res |
63 | def run_once (self, pos_cont, neg_cont): | 65 | |
64 | execs = 0; | 66 | def run_once(self, pos_cont, neg_cont): |
67 | execs = 0 | ||
65 | res = False | 68 | res = False |
66 | res = self.run() | 69 | res = self.run() |
67 | if ((res == False) and (neg_cont != None)): | 70 | if ((res == False) and (neg_cont != None)): |
68 | neg_cont (self) | 71 | neg_cont(self) |
69 | if ((res == True) and (pos_cont != None)): | 72 | if ((res == True) and (pos_cont != None)): |
70 | pos_cont (self) | 73 | pos_cont(self) |
71 | return res | 74 | return res |
72 | def evaluate (self, failed_only): | 75 | |
76 | def evaluate(self, failed_only): | ||
73 | pos = 0 | 77 | pos = 0 |
74 | neg = 0 | 78 | neg = 0 |
75 | for c in self.conditions: | 79 | for c in self.conditions: |
76 | if (False == c.evaluate (failed_only)): | 80 | if (False == c.evaluate(failed_only)): |
77 | neg += 1 | 81 | neg += 1 |
78 | else: | 82 | else: |
79 | pos += 1 | 83 | pos += 1 |
80 | print((str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled')) | 84 | print((str(pos) + ' out of ' + str(pos+neg) + ' conditions fulfilled')) |
81 | return self.fulfilled | 85 | return self.fulfilled |
82 | def reset (self): | 86 | |
83 | self.fulfilled = False | 87 | def reset(self): |
84 | for c in self.conditions: | 88 | self.fulfilled = False |
85 | c.fulfilled = False | 89 | for c in self.conditions: |
86 | 90 | c.fulfilled = False | |
91 | |||
92 | |||
87 | class Condition: | 93 | class Condition: |
88 | def __init__(self): | 94 | def __init__(self): |
89 | self.fulfilled = False | 95 | self.fulfilled = False |
90 | self.type = 'generic' | 96 | self.type = 'generic' |
97 | |||
91 | def __init__(self, type): | 98 | def __init__(self, type): |
92 | self.fulfilled = False | 99 | self.fulfilled = False |
93 | self.type = type | 100 | self.type = type |
101 | |||
94 | def check(self): | 102 | def check(self): |
95 | return False; | 103 | return False |
96 | def evaluate (self, failed_only): | 104 | |
105 | def evaluate(self, failed_only): | ||
97 | if ((self.fulfilled == False) and (failed_only == True)): | 106 | if ((self.fulfilled == False) and (failed_only == True)): |
98 | print(str(self.type) + 'condition for was ' + str(self.fulfilled)) | 107 | print(str(self.type) + 'condition for was ' + str(self.fulfilled)) |
99 | elif (failed_only == False): | 108 | elif (failed_only == False): |
100 | print(str(self.type) + 'condition for was ' + str(self.fulfilled)) | 109 | print(str(self.type) + 'condition for was ' + str(self.fulfilled)) |
101 | return self.fulfilled | 110 | return self.fulfilled |
111 | |||
102 | 112 | ||
103 | class FileExistCondition (Condition): | 113 | class FileExistCondition(Condition): |
104 | def __init__(self, file): | 114 | def __init__(self, file): |
105 | self.fulfilled = False | 115 | self.fulfilled = False |
106 | self.type = 'file' | 116 | self.type = 'file' |
107 | self.file = file | 117 | self.file = file |
118 | |||
108 | def check(self): | 119 | def check(self): |
109 | if (self.fulfilled == False): | 120 | if (self.fulfilled == False): |
110 | res = os.path.isfile(self.file) | 121 | res = os.path.isfile(self.file) |
@@ -115,25 +126,28 @@ class FileExistCondition (Condition): | |||
115 | return False | 126 | return False |
116 | else: | 127 | else: |
117 | return True | 128 | return True |
118 | def evaluate (self, failed_only): | 129 | |
130 | def evaluate(self, failed_only): | ||
119 | if ((self.fulfilled == False) and (failed_only == True)): | 131 | if ((self.fulfilled == False) and (failed_only == True)): |
120 | print(str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)) | 132 | print(str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)) |
121 | elif (failed_only == False): | 133 | elif (failed_only == False): |
122 | print(str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)) | 134 | print(str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)) |
123 | return self.fulfilled | 135 | return self.fulfilled |
124 | 136 | ||
137 | |||
125 | class StatisticsCondition (Condition): | 138 | class StatisticsCondition (Condition): |
126 | def __init__(self, peer, subsystem, name, value): | 139 | def __init__(self, peer, subsystem, name, value): |
127 | self.fulfilled = False | 140 | self.fulfilled = False |
128 | self.type = 'statistics' | 141 | self.type = 'statistics' |
129 | self.peer = peer; | 142 | self.peer = peer |
130 | self.subsystem = subsystem; | 143 | self.subsystem = subsystem |
131 | self.name = name; | 144 | self.name = name |
132 | self.value = value; | 145 | self.value = value |
133 | self.result = -1; | 146 | self.result = -1 |
147 | |||
134 | def check(self): | 148 | def check(self): |
135 | if (self.fulfilled == False): | 149 | if (self.fulfilled == False): |
136 | self.result = self.peer.get_statistics_value (self.subsystem, self.name) | 150 | self.result = self.peer.get_statistics_value(self.subsystem, self.name) |
137 | if (str(self.result) == str(self.value)): | 151 | if (str(self.result) == str(self.value)): |
138 | self.fulfilled = True | 152 | self.fulfilled = True |
139 | return True | 153 | return True |
@@ -141,38 +155,41 @@ class StatisticsCondition (Condition): | |||
141 | return False | 155 | return False |
142 | else: | 156 | else: |
143 | return True | 157 | return True |
144 | def evaluate (self, failed_only): | 158 | |
159 | def evaluate(self, failed_only): | ||
145 | if (self.result == -1): | 160 | if (self.result == -1): |
146 | res = 'NaN' | 161 | res = 'NaN' |
147 | else: | 162 | else: |
148 | res = str(self.result) | 163 | res = str(self.result) |
149 | if (self.fulfilled == False): | 164 | if (self.fulfilled == False): |
150 | fail = " FAIL!" | 165 | fail = " FAIL!" |
151 | op = " != " | 166 | op = " != " |
152 | else: | 167 | else: |
153 | fail = "" | 168 | fail = "" |
154 | op = " == " | 169 | op = " == " |
155 | if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)): | 170 | if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)): |
156 | print(self.peer.id[:4] + " " +self.peer.cfg + " " + str(self.type) + ' condition in subsystem "' + self.subsystem.ljust(12) +'" : "' + self.name.ljust(30) +'" : (expected/real value) ' + str(self.value) + op + res + fail) | 171 | print(self.peer.id[:4] + " " + self.peer.cfg + " " + str(self.type) + ' condition in subsystem "' + self.subsystem.ljust(12) + '" : "' + self.name.ljust(30) + '" : (expected/real value) ' + str(self.value) + op + res + fail) |
157 | return self.fulfilled | 172 | return self.fulfilled |
158 | 173 | ||
159 | # Specify two statistic values and check if they are equal | 174 | |
175 | # Specify two statistic values and check if they are equal | ||
160 | class EqualStatisticsCondition (Condition): | 176 | class EqualStatisticsCondition (Condition): |
161 | def __init__(self, peer, subsystem, name, peer2, subsystem2, name2): | 177 | def __init__(self, peer, subsystem, name, peer2, subsystem2, name2): |
162 | self.fulfilled = False | 178 | self.fulfilled = False |
163 | self.type = 'equalstatistics' | 179 | self.type = 'equalstatistics' |
164 | self.peer = peer; | 180 | self.peer = peer |
165 | self.subsystem = subsystem; | 181 | self.subsystem = subsystem |
166 | self.name = name; | 182 | self.name = name |
167 | self.result = -1; | 183 | self.result = -1 |
168 | self.peer2 = peer2; | 184 | self.peer2 = peer2 |
169 | self.subsystem2 = subsystem2; | 185 | self.subsystem2 = subsystem2 |
170 | self.name2 = name2; | 186 | self.name2 = name2 |
171 | self.result2 = -1; | 187 | self.result2 = -1 |
188 | |||
172 | def check(self): | 189 | def check(self): |
173 | if (self.fulfilled == False): | 190 | if (self.fulfilled == False): |
174 | self.result = self.peer.get_statistics_value (self.subsystem, self.name); | 191 | self.result = self.peer.get_statistics_value(self.subsystem, self.name) |
175 | self.result2 = self.peer2.get_statistics_value (self.subsystem2, self.name2); | 192 | self.result2 = self.peer2.get_statistics_value(self.subsystem2, self.name2) |
176 | if (str(self.result) == str(self.result2)): | 193 | if (str(self.result) == str(self.result2)): |
177 | self.fulfilled = True | 194 | self.fulfilled = True |
178 | return True | 195 | return True |
@@ -180,7 +197,8 @@ class EqualStatisticsCondition (Condition): | |||
180 | return False | 197 | return False |
181 | else: | 198 | else: |
182 | return True | 199 | return True |
183 | def evaluate (self, failed_only): | 200 | |
201 | def evaluate(self, failed_only): | ||
184 | if (self.result == -1): | 202 | if (self.result == -1): |
185 | res = 'NaN' | 203 | res = 'NaN' |
186 | else: | 204 | else: |
@@ -188,27 +206,28 @@ class EqualStatisticsCondition (Condition): | |||
188 | if (self.result2 == -1): | 206 | if (self.result2 == -1): |
189 | res2 = 'NaN' | 207 | res2 = 'NaN' |
190 | else: | 208 | else: |
191 | res2 = str(self.result2) | 209 | res2 = str(self.result2) |
192 | if (self.fulfilled == False): | 210 | if (self.fulfilled == False): |
193 | fail = " FAIL!" | 211 | fail = " FAIL!" |
194 | op = " != " | 212 | op = " != " |
195 | else: | 213 | else: |
196 | fail = "" | 214 | fail = "" |
197 | op = " == " | 215 | op = " == " |
198 | if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)): | 216 | if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)): |
199 | print(self.peer.id[:4] + ' "' + self.subsystem.ljust(12) + '" "' + self.name.ljust(30) + '" == ' + str(self.result) +" " + self.peer2.id[:4] + ' "' + self.subsystem2.ljust(12) + '" '+ self.name2.ljust(30) + '" ' + str(self.result2)) | 217 | print(self.peer.id[:4] + ' "' + self.subsystem.ljust(12) + '" "' + self.name.ljust(30) + '" == ' + str(self.result) + " " + self.peer2.id[:4] + ' "' + self.subsystem2.ljust(12) + '" ' + self.name2.ljust(30) + '" ' + str(self.result2)) |
200 | return self.fulfilled | 218 | return self.fulfilled |
201 | 219 | ||
220 | |||
202 | class Test: | 221 | class Test: |
203 | def __init__(self, testname, verbose): | 222 | def __init__(self, testname, verbose): |
204 | self.peers = list() | 223 | self.peers = list() |
205 | self.verbose = verbose; | 224 | self.verbose = verbose |
206 | self.name = testname; | 225 | self.name = testname |
207 | srcdir = "../.." | 226 | srcdir = "../.." |
208 | gnunet_pyexpect_dir = os.path.join (srcdir, "contrib") | 227 | gnunet_pyexpect_dir = os.path.join(srcdir, "contrib/scripts") |
209 | if gnunet_pyexpect_dir not in sys.path: | 228 | if gnunet_pyexpect_dir not in sys.path: |
210 | sys.path.append (gnunet_pyexpect_dir) | 229 | sys.path.append(gnunet_pyexpect_dir) |
211 | self.gnunetarm = '' | 230 | self.gnunetarm = '' |
212 | self.gnunetstatistics = '' | 231 | self.gnunetstatistics = '' |
213 | if os.name == 'posix': | 232 | if os.name == 'posix': |
214 | self.gnunetarm = 'gnunet-arm' | 233 | self.gnunetarm = 'gnunet-arm' |
@@ -217,17 +236,20 @@ class Test: | |||
217 | elif os.name == 'nt': | 236 | elif os.name == 'nt': |
218 | self.gnunetarm = 'gnunet-arm.exe' | 237 | self.gnunetarm = 'gnunet-arm.exe' |
219 | self.gnunetstatistics = 'gnunet-statistics.exe' | 238 | self.gnunetstatistics = 'gnunet-statistics.exe' |
220 | self.gnunetpeerinfo = 'gnunet-peerinfo.exe' | 239 | self.gnunetpeerinfo = 'gnunet-peerinfo.exe' |
221 | if os.name == "nt": | 240 | if os.name == "nt": |
222 | shutil.rmtree (os.path.join (os.getenv ("TEMP"), testname), True) | 241 | shutil.rmtree(os.path.join(os.getenv("TEMP"), testname), True) |
223 | else: | 242 | else: |
224 | shutil.rmtree ("/tmp/" + testname, True) | 243 | shutil.rmtree("/tmp/" + testname, True) |
225 | def add_peer (self, peer): | 244 | |
245 | def add_peer(self, peer): | ||
226 | self.peers.append(peer) | 246 | self.peers.append(peer) |
227 | def p (self, msg): | 247 | |
248 | def p(self, msg): | ||
228 | if (self.verbose == True): | 249 | if (self.verbose == True): |
229 | print(msg) | 250 | print(msg) |
230 | 251 | ||
252 | |||
231 | class Peer: | 253 | class Peer: |
232 | def __init__(self, test, cfg_file): | 254 | def __init__(self, test, cfg_file): |
233 | if (False == os.path.isfile(cfg_file)): | 255 | if (False == os.path.isfile(cfg_file)): |
@@ -235,53 +257,57 @@ class Peer: | |||
235 | self.id = "<NaN>" | 257 | self.id = "<NaN>" |
236 | self.test = test | 258 | self.test = test |
237 | self.started = False | 259 | self.started = False |
238 | self.cfg = cfg_file | 260 | self.cfg = cfg_file |
261 | |||
239 | def __del__(self): | 262 | def __del__(self): |
240 | if (self.started == True): | 263 | if (self.started == True): |
241 | print('ERROR! Peer using cfg ' + self.cfg + ' was not stopped') | 264 | print('ERROR! Peer using cfg ' + self.cfg + ' was not stopped') |
242 | ret = self.stop () | 265 | ret = self.stop() |
243 | if (False == ret): | 266 | if (False == ret): |
244 | print('ERROR! Peer using cfg ' + self.cfg + ' could not be stopped') | 267 | print('ERROR! Peer using cfg ' + self.cfg + ' could not be stopped') |
245 | self.started = False | 268 | self.started = False |
246 | return ret | 269 | return ret |
247 | else: | 270 | else: |
248 | return False | 271 | return False |
249 | def start (self): | 272 | |
250 | self.test.p ("Starting peer using cfg " + self.cfg) | 273 | def start(self): |
274 | self.test.p("Starting peer using cfg " + self.cfg) | ||
251 | try: | 275 | try: |
252 | server = subprocess.Popen ([self.test.gnunetarm, '-sq', '-c', self.cfg]) | 276 | server = subprocess.Popen([self.test.gnunetarm, '-sq', '-c', self.cfg]) |
253 | server.communicate () | 277 | server.communicate() |
254 | except OSError: | 278 | except OSError: |
255 | print("Can not start peer") | 279 | print("Can not start peer") |
256 | self.started = False | 280 | self.started = False |
257 | return False | 281 | return False |
258 | self.started = True; | 282 | self.started = True |
259 | test = '' | 283 | test = '' |
260 | try: | 284 | try: |
261 | server = pexpect () | 285 | server = pexpect() |
262 | server.spawn (None, [self.test.gnunetpeerinfo, '-c', self.cfg ,'-s'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | 286 | server.spawn(None, [self.test.gnunetpeerinfo, '-c', self.cfg, '-s'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
263 | test = server.read("stdout", 1024) | 287 | test = server.read("stdout", 1024) |
264 | except OSError: | 288 | except OSError: |
265 | print("Can not get peer identity") | 289 | print("Can not get peer identity") |
266 | test = (test.split('`')[1]) | 290 | test = (test.split('`')[1]) |
267 | self.id = test.split('\'')[0] | 291 | self.id = test.split('\'')[0] |
268 | return True | 292 | return True |
269 | def stop (self): | 293 | |
294 | def stop(self): | ||
270 | if (self.started == False): | 295 | if (self.started == False): |
271 | return False | 296 | return False |
272 | self.test.p ("Stopping peer using cfg " + self.cfg) | 297 | self.test.p("Stopping peer using cfg " + self.cfg) |
273 | try: | 298 | try: |
274 | server = subprocess.Popen ([self.test.gnunetarm, '-eq', '-c', self.cfg]) | 299 | server = subprocess.Popen([self.test.gnunetarm, '-eq', '-c', self.cfg]) |
275 | server.communicate () | 300 | server.communicate() |
276 | except OSError: | 301 | except OSError: |
277 | print("Can not stop peer") | 302 | print("Can not stop peer") |
278 | return False | 303 | return False |
279 | self.started = False | 304 | self.started = False |
280 | return True; | 305 | return True |
281 | def get_statistics_value (self, subsystem, name): | 306 | |
282 | server = pexpect () | 307 | def get_statistics_value(self, subsystem, name): |
283 | server.spawn (None, [self.test.gnunetstatistics, '-c', self.cfg ,'-q','-n', name, '-s', subsystem ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) | 308 | server = pexpect() |
284 | #server.expect ("stdout", re.compile (r"")) | 309 | server.spawn(None, [self.test.gnunetstatistics, '-c', self.cfg, '-q', '-n', name, '-s', subsystem], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
310 | # server.expect ("stdout", re.compile (r"")) | ||
285 | test = server.read("stdout", 10240) | 311 | test = server.read("stdout", 10240) |
286 | tests = test.partition('\n') | 312 | tests = test.partition('\n') |
287 | # On W32 GNUnet outputs with \r\n, rather than \n | 313 | # On W32 GNUnet outputs with \r\n, rather than \n |
@@ -292,4 +318,3 @@ class Peer: | |||
292 | return tests | 318 | return tests |
293 | else: | 319 | else: |
294 | return -1 | 320 | return -1 |
295 | |||