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
34 def __init__(self, test):
35 self.fulfilled = False
36 self.conditions = list()
39 def add(self, condition):
40 self.conditions.append(condition)
46 for c in self.conditions:
47 if (False == c.check()):
54 def run_blocking(self, timeout, pos_cont, neg_cont):
57 while ((False == res) and (execs < timeout)):
61 if ((False == res) and (execs >= timeout)):
62 print(('Check had timeout after ' + str(timeout) + ' seconds'))
64 elif ((False == res) and (execs < timeout)):
65 if (None != neg_cont):
68 if (None != pos_cont):
72 def run_once(self, pos_cont, neg_cont):
76 if ((res == False) and (neg_cont != None)):
78 if ((res == True) and (pos_cont != None)):
82 def evaluate(self, failed_only):
85 for c in self.conditions:
86 if (False == c.evaluate(failed_only)):
90 print((str(pos) + ' out of ' + str(pos+neg) + ' conditions fulfilled'))
94 self.fulfilled = False
95 for c in self.conditions:
99 class Condition(object):
101 self.fulfilled = False
102 self.type = 'generic'
104 def __init__(self, type):
105 self.fulfilled = False
111 def evaluate(self, failed_only):
112 if ((self.fulfilled == False) and (failed_only == True)):
113 print(str(self.type) + 'condition for was ' + str(self.fulfilled))
114 elif (failed_only == False):
115 print(str(self.type) + 'condition for was ' + str(self.fulfilled))
116 return self.fulfilled
119 class FileExistCondition(Condition):
120 def __init__(self, file):
121 self.fulfilled = False
126 if (self.fulfilled == False):
127 res = os.path.isfile(self.file)
129 self.fulfilled = True
136 def evaluate(self, failed_only):
137 if ((self.fulfilled == False) and (failed_only == True)):
138 print(str(self.type) +
139 'condition for file ' +
143 elif (failed_only == False):
144 print(str(self.type) +
145 'condition for file ' +
149 return self.fulfilled
152 class StatisticsCondition(Condition):
153 def __init__(self, peer, subsystem, name, value):
154 self.fulfilled = False
155 self.type = 'statistics'
157 self.subsystem = subsystem
163 if (self.fulfilled == False):
164 self.result = self.peer.get_statistics_value(self.subsystem, self.name)
165 if (str(self.result) == str(self.value)):
166 self.fulfilled = True
173 def evaluate(self, failed_only):
174 if (self.result == -1):
177 res = str(self.result).encode('utf-8')
178 if (self.fulfilled == False):
184 if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)):
185 print(self.peer.id[:4] +
187 self.peer.cfg.encode('utf-8') +
189 str(self.type).encode('utf-8') +
190 b' condition in subsystem "' +
191 self.subsystem.encode('utf-8').ljust(12) +
193 self.name.encode('utf-8').ljust(30) +
194 b'" : (expected/real value) ' +
195 str(self.value).encode('utf-8') +
199 return self.fulfilled
202 # Specify two statistic values and check if they are equal
203 class EqualStatisticsCondition(Condition):
204 def __init__(self, peer, subsystem, name, peer2, subsystem2, name2):
205 self.fulfilled = False
206 self.type = 'equalstatistics'
208 self.subsystem = subsystem
212 self.subsystem2 = subsystem2
217 if (self.fulfilled == False):
218 self.result = self.peer.get_statistics_value(self.subsystem, self.name)
219 self.result2 = self.peer2.get_statistics_value(self.subsystem2, self.name2)
220 if (str(self.result) == str(self.result2)):
221 self.fulfilled = True
228 def evaluate(self, failed_only):
229 if (self.result == -1):
232 res = str(self.result).encode('utf-8')
233 if (self.result2 == -1):
236 res2 = str(self.result2).encode('utf-8')
237 if (self.fulfilled == False):
243 if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)):
244 print(self.peer.id[:4] +
246 self.subsystem.encode('utf-8').ljust(12) +
248 self.name.encode('utf-8').ljust(30) +
250 str(self.result).encode('utf-8') +
254 self.subsystem2.encode('utf-8').ljust(12) +
256 self.name2.encode('utf-8').ljust(30) +
258 str(self.result2).encode('utf-8'))
259 return self.fulfilled
263 def __init__(self, testname, verbose):
265 self.verbose = verbose
268 gnunet_pyexpect_dir = os.path.join(srcdir, "contrib/scripts")
269 if gnunet_pyexpect_dir not in sys.path:
270 sys.path.append(gnunet_pyexpect_dir)
272 self.gnunetstatistics = ''
273 if os.name == 'posix':
274 self.gnunetarm = 'gnunet-arm'
275 self.gnunetstatistics = 'gnunet-statistics'
276 self.gnunetpeerinfo = 'gnunet-peerinfo'
277 elif os.name == 'nt':
278 self.gnunetarm = 'gnunet-arm.exe'
279 self.gnunetstatistics = 'gnunet-statistics.exe'
280 self.gnunetpeerinfo = 'gnunet-peerinfo.exe'
282 shutil.rmtree(os.path.join(os.getenv("TEMP"), testname), True)
284 shutil.rmtree("/tmp/" + testname, True)
286 def add_peer(self, peer):
287 self.peers.append(peer)
290 if (self.verbose == True):
295 def __init__(self, test, cfg_file):
296 if (False == os.path.isfile(cfg_file)):
297 print(("Peer cfg " + cfg_file + ": FILE NOT FOUND"))
304 if (self.started == True):
305 print('ERROR! Peer using cfg ' + self.cfg + ' was not stopped')
308 print('ERROR! Peer using cfg ' +
310 ' could not be stopped')
317 self.test.p("Starting peer using cfg " + self.cfg)
319 server = subprocess.Popen([self.test.gnunetarm, '-sq', '-c', self.cfg])
322 print("Can not start peer")
329 server.spawn(None, [self.test.gnunetpeerinfo, '-c', self.cfg, '-s'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
330 test = server.read("stdout", 1024)
332 print("Can not get peer identity")
333 test = (test.split(b'`')[1])
334 self.id = test.split(b'\'')[0]
338 if (self.started == False):
340 self.test.p("Stopping peer using cfg " + self.cfg)
342 server = subprocess.Popen([self.test.gnunetarm, '-eq', '-c', self.cfg])
345 print("Can not stop peer")
350 def get_statistics_value(self, subsystem, name):
352 server.spawn(None, [self.test.gnunetstatistics, '-c', self.cfg, '-q', '-n', name, '-s', subsystem], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
353 # server.expect ("stdout", re.compile (r""))
354 test = server.read("stdout", 10240)
355 tests = test.partition(b'\n')
356 # On W32 GNUnet outputs with \r\n, rather than \n
357 if os.name == 'nt' and tests[1] == b'\n' and tests[0][-1] == b'\r':
358 tests = (tests[0][:-1], tests[1], tests[2])
360 if (tests.isdigit() == True):