@@ -3,7 +3,7 @@
# Tests for IO throttling
#
# Copyright (C) 2015 Red Hat, Inc.
-# Copyright (C) 2015 Igalia, S.L.
+# Copyright (C) 2015-2016 Igalia, S.L.
#
# 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
@@ -21,6 +21,8 @@
import iotests
+nsec_per_sec = 1000000000
+
class ThrottleTestCase(iotests.QMPTestCase):
test_img = "null-aio://"
max_drives = 3
@@ -42,6 +44,15 @@ class ThrottleTestCase(iotests.QMPTestCase):
def tearDown(self):
self.vm.shutdown()
+ def configure_throttle(self, ndrives, params):
+ params['group'] = 'test'
+
+ # Set the I/O throttling parameters to all drives
+ for i in range(0, ndrives):
+ params['device'] = 'drive%d' % i
+ result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params)
+ self.assert_qmp(result, 'return', {})
+
def do_test_throttle(self, ndrives, seconds, params):
def check_limit(limit, num):
# IO throttling algorithm is discrete, allow 10% error so the test
@@ -50,23 +61,13 @@ class ThrottleTestCase(iotests.QMPTestCase):
(num < seconds * limit * 1.1 / ndrives
and num > seconds * limit * 0.9 / ndrives)
- nsec_per_sec = 1000000000
-
- params['group'] = 'test'
-
- # Set the I/O throttling parameters to all drives
- for i in range(0, ndrives):
- params['device'] = 'drive%d' % i
- result = self.vm.qmp("block_set_io_throttle", conv_keys=False, **params)
- self.assert_qmp(result, 'return', {})
-
# Set vm clock to a known value
ns = seconds * nsec_per_sec
self.vm.qtest("clock_step %d" % ns)
- # Submit enough requests. They will drain bps_max and iops_max, but the
- # rest requests won't get executed until we advance the virtual clock
- # with qtest interface
+ # Submit enough requests so the throttling mechanism kicks
+ # in. The throttled requests won't be executed until we
+ # advance the virtual clock.
rq_size = 512
rd_nr = max(params['bps'] / rq_size / 2,
params['bps_rd'] / rq_size,
@@ -142,8 +143,44 @@ class ThrottleTestCase(iotests.QMPTestCase):
for tk in params:
limits = dict([(k, 0) for k in params])
limits[tk] = params[tk] * ndrives
+ self.configure_throttle(ndrives, limits)
self.do_test_throttle(ndrives, 5, limits)
+ def test_burst(self):
+ params = {"bps": 4096,
+ "bps_rd": 4096,
+ "bps_wr": 4096,
+ "iops": 10,
+ "iops_rd": 10,
+ "iops_wr": 10,
+ }
+ ndrives = 1
+ # Pick each out of all possible params and test
+ for tk in params:
+ rate = params[tk] * ndrives
+ burst_rate = rate * 7
+ burst_length = 4
+
+ # Configure the throttling settings
+ settings = dict([(k, 0) for k in params])
+ settings[tk] = rate
+ settings['%s_max' % tk] = burst_rate
+ settings['%s_max_length' % tk] = burst_length
+ self.configure_throttle(ndrives, settings)
+
+ # Wait for the bucket to empty so we can do bursts
+ wait_ns = nsec_per_sec * burst_length * burst_rate / rate
+ self.vm.qtest("clock_step %d" % wait_ns)
+
+ # Test I/O at the max burst rate
+ limits = dict([(k, 0) for k in params])
+ limits[tk] = burst_rate
+ self.do_test_throttle(ndrives, burst_length, limits)
+
+ # Now test I/O at the normal rate
+ limits[tk] = rate
+ self.do_test_throttle(ndrives, 5, limits)
+
class ThrottleTestCoroutine(ThrottleTestCase):
test_img = "null-co://"
@@ -1,5 +1,5 @@
-..
+....
----------------------------------------------------------------------
-Ran 2 tests
+Ran 4 tests
OK
This patch adds a new test that checks that the burst settings ('iops_max', 'iops_max_length', etc.) of the throttling code work as expected. Signed-off-by: Alberto Garcia <berto@igalia.com> --- tests/qemu-iotests/093 | 65 ++++++++++++++++++++++++++++++++++++---------- tests/qemu-iotests/093.out | 4 +-- 2 files changed, 53 insertions(+), 16 deletions(-)