Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[tesh] bad cmd result: abort -> store retcode
authorMillian Poquet <millian.poquet@inria.fr>
Mon, 17 Jun 2019 16:04:06 +0000 (18:04 +0200)
committerMillian Poquet <millian.poquet@inria.fr>
Wed, 19 Jun 2019 11:43:27 +0000 (13:43 +0200)
tools/tesh/catch-all-bg-output.tesh [new file with mode: 0644]
tools/tesh/tesh.py

diff --git a/tools/tesh/catch-all-bg-output.tesh b/tools/tesh/catch-all-bg-output.tesh
new file mode 100644 (file)
index 0000000..5bf7704
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/env tesh
+
+# Checks that background processes' output is not lost when a foreground
+# process (or another background process) does not match its expectation.
+
+! expect return 2
+< ! timeout 3
+< & sh -c 'echo "I crash in background" && sleep 2'
+< 
+< ! timeout 2
+< & sh -c 'echo "I also crash in background" && sleep 1'
+< 
+< !timeout 1
+< $ sh -c 'echo "I crash in foreground"'
+$ ${bindir:=.}/tesh
+> Output of <meh.tesh:8> mismatch:
+> --- expected
+> +++ obtained
+> @@ -0,0 +1 @@
+> +I crash in foreground
+> Test suite `meh.tesh': NOK (<meh.tesh:8> output mismatch)
+> Output of <meh.tesh:5> mismatch:
+> --- expected
+> +++ obtained
+> @@ -0,0 +1 @@
+> +I also crash in background
+> Test suite `meh.tesh': NOK (<meh.tesh:5> output mismatch)
+> Test suite `meh.tesh': NOK (<meh.tesh:2> timeout after 4 sec)
+> Output of <meh.tesh:2> mismatch:
+> --- expected
+> +++ obtained
+> @@ -0,0 +1 @@
+> +I crash in background
+> Test suite `meh.tesh': NOK (<meh.tesh:2> output mismatch)
index 48ddd51..8972bbc 100755 (executable)
@@ -71,6 +71,7 @@ class Singleton(_Singleton('SingletonMeta', (object,), {})):
 SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n)
                              for n in dir(signal) if n.startswith('SIG') and '_' not in n)
 
+return_code = 0
 
 # exit correctly
 def tesh_exit(errcode):
@@ -328,6 +329,7 @@ class Cmd(object):
 
         global running_pgids
         local_pgid = None
+        global return_code
 
         try:
             preexec_function = None
@@ -352,16 +354,19 @@ class Cmd(object):
             print("[" + FileReader().filename + ":" + str(self.linenumber) +
                   "] Cannot start '" + args[0] + "': The binary is not executable.")
             print("[" + FileReader().filename + ":" + str(self.linenumber) + "] Current dir: " + os.getcwd())
-            tesh_exit(3)
+            return_code = max(3, return_code)
+            return
         except NotADirectoryError:
             print("[" + FileReader().filename + ":" + str(self.linenumber) + "] Cannot start '" +
                   args[0] + "': The path to binary does not exist.")
             print("[" + FileReader().filename + ":" + str(self.linenumber) + "] Current dir: " + os.getcwd())
-            tesh_exit(3)
+            return_code = max(3, return_code)
+            return
         except FileNotFoundError:
             print("[" + FileReader().filename + ":" + str(self.linenumber) +
                   "] Cannot start '" + args[0] + "': File not found")
-            tesh_exit(3)
+            return_code = max(3, return_code)
+            return
         except OSError as osE:
             if osE.errno == 8:
                 osE.strerror += "\nOSError: [Errno 8] Executed scripts should start with shebang line (like #!/usr/bin/env sh)"
@@ -384,7 +389,8 @@ class Cmd(object):
             except subprocess.TimeoutExpired:
                 print("[{file}:{number}] Could not retrieve output. Killing the process group failed?".format(
                     file=FileReader().filename, number=self.linenumber))
-                tesh_exit(3)
+                return_code = max(3, return_code)
+                return
 
         if self.output_display:
             print(stdout_data)
@@ -449,10 +455,12 @@ class Cmd(object):
                         f.write("> " + line + "\n")
                     f.close()
                     print("Obtained output kept as requested: " + os.path.abspath("obtained"))
-                tesh_exit(2)
+                return_code = max(2, return_code)
+                return
 
         if timeout_reached:
-            tesh_exit(3)
+            return_code = max(3, return_code)
+            return
 
         #print ((proc.returncode, self.expect_return))
 
@@ -462,13 +470,15 @@ class Cmd(object):
                       cmdName + "> returned code " + str(proc.returncode) + ")")
                 if lock is not None:
                     lock.release()
-                tesh_exit(2)
+                return_code = max(2, return_code)
+                return
             else:
                 print("Test suite `" + FileReader().filename + "': NOK (<" + cmdName +
                       "> got signal " + SIGNALS_TO_NAMES_DICT[-proc.returncode] + ")")
                 if lock is not None:
                     lock.release()
-                tesh_exit(-proc.returncode)
+                return_code = max(max(-proc.returncode, 1), return_code)
+                return
 
         if lock is not None:
             lock.release()
@@ -647,7 +657,10 @@ if __name__ == '__main__':
 
     TeshState().join_all_threads()
 
-    if f.filename == "(stdin)":
-        print("Test suite from stdin OK")
+    if return_code == 0:
+        if f.filename == "(stdin)":
+            print("Test suite from stdin OK")
+        else:
+            print("Test suite `" + f.filename + "' OK")
     else:
-        print("Test suite `" + f.filename + "' OK")
+        tesh_exit(return_code)