summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/buildperf
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/buildperf')
-rw-r--r--meta/lib/oeqa/buildperf/base.py64
1 files changed, 62 insertions, 2 deletions
diff --git a/meta/lib/oeqa/buildperf/base.py b/meta/lib/oeqa/buildperf/base.py
index 3ef038494f..d608061ec0 100644
--- a/meta/lib/oeqa/buildperf/base.py
+++ b/meta/lib/oeqa/buildperf/base.py
@@ -10,11 +10,14 @@
10# more details. 10# more details.
11# 11#
12"""Build performance test base classes and functionality""" 12"""Build performance test base classes and functionality"""
13import glob
13import logging 14import logging
14import os 15import os
16import re
15import shutil 17import shutil
18import tempfile
16import time 19import time
17from datetime import datetime 20from datetime import datetime, timedelta
18 21
19from oeqa.utils.commands import runCmd, get_bb_vars 22from oeqa.utils.commands import runCmd, get_bb_vars
20 23
@@ -55,8 +58,24 @@ class KernelDropCaches(object):
55 runCmd(cmd, data=input_data) 58 runCmd(cmd, data=input_data)
56 59
57 60
61def time_cmd(cmd, **kwargs):
62 """TIme a command"""
63 with tempfile.NamedTemporaryFile(mode='w+') as tmpf:
64 timecmd = ['/usr/bin/time', '-v', '-o', tmpf.name]
65 if isinstance(cmd, str):
66 timecmd = ' '.join(timecmd) + ' '
67 timecmd += cmd
68 # TODO: 'ignore_status' could/should be removed when globalres.log is
69 # deprecated. The function would just raise an exception, instead
70 ret = runCmd(timecmd, ignore_status=True, **kwargs)
71 timedata = tmpf.file.read()
72 return ret, timedata
73
74
58class BuildPerfTest(object): 75class BuildPerfTest(object):
59 """Base class for build performance tests""" 76 """Base class for build performance tests"""
77 SYSRES = 'sysres'
78
60 name = None 79 name = None
61 description = None 80 description = None
62 81
@@ -73,6 +92,10 @@ class BuildPerfTest(object):
73 if not self.name: 92 if not self.name:
74 self.name = self.__class__.__name__ 93 self.name = self.__class__.__name__
75 self.bb_vars = get_bb_vars() 94 self.bb_vars = get_bb_vars()
95 # TODO: remove the _failed flag when globalres.log is ditched as all
96 # failures should raise an exception
97 self._failed = False
98 self.cmd_log = os.path.join(self.out_dir, 'commands.log')
76 99
77 def run(self): 100 def run(self):
78 """Run test""" 101 """Run test"""
@@ -82,12 +105,49 @@ class BuildPerfTest(object):
82 self.results['elapsed_time'] = (datetime.now() - 105 self.results['elapsed_time'] = (datetime.now() -
83 self.results['start_time']) 106 self.results['start_time'])
84 # Test is regarded as completed if it doesn't raise an exception 107 # Test is regarded as completed if it doesn't raise an exception
85 self.results['status'] = 'COMPLETED' 108 if not self._failed:
109 self.results['status'] = 'COMPLETED'
86 110
87 def _run(self): 111 def _run(self):
88 """Actual test payload""" 112 """Actual test payload"""
89 raise NotImplementedError 113 raise NotImplementedError
90 114
115 def measure_cmd_resources(self, cmd, name, legend):
116 """Measure system resource usage of a command"""
117 def str_time_to_timedelta(strtime):
118 """Convert time strig from the time utility to timedelta"""
119 split = strtime.split(':')
120 hours = int(split[0]) if len(split) > 2 else 0
121 mins = int(split[-2])
122 secs, frac = split[-1].split('.')
123 secs = int(secs)
124 microsecs = int(float('0.' + frac) * pow(10, 6))
125 return timedelta(0, hours*3600 + mins*60 + secs, microsecs)
126
127 cmd_str = cmd if isinstance(cmd, str) else ' '.join(cmd)
128 log.info("Timing command: %s", cmd_str)
129 with open(self.cmd_log, 'a') as fobj:
130 ret, timedata = time_cmd(cmd, stdout=fobj)
131 if ret.status:
132 log.error("Time will be reported as 0. Command failed: %s",
133 ret.status)
134 etime = timedelta(0)
135 self._failed = True
136 else:
137 match = re.search(r'.*wall clock.*: (?P<etime>.*)\n', timedata)
138 etime = str_time_to_timedelta(match.group('etime'))
139
140 measurement = {'type': self.SYSRES,
141 'name': name,
142 'legend': legend}
143 measurement['values'] = {'elapsed_time': etime}
144 self.results['measurements'].append(measurement)
145 nlogs = len(glob.glob(self.out_dir + '/results.log*'))
146 results_log = os.path.join(self.out_dir,
147 'results.log.{}'.format(nlogs + 1))
148 with open(results_log, 'w') as fobj:
149 fobj.write(timedata)
150
91 @staticmethod 151 @staticmethod
92 def force_rm(path): 152 def force_rm(path):
93 """Equivalent of 'rm -rf'""" 153 """Equivalent of 'rm -rf'"""