]>
Commit | Line | Data |
---|---|---|
32d0add0 | 1 | # Copyright (C) 2013-2015 Free Software Foundation, Inc. |
f27a1236 YQ |
2 | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 3 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
15 | ||
16 | import time | |
17 | import os | |
18 | import gc | |
19 | ||
20 | class Measure(object): | |
21 | """A class that measure and collect the interesting data for a given testcase. | |
22 | ||
23 | An instance of Measure has a collection of measurements, and each | |
24 | of them is to measure a given aspect, such as time and memory. | |
25 | """ | |
26 | ||
27 | def __init__(self, measurements): | |
28 | """Constructor of measure. | |
29 | ||
30 | measurements is a collection of Measurement objects. | |
31 | """ | |
32 | ||
33 | self.measurements = measurements | |
34 | ||
35 | def measure(self, func, id): | |
36 | """Measure the operations done by func with a collection of measurements.""" | |
37 | # Enable GC, force GC and disable GC before running test in order to reduce | |
38 | # the interference from GC. | |
39 | gc.enable() | |
40 | gc.collect() | |
41 | gc.disable() | |
42 | ||
43 | for m in self.measurements: | |
44 | m.start(id) | |
45 | ||
46 | func() | |
47 | ||
48 | for m in self.measurements: | |
49 | m.stop(id) | |
50 | ||
51 | gc.enable() | |
52 | ||
53 | def report(self, reporter, name): | |
54 | """Report the measured results.""" | |
55 | for m in self.measurements: | |
56 | m.report(reporter, name) | |
57 | ||
58 | class Measurement(object): | |
59 | """A measurement for a certain aspect.""" | |
60 | ||
61 | def __init__(self, name, result): | |
62 | """Constructor of Measurement. | |
63 | ||
64 | Attribute result is the TestResult associated with measurement. | |
65 | """ | |
66 | self.name = name; | |
67 | self.result = result | |
68 | ||
69 | def start(self, id): | |
70 | """Abstract method to start the measurement.""" | |
71 | raise NotImplementedError("Abstract Method:start") | |
72 | ||
73 | def stop(self, id): | |
74 | """Abstract method to stop the measurement. | |
75 | ||
76 | When the measurement is stopped, we've got something, and | |
77 | record them in result. | |
78 | """ | |
79 | raise NotImplementedError("Abstract Method:stop.") | |
80 | ||
81 | def report(self, reporter, name): | |
82 | """Report the measured data by argument reporter.""" | |
83 | self.result.report(reporter, name + " " + self.name) | |
84 | ||
85 | class MeasurementCpuTime(Measurement): | |
86 | """Measurement on CPU time.""" | |
87 | # On UNIX, time.clock() measures the amount of CPU time that has | |
88 | # been used by the current process. On Windows it will measure | |
89 | # wall-clock seconds elapsed since the first call to the function. | |
90 | # Something other than time.clock() should be used to measure CPU | |
91 | # time on Windows. | |
92 | ||
93 | def __init__(self, result): | |
94 | super(MeasurementCpuTime, self).__init__("cpu_time", result) | |
95 | self.start_time = 0 | |
96 | ||
97 | def start(self, id): | |
98 | self.start_time = time.clock() | |
99 | ||
100 | def stop(self, id): | |
101 | if os.name == 'nt': | |
102 | cpu_time = 0 | |
103 | else: | |
104 | cpu_time = time.clock() - self.start_time | |
105 | self.result.record (id, cpu_time) | |
106 | ||
107 | class MeasurementWallTime(Measurement): | |
108 | """Measurement on Wall time.""" | |
109 | ||
110 | def __init__(self, result): | |
111 | super(MeasurementWallTime, self).__init__("wall_time", result) | |
112 | self.start_time = 0 | |
113 | ||
114 | def start(self, id): | |
115 | self.start_time = time.time() | |
116 | ||
117 | def stop(self, id): | |
118 | wall_time = time.time() - self.start_time | |
119 | self.result.record (id, wall_time) | |
120 | ||
121 | class MeasurementVmSize(Measurement): | |
122 | """Measurement on memory usage represented by VmSize.""" | |
123 | ||
124 | def __init__(self, result): | |
125 | super(MeasurementVmSize, self).__init__("vmsize", result) | |
126 | ||
127 | def _compute_process_memory_usage(self, key): | |
128 | file_path = "/proc/%d/status" % os.getpid() | |
129 | try: | |
130 | t = open(file_path) | |
131 | v = t.read() | |
132 | t.close() | |
133 | except: | |
134 | return 0 | |
135 | i = v.index(key) | |
136 | v = v[i:].split(None, 3) | |
137 | if len(v) < 3: | |
138 | return 0 | |
139 | return int(v[1]) | |
140 | ||
141 | def start(self, id): | |
142 | pass | |
143 | ||
144 | def stop(self, id): | |
145 | memory_used = self._compute_process_memory_usage("VmSize:") | |
146 | self.result.record (id, memory_used) |