annotate clang/utils/analyzer/SATestUtils.py @ 225:f7655407a6ba

remove unnecessary files
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 19 Jul 2021 03:48:36 +0900
parents 2e18cbf3894f
children 1f2b6ac9f198
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 import os
anatofuz
parents:
diff changeset
2 import sys
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
3 import time
150
anatofuz
parents:
diff changeset
4
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
5 from subprocess import CalledProcessError, check_call
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
6 from typing import List, IO, Optional, Tuple
150
anatofuz
parents:
diff changeset
7
anatofuz
parents:
diff changeset
8
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
9 def which(command: str, paths: Optional[str] = None) -> Optional[str]:
150
anatofuz
parents:
diff changeset
10 """which(command, [paths]) - Look up the given command in the paths string
anatofuz
parents:
diff changeset
11 (or the PATH environment variable, if unspecified)."""
anatofuz
parents:
diff changeset
12
anatofuz
parents:
diff changeset
13 if paths is None:
anatofuz
parents:
diff changeset
14 paths = os.environ.get('PATH', '')
anatofuz
parents:
diff changeset
15
anatofuz
parents:
diff changeset
16 # Check for absolute match first.
anatofuz
parents:
diff changeset
17 if os.path.exists(command):
anatofuz
parents:
diff changeset
18 return command
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 # Would be nice if Python had a lib function for this.
anatofuz
parents:
diff changeset
21 if not paths:
anatofuz
parents:
diff changeset
22 paths = os.defpath
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 # Get suffixes to search.
anatofuz
parents:
diff changeset
25 # On Cygwin, 'PATHEXT' may exist but it should not be used.
anatofuz
parents:
diff changeset
26 if os.pathsep == ';':
anatofuz
parents:
diff changeset
27 pathext = os.environ.get('PATHEXT', '').split(';')
anatofuz
parents:
diff changeset
28 else:
anatofuz
parents:
diff changeset
29 pathext = ['']
anatofuz
parents:
diff changeset
30
anatofuz
parents:
diff changeset
31 # Search the paths...
anatofuz
parents:
diff changeset
32 for path in paths.split(os.pathsep):
anatofuz
parents:
diff changeset
33 for ext in pathext:
anatofuz
parents:
diff changeset
34 p = os.path.join(path, command + ext)
anatofuz
parents:
diff changeset
35 if os.path.exists(p):
anatofuz
parents:
diff changeset
36 return p
anatofuz
parents:
diff changeset
37
anatofuz
parents:
diff changeset
38 return None
anatofuz
parents:
diff changeset
39
anatofuz
parents:
diff changeset
40
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
41 def has_no_extension(file_name: str) -> bool:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
42 root, ext = os.path.splitext(file_name)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
43 return ext == ""
150
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
46 def is_valid_single_input_file(file_name: str) -> bool:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
47 root, ext = os.path.splitext(file_name)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
48 return ext in (".i", ".ii", ".c", ".cpp", ".m", "")
150
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
51 def time_to_str(time: float) -> str:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
52 """
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
53 Convert given time in seconds into a human-readable string.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
54 """
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
55 return f"{time:.2f}s"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
56
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
57
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
58 def memory_to_str(memory: int) -> str:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
59 """
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
60 Convert given number of bytes into a human-readable string.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
61 """
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
62 if memory:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
63 try:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
64 import humanize
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
65 return humanize.naturalsize(memory, gnu=True)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
66 except ImportError:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
67 # no formatter installed, let's keep it in bytes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
68 return f"{memory}B"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
69
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
70 # If memory is 0, we didn't succeed measuring it.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
71 return "N/A"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
72
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
73
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
74 def check_and_measure_call(*popenargs, **kwargs) -> Tuple[float, int]:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
75 """
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
76 Run command with arguments. Wait for command to complete and measure
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
77 execution time and peak memory consumption.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
78 If the exit code was zero then return, otherwise raise
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
79 CalledProcessError. The CalledProcessError object will have the
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
80 return code in the returncode attribute.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
81
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
82 The arguments are the same as for the call and check_call functions.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
83
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
84 Return a tuple of execution time and peak memory.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
85 """
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
86 peak_mem = 0
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
87 start_time = time.time()
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
88
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
89 try:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
90 import psutil as ps
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
91
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
92 def get_memory(process: ps.Process) -> int:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
93 mem = 0
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
94
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
95 # we want to gather memory usage from all of the child processes
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
96 descendants = list(process.children(recursive=True))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
97 descendants.append(process)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
98
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
99 for subprocess in descendants:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
100 try:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
101 mem += subprocess.memory_info().rss
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
102 except (ps.NoSuchProcess, ps.AccessDenied):
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
103 continue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
104
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
105 return mem
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
106
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
107 with ps.Popen(*popenargs, **kwargs) as process:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
108 # while the process is running calculate resource utilization.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
109 while (process.is_running() and
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
110 process.status() != ps.STATUS_ZOMBIE):
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
111 # track the peak utilization of the process
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
112 peak_mem = max(peak_mem, get_memory(process))
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
113 time.sleep(.5)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
114
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
115 if process.is_running():
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
116 process.kill()
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
117
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
118 if process.returncode != 0:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
119 cmd = kwargs.get("args")
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
120 if cmd is None:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
121 cmd = popenargs[0]
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
122 raise CalledProcessError(process.returncode, cmd)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
123
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
124 except ImportError:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
125 # back off to subprocess if we don't have psutil installed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
126 peak_mem = 0
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
127 check_call(*popenargs, **kwargs)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
128
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
129 return time.time() - start_time, peak_mem
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
130
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 173
diff changeset
131
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
132 def run_script(script_path: str, build_log_file: IO, cwd: str,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
133 out=sys.stdout, err=sys.stderr, verbose: int = 0):
150
anatofuz
parents:
diff changeset
134 """
anatofuz
parents:
diff changeset
135 Run the provided script if it exists.
anatofuz
parents:
diff changeset
136 """
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
137 if os.path.exists(script_path):
150
anatofuz
parents:
diff changeset
138 try:
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
139 if verbose == 1:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
140 out.write(f" Executing: {script_path}\n")
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
141
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
142 check_call(f"chmod +x '{script_path}'", cwd=cwd,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
143 stderr=build_log_file,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
144 stdout=build_log_file,
150
anatofuz
parents:
diff changeset
145 shell=True)
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
146
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
147 check_call(f"'{script_path}'", cwd=cwd,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
148 stderr=build_log_file,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
149 stdout=build_log_file,
150
anatofuz
parents:
diff changeset
150 shell=True)
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
151
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
152 except CalledProcessError:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
153 err.write(f"Error: Running {script_path} failed. "
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
154 f"See {build_log_file.name} for details.\n")
150
anatofuz
parents:
diff changeset
155 sys.exit(-1)
anatofuz
parents:
diff changeset
156
anatofuz
parents:
diff changeset
157
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
158 def is_comment_csv_line(entries: List[str]) -> bool:
150
anatofuz
parents:
diff changeset
159 """
anatofuz
parents:
diff changeset
160 Treat CSV lines starting with a '#' as a comment.
anatofuz
parents:
diff changeset
161 """
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
162 return len(entries) > 0 and entries[0].startswith("#")