-fixing source port randomization for DNS service
[oweals/gnunet.git] / src / integration-tests / gnunet_testing.py.in
1 #!@PYTHON@
2 #    This file is part of GNUnet.
3 #    (C) 2010 Christian Grothoff (and other contributing authors)
4 #
5 #    GNUnet is free software; you can redistribute it and/or modify
6 #    it under the terms of the GNU General Public License as published
7 #    by the Free Software Foundation; either version 2, or (at your
8 #    option) any later version.
9 #
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 #    General Public License for more details.
14 #
15 #    You should have received a copy of the GNU General Public License
16 #    along with GNUnet; see the file COPYING.  If not, write to the
17 #    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 #    Boston, MA 02111-1307, USA.
19 #
20 # Functions for integration testing
21 import os
22 import re
23 import subprocess
24 import sys
25 import shutil
26 import time
27
28
29 class Check:
30     def __init__(self, test):
31         self.fulfilled = False
32         self.conditions = list()
33         self.test = test
34     def add (self, condition):
35         self.conditions.append(condition)
36     def run (self):
37         fulfilled = True
38         pos = 0
39         neg = 0
40         for c in self.conditions:
41             if (False == c.check ()):
42                 fulfilled = False
43                 neg += 1
44             else:
45                 pos += 1
46         self.test.p (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled')
47         return fulfilled
48     def run_blocking (self, timeout, pos_cont, neg_cont):
49         execs = 0;
50         res = False
51         while ((False == res) and (execs < timeout)):
52             res = self.run()
53             time.sleep(1)
54             execs += 1
55         if (res == False):
56             neg_cont (self)
57         else:
58             pos_cont (self)
59     def eval(self, failed_only):
60         pos = 0
61         neg = 0
62         for c in self.conditions:
63             if (False == c.eval (failed_only)):
64                 neg += 1
65             else:
66                 pos += 1
67         print (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled')
68         return self.fulfilled
69         
70 class Condition:
71     def __init__(self):
72         self.fulfilled = False
73         self.type = 'generic'
74     def __init__(self, type):
75         self.fulfilled = False
76         self.type = type
77     def check(self):
78         return False;
79     def eval(self, failed_only):
80         if ((self.fulfilled == False) and (failed_only == True)):
81             print str(self.type) + 'condition for was ' + str(self.fulfilled)
82         elif (failed_only == False): 
83             print str(self.type) + 'condition for was ' + str(self.fulfilled)
84         return self.fulfilled            
85
86 class FileExistCondition (Condition):
87     def __init__(self, file):
88         self.fulfilled = False
89         self.type = 'file'
90         self.file = file
91     def check(self):
92         if (self.fulfilled == False):
93             res = os.path.isfile(self.file)
94             if (res == True):
95                 self.fulfilled = True
96                 return True
97             else:
98                 return False
99         else:
100             return True
101     def eval(self, failed_only):
102         if ((self.fulfilled == False) and (failed_only == True)):
103             print str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)
104         elif (failed_only == False): 
105             print str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)
106         return self.fulfilled
107
108 class StatisticsCondition (Condition):
109     def __init__(self, peer, subsystem, name, value):
110         self.fulfilled = False
111         self.type = 'statistics'
112         self.peer = peer;
113         self.subsystem = subsystem;
114         self.name = name;
115         self.value = value;
116         self.result = -1;
117     def check(self):
118         if (self.fulfilled == False):
119             self.result = self.peer.get_statistics_value (self.subsystem, self.name);
120             if (str(self.result) == str(self.value)):
121                 self.fulfilled = True
122                 return True
123             else:
124                 return False
125         else:
126             return True
127     def eval(self, failed_only):
128         if (self.result == -1):
129                 res = 'NaN'
130         else:
131                 res = str(self.result)
132         if (self.fulfilled == False):
133             fail = " FAIL!" 
134             op = " != "
135         else: 
136             fail = ""
137             op = " == "
138         if ((self.fulfilled == False) and (failed_only == True)):
139             print 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
140         elif (failed_only == False): 
141             print 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 
142         return self.fulfilled    
143         
144 class Test:
145     def __init__(self, testname, verbose):
146         self.peers = list()
147         self.verbose = verbose;
148         self.name = testname;
149         srcdir = "../.."
150         gnunet_pyexpect_dir = os.path.join (srcdir, "contrib")
151         if gnunet_pyexpect_dir not in sys.path:
152                 sys.path.append (gnunet_pyexpect_dir)
153                 from gnunet_pyexpect import pexpect
154         self.gnunetarm = ''        
155         self.gnunetstatistics = ''
156         if os.name == 'posix':
157            self.gnunetarm = 'gnunet-arm'
158            self.gnunetstatistics = 'gnunet-statistics'
159         elif os.name == 'nt':
160            self.gnunetarm = 'gnunet-arm.exe'
161            self.gnunetstatistics = 'gnunet-statistics.exe'    
162         if os.name == "nt":
163             shutil.rmtree (os.path.join (os.getenv ("TEMP"), testname), True)
164         else:
165             shutil.rmtree ("/tmp/" + testname, True)
166     def add_peer (peer):
167         self.conditions.append(condition)
168     def p (self, msg):
169         if (self.verbose == True):
170            print msg    
171
172 class Peer:
173     def __init__(self, test, cfg_file):
174         if (False == os.path.isfile(cfg_file)):
175             print ("Peer cfg " + cfg_file + ": FILE NOT FOUND")
176         self.test = test
177         self.started = False
178         self.cfg = cfg_file 
179     def __del__(self):
180         if (self.started == True):
181                 print 'ERROR! Peer using cfg ' + self.cfg + ' was not stopped'
182                 if (ret == self.stop ()):
183                         print 'ERROR! Peer using cfg ' + self.cfg + ' could not be stopped'
184                 self.started == False
185                 return ret
186         else:
187                 return False
188     def start (self):
189         self.test.p ("Starting peer using cfg " + self.cfg)
190         try:
191             server = subprocess.Popen ([self.test.gnunetarm, '-sq', '-c', self.cfg])
192             server.communicate ()    
193         except OSError:
194             print "Can not start peer"
195             self.started = False
196             return False
197         self.started = True
198         return True 
199     def stop (self):
200         if (self.started == False):
201                 return False
202         self.test.p ("Stopping peer using cfg " + self.cfg)
203         try:
204             server = subprocess.Popen ([self.test.gnunetarm, '-eq', '-c', self.cfg])
205             server.communicate ()    
206         except OSError:
207             print "Can not stop peer"
208             return False
209         self.started = False
210         return True;
211     def get_statistics_value (self, subsystem, name):
212         from gnunet_pyexpect import pexpect
213         server = pexpect ()
214         server.spawn (None, [self.test.gnunetstatistics, '-c', self.cfg ,'-q','-n', name, '-s', subsystem ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
215         #server.expect ("stdout", re.compile (r""))
216         test = server.read("stdout", 10240)
217         tests = test.partition('\n')[0]
218         if (tests.isdigit() == True):
219             return tests
220         else:
221             return -1
222