All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduardo Habkost <ehabkost@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Amador Pahim" <apahim@redhat.com>,
	"Stefan Hajnoczi" <stefanha@gmail.com>,
	"Lukáš Doktor" <ldoktor@redhat.com>,
	"Alistair Francis" <alistair23@gmail.com>,
	"Cleber Rosa" <crosa@redhat.com>, "Fam Zheng" <famz@redhat.com>
Subject: [Qemu-devel] [RFC 16/24] avocado_qemu: Functional test for RHBZ1473203
Date: Fri, 20 Apr 2018 15:19:43 -0300	[thread overview]
Message-ID: <20180420181951.7252-17-ehabkost@redhat.com> (raw)
In-Reply-To: <20180420181951.7252-1-ehabkost@redhat.com>

From: Lukáš Doktor <ldoktor@redhat.com>

Adds regresion test for RHBZ1473203 which runs VM with 16 numa nodes and
then verifies memory allocation is accurate before and after hotplugging
memory into default and 13th node.

Signed-off-by: Lukáš Doktor <ldoktor@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 tests/avocado/test_numa_hotplug.py | 116 +++++++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 tests/avocado/test_numa_hotplug.py

diff --git a/tests/avocado/test_numa_hotplug.py b/tests/avocado/test_numa_hotplug.py
new file mode 100644
index 0000000000..a99b8dcebf
--- /dev/null
+++ b/tests/avocado/test_numa_hotplug.py
@@ -0,0 +1,116 @@
+import re
+import time
+
+from avocado_qemu import test
+
+
+class TestNumaHotplug(test.QemuTest):
+    """
+    Verifies that "info numa" and "/sys/devices/system/node/" contains
+    correct values before/after inserting memory devices into default
+    and then into 13th numa node.
+
+    Associated bug trackers: RHBZ1473203
+        https://bugzilla.redhat.com/show_bug.cgi?id=1473203
+
+    Fixed in kernel commit dc421b200f91930c9c6a9586810ff8c232cf10fc.
+
+    :avocado: enable
+    :avocado: tags=RHBZ1473203,requires_linux,numa,memory,ppc64le
+    """
+
+    def setUp(self):
+        self.request_image()
+        self.vm.args.extend(["-m", "4G,slots=208,maxmem=80G"])
+        self.vm.args.extend(["-numa", "node"] * 16)
+        self.vm.launch()
+
+    def check_mem_console(self, console, exp):
+        """
+        Verifies that memory layout is according to exp using console/ssh
+
+        :param console: session
+        :param exp: list of MemTotals per node in MB, tolerance is +-100MB
+        """
+        out = console.cmd_output_safe("echo /sys/devices/system/node/node*")
+        nodes = re.findall(r"/sys/devices/system/node/node\d+", out)
+        self.assertEqual(len(nodes), len(exp), "Number of nodes is not "
+                         "%s:\n%s" % (len(exp), out))
+        for i in xrange(len(exp)):
+            out = console.cmd_output_safe("cat /sys/devices/system/node/"
+                                          "node%s/meminfo" % i)
+            mem = re.search(r"MemTotal:\s*(\d+) kB", out)
+            self.assertTrue(mem, "Failed to obtain node%s MemTotal:\n%s"
+                            % (i, out))
+            _exp = exp[i] * 1024
+            mem = int(mem.group(1))
+            self.assertGreater(mem, _exp - 102400, "TotalMem of node%s is not "
+                               "%s+-51200 kb (%s)" % (i, _exp, mem))
+            self.assertLess(mem, _exp + 102400, "TotalMem of node%s is not "
+                            "%s+-51200 kb (%s)" % (i, _exp, mem))
+
+    def check_mem_monitor(self, monitor, exp):
+        """
+        Verifies that memory layout is according to exp using QMP monitor
+
+        :param console: session
+        :param exp: list of MemTotals per node in MB, tolerance is +-100MB
+        """
+        ret = monitor("human-monitor-command", command_line="info numa")
+        out = ret["return"]
+        self.assertTrue(out.startswith("%s nodes" % len(exp)), "Number of "
+                        "nodes is not %s:\n%s" % (len(exp), out))
+        for i in xrange(len(exp)):
+            _exp = "node %s size: %s MB" % (i, exp[i])
+            self.assertIn(_exp, out, "%s is not in 'info numa' output, "
+                          "probably wrong memory size reported:\n%s"
+                          % (_exp, out))
+
+    @staticmethod
+    def _retry_until_timeout(timeout, func, *args, **kwargs):
+        """
+        Repeat the function until it returns anything ignoring AssertionError.
+        After the deadline repeate the function one more time without ignoring
+        timeout.
+        """
+        end = time.time() + timeout
+        while time.time() < end:
+            try:
+                ret = func(*args, **kwargs)
+            except AssertionError:
+                continue
+            break
+        else:
+            ret = func(*args, **kwargs)
+        return ret
+
+    def test_hotplug_mem_into_node(self):
+        console = self.vm.get_console()
+        exp = [256] * 16
+        self.check_mem_monitor(self.vm.qmp, exp)
+        self.check_mem_console(console, exp)
+        cmd = "object_add memory-backend-ram,id=mem2,size=1G"
+        res = self.vm.qmp("human-monitor-command", command_line=cmd)
+        self.assertEqual(res["return"], "")
+        cmd = "device_add pc-dimm,id=dimm2,memdev=mem2"
+        res = self.vm.qmp("human-monitor-command", command_line=cmd)
+        self.assertEqual(res["return"], "")
+        exp = [1280] + [256] * 15
+        self.check_mem_monitor(self.vm.qmp, exp)
+        # Wait up to 10s to propagate the changes
+        self._retry_until_timeout(10, self.check_mem_console, console, exp)
+        cmd = "object_add memory-backend-ram,id=mem8,size=1G"
+        res = self.vm.qmp("human-monitor-command", command_line=cmd)
+        self.assertEqual(res["return"], "")
+        cmd = "device_add pc-dimm,id=dimm8,memdev=mem8,node=13"
+        res = self.vm.qmp("human-monitor-command", command_line=cmd)
+        self.assertEqual(res["return"], "")
+        time.sleep(5)
+        exp = [1280] + [256] * 12 + [1280] + [256] * 2
+        self.check_mem_monitor(self.vm.qmp, exp)
+        # Wait up to 10s to propagate the changes
+        self._retry_until_timeout(10, self.check_mem_console, console, exp)
+        console.close()
+
+    def tearDown(self):
+        self.vm.shutdown()
-- 
2.14.3

  parent reply	other threads:[~2018-04-20 18:23 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-20 18:19 [Qemu-devel] [RFC 00/24] Avocado-based functional tests Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 01/24] qemu.py: Introduce _create_console() method Eduardo Habkost
2018-04-20 19:56   ` Eduardo Habkost
2018-04-23  3:26     ` Thomas Huth
2018-04-23 19:47       ` Eduardo Habkost
2018-05-11 15:37     ` Cleber Rosa
2018-04-20 18:19 ` [Qemu-devel] [RFC 02/24] Introduce the basic framework to run Avocado tests Eduardo Habkost
2018-04-20 19:59   ` Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 03/24] avocado_qemu: Improve handle_prompts to allow login after booted vm Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 04/24] avocado_qemu: Be lenient towards poluted serial console Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 05/24] avocado_qemu: Increase the login timeout to 60s Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 06/24] avocado_qemu: Add " " after the default prompt regexp Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 07/24] avocado_qemu: Store "arch" in VM Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 08/24] avocado_qemu: Provide defaults for user and pass Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 09/24] avocado_qemu: Ignore kernel messages on get_console Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 10/24] avocado_qemu: Add support to request image for testing Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 11/24] avocado_qemu: Fix exception name in caller Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 12/24] avocado_qemu: Improve migration error message Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 13/24] avocado_qemu: Functional test for RHBZ#1431939 Eduardo Habkost
2018-04-30 13:02   ` Stefan Hajnoczi
2018-05-07 14:03     ` Eduardo Habkost
2018-05-10  9:14       ` Stefan Hajnoczi
2018-04-20 18:19 ` [Qemu-devel] [RFC 14/24] avocado_qemu: Functional test for RHBZ#1447027 Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 15/24] avocado_qemu: Functional test for RHBZ#1436616 Eduardo Habkost
2018-04-20 18:19 ` Eduardo Habkost [this message]
2018-04-20 18:19 ` [Qemu-devel] [RFC 17/24] avocado_qemu: Remove duplicate PortTracker implementation Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 18/24] avocado_qemu: Simplify the installation instructions Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 19/24] avocado_qemu: Clean unneeded 'pass' Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 20/24] avocado_qemu: Set QMP log level to INFO Eduardo Habkost
2018-04-20 20:03   ` Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 21/24] avocado_qemu: Introduce the add_image() VM API Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 22/24] avocado_qemu: Tests fixes Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 23/24] avocado_qemu: Force vmimage distro Eduardo Habkost
2018-04-20 18:19 ` [Qemu-devel] [RFC 24/24] avocado_qemu: Add a few VNC related tests Eduardo Habkost
2018-04-20 18:47 ` [Qemu-devel] [RFC 00/24] Avocado-based functional tests no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180420181951.7252-17-ehabkost@redhat.com \
    --to=ehabkost@redhat.com \
    --cc=alistair23@gmail.com \
    --cc=apahim@redhat.com \
    --cc=crosa@redhat.com \
    --cc=famz@redhat.com \
    --cc=ldoktor@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.