if start fails, clean up and exit
[oweals/gnunet.git] / src / integration-tests / gnunet_testing.py.in
index 9d4a328770cd2498cae46b5237b486c1791b2a98..0e3cdaaf8228386647424f8d742f54a5d5b55a67 100644 (file)
 #
 # Functions for integration testing
 import os
-import re
 import subprocess
 import sys
 import shutil
 import time
-
+from gnunet_pyexpect import pexpect
 
 class Check:
     def __init__(self, test):
@@ -43,7 +42,6 @@ class Check:
                 neg += 1
             else:
                 pos += 1
-        self.test.p (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled')
         return fulfilled
     def run_blocking (self, timeout, pos_cont, neg_cont):
         execs = 0;
@@ -52,20 +50,39 @@ class Check:
             res = self.run()
             time.sleep(1)
             execs += 1
-        if (res == False):
-            neg_cont (self)
+        if ((False == res) and (execs >= timeout)):
+           print ('Check had timeout after ' +str(timeout)+ ' seconds')
+           neg_cont (self)
+        elif ((False == res) and (execs < timeout)):
+            if (None != neg_cont):
+                neg_cont (self)
         else:
-            pos_cont (self)
-    def eval(self, failed_only):
+            if (None != pos_cont):
+                pos_cont (self)
+        return res     
+    def run_once (self, pos_cont, neg_cont):
+        execs = 0;
+        res = False
+        res = self.run()
+        if ((res == False) and (neg_cont != None)):
+            neg_cont (self)
+        if ((res == True) and (pos_cont != None)):
+            pos_cont (self)            
+        return res
+    def evaluate (self, failed_only):
         pos = 0
         neg = 0
         for c in self.conditions:
-            if (False == c.eval (failed_only)):
+            if (False == c.evaluate (failed_only)):
                 neg += 1
             else:
                 pos += 1
         print (str(pos) +' out of '+ str (pos+neg) + ' conditions fulfilled')
         return self.fulfilled
+    def reset (self):
+               self.fulfilled = False     
+               for c in self.conditions:
+                       c.fulfilled = False
         
 class Condition:
     def __init__(self):
@@ -76,7 +93,7 @@ class Condition:
         self.type = type
     def check(self):
         return False;
-    def eval(self, failed_only):
+    def evaluate (self, failed_only):
         if ((self.fulfilled == False) and (failed_only == True)):
             print str(self.type) + 'condition for was ' + str(self.fulfilled)
         elif (failed_only == False): 
@@ -98,7 +115,7 @@ class FileExistCondition (Condition):
                 return False
         else:
             return True
-    def eval(self, failed_only):
+    def evaluate (self, failed_only):
         if ((self.fulfilled == False) and (failed_only == True)):
             print str(self.type) + 'condition for file '+self.file+' was ' + str(self.fulfilled)
         elif (failed_only == False): 
@@ -116,7 +133,7 @@ class StatisticsCondition (Condition):
         self.result = -1;
     def check(self):
         if (self.fulfilled == False):
-            self.result = self.peer.get_statistics_value (self.subsystem, self.name);
+            self.result = self.peer.get_statistics_value (self.subsystem, self.name)
             if (str(self.result) == str(self.value)):
                 self.fulfilled = True
                 return True
@@ -124,67 +141,111 @@ class StatisticsCondition (Condition):
                 return False
         else:
             return True
-    def eval(self, failed_only):
-       if (self.result == -1):
-               res = 'NaN'
-       else:
-               res = str(self.result)
+    def evaluate (self, failed_only):
+        if (self.result == -1):
+            res = 'NaN'
+        else:
+            res = str(self.result)
         if (self.fulfilled == False):
             fail = " FAIL!" 
             op = " != "
         else: 
             fail = ""
             op = " == "
-        if ((self.fulfilled == False) and (failed_only == True)):
-            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
-        elif (failed_only == False): 
-            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 
+        if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)):
+            print self.peer.id[:4] + " " +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
         return self.fulfilled    
+
+# Specify two statistic values and check if they are equal  
+class EqualStatisticsCondition (Condition):
+    def __init__(self, peer, subsystem, name, peer2, subsystem2, name2):
+        self.fulfilled = False
+        self.type = 'equalstatistics'
+        self.peer = peer;
+        self.subsystem = subsystem;
+        self.name = name;
+        self.result = -1;
+        self.peer2 = peer2;
+        self.subsystem2 = subsystem2;
+        self.name2 = name2;
+        self.result2 = -1;
+    def check(self):
+        if (self.fulfilled == False):
+            self.result = self.peer.get_statistics_value (self.subsystem, self.name);
+            self.result2 = self.peer2.get_statistics_value (self.subsystem2, self.name2);
+            if (str(self.result) == str(self.result2)):
+                self.fulfilled = True
+                return True
+            else:
+                return False
+        else:
+            return True
+    def evaluate (self, failed_only):
+        if (self.result == -1):
+            res = 'NaN'
+        else:
+            res = str(self.result)
+        if (self.result2 == -1):
+            res2 = 'NaN'
+        else:
+            res2 = str(self.result2)            
+        if (self.fulfilled == False):
+            fail = " FAIL!" 
+            op = " != "
+        else: 
+            fail = ""
+            op = " == "
+        if (((self.fulfilled == False) and (failed_only == True)) or (failed_only == False)):
+            print self.peer.id[:4] + ' "'  + self.subsystem.ljust(12) + '" "' + self.name.ljust(30) + '" == ' + str(self.result) +" " + self.peer2.id[:4] + ' "'  + self.subsystem2.ljust(12) + '" '+ self.name2.ljust(30) +  '" ' + str(self.result2) 
+        return self.fulfilled                    
         
 class Test:
     def __init__(self, testname, verbose):
         self.peers = list()
-       self.verbose = verbose;
-       self.name = testname;
-       srcdir = "../.."
+        self.verbose = verbose;
+        self.name = testname;
+        srcdir = "../.."
         gnunet_pyexpect_dir = os.path.join (srcdir, "contrib")
         if gnunet_pyexpect_dir not in sys.path:
-               sys.path.append (gnunet_pyexpect_dir)
-               from gnunet_pyexpect import pexpect
+            sys.path.append (gnunet_pyexpect_dir)
         self.gnunetarm = ''        
         self.gnunetstatistics = ''
         if os.name == 'posix':
-           self.gnunetarm = 'gnunet-arm'
-           self.gnunetstatistics = 'gnunet-statistics'
+            self.gnunetarm = 'gnunet-arm'
+            self.gnunetstatistics = 'gnunet-statistics'
+            self.gnunetpeerinfo = 'gnunet-peerinfo'
         elif os.name == 'nt':
-           self.gnunetarm = 'gnunet-arm.exe'
-           self.gnunetstatistics = 'gnunet-statistics.exe'    
+            self.gnunetarm = 'gnunet-arm.exe'
+            self.gnunetstatistics = 'gnunet-statistics.exe'
+            self.gnunetpeerinfo = 'gnunet-peerinfo.exe'    
         if os.name == "nt":
             shutil.rmtree (os.path.join (os.getenv ("TEMP"), testname), True)
         else:
             shutil.rmtree ("/tmp/" + testname, True)
-    def add_peer (peer):
-       self.conditions.append(condition)
+    def add_peer (self, peer):
+        self.peers.append(peer)
     def p (self, msg):
         if (self.verbose == True):
-          print msg    
+            print msg    
 
 class Peer:
     def __init__(self, test, cfg_file):
         if (False == os.path.isfile(cfg_file)):
             print ("Peer cfg " + cfg_file + ": FILE NOT FOUND")
+        self.id = "<NaN>"
         self.test = test
         self.started = False
         self.cfg = cfg_file 
     def __del__(self):
-       if (self.started == True):
-               print 'ERROR! Peer using cfg ' + self.cfg + ' was not stopped'
-               if (ret == self.stop ()):
-                       print 'ERROR! Peer using cfg ' + self.cfg + ' could not be stopped'
-               self.started == False
-               return ret
-       else:
-               return False
+        if (self.started == True): 
+            print 'ERROR! Peer using cfg ' + self.cfg + ' was not stopped'
+            ret = self.stop ()
+            if (False == ret):
+                print 'ERROR! Peer using cfg ' + self.cfg + ' could not be stopped'
+                self.started = False
+            return ret
+        else:
+            return False
     def start (self):
         self.test.p ("Starting peer using cfg " + self.cfg)
         try:
@@ -194,11 +255,20 @@ class Peer:
             print "Can not start peer"
             self.started = False
             return False
-        self.started = True
+        self.started = True;
+        test = ''
+        try:
+            server = pexpect ()
+            server.spawn (None, [self.test.gnunetpeerinfo, '-c', self.cfg ,'-s'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+            test = server.read("stdout", 1024)
+        except OSError:
+            print "Can not get peer identity"
+        test = (test.split('`')[1])
+        self.id = test.split('\'')[0]
         return True 
     def stop (self):
-       if (self.started == False):
-               return False
+        if (self.started == False):
+            return False
         self.test.p ("Stopping peer using cfg " + self.cfg)
         try:
             server = subprocess.Popen ([self.test.gnunetarm, '-eq', '-c', self.cfg])
@@ -209,12 +279,15 @@ class Peer:
         self.started = False
         return True;
     def get_statistics_value (self, subsystem, name):
-        from gnunet_pyexpect import pexpect
         server = pexpect ()
         server.spawn (None, [self.test.gnunetstatistics, '-c', self.cfg ,'-q','-n', name, '-s', subsystem ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
         #server.expect ("stdout", re.compile (r""))
         test = server.read("stdout", 10240)
-        tests = test.partition('\n')[0]
+        tests = test.partition('\n')
+        # On W32 GNUnet outputs with \r\n, rather than \n
+        if os.name == 'nt' and tests[1] == '\n' and tests[0][-1] == '\r':
+            tests = (tests[0][:-1], tests[1], tests[2])
+        tests = tests[0]
         if (tests.isdigit() == True):
             return tests
         else: