Salome HOME
spns #26801 : bug sat package, le lanceur ne faisait pas le réinit
[tools/sat.git] / src / fork.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2013  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20 import sys
21 import time
22 import pickle
23 import subprocess
24
25 # OP
26 import src
27
28 def show_progress(logger, top, delai, ss=""):
29     """shortcut function to display the progression
30     
31     :param logger Logger: The logging instance
32     :param top int: the number to display
33     :param delai int: the number max
34     :param ss str: the string to display
35     """
36     logger.write("\r%s\r%s timeout %s / %s stay %s s    " % ((" " * 30), ss, top, delai, (delai - top)), 4, False)
37     logger.flush()
38
39 def write_back(logger, message, level):
40     """shortcut function to write at the begin of the line
41     
42     :param logger Logger: The logging instance
43     :param message str: the text to display
44     :param level int: the level of verbosity
45     """
46     logger.write("\r%s\r%s" % ((" " * 40), message), level)
47
48 # Launch command
49 # --------------
50 def launch_command(cmd, logger, cwd, args=[], log=None):
51     if log:
52         log = open(log, "a")  # python2 file(log, "a")
53     for arg in args:
54         cmd += " " + arg
55
56     logger.write("launch_command:\n  %s\n" % cmd, 5, screenOnly=True)
57
58     # Add Windows case
59     if src.architecture.is_windows():
60         prs = subprocess.Popen(cmd,
61                            shell=True,
62                            stdout=log,
63                            stderr=subprocess.STDOUT,
64                            cwd=cwd)
65
66     else:
67         prs = subprocess.Popen(cmd,
68                            shell=True,
69                            stdout=log,
70                            stderr=subprocess.STDOUT,
71                            cwd=cwd,
72                            executable='/bin/bash')
73
74     return prs
75
76 # Launch a batch
77 # --------------
78 def batch(cmd, logger, cwd, args=[], log=None, delai=20, sommeil=1):
79     proc = launch_command(cmd, logger, cwd, args, log)
80     top = 0
81     sys.stdout.softspace = True
82     begin = time.time()
83     while proc.poll() is None:
84         if time.time() - begin >= 1:
85             show_progress(logger, top, delai, "batch:")
86             if top == delai:
87                 logger.write("batch: time out KILL\n", 3)
88                 import signal
89                 os.kill(proc.pid, signal.SIGTERM)
90                 break
91             else:
92                 begin = time.time()
93                 time.sleep(sommeil)
94                 top += 1
95         sys.stdout.flush()
96     else:
97         write_back(logger, "batch: exit (%s)\n" % str(proc.returncode), 5)
98     return (proc.returncode == 0), top
99
100
101 # Launch a salome process
102 # -----------------------
103 def batch_salome(cmd, logger, cwd, args, getTmpDir,
104                  pendant="SALOME_Session_Server", fin="killSalome.py",
105                  log=None, delai=20, sommeil=1, delaiapp=0):
106
107     beginTime = time.time()
108     launch_command(cmd, logger, cwd, args, log)
109
110     if delaiapp == 0:
111         delaiapp = delai
112
113     # first launch salome (looking for _pidict file)
114     top = 0
115     found = False
116     foundSalome = "batch salome not seen"
117     tmp_dir = getTmpDir()
118     # print("batch_salome %s %s / %s sommeil %s:\n%s" % (tmp_dir, delai, delaiapp, sommeil, cmd))
119     while (not found and top < delaiapp):
120         if os.path.exists(tmp_dir):
121             listFile = os.listdir(tmp_dir)
122             listFile = [f for f in listFile if f.endswith("_pidict")]
123             # print("listFile %s" % listFile)
124         else:
125             listFile = []
126
127         for file_name in listFile:
128             # sometime we get a old file that will be removed by runSalome.
129             # So we test that we can read it.
130             currentTime = None
131             try:
132                 statinfo = os.stat(os.path.join(tmp_dir, file_name))
133                 currentTime = statinfo.st_mtime
134             except:
135                 pass
136
137             if currentTime and currentTime > beginTime:
138                 found = True
139                 pidictFile = file_name
140
141                 """
142                 # CVW avoid unsupported pickle protocol: 3 because pidict from python3 KERNEL/bin/salome/addToKillList.py
143                 try:
144                     with open(os.path.join(tmp_dir, file_name), "r") as file_:
145                         process_ids = pickle.load(file_)
146                     # print("pidict %s" % process_ids)
147                     for process_id in process_ids:
148                         for __, cmd in process_id.items():
149                             if cmd == [pendant]:
150                                 foundSalome = "batch salome started"
151                                 pidictFile = file_name
152                 except Exception as e:
153                     foundSalome = "python version %s problem reading file: %s" % (sys.version, e)
154                     pass
155                 """
156
157         time.sleep(sommeil)
158         top += 1
159         show_progress(logger, top, delaiapp, "launching salome or appli found=%s:" % found)
160
161     # continue or not
162     if found:
163         logger.write("\nbatch_salome: supposed started\n", 5)
164     else:
165         logger.write("\nbatch_salome: seems FAILED to launch salome or appli : %s\n" % foundSalome, 3)
166         return False, -1
167
168     # salome launched run the script
169     top = 0
170     code = None
171     while code is None:
172         show_progress(logger, top, delai, "running salome or appli:")
173
174         if not os.access(os.path.join(tmp_dir, pidictFile), os.F_OK):
175             write_back(logger, "batch_salome: exit\n", 5)
176             code = True
177         elif top >= delai:
178             # timeout kill the test
179             os.system(fin)
180             logger.write("batch_salome: time out KILL\n", 3)
181             code = False
182         else:
183             # still waiting
184             time.sleep(sommeil)
185             top = top + 1
186
187     return code, top