2 # This file is part of GNUnet.
3 # (C) 2010, 2017, 2018 Christian Grothoff (and other contributing authors)
5 # GNUnet is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Affero General Public License as published
7 # by the Free Software Foundation, either version 3 of the License,
8 # or (at your option) any later version.
10 # GNUnet is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Affero General Public License for more details.
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # SPDX-License-Identifier: AGPL3.0-or-later
20 # Functions for integration testing
21 from __future__ import unicode_literals
22 from __future__ import print_function
23 from builtins import object
24 from builtins import str
30 from gnunet_pyexpect import pexpect
33 logger = logging.getLogger()
34 handler = logging.StreamHandler()
35 formatter = logging.Formatter(
36 '%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
37 handler.setFormatter(formatter)
38 logger.addHandler(handler)
39 logger.setLevel(logging.DEBUG)
42 def __init__(self, test):
43 self.fulfilled = False
44 self.conditions = list()
47 def add(self, condition):
48 self.conditions.append(condition)
54 for c in self.conditions:
55 if (False == c.check()):
62 def run_blocking(self, timeout, pos_cont, neg_cont):
65 while ((False == res) and (execs < timeout)):
69 if ((False == res) and (execs >= timeout)):
70 logger.debug('Check had timeout after %s seconds', str(timeout))
71 # print(('Check had timeout after ' + str(timeout) + ' seconds'))
73 elif ((False == res) and (execs < timeout)):
74 if (None != neg_cont):
77 if (None != pos_cont):
81 def run_once(self, pos_cont, neg_cont):
85 if ((res == False) and (neg_cont != None)):
87 if ((res == True) and (pos_cont != None)):
91 def evaluate(self, failed_only):
94 for c in self.conditions:
95 if (False == c.evaluate(failed_only)):
99 # print((str(pos) + ' out of ' + str(pos+neg) + ' conditions fulfilled'))
100 logger.debug('%s out of %s conditions fulfilled', str(pos), str(pos+neg))
101 return self.fulfilled
104 self.fulfilled = False
105 for c in self.conditions:
109 class Condition(object):
111 self.fulfilled = False
112 self.type = 'generic'
114 def __init__(self, type):
115 self.fulfilled = False
121 def evaluate(self, failed_only):
122 if ((self.fulfilled == False) and (failed_only == True)):
123 # print(str(self.type) + 'condition for was ' + str(self.fulfilled))
124 logger.debug('%s condition for was %s', str(self.type), str(self.fulfilled))
125 elif (failed_only == False):
126 # print(str(self.type) + 'condition for was ' + str(self.fulfilled))
127 logger.debug('%s condition for was %s', str(self.type), str(self.fulfilled))
128 return self.fulfilled
131 class FileExistCondition(Condition):
132 def __init__(self, file):
133 self.fulfilled = False
138 if (self.fulfilled == False):
139 res = os.path.isfile(self.file)
141 self.fulfilled = True
148 def evaluate(self, failed_only):
149 if ((self.fulfilled == False) and (failed_only == True)):
150 # print(str(self.type) +
151 # 'condition for file ' +
154 # str(self.fulfilled))
155 logger.debug('%s confition for file %s was %s', str(self.type), self.file, str(self.fulfilled))
156 elif (failed_only == False):
157 # print(str(self.type) +
158 # 'condition for file ' +
161 # str(self.fulfilled))
162 logger.debug('%s confition for file %s was %s', str(self.type), self.file, str(self.fulfilled))
163 return self.fulfilled
166 class StatisticsCondition(Condition):
167 def __init__(self, peer, subsystem, name, value):
168 self.fulfilled = False
169 self.type = 'statistics'
171 self.subsystem = subsystem
177 if (self.fulfilled == False):
178 self.result = self.peer.get_statistics_value(self.subsystem, self.name)
179 if (str(self.result) == str(self.value)):
180 self.fulfilled = True
187 def evaluate(self, failed_only):
188 if (self.result == -1):
191 res = str(self.result).encode('utf-8')
192 if (self.fulfilled == False):
198 if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)):
199 # print(self.peer.id[:4] +
201 # self.peer.cfg.encode('utf-8') +
203 # str(self.type).encode('utf-8') +
204 # b' condition in subsystem "' +
205 # self.subsystem.encode('utf-8').ljust(12) +
207 # self.name.encode('utf-8').ljust(30) +
208 # b'" : (expected/real value) ' +
209 # str(self.value).encode('utf-8') +
213 logger.debug('%s %s %s condition in subsystem %s : %s : (expected/real value) %s %s %s %s', self.peer.id[:4], self.peer.cfg.encode('utf-8'), str(self.type).encode('utf-8'), self.subsystem.encode('utf-8').ljust(12), self.name.encode('utf-8').ljust(30), str(self.value).encode('utf-8'), op, res, fail)
214 return self.fulfilled
217 # Specify two statistic values and check if they are equal
218 class EqualStatisticsCondition(Condition):
219 def __init__(self, peer, subsystem, name, peer2, subsystem2, name2):
220 self.fulfilled = False
221 self.type = 'equalstatistics'
223 self.subsystem = subsystem
227 self.subsystem2 = subsystem2
232 if (self.fulfilled == False):
233 self.result = self.peer.get_statistics_value(self.subsystem, self.name)
234 self.result2 = self.peer2.get_statistics_value(self.subsystem2, self.name2)
235 if (str(self.result) == str(self.result2)):
236 self.fulfilled = True
243 def evaluate(self, failed_only):
244 if (self.result == -1):
247 res = str(self.result).encode('utf-8')
248 if (self.result2 == -1):
251 res2 = str(self.result2).encode('utf-8')
252 if (self.fulfilled == False):
258 if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)):
259 # print(self.peer.id[:4] +
261 # self.subsystem.encode('utf-8').ljust(12) +
263 # self.name.encode('utf-8').ljust(30) +
265 # str(self.result).encode('utf-8') +
267 # self.peer2.id[:4] +
269 # self.subsystem2.encode('utf-8').ljust(12) +
271 # self.name2.encode('utf-8').ljust(30) +
273 # str(self.result2).encode('utf-8'))
274 logger.debug('%s %s %s == %s %s %s %s %s', self.peer.id[:4], self.subsystem.encode('utf-8').ljust(12), self.name.encode('utf-8').ljust(30), str(self.result).encode('utf-8'), self.peer2.id[:4], self.subsystem2.encode('uft-8').ljust(12), self.name2.encode('utf-8').ljust(30), str(self.result2).encode('utf-8'))
275 return self.fulfilled
279 def __init__(self, testname, verbose):
281 self.verbose = verbose
284 gnunet_pyexpect_dir = os.path.join(srcdir, "contrib/scripts")
285 if gnunet_pyexpect_dir not in sys.path:
286 sys.path.append(gnunet_pyexpect_dir)
288 self.gnunetstatistics = ''
289 if os.name == 'posix':
290 self.gnunetarm = 'gnunet-arm'
291 self.gnunetstatistics = 'gnunet-statistics'
292 self.gnunetpeerinfo = 'gnunet-peerinfo'
293 elif os.name == 'nt':
294 self.gnunetarm = 'gnunet-arm.exe'
295 self.gnunetstatistics = 'gnunet-statistics.exe'
296 self.gnunetpeerinfo = 'gnunet-peerinfo.exe'
298 shutil.rmtree(os.path.join(os.getenv("TEMP"), testname), True)
300 shutil.rmtree("/tmp/" + testname, True)
302 def add_peer(self, peer):
303 self.peers.append(peer)
306 if (self.verbose == True):
311 def __init__(self, test, cfg_file):
312 if (False == os.path.isfile(cfg_file)):
313 # print(("Peer cfg " + cfg_file + ": FILE NOT FOUND"))
314 logger.debug('Peer cfg %s : FILE NOT FOUND', cfg_file)
321 if (self.started == True):
322 # print('ERROR! Peer using cfg ' + self.cfg + ' was not stopped')
323 logger.debug('ERROR! Peer using cfg %s was not stopped', self.cfg)
326 # print('ERROR! Peer using cfg ' +
328 # ' could not be stopped')
329 logger.debug('ERROR! Peer using cfg %s could not be stopped', self.cfg)
336 self.test.p("Starting peer using cfg " + self.cfg)
338 server = subprocess.Popen([self.test.gnunetarm, '-sq', '-c', self.cfg])
341 # print("Can not start peer")
342 logger.debug('Can not start peer')
349 server.spawn(None, [self.test.gnunetpeerinfo, '-c', self.cfg, '-s'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
350 test = server.read("stdout", 1024)
352 # print("Can not get peer identity")
353 logger.debug('Can not get peer identity')
354 test = (test.split(b'`')[1])
355 self.id = test.split(b'\'')[0]
359 if (self.started == False):
361 self.test.p("Stopping peer using cfg " + self.cfg)
363 server = subprocess.Popen([self.test.gnunetarm, '-eq', '-c', self.cfg])
366 # print("Can not stop peer")
367 logger.debug('Can not stop peer')
372 def get_statistics_value(self, subsystem, name):
374 server.spawn(None, [self.test.gnunetstatistics, '-c', self.cfg, '-q', '-n', name, '-s', subsystem], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
375 # server.expect ("stdout", re.compile (r""))
376 test = server.read("stdout", 10240)
377 tests = test.partition(b'\n')
378 # On W32 GNUnet outputs with \r\n, rather than \n
379 if os.name == 'nt' and tests[1] == b'\n' and tests[0][-1] == b'\r':
380 tests = (tests[0][:-1], tests[1], tests[2])
382 # print("running gnunet-statistics " + self.cfg + " for " + name + "/" + subsystem + " yields " + tests.decode("utf-8"))
383 logger.debug('running gnunet-statistics %s for %s "/" %s yields %s', self.cfg, name, subsystem, test.decode("utf-8"))
384 if (tests.isdigit() == True):
387 # print("Invalid statistics value: " + str(tests) + " is not a number!")
388 logger.debug('Invalid statistics value: %s is not a number!', str(tests))