From 12d5ee3a7e83a42ba75a79b220a9db4dacd70a6e Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Fri, 19 Feb 2016 16:48:10 +0100 Subject: block: Fix -incoming with snapshot=on The BDRV_O_INACTIVE flag should only be set for images explicitly opened by the user. snapshot=on needs to create a new qcow2 image and write some metadata to it. This is not a problem because it can't come from the source, so there's no reason to mark it as BDRV_O_INACTIVE, even though it is opened while waiting for the migration to complete. This fixes an assertion failure when -incoming and snapshot=on are combined. Signed-off-by: Kevin Wolf --- tests/qemu-iotests/145 | 52 ++++++++++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/145.out | 5 +++++ tests/qemu-iotests/group | 1 + 3 files changed, 58 insertions(+) create mode 100755 tests/qemu-iotests/145 create mode 100644 tests/qemu-iotests/145.out (limited to 'tests') diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145 new file mode 100755 index 0000000..7d8febb --- /dev/null +++ b/tests/qemu-iotests/145 @@ -0,0 +1,52 @@ +#!/bin/bash +# +# Test the combination of -incoming and snapshot=on +# +# Copyright (C) 2016 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 . +# + +# creator +owner=kwolf@redhat.com + +seq=`basename $0` +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img + true +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt generic +_supported_proto generic +_supported_os Linux + +_make_test_img 1M +echo quit | $QEMU -nographic -hda "$TEST_IMG" -incoming 'exec:true' -snapshot -serial none -monitor stdio | _filter_qemu + +# success, all done +echo "*** done" +rm -f $seq.full +status=0 diff --git a/tests/qemu-iotests/145.out b/tests/qemu-iotests/145.out new file mode 100644 index 0000000..75b5c8a --- /dev/null +++ b/tests/qemu-iotests/145.out @@ -0,0 +1,5 @@ +QA output created by 145 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qququiquit +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 65df029..47fd40c 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -147,3 +147,4 @@ 142 auto 143 auto quick 144 rw auto quick +145 auto quick -- cgit v1.1 From 6921b1809507797752b039b2892fc33bf6bccb7e Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:26:55 +0200 Subject: throttle: Make throttle_conflicting() set errp The caller does not need to set it, and this will allow us to refactor this function later. Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 858f1aa..579b8af 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -255,31 +255,31 @@ static void test_conflicts_for_one_set(bool is_max, int write) { memset(&cfg, 0, sizeof(cfg)); - g_assert(!throttle_conflicting(&cfg)); + g_assert(!throttle_conflicting(&cfg, NULL)); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, read, 1); - g_assert(throttle_conflicting(&cfg)); + g_assert(throttle_conflicting(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, write, 1); - g_assert(throttle_conflicting(&cfg)); + g_assert(throttle_conflicting(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, read, 1); set_cfg_value(is_max, write, 1); - g_assert(throttle_conflicting(&cfg)); + g_assert(throttle_conflicting(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, total, 1); - g_assert(!throttle_conflicting(&cfg)); + g_assert(!throttle_conflicting(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, read, 1); set_cfg_value(is_max, write, 1); - g_assert(!throttle_conflicting(&cfg)); + g_assert(!throttle_conflicting(&cfg, NULL)); } static void test_conflicting_config(void) -- cgit v1.1 From 45b2d418e05e8b3cce9c8370ef6daac4b073b57a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:26:56 +0200 Subject: throttle: Make throttle_max_is_missing_limit() set errp The caller does not need to set it, and this will allow us to refactor this function later. Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 579b8af..49bd3bc 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -338,15 +338,15 @@ static void test_max_is_missing_limit(void) memset(&cfg, 0, sizeof(cfg)); cfg.buckets[i].max = 100; cfg.buckets[i].avg = 0; - g_assert(throttle_max_is_missing_limit(&cfg)); + g_assert(throttle_max_is_missing_limit(&cfg, NULL)); cfg.buckets[i].max = 0; cfg.buckets[i].avg = 0; - g_assert(!throttle_max_is_missing_limit(&cfg)); + g_assert(!throttle_max_is_missing_limit(&cfg, NULL)); cfg.buckets[i].max = 0; cfg.buckets[i].avg = 100; - g_assert(!throttle_max_is_missing_limit(&cfg)); + g_assert(!throttle_max_is_missing_limit(&cfg, NULL)); } } -- cgit v1.1 From 03ba36c83d136a9d039b56f0a834e65676b58c22 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:26:57 +0200 Subject: throttle: Make throttle_is_valid() set errp The caller does not need to set it, and this will allow us to refactor this function later. Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 49bd3bc..0e7c7e0 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -315,7 +315,7 @@ static void test_is_valid_for_value(int value, bool should_be_valid) for (index = 0; index < BUCKETS_COUNT; index++) { memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, index, value); - g_assert(throttle_is_valid(&cfg) == should_be_valid); + g_assert(throttle_is_valid(&cfg, NULL) == should_be_valid); } } } -- cgit v1.1 From 6f9b6d57ae3cd8a5f82e06f79d22e7a591116b5b Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:26:58 +0200 Subject: throttle: Set always an average value when setting a maximum value When testing the ranges of valid values, set_cfg_value() creates sometimes invalid throttling configurations by setting bucket.max while leaving bucket.avg uninitialized. While this doesn't break the current tests, it will as soon as we unify all functions that check the validity of the throttling configuration. This patch ensures that the value of bucket.avg is valid when setting bucket.max. Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 0e7c7e0..3e208a8 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -222,6 +222,8 @@ static void set_cfg_value(bool is_max, int index, int value) { if (is_max) { cfg.buckets[index].max = value; + /* If max is set, avg should never be 0 */ + cfg.buckets[index].avg = MAX(cfg.buckets[index].avg, 1); } else { cfg.buckets[index].avg = value; } -- cgit v1.1 From d5851089a8a77d5c23e8d5fffb5b99265009ba62 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:26:59 +0200 Subject: throttle: Merge all functions that check the configuration into one There's no need to keep throttle_conflicting(), throttle_is_valid() and throttle_max_is_missing_limit() as separate functions, so this patch merges all three into one. As a consequence, check_throttle_config() becomes redundant and can be replaced with throttle_is_valid(). Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 3e208a8..a0c17ac 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -257,31 +257,31 @@ static void test_conflicts_for_one_set(bool is_max, int write) { memset(&cfg, 0, sizeof(cfg)); - g_assert(!throttle_conflicting(&cfg, NULL)); + g_assert(throttle_is_valid(&cfg, NULL)); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, read, 1); - g_assert(throttle_conflicting(&cfg, NULL)); + g_assert(!throttle_is_valid(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, write, 1); - g_assert(throttle_conflicting(&cfg, NULL)); + g_assert(!throttle_is_valid(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, read, 1); set_cfg_value(is_max, write, 1); - g_assert(throttle_conflicting(&cfg, NULL)); + g_assert(!throttle_is_valid(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, total, 1); - g_assert(!throttle_conflicting(&cfg, NULL)); + g_assert(throttle_is_valid(&cfg, NULL)); memset(&cfg, 0, sizeof(cfg)); set_cfg_value(is_max, read, 1); set_cfg_value(is_max, write, 1); - g_assert(!throttle_conflicting(&cfg, NULL)); + g_assert(throttle_is_valid(&cfg, NULL)); } static void test_conflicting_config(void) @@ -340,15 +340,15 @@ static void test_max_is_missing_limit(void) memset(&cfg, 0, sizeof(cfg)); cfg.buckets[i].max = 100; cfg.buckets[i].avg = 0; - g_assert(throttle_max_is_missing_limit(&cfg, NULL)); + g_assert(!throttle_is_valid(&cfg, NULL)); cfg.buckets[i].max = 0; cfg.buckets[i].avg = 0; - g_assert(!throttle_max_is_missing_limit(&cfg, NULL)); + g_assert(throttle_is_valid(&cfg, NULL)); cfg.buckets[i].max = 0; cfg.buckets[i].avg = 100; - g_assert(!throttle_max_is_missing_limit(&cfg, NULL)); + g_assert(throttle_is_valid(&cfg, NULL)); } } -- cgit v1.1 From 1588ab5d0b96301b893d63aa342faad0e37a02ff Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:27:00 +0200 Subject: throttle: Use throttle_config_init() to initialize ThrottleConfig We can currently initialize ThrottleConfig by zeroing all its fields, but this will change with the new fields to define the length of the burst periods. This patch introduces a new throttle_config_init() function and uses it to replace all memset() calls that initialize ThrottleConfig directly. Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index a0c17ac..34f1f9e 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -35,6 +35,9 @@ static bool double_cmp(double x, double y) /* tests for single bucket operations */ static void test_leak_bucket(void) { + throttle_config_init(&cfg); + bkt = cfg.buckets[THROTTLE_BPS_TOTAL]; + /* set initial value */ bkt.avg = 150; bkt.max = 15; @@ -64,6 +67,9 @@ static void test_compute_wait(void) int64_t wait; int64_t result; + throttle_config_init(&cfg); + bkt = cfg.buckets[THROTTLE_BPS_TOTAL]; + /* no operation limit set */ bkt.avg = 0; bkt.max = 15; @@ -233,17 +239,17 @@ static void test_enabled(void) { int i; - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); g_assert(!throttle_enabled(&cfg)); for (i = 0; i < BUCKETS_COUNT; i++) { - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); set_cfg_value(false, i, 150); g_assert(throttle_enabled(&cfg)); } for (i = 0; i < BUCKETS_COUNT; i++) { - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); set_cfg_value(false, i, -150); g_assert(!throttle_enabled(&cfg)); } @@ -256,29 +262,29 @@ static void test_conflicts_for_one_set(bool is_max, int read, int write) { - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); g_assert(throttle_is_valid(&cfg, NULL)); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, read, 1); g_assert(!throttle_is_valid(&cfg, NULL)); - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, write, 1); g_assert(!throttle_is_valid(&cfg, NULL)); - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); set_cfg_value(is_max, total, 1); set_cfg_value(is_max, read, 1); set_cfg_value(is_max, write, 1); g_assert(!throttle_is_valid(&cfg, NULL)); - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); set_cfg_value(is_max, total, 1); g_assert(throttle_is_valid(&cfg, NULL)); - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); set_cfg_value(is_max, read, 1); set_cfg_value(is_max, write, 1); g_assert(throttle_is_valid(&cfg, NULL)); @@ -315,7 +321,7 @@ static void test_is_valid_for_value(int value, bool should_be_valid) int is_max, index; for (is_max = 0; is_max < 2; is_max++) { for (index = 0; index < BUCKETS_COUNT; index++) { - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); set_cfg_value(is_max, index, value); g_assert(throttle_is_valid(&cfg, NULL) == should_be_valid); } @@ -337,7 +343,7 @@ static void test_max_is_missing_limit(void) int i; for (i = 0; i < BUCKETS_COUNT; i++) { - memset(&cfg, 0, sizeof(cfg)); + throttle_config_init(&cfg); cfg.buckets[i].max = 100; cfg.buckets[i].avg = 0; g_assert(!throttle_is_valid(&cfg, NULL)); @@ -552,7 +558,7 @@ static void test_groups(void) g_assert(bdrv1->throttle_state == bdrv3->throttle_state); /* Setting the config of a group member affects the whole group */ - memset(&cfg1, 0, sizeof(cfg1)); + throttle_config_init(&cfg1); cfg1.buckets[THROTTLE_BPS_READ].avg = 500000; cfg1.buckets[THROTTLE_BPS_WRITE].avg = 285000; cfg1.buckets[THROTTLE_OPS_READ].avg = 20000; -- cgit v1.1 From eb8a1a1cbda15d776d6d505f14f61c7852f6a51a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:27:05 +0200 Subject: throttle: Check that burst_level leaks correctly This patch expands test_leak_bucket() to check that burst_level leaks correctly. Signed-off-by: Alberto Garcia Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 34f1f9e..145ba08 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -60,6 +60,22 @@ static void test_leak_bucket(void) g_assert(bkt.avg == 150); g_assert(bkt.max == 15); g_assert(double_cmp(bkt.level, 0)); + + /* check that burst_level leaks correctly */ + bkt.burst_level = 6; + bkt.max = 250; + bkt.burst_length = 2; /* otherwise burst_level will not leak */ + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); + g_assert(double_cmp(bkt.burst_level, 3.5)); + + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); + g_assert(double_cmp(bkt.burst_level, 1)); + + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); + g_assert(double_cmp(bkt.burst_level, 0)); + + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); + g_assert(double_cmp(bkt.burst_level, 0)); } static void test_compute_wait(void) -- cgit v1.1 From f9d058852c9f28d378f003ad94cc881fd91ea385 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:27:06 +0200 Subject: throttle: Test throttle_compute_wait() during bursts This test simulates an I/O burst for more than two seconds and checks that it works as expected. Signed-off-by: Alberto Garcia Reviewed-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- tests/test-throttle.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'tests') diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 145ba08..59675fa 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -80,6 +80,7 @@ static void test_leak_bucket(void) static void test_compute_wait(void) { + unsigned i; int64_t wait; int64_t result; @@ -115,6 +116,27 @@ static void test_compute_wait(void) /* time required to do half an operation */ result = (int64_t) NANOSECONDS_PER_SECOND / 150 / 2; g_assert(wait == result); + + /* Perform I/O for 2.2 seconds at a rate of bkt.max */ + bkt.burst_length = 2; + bkt.level = 0; + bkt.avg = 10; + bkt.max = 200; + for (i = 0; i < 22; i++) { + double units = bkt.max / 10; + bkt.level += units; + bkt.burst_level += units; + throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 10); + wait = throttle_compute_wait(&bkt); + g_assert(double_cmp(bkt.burst_level, 0)); + g_assert(double_cmp(bkt.level, (i + 1) * (bkt.max - bkt.avg) / 10)); + /* We can do bursts for the 2 seconds we have configured in + * burst_length. We have 100 extra miliseconds of burst + * because bkt.level has been leaking during this time. + * After that, we have to wait. */ + result = i < 21 ? 0 : 1.8 * NANOSECONDS_PER_SECOND; + g_assert(wait == result); + } } /* functions to test ThrottleState initialization/destroy methods */ -- cgit v1.1 From a90cade023ab5559f43583958f871d28d9bb7b32 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Thu, 18 Feb 2016 12:27:07 +0200 Subject: qemu-iotests: Extend iotest 093 to test bursts 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 Signed-off-by: Kevin Wolf --- tests/qemu-iotests/093 | 65 ++++++++++++++++++++++++++++++++++++---------- tests/qemu-iotests/093.out | 4 +-- 2 files changed, 53 insertions(+), 16 deletions(-) (limited to 'tests') diff --git a/tests/qemu-iotests/093 b/tests/qemu-iotests/093 index c0e9e2b..ce8e13c 100755 --- a/tests/qemu-iotests/093 +++ b/tests/qemu-iotests/093 @@ -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,16 +44,7 @@ class ThrottleTestCase(iotests.QMPTestCase): def tearDown(self): self.vm.shutdown() - def do_test_throttle(self, ndrives, seconds, params): - def check_limit(limit, num): - # IO throttling algorithm is discrete, allow 10% error so the test - # is more robust - return limit == 0 or \ - (num < seconds * limit * 1.1 / ndrives - and num > seconds * limit * 0.9 / ndrives) - - nsec_per_sec = 1000000000 - + def configure_throttle(self, ndrives, params): params['group'] = 'test' # Set the I/O throttling parameters to all drives @@ -60,13 +53,21 @@ class ThrottleTestCase(iotests.QMPTestCase): 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 + # is more robust + return limit == 0 or \ + (num < seconds * limit * 1.1 / ndrives + and num > seconds * limit * 0.9 / ndrives) + # 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://" diff --git a/tests/qemu-iotests/093.out b/tests/qemu-iotests/093.out index fbc63e6..89968f3 100644 --- a/tests/qemu-iotests/093.out +++ b/tests/qemu-iotests/093.out @@ -1,5 +1,5 @@ -.. +.... ---------------------------------------------------------------------- -Ran 2 tests +Ran 4 tests OK -- cgit v1.1 From f436c94102274f14b556beb655da8a54400e56f3 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Fri, 19 Feb 2016 14:01:09 +0100 Subject: qemu-iotests: 067: ignore QMP events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The relative ordering of "device_del" return value and the "DEVICE_DELETED" QMP event depends on the architecture being tested. On x86 unplugging virtio disks is asynchronous (=qdev_unplug()= → =hotplug_handler_unplug_request()=) while on s390x it is synchronous (=qdev_unplug()= → =hotplug_handler_unplug()=). This leads to the actual output on s390x consistently differing from the reference output (that was probably produced on x86). The easiest way to address this is to filter out QMP events in 067. The DEVICE_DELETED event is already getting explicitly tested by the Python-based test case 139, so the test coverage should be unaffected. Make use of the recently introduced _filter_qmp_events() to remove QMP events from the test case output and adjust the reference output accordingly. The tr / sed / tr trick used for filtering was suggested by Max Reitz . Signed-off-by: Sascha Silbe Message-id: 1455886869-139916-2-git-send-email-silbe@linux.vnet.ibm.com Signed-off-by: Max Reitz --- tests/qemu-iotests/067 | 11 +++- tests/qemu-iotests/067.out | 144 --------------------------------------------- 2 files changed, 10 insertions(+), 145 deletions(-) (limited to 'tests') diff --git a/tests/qemu-iotests/067 b/tests/qemu-iotests/067 index 3788534..77dec0d 100755 --- a/tests/qemu-iotests/067 +++ b/tests/qemu-iotests/067 @@ -45,11 +45,20 @@ function do_run_qemu() echo } +# Remove QMP events from (pretty-printed) output. Doesn't handle +# nested dicts correctly, but we don't get any of those in this test. +_filter_qmp_events() +{ + tr '\n' '\t' | sed -e \ + 's/{\s*"timestamp":\s*{[^}]*},\s*"event":[^,}]*\(,\s*"data":\s*{[^}]*}\)\?\s*}\s*//g' \ + | tr '\t' '\n' +} + function run_qemu() { do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | _filter_qemu \ | sed -e 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g' \ - | _filter_generated_node_ids + | _filter_generated_node_ids | _filter_qmp_events } size=128M diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out index ae3fccb..7e25a49 100644 --- a/tests/qemu-iotests/067.out +++ b/tests/qemu-iotests/067.out @@ -70,34 +70,6 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti } } { - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "path": "/machine/peripheral/virtio0/virtio-backend" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "device": "virtio0", - "path": "/machine/peripheral/virtio0" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "RESET" -} -{ "return": [ ] } @@ -105,14 +77,6 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti "return": { } } -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} - === -drive/device_add and device_del === @@ -186,34 +150,6 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk } } { - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "path": "/machine/peripheral/virtio0/virtio-backend" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "device": "virtio0", - "path": "/machine/peripheral/virtio0" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "RESET" -} -{ "return": [ ] } @@ -221,14 +157,6 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk "return": { } } -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} - === drive_add/device_add and device_del === @@ -305,34 +233,6 @@ Testing: } } { - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "path": "/machine/peripheral/virtio0/virtio-backend" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "device": "virtio0", - "path": "/machine/peripheral/virtio0" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "RESET" -} -{ "return": [ ] } @@ -340,14 +240,6 @@ Testing: "return": { } } -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} - === blockdev_add/device_add and device_del === @@ -425,34 +317,6 @@ Testing: } } { - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "path": "/machine/peripheral/virtio0/virtio-backend" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "DEVICE_DELETED", - "data": { - "device": "virtio0", - "path": "/machine/peripheral/virtio0" - } -} -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "RESET" -} -{ "return": [ { "io-status": "ok", @@ -506,12 +370,4 @@ Testing: "return": { } } -{ - "timestamp": { - "seconds": TIMESTAMP, - "microseconds": TIMESTAMP - }, - "event": "SHUTDOWN" -} - *** done -- cgit v1.1 From 4b84fc70cecd616ccc61b563def2230d73b438b8 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Thu, 18 Feb 2016 21:37:32 +0100 Subject: qemu-iotests: 140: don't use IDE device IDE is only implemented by very few architectures (mostly PC). The test doesn't actually need a block device attached to the BlockBackend, so just drop it and adjust the reference output accordingly. Fixes: 16dee418 ("iotests: Add test for eject under NBD server") Signed-off-by: Sascha Silbe Message-id: 1455827853-33477-2-git-send-email-silbe@linux.vnet.ibm.com Signed-off-by: Max Reitz --- tests/qemu-iotests/140 | 2 +- tests/qemu-iotests/140.out | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140 index f78c317..baaf64e 100755 --- a/tests/qemu-iotests/140 +++ b/tests/qemu-iotests/140 @@ -49,7 +49,7 @@ _make_test_img 64k $QEMU_IO -c 'write -P 42 0 64k' "$TEST_IMG" | _filter_qemu_io keep_stderr=y \ -_launch_qemu -drive if=ide,media=cdrom,id=drv,file="$TEST_IMG",format=$IMGFMT \ +_launch_qemu -drive if=none,media=cdrom,id=drv,file="$TEST_IMG",format=$IMGFMT \ 2> >(_filter_nbd) _send_qemu_cmd $QEMU_HANDLE \ diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out index 72f1b4c..0409cd0 100644 --- a/tests/qemu-iotests/140.out +++ b/tests/qemu-iotests/140.out @@ -7,7 +7,6 @@ wrote 65536/65536 bytes at offset 0 {"return": {}} read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "drv", "tray-open": true}} {"return": {}} can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: No export with name 'drv' available no file open, try 'help open' -- cgit v1.1 From 43e15ed4fded6be585072a6dd2ef8dc3956bad67 Mon Sep 17 00:00:00 2001 From: Sascha Silbe Date: Thu, 18 Feb 2016 21:37:33 +0100 Subject: qemu-iotests: 140: make description slightly more verbose Describe in a little more detail what the test is supposed to achieve. Signed-off-by: Sascha Silbe Message-id: 1455827853-33477-3-git-send-email-silbe@linux.vnet.ibm.com Signed-off-by: Max Reitz --- tests/qemu-iotests/140 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140 index baaf64e..05e4506 100755 --- a/tests/qemu-iotests/140 +++ b/tests/qemu-iotests/140 @@ -1,6 +1,10 @@ #!/bin/bash # -# Test case for ejecting a BB with an NBD server attached to it +# Test case for ejecting a BlockBackend with an NBD server attached to it +# +# Verify that the NBD server stops offering the drive when ejecting a +# BlockDriverState tree from a BlockBackend (that is, a medium from a +# drive) exposed via an NBD server. # # Copyright (C) 2016 Red Hat, Inc. # -- cgit v1.1