added support for interupting a test
[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         
71
72 class Condition:
73     def __init__(self):
74         self.fulfilled = False
75         self.type = 'generic'
76     def __init__(self, type):
77         self.fulfilled = False
78         self.type = type
79     def check(self):
80         return False;
81     def eval(self, failed_only):
82         if ((self.fulfilled == False) and (failed_only == True)):
83             print str(self.type) + 'condition for was ' + str(self.fulfilled)
84         elif (failed_only == False): 
85             print str(self.type) + 'condition for was ' + str(self.fulfilled)
86         return self.fulfilled            
87
88 class FileExistCondition (Condition):
89     def __init__(self, file):
90         self.fulfilled = False
91         self.type = 'file'
92         self.file = file
93     def check(self):
94         if (self.fulfilled == False):
95             res = os.path.isfile(self.file)
96             if (res == True):
97                 self.fulfilled = True
98                 return True
99             else:
100                 return False
101         else:
102             return True
103     def eval(self, failed_only):
104         if ((self.fulfilled == False) and (failed_only == True)):
105             print str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)
106         elif (failed_only == False): 
107             print str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)
108         return self.fulfilled
109
110 class StatisticsCondition (Condition):
111     def __init__(self, peer, subsystem, name, value):
112         self.fulfilled = False
113         self.type = 'statistics'
114         self.peer = peer;
115         self.subsystem = subsystem;
116         self.name = name;
117         self.value = value;
118     def check(self):
119         if (self.fulfilled == False):
120             res = self.peer.check (self.subsystem, self.name, self.value);
121             if (res == True):
122                 self.fulfilled = True
123                 return True
124             else:
125                 return False
126         else:
127             return True
128     def eval(self, failed_only):
129         if ((self.fulfilled == False) and (failed_only == True)):
130             print str(self.type) + ' condition for value "'+str(self.value)+'" in subsystem "' + self.subsystem +'" : "' + self.name +'" was ' + str(self.fulfilled)
131         elif (failed_only == False): 
132             print str(self.type) + ' condition for value "'+str(self.value)+'" in subsystem "' + self.subsystem +'" : "' + self.name +'" was ' + str(self.fulfilled)
133         return self.fulfilled    
134         
135 class Test:
136     def __init__(self, testname, verbose):
137         self.peers = list()
138         self.verbose = verbose;
139         self.name = testname;
140         srcdir = "../.."
141         gnunet_pyexpect_dir = os.path.join (srcdir, "contrib")
142         if gnunet_pyexpect_dir not in sys.path:
143                 sys.path.append (gnunet_pyexpect_dir)
144                 from gnunet_pyexpect import pexpect
145         self.gnunetarm = ''        
146         self.gnunetstatistics = ''
147         if os.name == 'posix':
148            self.gnunetarm = 'gnunet-arm'
149            self.gnunetstatistics = 'gnunet-statistics'
150         elif os.name == 'nt':
151            self.gnunetarm = 'gnunet-arm.exe'
152            self.gnunetstatistics = 'gnunet-statistics.exe'    
153         if os.name == "nt":
154             shutil.rmtree (os.path.join (os.getenv ("TEMP"), testname), True)
155         else:
156             shutil.rmtree ("/tmp/" + testname, True)
157     def add_peer (peer):
158         self.conditions.append(condition)
159     def p (self, msg):
160         if (self.verbose == True):
161            print msg    
162
163 class Peer:
164     def __init__(self, test, cfg_file):
165         if (False == os.path.isfile(cfg_file)):
166             print ("Peer cfg " + cfg_file + ": FILE NOT FOUND")
167         self.test = test
168         self.started = False
169         self.cfg = cfg_file 
170     def __del__(self):
171         if (self.started == True):
172                 print 'ERROR! Peer using cfg ' + self.cfg + ' was not stopped'
173                 if (ret == self.stop ()):
174                         print 'ERROR! Peer using cfg ' + self.cfg + ' could not be stopped'
175                 self.started == False
176                 return ret
177         else:
178                 return False
179     def start (self):
180         self.test.p ("Starting peer using cfg " + self.cfg)
181         try:
182             server = subprocess.Popen ([self.test.gnunetarm, '-sq', '-c', self.cfg])
183             server.communicate ()    
184         except OSError:
185             print "Can not start peer"
186             self.started = False
187             return False
188         self.started = True
189         return True 
190     def stop (self):
191         if (self.started == False):
192                 return False
193         self.test.p ("Stopping peer using cfg " + self.cfg)
194         try:
195             server = subprocess.Popen ([self.test.gnunetarm, '-eq', '-c', self.cfg])
196             server.communicate ()    
197         except OSError:
198             print "Can not stop peer"
199             return False
200         self.started = False
201         return True;
202     def check (self, subsystem, name, value):
203         from gnunet_pyexpect import pexpect
204         server = pexpect ()
205         server.spawn (None, [self.test.gnunetstatistics, '-c', self.cfg ,'-q','-n', name, '-s', subsystem ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
206         #server.expect ("stdout", re.compile (r""))
207         test = server.read("stdout", 10240)
208         if (test.find(str(value)) == -1): 
209             return False
210         else:
211             return True  
212