From 217b112060448b3dc28dc062ffe45ddcd64bbcbf Mon Sep 17 00:00:00 2001 From: JingLu5 Date: Thu, 7 Jul 2016 17:01:33 +0800 Subject: Enhence CPUload scenario Enhence CPUload to measure maximum, minimum and average CPU usage. Change-Id: I22d5e56a120ef6bb6ab93094bb053d9999173b32 Signed-off-by: JingLu5 --- samples/cpuload.yaml | 3 +- .../scenarios/compute/cpuload_sample_output1.txt | 12 +- .../benchmark/scenarios/compute/test_cpuload.py | 161 ++++++++++++--------- yardstick/benchmark/scenarios/compute/cpuload.py | 71 +++++++-- 4 files changed, 160 insertions(+), 87 deletions(-) diff --git a/samples/cpuload.yaml b/samples/cpuload.yaml index 7ca528278..21d068205 100644 --- a/samples/cpuload.yaml +++ b/samples/cpuload.yaml @@ -10,7 +10,8 @@ scenarios: - type: CPUload options: - interval: 2 + interval: 1 + count: 1 host: apollo.demo runner: type: Duration diff --git a/tests/unit/benchmark/scenarios/compute/cpuload_sample_output1.txt b/tests/unit/benchmark/scenarios/compute/cpuload_sample_output1.txt index b1723ae17..723e64bcb 100644 --- a/tests/unit/benchmark/scenarios/compute/cpuload_sample_output1.txt +++ b/tests/unit/benchmark/scenarios/compute/cpuload_sample_output1.txt @@ -1,5 +1,9 @@ -Linux 3.13.0-68-generic (elxg482ls42) 11/30/2015 _x86_64_ (12 CPU) +Linux 3.13.0-68-generic (elxg482ls42) 11/30/2015 _x86_64_ (1 CPU) -04:53:04 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle -04:53:04 PM all 11.31 0.03 1.19 0.18 0.00 0.01 0.00 5.51 0.00 81.77 -04:53:04 PM 0 20.03 0.03 1.36 0.33 0.00 0.06 0.00 6.62 0.00 71.56 +04:34:26 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle +04:34:26 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 +04:34:26 PM 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 + +Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle +Average: all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 +Average: 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 diff --git a/tests/unit/benchmark/scenarios/compute/test_cpuload.py b/tests/unit/benchmark/scenarios/compute/test_cpuload.py index 22c4419b2..77f2a02d8 100644 --- a/tests/unit/benchmark/scenarios/compute/test_cpuload.py +++ b/tests/unit/benchmark/scenarios/compute/test_cpuload.py @@ -33,7 +33,14 @@ class CPULoadTestCase(unittest.TestCase): self.result = {} def test_setup_mpstat_installed(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + options = { + "interval": 1, + "count": 1 + } + + args = {'options': options} + + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (0, '', '') l.setup() @@ -42,7 +49,14 @@ class CPULoadTestCase(unittest.TestCase): self.assertTrue(l.has_mpstat) def test_setup_mpstat_not_installed(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + options = { + "interval": 1, + "count": 1 + } + + args = {'options': options} + + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (127, '', '') l.setup() @@ -51,7 +65,14 @@ class CPULoadTestCase(unittest.TestCase): self.assertFalse(l.has_mpstat) def test_execute_command_success(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + options = { + "interval": 1, + "count": 1 + } + + args = {'options': options} + + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (0, '', '') l.setup() @@ -61,7 +82,14 @@ class CPULoadTestCase(unittest.TestCase): self.assertEqual(result, expected_result) def test_execute_command_failed(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + options = { + "interval": 1, + "count": 1 + } + + args = {'options': options} + + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (0, '', '') l.setup() @@ -70,7 +98,14 @@ class CPULoadTestCase(unittest.TestCase): "cat /proc/loadavg") def test_get_loadavg(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + options = { + "interval": 1, + "count": 1 + } + + args = {'options': options} + + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (0, '', '') l.setup() @@ -82,44 +117,63 @@ class CPULoadTestCase(unittest.TestCase): self.assertEqual(result, expected_result) def test_get_cpu_usage_mpstat(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + options = { + "interval": 1, + "count": 1 + } + + args = {'options': options} + + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (0, '', '') l.setup() - l.interval = 0 + l.interval = 1 + l.count = 1 mpstat_output = self._read_file("cpuload_sample_output1.txt") mock_ssh.SSH().execute.return_value = (0, mpstat_output, '') result = l._get_cpu_usage_mpstat() expected_result = \ - {'mpstat': - {'cpu': - {'%gnice': '0.00', - '%guest': '5.51', - '%idle': '81.77', - '%iowait': '0.18', - '%irq': '0.00', - '%nice': '0.03', - '%soft': '0.01', - '%steal': '0.00', - '%sys': '1.19', - '%usr': '11.31'}, - 'cpu0': - {'%gnice': '0.00', - '%guest': '6.62', - '%idle': '71.56', - '%iowait': '0.33', - '%irq': '0.00', - '%nice': '0.03', - '%soft': '0.06', - '%steal': '0.00', - '%sys': '1.36', - '%usr': '20.03'}}} + {"mpstat_minimum": + {"cpu": {"%steal": "0.00", "%usr": "0.00", "%gnice": "0.00", + "%idle": "100.00", "%guest": "0.00", + "%iowait": "0.00", "%sys": "0.00", "%soft": "0.00", + "%irq": "0.00", "%nice": "0.00"}, + "cpu0": {"%steal": "0.00", "%usr": "0.00", "%gnice": "0.00", + "%idle": "100.00", "%guest": "0.00", + "%iowait": "0.00", "%sys": "0.00", "%soft": "0.00", + "%irq": "0.00", "%nice": "0.00"}}, + "mpstat_average": + {"cpu": {"%steal": "0.00", "%usr": "0.00", "%gnice": "0.00", + "%idle": "100.00", "%guest": "0.00", + "%iowait": "0.00", "%sys": "0.00", "%soft": "0.00", + "%irq": "0.00", "%nice": "0.00"}, + "cpu0": {"%steal": "0.00", "%usr": "0.00", "%gnice": "0.00", + "%idle": "100.00", "%guest": "0.00", + "%iowait": "0.00", "%sys": "0.00", "%soft": "0.00", + "%irq": "0.00", "%nice": "0.00"}}, + "mpstat_maximun": + {"cpu": {"%steal": "0.00", "%usr": "0.00", "%gnice": "0.00", + "%idle": "100.00", "%guest": "0.00", + "%iowait": "0.00", "%sys": "0.00", "%soft": "0.00", + "%irq": "0.00", "%nice": "0.00"}, + "cpu0": {"%steal": "0.00", "%usr": "0.00", "%gnice": "0.00", + "%idle": "100.00", "%guest": "0.00", + "%iowait": "0.00", "%sys": "0.00", "%soft": "0.00", + "%irq": "0.00", "%nice": "0.00"}}} self.assertDictEqual(result, expected_result) def test_get_cpu_usage(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + options = { + "interval": 0, + "count": 1 + } + + args = {'options': options} + + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (0, '', '') l.setup() @@ -154,45 +208,16 @@ class CPULoadTestCase(unittest.TestCase): '%nice': '0.03'}}} self.assertDictEqual(result, expected_result) + + def test_run_proc_stat(self, mock_ssh): + options = { + "interval": 1, + "count": 1 + } - def test_run_mpstat(self, mock_ssh): - l = cpuload.CPULoad({'options': {'interval': 1}}, self.ctx) - mock_ssh.SSH().execute.return_value = (0, '', '') - - mpstat_output = self._read_file("cpuload_sample_output1.txt") - mock_ssh.SSH().execute.side_effect = \ - [(0, '', ''), (0, '1.50 1.45 1.51 3/813 14322', ''), (0, mpstat_output, '')] - - l.run(self.result) - - expected_result = { - 'loadavg': ['1.50', '1.45', '1.51', '3/813', '14322'], - 'mpstat': - {'cpu': {'%gnice': '0.00', - '%guest': '5.51', - '%idle': '81.77', - '%iowait': '0.18', - '%irq': '0.00', - '%nice': '0.03', - '%soft': '0.01', - '%steal': '0.00', - '%sys': '1.19', - '%usr': '11.31'}, - 'cpu0': {'%gnice': '0.00', - '%guest': '6.62', - '%idle': '71.56', - '%iowait': '0.33', - '%irq': '0.00', - '%nice': '0.03', - '%soft': '0.06', - '%steal': '0.00', - '%sys': '1.36', - '%usr': '20.03'}}} - - self.assertDictEqual(self.result, expected_result) + args = {'options': options} - def test_run_proc_stat(self, mock_ssh): - l = cpuload.CPULoad({}, self.ctx) + l = cpuload.CPULoad(args, self.ctx) mock_ssh.SSH().execute.return_value = (1, '', '') l.setup() diff --git a/yardstick/benchmark/scenarios/compute/cpuload.py b/yardstick/benchmark/scenarios/compute/cpuload.py index d11bec5c3..f45313e91 100644 --- a/yardstick/benchmark/scenarios/compute/cpuload.py +++ b/yardstick/benchmark/scenarios/compute/cpuload.py @@ -36,13 +36,17 @@ class CPULoad(base.Scenario): on the Linux host. Parameters - interval - Time interval to measure CPU usage. A value of 0 - indicates that processors statistics are to be - reported for the time since system startup (boot) + interval - Time interval to measure CPU usage. type: [int] unit: seconds - default: 0 + default: 1 + + count (for mpstat only) - Number of CPU usage measurment. + + type: [int] + unit: N/A + default: 1 """ @@ -56,6 +60,7 @@ class CPULoad(base.Scenario): self.context_cfg = context_cfg self.setup_done = False self.has_mpstat = False + self.has_count = False def setup(self): """Scenario setup.""" @@ -77,10 +82,13 @@ class CPULoad(base.Scenario): LOG.info("MPSTAT is installed") self.has_mpstat = True - if 'options' in self.scenario_cfg: - self.interval = self.scenario_cfg['options'].get("interval", 0) + options = self.scenario_cfg['options'] + self.interval = options.get("interval", 1) + if 'count' in options: + self.count = options.get("count", 1) + self.has_count = True else: - self.interval = 0 + self.has_count = False self.setup_done = True @@ -99,15 +107,17 @@ class CPULoad(base.Scenario): def _get_cpu_usage_mpstat(self): """Get processor usage using mpstat.""" - if self.interval > 0: - cmd = "mpstat -P ON %s 1" % self.interval + if self.interval > 0 and self.has_count: + cmd = "mpstat -P ON %s %s" % (self.interval, self.count) else: - cmd = "mpstat -P ON" + cmd = "mpstat -P ON %s 1" % self.interval result = self._execute_command(cmd) fields = [] - mpstat = {} + maximum = {} + minimum = {} + average = {} time_marker = re.compile("^([0-9]+):([0-9]+):([0-9]+)$") ampm_marker = re.compile("(AM|PM)$") @@ -117,7 +127,6 @@ class CPULoad(base.Scenario): line = row.split() if line and re.match(time_marker, line[0]): - if re.match(ampm_marker, line[1]): del line[:2] else: @@ -134,11 +143,45 @@ class CPULoad(base.Scenario): cpu = 'cpu' if line[0] == 'all' else 'cpu' + line[0] values = line[1:] if values and len(values) == len(fields): - mpstat[cpu] = dict(zip(fields, values)) + temp_dict = dict(zip(fields, values)) + if cpu not in maximum: + maximum[cpu] = temp_dict + else: + for item in temp_dict: + if float(maximum[cpu][item]) <\ + float(temp_dict[item]): + maximum[cpu][item] = temp_dict[item] + + if cpu not in minimum: + minimum[cpu] = temp_dict + else: + for item in temp_dict: + if float(minimum[cpu][item]) >\ + float(temp_dict[item]): + minimum[cpu][item] = temp_dict[item] else: raise RuntimeError("mpstat: parse error", fields, line) - return {'mpstat': mpstat} + elif line and line[0] == 'Average:': + del line[:1] + if line[0] == 'CPU': + # header fields + fields = line[1:] + if len(fields) != CPULoad.MPSTAT_FIELD_SIZE: + raise RuntimeError("mpstat average: unexpected field\ + size", fields) + else: + # value fields + cpu = 'cpu' if line[0] == 'all' else 'cpu' + line[0] + values = line[1:] + if values and len(values) == len(fields): + average[cpu] = dict(zip(fields, values)) + else: + raise RuntimeError("mpstat average: parse error", + fields, line) + + return {'mpstat_maximun': maximum, 'mpstat_minimum': minimum, + 'mpstat_average': average} def _get_cpu_usage(self): """Get processor usage from /proc/stat.""" -- cgit 1.2.3-korg