From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54275) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8XAO-00047Q-94 for qemu-devel@nongnu.org; Wed, 29 Jan 2014 10:35:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W8XAJ-0007b1-RT for qemu-devel@nongnu.org; Wed, 29 Jan 2014 10:35:04 -0500 Received: from paradis.irqsave.net ([62.212.105.220]:48618) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8XAJ-0007aw-8e for qemu-devel@nongnu.org; Wed, 29 Jan 2014 10:34:59 -0500 Date: Wed, 29 Jan 2014 16:34:58 +0100 From: =?iso-8859-1?Q?Beno=EEt?= Canet Message-ID: <20140129153458.GC3079@irqsave.net> References: <1390984843-2101-1-git-send-email-famz@redhat.com> <1390984843-2101-5-git-send-email-famz@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: <1390984843-2101-5-git-send-email-famz@redhat.com> Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 4/4] qemu-iotests: Add 080 for IO throttling List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Fam Zheng Cc: Kevin Wolf , =?iso-8859-1?Q?Beno=EEt?= Canet , qemu-devel@nongnu.org, Stefan Hajnoczi Le Wednesday 29 Jan 2014 =E0 16:40:43 (+0800), Fam Zheng a =E9crit : > This case utilizes qemu-io command "aio_{read,write} -a -q" to verify > the effectiveness of IO throttling options. >=20 > The "-a" option will cause qemu-io requests to be accounted. >=20 > It's implemented by driving the vm timer from qtest protocol, so the > throttling timers are signaled with determinied time duration. Then we > verify the completed IO requests are within 110% of bps and iops limits= . >=20 > Signed-off-by: Fam Zheng > --- > tests/qemu-iotests/080 | 164 +++++++++++++++++++++++++++++++++++++= ++++++++ > tests/qemu-iotests/080.out | 5 ++ > tests/qemu-iotests/group | 1 + > 3 files changed, 170 insertions(+) > create mode 100755 tests/qemu-iotests/080 > create mode 100644 tests/qemu-iotests/080.out >=20 > diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080 > new file mode 100755 > index 0000000..222bb37 > --- /dev/null > +++ b/tests/qemu-iotests/080 > @@ -0,0 +1,164 @@ > +#!/usr/bin/env python > +# > +# Tests for IO throttling > +# > +# Copyright (C) 2014 Red Hat, Inc. > +# > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program. If not, see = . > +# > + > +import time > +import os > +import iotests > +from iotests import qemu_img > + > +test_img =3D os.path.join(iotests.test_dir, 'test.img') > + > +class ThrottleTestCase(iotests.QMPTestCase): > + image_len =3D 80 * 1024 * 1024 # MB > + > + def blockstats(self, device): > + result =3D self.vm.qmp("query-blockstats") > + for r in result['return']: > + if r['device'] =3D=3D device: > + stat =3D r['stats'] > + return stat['rd_bytes'], stat['rd_operations'], stat['= wr_bytes'], stat['wr_operations'] > + raise Exception("Device not found for blockstats: %s" % device= ) > + > + def setUp(self): > + qemu_img('create', '-f', iotests.imgfmt, test_img, "1G") > + #self.vm =3D iotests.VM().add_drive(test_img, "bps=3D1024,bps_= max=3D1") > + self.vm =3D iotests.VM().add_drive(test_img) > + self.vm.launch() > + > + def tearDown(self): > + self.vm.shutdown() > + os.remove(test_img) > + > + def do_test_throttle(self, seconds=3D10, **limits): > + def check_limit(limit, num): > + # IO throttling algorithm is discrete, allow 10% error so = the test > + # is more deterministic > + return limit =3D=3D 0 or num < seconds * limit * 1.1 > + > + nsec_per_sec =3D 1000000000 > + > + limits['bps_max'] =3D 1 > + limits['iops_max'] =3D 1 > + > + # Enqueue many requests to throttling queue > + result =3D self.vm.qmp("block_set_io_throttle", conv_keys=3DFa= lse, **limits) > + self.assert_qmp(result, 'return', {}) > + > + # Set vm clock to a known value > + ns =3D nsec_per_sec > + self.vm.qtest_cmd("clock_step %d" % ns) > + > + # Append many requests into the throttle queue > + # They drain bps_max and iops_max > + # The rest requests won't get executed until qtest clock is dr= iven > + for i in range(1000): > + self.vm.hmp_qemu_io("drive0", "aio_read -a -q 0 512") > + self.vm.hmp_qemu_io("drive0", "aio_write -a -q 0 512") > + > + start_rd_bytes, start_rd_iops, start_wr_bytes, start_wr_iops =3D= self.blockstats('drive0') > + > + ns +=3D seconds * nsec_per_sec > + self.vm.qtest_cmd("clock_step %d" % ns) > + # wait for a while to let requests take off > + time.sleep(1) > + end_rd_bytes, end_rd_iops, end_wr_bytes, end_wr_iops =3D self.= blockstats('drive0') > + > + rd_bytes =3D end_rd_bytes - start_rd_bytes > + rd_iops =3D end_rd_iops - start_rd_iops > + wr_bytes =3D end_wr_bytes - start_wr_bytes > + wr_iops =3D end_wr_iops - start_wr_iops > + > + assert check_limit(limits['bps'], rd_bytes) > + assert check_limit(limits['bps_rd'], rd_bytes) > + assert check_limit(limits['bps'], wr_bytes) > + assert check_limit(limits['bps_wr'], wr_bytes) > + assert check_limit(limits['iops'], rd_iops) > + assert check_limit(limits['iops_rd'], rd_iops) > + assert check_limit(limits['iops'], wr_iops) > + assert check_limit(limits['iops_wr'], wr_iops) > + > + def test_bps(self): > + self.do_test_throttle(**{ > + 'device': 'drive0', > + 'bps': 1000, > + 'bps_rd': 0, > + 'bps_wr': 0, > + 'iops': 0, > + 'iops_rd': 0, > + 'iops_wr': 0, > + }) > + > + def test_bps_rd(self): > + self.do_test_throttle(**{ > + 'device': 'drive0', > + 'bps': 0, > + 'bps_rd': 1000, > + 'bps_wr': 0, > + 'iops': 0, > + 'iops_rd': 0, > + 'iops_wr': 0, > + }) > + > + def test_bps_wr(self): > + self.do_test_throttle(**{ > + 'device': 'drive0', > + 'bps': 0, > + 'bps_rd': 0, > + 'bps_wr': 1000, > + 'iops': 0, > + 'iops_rd': 0, > + 'iops_wr': 0, > + }) > + > + def test_iops(self): > + self.do_test_throttle(**{ > + 'device': 'drive0', > + 'bps': 0, > + 'bps_rd': 0, > + 'bps_wr': 0, > + 'iops': 10, > + 'iops_rd': 0, > + 'iops_wr': 0, > + }) > + > + def test_iops_rd(self): > + self.do_test_throttle(**{ > + 'device': 'drive0', > + 'bps': 0, > + 'bps_rd': 0, > + 'bps_wr': 0, > + 'iops': 0, > + 'iops_rd': 10, > + 'iops_wr': 0, > + }) > + > + def test_iops_wr(self): > + self.do_test_throttle(**{ > + 'device': 'drive0', > + 'bps': 0, > + 'bps_rd': 0, > + 'bps_wr': 0, > + 'iops': 0, > + 'iops_rd': 0, > + 'iops_wr': 10, > + }) > + > +if __name__ =3D=3D '__main__': > + iotests.main() > diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out > new file mode 100644 > index 0000000..3f8a935 > --- /dev/null > +++ b/tests/qemu-iotests/080.out > @@ -0,0 +1,5 @@ > +...... > +---------------------------------------------------------------------- > +Ran 6 tests > + > +OK > diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group > index 03c762f..013a7ef 100644 > --- a/tests/qemu-iotests/group > +++ b/tests/qemu-iotests/group > @@ -82,3 +82,4 @@ > 073 rw auto > 074 rw auto > 077 rw auto > +080 rw auto > --=20 > 1.8.5.3 >=20 >=20 I like the way it's done. Reviewed-by: Benoit Canet