- changes to integration
[oweals/gnunet.git] / src / integration-tests / gnunet_testing.py.in
1 #!/usr/bin/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 subprocess
23 import sys
24 import shutil
25 import time
26 from gnunet_pyexpect import pexpect
27
28 class Check:
29     def __init__(self, test):
30         self.fulfilled = False
31         self.conditions = list()
32         self.test = test
33     def add (self, condition):
34         self.conditions.append(condition)
35     def run (self):
36         fulfilled = True
37         pos = 0
38         neg = 0
39         for c in self.conditions:
40             if (False == c.check ()):
41                 fulfilled = False
42                 neg += 1
43             else:
44                 pos += 1
45         self.test.p (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled')
46         return fulfilled
47     def run_blocking (self, timeout, pos_cont, neg_cont):
48         execs = 0;
49         res = False
50         while ((False == res) and (execs < timeout)):
51             res = self.run()
52             time.sleep(1)
53             execs += 1
54         if (res == False):
55             neg_cont (self)
56         else:
57             pos_cont (self)
58     def evaluate (self, failed_only):
59         pos = 0
60         neg = 0
61         for c in self.conditions:
62             if (False == c.evaluate (failed_only)):
63                 neg += 1
64             else:
65                 pos += 1
66         print (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled')
67         return self.fulfilled
68         
69 class Condition:
70     def __init__(self):
71         self.fulfilled = False
72         self.type = 'generic'
73     def __init__(self, type):
74         self.fulfilled = False
75         self.type = type
76     def check(self):
77         return False;
78     def evaluate (self, failed_only):
79         if ((self.fulfilled == False) and (failed_only == True)):
80             print str(self.type) + 'condition for was ' + str(self.fulfilled)
81         elif (failed_only == False): 
82             print str(self.type) + 'condition for was ' + str(self.fulfilled)
83         return self.fulfilled            
84
85 class FileExistCondition (Condition):
86     def __init__(self, file):
87         self.fulfilled = False
88         self.type = 'file'
89         self.file = file
90     def check(self):
91         if (self.fulfilled == False):
92             res = os.path.isfile(self.file)
93             if (res == True):
94                 self.fulfilled = True
95                 return True
96             else:
97                 return False
98         else:
99             return True
100     def evaluate (self, failed_only):
101         if ((self.fulfilled == False) and (failed_only == True)):
102             print str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)
103         elif (failed_only == False): 
104             print str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)
105         return self.fulfilled
106
107 class StatisticsCondition (Condition):
108     def __init__(self, peer, subsystem, name, value):
109         self.fulfilled = False
110         self.type = 'statistics'
111         self.peer = peer;
112         self.subsystem = subsystem;
113         self.name = name;
114         self.value = value;
115         self.result = -1;
116     def check(self):
117         if (self.fulfilled == False):
118             self.result = self.peer.get_statistics_value (self.subsystem, self.name);
119             if (str(self.result) == str(self.value)):
120                 self.fulfilled = True
121                 return True
122             else:
123                 return False
124         else:
125             return True
126     def evaluate (self, failed_only):
127         if (self.result == -1):
128             res = 'NaN'
129         else:
130             res = str(self.result)
131         if (self.fulfilled == False):
132             fail = " FAIL!" 
133             op = " != "
134         else: 
135             fail = ""
136             op = " == "
137         if ((self.fulfilled == False) and (failed_only == True)):
138             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
139         elif (failed_only == False): 
140             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 
141         return self.fulfilled    
142         
143 class Test:
144     def __init__(self, testname, verbose):
145         self.peers = list()
146         self.verbose = verbose;
147         self.name = testname;
148         srcdir = "../.."
149         gnunet_pyexpect_dir = os.path.join (srcdir, "contrib")
150         if gnunet_pyexpect_dir not in sys.path:
151             sys.path.append (gnunet_pyexpect_dir)
152         self.gnunetarm = ''        
153         self.gnunetstatistics = ''
154         if os.name == 'posix':
155             self.gnunetarm = 'gnunet-arm'
156             self.gnunetstatistics = 'gnunet-statistics'
157             self.gnunetpeerinfo = 'gnunet-peerinfo'
158         elif os.name == 'nt':
159             self.gnunetarm = 'gnunet-arm.exe'
160             self.gnunetstatistics = 'gnunet-statistics.exe'
161             self.gnunetpeerinfo = 'gnunet-peerinfo.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 (self, peer):
167         self.peers.append(peer)
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.id = ""
177         self.test = test
178         self.started = False
179         self.cfg = cfg_file 
180     def __del__(self):
181         if (self.started == True): 
182             print 'ERROR! Peer using cfg ' + self.cfg + ' was not stopped'
183             ret = self.stop ()
184             if (False == ret):
185                 print 'ERROR! Peer using cfg ' + self.cfg + ' could not be stopped'
186                 self.started = False
187             return ret
188         else:
189             return False
190     def start (self):
191         self.test.p ("Starting peer using cfg " + self.cfg)
192         try:
193             server = subprocess.Popen ([self.test.gnunetarm, '-sq', '-c', self.cfg])
194             server.communicate ()    
195         except OSError:
196             print "Can not start peer"
197             self.started = False
198             return False
199         self.started = True;
200         test = ''
201         try:
202             server = pexpect ()
203             server.spawn (None, [self.test.gnunetpeerinfo, '-c', self.cfg ,'-s'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
204             test = server.read("stdout", 1024)
205         except OSError:
206             print "Can not get peer identity"
207         test = (test.split('`')[1])
208         self.id = test.split('\'')[0]
209         return True 
210     def stop (self):
211         if (self.started == False):
212             return False
213         self.test.p ("Stopping peer using cfg " + self.cfg)
214         try:
215             server = subprocess.Popen ([self.test.gnunetarm, '-eq', '-c', self.cfg])
216             server.communicate ()    
217         except OSError:
218             print "Can not stop peer"
219             return False
220         self.started = False
221         return True;
222     def get_statistics_value (self, subsystem, name):
223         server = pexpect ()
224         server.spawn (None, [self.test.gnunetstatistics, '-c', self.cfg ,'-q','-n', name, '-s', subsystem ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
225         #server.expect ("stdout", re.compile (r""))
226         test = server.read("stdout", 10240)
227         tests = test.partition('\n')[0]
228         if (tests.isdigit() == True):
229             return tests
230         else:
231             return -1
232