Enhence CPUload scenario 27/16527/1
authorJingLu5 <lvjing5@huawei.com>
Thu, 7 Jul 2016 09:01:33 +0000 (17:01 +0800)
committerJingLu5 <lvjing5@huawei.com>
Thu, 7 Jul 2016 09:01:33 +0000 (17:01 +0800)
Enhence CPUload to measure maximum, minimum and average CPU usage.

Change-Id: I22d5e56a120ef6bb6ab93094bb053d9999173b32
Signed-off-by: JingLu5 <lvjing5@huawei.com>
samples/cpuload.yaml
tests/unit/benchmark/scenarios/compute/cpuload_sample_output1.txt
tests/unit/benchmark/scenarios/compute/test_cpuload.py
yardstick/benchmark/scenarios/compute/cpuload.py

index 7ca5282..21d0682 100644 (file)
@@ -10,7 +10,8 @@ scenarios:
 -
   type: CPUload
   options:
-    interval: 2
+    interval: 1
+    count: 1
   host: apollo.demo
   runner:
     type: Duration
index b1723ae..723e64b 100644 (file)
@@ -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
index 22c4419..77f2a02 100644 (file)
@@ -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()
 
index d11bec5..f45313e 100644 (file)
@@ -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."""