|
@@ -114,6 +114,10 @@ class RunningProcess:
|
|
|
self._create_filenames()
|
|
|
self._start_process(args)
|
|
|
|
|
|
+ # used in _wait_for_output_str, map from (filename, (strings))
|
|
|
+ # to a file offset.
|
|
|
+ self.__file_offsets = {}
|
|
|
+
|
|
|
def _start_process(self, args):
|
|
|
"""
|
|
|
Start the process.
|
|
@@ -194,11 +198,29 @@ class RunningProcess:
|
|
|
os.remove(self.stderr_filename)
|
|
|
os.remove(self.stdout_filename)
|
|
|
|
|
|
- def _wait_for_output_str(self, filename, running_file, strings, only_new, matches = 1):
|
|
|
- """
|
|
|
- Wait for a line of output in this process. This will (if only_new is
|
|
|
- False) first check all previous output from the process, and if not
|
|
|
- found, check all output since the last time this method was called.
|
|
|
+ def _wait_for_output_str(self, filename, running_file, strings, only_new,
|
|
|
+ matches=1):
|
|
|
+ """
|
|
|
+ Wait for a line of output in this process. This will (if
|
|
|
+ only_new is False) check all output from the process including
|
|
|
+ that may have been checked before. If only_new is True, it
|
|
|
+ only checks output that has not been covered in previous calls
|
|
|
+ to this method for the file (if there was no such previous call to
|
|
|
+ this method, it works same as the case of only_new=False).
|
|
|
+
|
|
|
+ Care should be taken if only_new is to be set to True, as it may cause
|
|
|
+ counter-intuitive results. For example, assume the file is expected
|
|
|
+ to contain a line that has XXX and another line has YYY, but the
|
|
|
+ ordering is not predictable. If this method is called with XXX as
|
|
|
+ the search string, but the line containing YYY appears before the
|
|
|
+ target line, this method remembers the point in the file beyond
|
|
|
+ the line that has XXX. If a next call to this method specifies
|
|
|
+ YYY as the search string with only_new being True, the search will
|
|
|
+ fail. If the same string is expected to appear multiple times
|
|
|
+ and you want to catch the latest one, a more reliable way is to
|
|
|
+ specify the match number and set only_new to False, if the number
|
|
|
+ of matches is predictable.
|
|
|
+
|
|
|
For each line in the output, the given strings array is checked. If
|
|
|
any output lines checked contains one of the strings in the strings
|
|
|
array, that string (not the line!) is returned.
|
|
@@ -206,33 +228,34 @@ class RunningProcess:
|
|
|
filename: The filename to read previous output from, if applicable.
|
|
|
running_file: The open file to read new output from.
|
|
|
strings: Array of strings to look for.
|
|
|
- only_new: If true, only check output since last time this method was
|
|
|
- called. If false, first check earlier output.
|
|
|
+ only_new: See above.
|
|
|
matches: Check for the string this many times.
|
|
|
Returns a tuple containing the matched string, and the complete line
|
|
|
it was found in.
|
|
|
Fails if none of the strings was read after 10 seconds
|
|
|
(OUTPUT_WAIT_INTERVAL * OUTPUT_WAIT_MAX_INTERVALS).
|
|
|
"""
|
|
|
+ # Identify the start offset of search. if only_new=True, start from
|
|
|
+ # the farthest point we've reached in the file; otherwise start from
|
|
|
+ # the beginning.
|
|
|
+ if not filename in self.__file_offsets:
|
|
|
+ self.__file_offsets[filename] = 0
|
|
|
+ offset = self.__file_offsets[filename] if only_new else 0
|
|
|
+ running_file.seek(offset)
|
|
|
+
|
|
|
match_count = 0
|
|
|
- if not only_new:
|
|
|
- full_file = open(filename, "r")
|
|
|
- for line in full_file:
|
|
|
- for string in strings:
|
|
|
- if line.find(string) != -1:
|
|
|
- match_count += 1
|
|
|
- if match_count >= matches:
|
|
|
- full_file.close()
|
|
|
- return (string, line)
|
|
|
wait_count = 0
|
|
|
while wait_count < OUTPUT_WAIT_MAX_INTERVALS:
|
|
|
- where = running_file.tell()
|
|
|
line = running_file.readline()
|
|
|
+ where = running_file.tell()
|
|
|
if line:
|
|
|
for string in strings:
|
|
|
if line.find(string) != -1:
|
|
|
match_count += 1
|
|
|
if match_count >= matches:
|
|
|
+ # If we've gone further, update the recorded offset
|
|
|
+ if where > self.__file_offsets[filename]:
|
|
|
+ self.__file_offsets[filename] = where
|
|
|
return (string, line)
|
|
|
else:
|
|
|
wait_count += 1
|
|
@@ -245,8 +268,7 @@ class RunningProcess:
|
|
|
Wait for one of the given strings in this process's stderr output.
|
|
|
Parameters:
|
|
|
strings: Array of strings to look for.
|
|
|
- only_new: If true, only check output since last time this method was
|
|
|
- called. If false, first check earlier output.
|
|
|
+ only_new: See _wait_for_output_str.
|
|
|
matches: Check for the string this many times.
|
|
|
Returns a tuple containing the matched string, and the complete line
|
|
|
it was found in.
|
|
@@ -261,8 +283,7 @@ class RunningProcess:
|
|
|
Wait for one of the given strings in this process's stdout output.
|
|
|
Parameters:
|
|
|
strings: Array of strings to look for.
|
|
|
- only_new: If true, only check output since last time this method was
|
|
|
- called. If false, first check earlier output.
|
|
|
+ only_new: See _wait_for_output_str.
|
|
|
matches: Check for the string this many times.
|
|
|
Returns a tuple containing the matched string, and the complete line
|
|
|
it was found in.
|
|
@@ -342,8 +363,7 @@ class RunningProcesses:
|
|
|
Parameters:
|
|
|
process_name: The name of the process to check the stderr output of.
|
|
|
strings: Array of strings to look for.
|
|
|
- only_new: If true, only check output since last time this method was
|
|
|
- called. If false, first check earlier output.
|
|
|
+ only_new: See _wait_for_output_str.
|
|
|
matches: Check for the string this many times.
|
|
|
Returns the matched string.
|
|
|
Fails if none of the strings was read after 10 seconds
|
|
@@ -362,8 +382,7 @@ class RunningProcesses:
|
|
|
Parameters:
|
|
|
process_name: The name of the process to check the stdout output of.
|
|
|
strings: Array of strings to look for.
|
|
|
- only_new: If true, only check output since last time this method was
|
|
|
- called. If false, first check earlier output.
|
|
|
+ only_new: See _wait_for_output_str.
|
|
|
matches: Check for the string this many times.
|
|
|
Returns the matched string.
|
|
|
Fails if none of the strings was read after 10 seconds
|