aboutsummaryrefslogtreecommitdiff
path: root/src/integration-tests/gnunet_testing.py.in
diff options
context:
space:
mode:
Diffstat (limited to 'src/integration-tests/gnunet_testing.py.in')
-rw-r--r--src/integration-tests/gnunet_testing.py.in225
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
21import os 19import os
@@ -25,86 +23,99 @@ import shutil
25import time 23import time
26from gnunet_pyexpect import pexpect 24from gnunet_pyexpect import pexpect
27 25
26
28class Check: 27class 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
87class Condition: 93class 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
103class FileExistCondition (Condition): 113class 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
125class StatisticsCondition (Condition): 138class 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
160class EqualStatisticsCondition (Condition): 176class 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
202class Test: 221class 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
231class Peer: 253class 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