Roman Mohr has uploaded a new change for review.

Change subject: host stats: Collect stats from online cpu cores only
......................................................................

host stats: Collect stats from online cpu cores only

When a cpu goes offline while vdsm is running, the getVdsStats call still
tries to collect sampling data for this CPU and fails with an exception.

When vdsm is already running, it is enough to do something like

  echo 0 > /sys/devices/system/cpu/cpu2/online

to break getVdsStats.

Change-Id: Ia9c247f9138e02a9230a0849a04cb2e1705e7fac
Signed-off-by: Roman Mohr <rm...@redhat.com>
---
M tests/samplingTests.py
M tests/vmfakelib.py
M vdsm/virt/sampling.py
3 files changed, 47 insertions(+), 16 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/69/46269/4

diff --git a/tests/samplingTests.py b/tests/samplingTests.py
index 73e88b1..49b0410 100644
--- a/tests/samplingTests.py
+++ b/tests/samplingTests.py
@@ -313,34 +313,61 @@
             self.assertEqual(last.id,
                              FakeHostSample.counter - 1)
 
-    def testCpuCoreStats(self):
-        node_id, cpu_id = 0, 0
-        cpu_sample = {'user': 1.0, 'sys': 2.0}
-
-        first_sample = fake.HostSample(1.0, {cpu_id: cpu_sample})
-        last_sample = fake.HostSample(2.0, {cpu_id: cpu_sample})
-
+    def _monkeyPatchedFakeNumaTopology(self):
         def fakeNumaTopology():
             return {
-                node_id: {
-                    'cpus': [cpu_id]
+                0: {
+                    'cpus': [0]
+                },
+                1: {
+                    'cpus': [1]
                 }
             }
+        return MonkeyPatchScope([(caps, 'getNumaTopology',
+                                fakeNumaTopology)])
 
-        expected = {
-            '0': {
+    def _expectedResult(self, node_index=0):
+        return {
+            str(node_index): {
                 'cpuIdle': '100.00',
                 'cpuSys': '0.00',
                 'cpuUser': '0.00',
-                'nodeIndex': 0
+                'nodeIndex': node_index
             }
         }
 
-        with MonkeyPatchScope([(caps, 'getNumaTopology',
-                                fakeNumaTopology)]):
+    def testCpuCoreStats(self):
+        cpu_sample = {'user': 1.0, 'sys': 2.0}
+
+        first_sample = fake.HostSample(1.0, {0: cpu_sample, 1: cpu_sample})
+        last_sample = fake.HostSample(2.0, {0: cpu_sample, 1: cpu_sample})
+
+        with self._monkeyPatchedFakeNumaTopology():
+            result = sampling._get_cpu_core_stats(first_sample, last_sample)
+            self.assertEqual(result['0'], self._expectedResult()['0'])
+            self.assertEqual(result['1'], self._expectedResult(1)['1'])
+
+    def testSkipStatsOnMissingFirstSample(self):
+        cpu_sample = {'user': 1.0, 'sys': 2.0}
+
+        first_sample = fake.HostSample(1.0, {0: cpu_sample})
+        last_sample = fake.HostSample(2.0, {0: cpu_sample, 1: cpu_sample})
+
+        with self._monkeyPatchedFakeNumaTopology():
             self.assertEqual(
                 sampling._get_cpu_core_stats(first_sample, last_sample),
-                expected)
+                self._expectedResult())
+
+    def testSkipStatsOnMissingLastSample(self):
+        cpu_sample = {'user': 1.0, 'sys': 2.0}
+
+        first_sample = fake.HostSample(1.0, {0: cpu_sample, 1: cpu_sample})
+        last_sample = fake.HostSample(2.0, {0: cpu_sample})
+
+        with self._monkeyPatchedFakeNumaTopology():
+            self.assertEqual(
+                sampling._get_cpu_core_stats(first_sample, last_sample),
+                self._expectedResult())
 
 
 class NumaNodeMemorySampleTests(TestCaseBase):
diff --git a/tests/vmfakelib.py b/tests/vmfakelib.py
index 99cbcb9..361919d 100644
--- a/tests/vmfakelib.py
+++ b/tests/vmfakelib.py
@@ -383,7 +383,7 @@
         self._samples = samples
 
     def getCoreSample(self, key):
-        return self._samples[key]
+        return self._samples.get(key)
 
 
 class HostSample(object):
diff --git a/vdsm/virt/sampling.py b/vdsm/virt/sampling.py
index 1ad9d46..b6b5bc9 100644
--- a/vdsm/virt/sampling.py
+++ b/vdsm/virt/sampling.py
@@ -691,6 +691,10 @@
     for node_index, numa_node in six.iteritems(caps.getNumaTopology()):
         cpu_cores = numa_node['cpus']
         for cpu_core in cpu_cores:
+            # Do not try to collect cpu core data when no samples are present
+            if (not last_sample.cpuCores.getCoreSample(cpu_core) or not
+                    first_sample.cpuCores.getCoreSample(cpu_core)):
+                continue
             core_stat = {
                 'nodeIndex': int(node_index),
                 'cpuUser': compute_cpu_usage(cpu_core, 'user'),


-- 
To view, visit https://gerrit.ovirt.org/46269
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia9c247f9138e02a9230a0849a04cb2e1705e7fac
Gerrit-PatchSet: 4
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Roman Mohr <rm...@redhat.com>
Gerrit-Reviewer: Francesco Romani <from...@redhat.com>
Gerrit-Reviewer: Roman Mohr <rm...@redhat.com>
Gerrit-Reviewer: automat...@ovirt.org
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to