1f17cfe81SBenoît Canet /* 2f17cfe81SBenoît Canet * Throttle infrastructure tests 3f17cfe81SBenoît Canet * 41fee955fSAlberto Garcia * Copyright Nodalink, EURL. 2013-2014 51fee955fSAlberto Garcia * Copyright Igalia, S.L. 2015 6f17cfe81SBenoît Canet * 7f17cfe81SBenoît Canet * Authors: 81fee955fSAlberto Garcia * Benoît Canet <benoit.canet@nodalink.com> 91fee955fSAlberto Garcia * Alberto Garcia <berto@igalia.com> 10f17cfe81SBenoît Canet * 11f17cfe81SBenoît Canet * This work is licensed under the terms of the GNU LGPL, version 2 or later. 12f17cfe81SBenoît Canet * See the COPYING.LIB file in the top-level directory. 13f17cfe81SBenoît Canet */ 14f17cfe81SBenoît Canet 15681c28a3SPeter Maydell #include "qemu/osdep.h" 16f17cfe81SBenoît Canet #include <math.h> 1713af91ebSStefan Hajnoczi #include "block/aio.h" 18da34e65cSMarkus Armbruster #include "qapi/error.h" 19f17cfe81SBenoît Canet #include "qemu/throttle.h" 202f78e491SChrysostomos Nanakos #include "qemu/error-report.h" 211fee955fSAlberto Garcia #include "block/throttle-groups.h" 2231dce3ccSKevin Wolf #include "sysemu/block-backend.h" 23f17cfe81SBenoît Canet 24748bfb4eSStefan Weil static AioContext *ctx; 25748bfb4eSStefan Weil static LeakyBucket bkt; 26748bfb4eSStefan Weil static ThrottleConfig cfg; 27c61791fcSManos Pitsidianakis static ThrottleGroupMember tgm; 28748bfb4eSStefan Weil static ThrottleState ts; 29c61791fcSManos Pitsidianakis static ThrottleTimers *tt; 30f17cfe81SBenoît Canet 3173f395faSStefan Weil /* useful function */ 32f17cfe81SBenoît Canet static bool double_cmp(double x, double y) 33f17cfe81SBenoît Canet { 34f17cfe81SBenoît Canet return fabsl(x - y) < 1e-6; 35f17cfe81SBenoît Canet } 36f17cfe81SBenoît Canet 37f17cfe81SBenoît Canet /* tests for single bucket operations */ 38f17cfe81SBenoît Canet static void test_leak_bucket(void) 39f17cfe81SBenoît Canet { 401588ab5dSAlberto Garcia throttle_config_init(&cfg); 411588ab5dSAlberto Garcia bkt = cfg.buckets[THROTTLE_BPS_TOTAL]; 421588ab5dSAlberto Garcia 43f17cfe81SBenoît Canet /* set initial value */ 44f17cfe81SBenoît Canet bkt.avg = 150; 45f17cfe81SBenoît Canet bkt.max = 15; 46f17cfe81SBenoît Canet bkt.level = 1.5; 47f17cfe81SBenoît Canet 48f17cfe81SBenoît Canet /* leak an op work of time */ 4913566fe3SStefan Hajnoczi throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150); 50f17cfe81SBenoît Canet g_assert(bkt.avg == 150); 51f17cfe81SBenoît Canet g_assert(bkt.max == 15); 52f17cfe81SBenoît Canet g_assert(double_cmp(bkt.level, 0.5)); 53f17cfe81SBenoît Canet 54f17cfe81SBenoît Canet /* leak again emptying the bucket */ 5513566fe3SStefan Hajnoczi throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150); 56f17cfe81SBenoît Canet g_assert(bkt.avg == 150); 57f17cfe81SBenoît Canet g_assert(bkt.max == 15); 58f17cfe81SBenoît Canet g_assert(double_cmp(bkt.level, 0)); 59f17cfe81SBenoît Canet 60f17cfe81SBenoît Canet /* check that the bucket level won't go lower */ 6113566fe3SStefan Hajnoczi throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150); 62f17cfe81SBenoît Canet g_assert(bkt.avg == 150); 63f17cfe81SBenoît Canet g_assert(bkt.max == 15); 64f17cfe81SBenoît Canet g_assert(double_cmp(bkt.level, 0)); 65eb8a1a1cSAlberto Garcia 66eb8a1a1cSAlberto Garcia /* check that burst_level leaks correctly */ 67eb8a1a1cSAlberto Garcia bkt.burst_level = 6; 68eb8a1a1cSAlberto Garcia bkt.max = 250; 69eb8a1a1cSAlberto Garcia bkt.burst_length = 2; /* otherwise burst_level will not leak */ 70eb8a1a1cSAlberto Garcia throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); 71eb8a1a1cSAlberto Garcia g_assert(double_cmp(bkt.burst_level, 3.5)); 72eb8a1a1cSAlberto Garcia 73eb8a1a1cSAlberto Garcia throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); 74eb8a1a1cSAlberto Garcia g_assert(double_cmp(bkt.burst_level, 1)); 75eb8a1a1cSAlberto Garcia 76eb8a1a1cSAlberto Garcia throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); 77eb8a1a1cSAlberto Garcia g_assert(double_cmp(bkt.burst_level, 0)); 78eb8a1a1cSAlberto Garcia 79eb8a1a1cSAlberto Garcia throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100); 80eb8a1a1cSAlberto Garcia g_assert(double_cmp(bkt.burst_level, 0)); 81f17cfe81SBenoît Canet } 82f17cfe81SBenoît Canet 83f17cfe81SBenoît Canet static void test_compute_wait(void) 84f17cfe81SBenoît Canet { 85f9d05885SAlberto Garcia unsigned i; 86f17cfe81SBenoît Canet int64_t wait; 87f17cfe81SBenoît Canet int64_t result; 88f17cfe81SBenoît Canet 891588ab5dSAlberto Garcia throttle_config_init(&cfg); 901588ab5dSAlberto Garcia bkt = cfg.buckets[THROTTLE_BPS_TOTAL]; 911588ab5dSAlberto Garcia 92f17cfe81SBenoît Canet /* no operation limit set */ 93f17cfe81SBenoît Canet bkt.avg = 0; 94f17cfe81SBenoît Canet bkt.max = 15; 95f17cfe81SBenoît Canet bkt.level = 1.5; 96f17cfe81SBenoît Canet wait = throttle_compute_wait(&bkt); 97f17cfe81SBenoît Canet g_assert(!wait); 98f17cfe81SBenoît Canet 99f17cfe81SBenoît Canet /* zero delta */ 100f17cfe81SBenoît Canet bkt.avg = 150; 101f17cfe81SBenoît Canet bkt.max = 15; 102f17cfe81SBenoît Canet bkt.level = 15; 103f17cfe81SBenoît Canet wait = throttle_compute_wait(&bkt); 104f17cfe81SBenoît Canet g_assert(!wait); 105f17cfe81SBenoît Canet 106f17cfe81SBenoît Canet /* below zero delta */ 107f17cfe81SBenoît Canet bkt.avg = 150; 108f17cfe81SBenoît Canet bkt.max = 15; 109f17cfe81SBenoît Canet bkt.level = 9; 110f17cfe81SBenoît Canet wait = throttle_compute_wait(&bkt); 111f17cfe81SBenoît Canet g_assert(!wait); 112f17cfe81SBenoît Canet 113f17cfe81SBenoît Canet /* half an operation above max */ 114f17cfe81SBenoît Canet bkt.avg = 150; 115f17cfe81SBenoît Canet bkt.max = 15; 116f17cfe81SBenoît Canet bkt.level = 15.5; 117f17cfe81SBenoît Canet wait = throttle_compute_wait(&bkt); 118f17cfe81SBenoît Canet /* time required to do half an operation */ 11913566fe3SStefan Hajnoczi result = (int64_t) NANOSECONDS_PER_SECOND / 150 / 2; 120f17cfe81SBenoît Canet g_assert(wait == result); 121f9d05885SAlberto Garcia 122f9d05885SAlberto Garcia /* Perform I/O for 2.2 seconds at a rate of bkt.max */ 123f9d05885SAlberto Garcia bkt.burst_length = 2; 124f9d05885SAlberto Garcia bkt.level = 0; 125f9d05885SAlberto Garcia bkt.avg = 10; 126f9d05885SAlberto Garcia bkt.max = 200; 127f9d05885SAlberto Garcia for (i = 0; i < 22; i++) { 128f9d05885SAlberto Garcia double units = bkt.max / 10; 129f9d05885SAlberto Garcia bkt.level += units; 130f9d05885SAlberto Garcia bkt.burst_level += units; 131f9d05885SAlberto Garcia throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 10); 132f9d05885SAlberto Garcia wait = throttle_compute_wait(&bkt); 133f9d05885SAlberto Garcia g_assert(double_cmp(bkt.burst_level, 0)); 134f9d05885SAlberto Garcia g_assert(double_cmp(bkt.level, (i + 1) * (bkt.max - bkt.avg) / 10)); 135f9d05885SAlberto Garcia /* We can do bursts for the 2 seconds we have configured in 136f9d05885SAlberto Garcia * burst_length. We have 100 extra miliseconds of burst 137f9d05885SAlberto Garcia * because bkt.level has been leaking during this time. 138f9d05885SAlberto Garcia * After that, we have to wait. */ 139f9d05885SAlberto Garcia result = i < 21 ? 0 : 1.8 * NANOSECONDS_PER_SECOND; 140f9d05885SAlberto Garcia g_assert(wait == result); 141f9d05885SAlberto Garcia } 142f17cfe81SBenoît Canet } 143f17cfe81SBenoît Canet 144f17cfe81SBenoît Canet /* functions to test ThrottleState initialization/destroy methods */ 145f17cfe81SBenoît Canet static void read_timer_cb(void *opaque) 146f17cfe81SBenoît Canet { 147f17cfe81SBenoît Canet } 148f17cfe81SBenoît Canet 149f17cfe81SBenoît Canet static void write_timer_cb(void *opaque) 150f17cfe81SBenoît Canet { 151f17cfe81SBenoît Canet } 152f17cfe81SBenoît Canet 153f17cfe81SBenoît Canet static void test_init(void) 154f17cfe81SBenoît Canet { 155f17cfe81SBenoît Canet int i; 156f17cfe81SBenoît Canet 157c61791fcSManos Pitsidianakis tt = &tgm.throttle_timers; 158c61791fcSManos Pitsidianakis 1590e5b0a2dSBenoît Canet /* fill the structures with crap */ 160f17cfe81SBenoît Canet memset(&ts, 1, sizeof(ts)); 161c61791fcSManos Pitsidianakis memset(tt, 1, sizeof(*tt)); 162f17cfe81SBenoît Canet 1630e5b0a2dSBenoît Canet /* init structures */ 1640e5b0a2dSBenoît Canet throttle_init(&ts); 165c61791fcSManos Pitsidianakis throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL, 16613af91ebSStefan Hajnoczi read_timer_cb, write_timer_cb, &ts); 167f17cfe81SBenoît Canet 168f17cfe81SBenoît Canet /* check initialized fields */ 169c61791fcSManos Pitsidianakis g_assert(tt->clock_type == QEMU_CLOCK_VIRTUAL); 170c61791fcSManos Pitsidianakis g_assert(tt->timers[0]); 171c61791fcSManos Pitsidianakis g_assert(tt->timers[1]); 172f17cfe81SBenoît Canet 173f17cfe81SBenoît Canet /* check other fields where cleared */ 174f17cfe81SBenoît Canet g_assert(!ts.previous_leak); 175f17cfe81SBenoît Canet g_assert(!ts.cfg.op_size); 176f17cfe81SBenoît Canet for (i = 0; i < BUCKETS_COUNT; i++) { 177f17cfe81SBenoît Canet g_assert(!ts.cfg.buckets[i].avg); 178f17cfe81SBenoît Canet g_assert(!ts.cfg.buckets[i].max); 179f17cfe81SBenoît Canet g_assert(!ts.cfg.buckets[i].level); 180f17cfe81SBenoît Canet } 181f17cfe81SBenoît Canet 182c61791fcSManos Pitsidianakis throttle_timers_destroy(tt); 183f17cfe81SBenoît Canet } 184f17cfe81SBenoît Canet 185f17cfe81SBenoît Canet static void test_destroy(void) 186f17cfe81SBenoît Canet { 187f17cfe81SBenoît Canet int i; 1880e5b0a2dSBenoît Canet throttle_init(&ts); 189c61791fcSManos Pitsidianakis throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL, 19013af91ebSStefan Hajnoczi read_timer_cb, write_timer_cb, &ts); 191c61791fcSManos Pitsidianakis throttle_timers_destroy(tt); 192f17cfe81SBenoît Canet for (i = 0; i < 2; i++) { 193c61791fcSManos Pitsidianakis g_assert(!tt->timers[i]); 194f17cfe81SBenoît Canet } 195f17cfe81SBenoît Canet } 196f17cfe81SBenoît Canet 197f17cfe81SBenoît Canet /* function to test throttle_config and throttle_get_config */ 198f17cfe81SBenoît Canet static void test_config_functions(void) 199f17cfe81SBenoît Canet { 200f17cfe81SBenoît Canet int i; 201f17cfe81SBenoît Canet ThrottleConfig orig_cfg, final_cfg; 202f17cfe81SBenoît Canet 203f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_BPS_TOTAL].avg = 153; 204f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_BPS_READ].avg = 56; 205f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_BPS_WRITE].avg = 1; 206f17cfe81SBenoît Canet 207f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_TOTAL].avg = 150; 208f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_READ].avg = 69; 209f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_WRITE].avg = 23; 210f17cfe81SBenoît Canet 211d72915c6SStefan Hajnoczi orig_cfg.buckets[THROTTLE_BPS_TOTAL].max = 0; 212d72915c6SStefan Hajnoczi orig_cfg.buckets[THROTTLE_BPS_READ].max = 56; 213f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_BPS_WRITE].max = 120; 214f17cfe81SBenoît Canet 215f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_TOTAL].max = 150; 216f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_READ].max = 400; 217f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_WRITE].max = 500; 218f17cfe81SBenoît Canet 219f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_BPS_TOTAL].level = 45; 220f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_BPS_READ].level = 65; 221f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_BPS_WRITE].level = 23; 222f17cfe81SBenoît Canet 223f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_TOTAL].level = 1; 224f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_READ].level = 90; 225f17cfe81SBenoît Canet orig_cfg.buckets[THROTTLE_OPS_WRITE].level = 75; 226f17cfe81SBenoît Canet 227f17cfe81SBenoît Canet orig_cfg.op_size = 1; 228f17cfe81SBenoît Canet 2290e5b0a2dSBenoît Canet throttle_init(&ts); 230c61791fcSManos Pitsidianakis throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL, 23113af91ebSStefan Hajnoczi read_timer_cb, write_timer_cb, &ts); 232f17cfe81SBenoît Canet /* structure reset by throttle_init previous_leak should be null */ 233f17cfe81SBenoît Canet g_assert(!ts.previous_leak); 23427e4cf13SManos Pitsidianakis throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &orig_cfg); 235f17cfe81SBenoît Canet 236f17cfe81SBenoît Canet /* has previous leak been initialized by throttle_config ? */ 237f17cfe81SBenoît Canet g_assert(ts.previous_leak); 238f17cfe81SBenoît Canet 239f17cfe81SBenoît Canet /* get back the fixed configuration */ 240f17cfe81SBenoît Canet throttle_get_config(&ts, &final_cfg); 241f17cfe81SBenoît Canet 242c61791fcSManos Pitsidianakis throttle_timers_destroy(tt); 243f17cfe81SBenoît Canet 244f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_BPS_TOTAL].avg == 153); 245f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_BPS_READ].avg == 56); 246f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_BPS_WRITE].avg == 1); 247f17cfe81SBenoît Canet 248f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_OPS_TOTAL].avg == 150); 249f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_OPS_READ].avg == 69); 250f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_OPS_WRITE].avg == 23); 251f17cfe81SBenoît Canet 252d72915c6SStefan Hajnoczi g_assert(final_cfg.buckets[THROTTLE_BPS_TOTAL].max == 0); 253d72915c6SStefan Hajnoczi g_assert(final_cfg.buckets[THROTTLE_BPS_READ].max == 56); 254f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_BPS_WRITE].max == 120); 255f17cfe81SBenoît Canet 256f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_OPS_TOTAL].max == 150); 257f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_OPS_READ].max == 400); 258f17cfe81SBenoît Canet g_assert(final_cfg.buckets[THROTTLE_OPS_WRITE].max == 500); 259f17cfe81SBenoît Canet 260f17cfe81SBenoît Canet g_assert(final_cfg.op_size == 1); 261f17cfe81SBenoît Canet 262f17cfe81SBenoît Canet /* check bucket have been cleared */ 263f17cfe81SBenoît Canet for (i = 0; i < BUCKETS_COUNT; i++) { 264f17cfe81SBenoît Canet g_assert(!final_cfg.buckets[i].level); 265f17cfe81SBenoît Canet } 266f17cfe81SBenoît Canet } 267f17cfe81SBenoît Canet 268f17cfe81SBenoît Canet /* functions to test is throttle is enabled by a config */ 269f17cfe81SBenoît Canet static void set_cfg_value(bool is_max, int index, int value) 270f17cfe81SBenoît Canet { 271f17cfe81SBenoît Canet if (is_max) { 272f17cfe81SBenoît Canet cfg.buckets[index].max = value; 2736f9b6d57SAlberto Garcia /* If max is set, avg should never be 0 */ 2746f9b6d57SAlberto Garcia cfg.buckets[index].avg = MAX(cfg.buckets[index].avg, 1); 275f17cfe81SBenoît Canet } else { 276f17cfe81SBenoît Canet cfg.buckets[index].avg = value; 277f17cfe81SBenoît Canet } 278f17cfe81SBenoît Canet } 279f17cfe81SBenoît Canet 280f17cfe81SBenoît Canet static void test_enabled(void) 281f17cfe81SBenoît Canet { 282f17cfe81SBenoît Canet int i; 283f17cfe81SBenoît Canet 2841588ab5dSAlberto Garcia throttle_config_init(&cfg); 285f17cfe81SBenoît Canet g_assert(!throttle_enabled(&cfg)); 286f17cfe81SBenoît Canet 287f17cfe81SBenoît Canet for (i = 0; i < BUCKETS_COUNT; i++) { 2881588ab5dSAlberto Garcia throttle_config_init(&cfg); 289f17cfe81SBenoît Canet set_cfg_value(false, i, 150); 290d00e6923SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 291f17cfe81SBenoît Canet g_assert(throttle_enabled(&cfg)); 292f17cfe81SBenoît Canet } 293f17cfe81SBenoît Canet 294f17cfe81SBenoît Canet for (i = 0; i < BUCKETS_COUNT; i++) { 2951588ab5dSAlberto Garcia throttle_config_init(&cfg); 296f17cfe81SBenoît Canet set_cfg_value(false, i, -150); 297d00e6923SAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 298f17cfe81SBenoît Canet } 299f17cfe81SBenoît Canet } 300f17cfe81SBenoît Canet 301f17cfe81SBenoît Canet /* tests functions for throttle_conflicting */ 302f17cfe81SBenoît Canet 303f17cfe81SBenoît Canet static void test_conflicts_for_one_set(bool is_max, 304f17cfe81SBenoît Canet int total, 305f17cfe81SBenoît Canet int read, 306f17cfe81SBenoît Canet int write) 307f17cfe81SBenoît Canet { 3081588ab5dSAlberto Garcia throttle_config_init(&cfg); 309d5851089SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 310f17cfe81SBenoît Canet 311f17cfe81SBenoît Canet set_cfg_value(is_max, total, 1); 312f17cfe81SBenoît Canet set_cfg_value(is_max, read, 1); 313d5851089SAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 314f17cfe81SBenoît Canet 3151588ab5dSAlberto Garcia throttle_config_init(&cfg); 316f17cfe81SBenoît Canet set_cfg_value(is_max, total, 1); 317f17cfe81SBenoît Canet set_cfg_value(is_max, write, 1); 318d5851089SAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 319f17cfe81SBenoît Canet 3201588ab5dSAlberto Garcia throttle_config_init(&cfg); 321f17cfe81SBenoît Canet set_cfg_value(is_max, total, 1); 322f17cfe81SBenoît Canet set_cfg_value(is_max, read, 1); 323f17cfe81SBenoît Canet set_cfg_value(is_max, write, 1); 324d5851089SAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 325f17cfe81SBenoît Canet 3261588ab5dSAlberto Garcia throttle_config_init(&cfg); 327f17cfe81SBenoît Canet set_cfg_value(is_max, total, 1); 328d5851089SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 329f17cfe81SBenoît Canet 3301588ab5dSAlberto Garcia throttle_config_init(&cfg); 331f17cfe81SBenoît Canet set_cfg_value(is_max, read, 1); 332f17cfe81SBenoît Canet set_cfg_value(is_max, write, 1); 333d5851089SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 334f17cfe81SBenoît Canet } 335f17cfe81SBenoît Canet 336f17cfe81SBenoît Canet static void test_conflicting_config(void) 337f17cfe81SBenoît Canet { 338f17cfe81SBenoît Canet /* bps average conflicts */ 339f17cfe81SBenoît Canet test_conflicts_for_one_set(false, 340f17cfe81SBenoît Canet THROTTLE_BPS_TOTAL, 341f17cfe81SBenoît Canet THROTTLE_BPS_READ, 342f17cfe81SBenoît Canet THROTTLE_BPS_WRITE); 343f17cfe81SBenoît Canet 344f17cfe81SBenoît Canet /* ops average conflicts */ 345f17cfe81SBenoît Canet test_conflicts_for_one_set(false, 346f17cfe81SBenoît Canet THROTTLE_OPS_TOTAL, 347f17cfe81SBenoît Canet THROTTLE_OPS_READ, 348f17cfe81SBenoît Canet THROTTLE_OPS_WRITE); 349f17cfe81SBenoît Canet 350f17cfe81SBenoît Canet /* bps average conflicts */ 351f17cfe81SBenoît Canet test_conflicts_for_one_set(true, 352f17cfe81SBenoît Canet THROTTLE_BPS_TOTAL, 353f17cfe81SBenoît Canet THROTTLE_BPS_READ, 354f17cfe81SBenoît Canet THROTTLE_BPS_WRITE); 355f17cfe81SBenoît Canet /* ops average conflicts */ 356f17cfe81SBenoît Canet test_conflicts_for_one_set(true, 357f17cfe81SBenoît Canet THROTTLE_OPS_TOTAL, 358f17cfe81SBenoît Canet THROTTLE_OPS_READ, 359f17cfe81SBenoît Canet THROTTLE_OPS_WRITE); 360f17cfe81SBenoît Canet } 361f17cfe81SBenoît Canet /* functions to test the throttle_is_valid function */ 362f17cfe81SBenoît Canet static void test_is_valid_for_value(int value, bool should_be_valid) 363f17cfe81SBenoît Canet { 364f17cfe81SBenoît Canet int is_max, index; 365f17cfe81SBenoît Canet for (is_max = 0; is_max < 2; is_max++) { 366f17cfe81SBenoît Canet for (index = 0; index < BUCKETS_COUNT; index++) { 3671588ab5dSAlberto Garcia throttle_config_init(&cfg); 368f17cfe81SBenoît Canet set_cfg_value(is_max, index, value); 36903ba36c8SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL) == should_be_valid); 370f17cfe81SBenoît Canet } 371f17cfe81SBenoît Canet } 372f17cfe81SBenoît Canet } 373f17cfe81SBenoît Canet 374f17cfe81SBenoît Canet static void test_is_valid(void) 375f17cfe81SBenoît Canet { 376f17cfe81SBenoît Canet /* negative number are invalid */ 377f17cfe81SBenoît Canet test_is_valid_for_value(-1, false); 378f17cfe81SBenoît Canet /* zero are valids */ 379f17cfe81SBenoît Canet test_is_valid_for_value(0, true); 380f17cfe81SBenoît Canet /* positives numers are valids */ 381f17cfe81SBenoît Canet test_is_valid_for_value(1, true); 382f17cfe81SBenoît Canet } 383f17cfe81SBenoît Canet 384d942feecSAlberto Garcia static void test_ranges(void) 385d942feecSAlberto Garcia { 386d942feecSAlberto Garcia int i; 387d942feecSAlberto Garcia 388d942feecSAlberto Garcia for (i = 0; i < BUCKETS_COUNT; i++) { 389d942feecSAlberto Garcia LeakyBucket *b = &cfg.buckets[i]; 390d942feecSAlberto Garcia throttle_config_init(&cfg); 391d942feecSAlberto Garcia 392d942feecSAlberto Garcia /* avg = 0 means throttling is disabled, but the config is valid */ 393d942feecSAlberto Garcia b->avg = 0; 394d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 395d942feecSAlberto Garcia g_assert(!throttle_enabled(&cfg)); 396d942feecSAlberto Garcia 397d942feecSAlberto Garcia /* These are valid configurations (values <= THROTTLE_VALUE_MAX) */ 398d942feecSAlberto Garcia b->avg = 1; 399d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 400d942feecSAlberto Garcia 401d942feecSAlberto Garcia b->avg = THROTTLE_VALUE_MAX; 402d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 403d942feecSAlberto Garcia 404d942feecSAlberto Garcia b->avg = THROTTLE_VALUE_MAX; 405d942feecSAlberto Garcia b->max = THROTTLE_VALUE_MAX; 406d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 407d942feecSAlberto Garcia 408d942feecSAlberto Garcia /* Values over THROTTLE_VALUE_MAX are not allowed */ 409d942feecSAlberto Garcia b->avg = THROTTLE_VALUE_MAX + 1; 410d942feecSAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 411d942feecSAlberto Garcia 412d942feecSAlberto Garcia b->avg = THROTTLE_VALUE_MAX; 413d942feecSAlberto Garcia b->max = THROTTLE_VALUE_MAX + 1; 414d942feecSAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 415d942feecSAlberto Garcia 416d942feecSAlberto Garcia /* burst_length must be between 1 and THROTTLE_VALUE_MAX */ 417d942feecSAlberto Garcia b->avg = 1; 418d942feecSAlberto Garcia b->max = 1; 419d942feecSAlberto Garcia b->burst_length = 0; 420d942feecSAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 421d942feecSAlberto Garcia 422d942feecSAlberto Garcia b->avg = 1; 423d942feecSAlberto Garcia b->max = 1; 424d942feecSAlberto Garcia b->burst_length = 1; 425d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 426d942feecSAlberto Garcia 427d942feecSAlberto Garcia b->avg = 1; 428d942feecSAlberto Garcia b->max = 1; 429d942feecSAlberto Garcia b->burst_length = THROTTLE_VALUE_MAX; 430d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 431d942feecSAlberto Garcia 432d942feecSAlberto Garcia b->avg = 1; 433d942feecSAlberto Garcia b->max = 1; 434d942feecSAlberto Garcia b->burst_length = THROTTLE_VALUE_MAX + 1; 435d942feecSAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 436d942feecSAlberto Garcia 437d942feecSAlberto Garcia /* burst_length * max cannot exceed THROTTLE_VALUE_MAX */ 438d942feecSAlberto Garcia b->avg = 1; 439d942feecSAlberto Garcia b->max = 2; 440d942feecSAlberto Garcia b->burst_length = THROTTLE_VALUE_MAX / 2; 441d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 442d942feecSAlberto Garcia 443d942feecSAlberto Garcia b->avg = 1; 444d942feecSAlberto Garcia b->max = 3; 445d942feecSAlberto Garcia b->burst_length = THROTTLE_VALUE_MAX / 2; 446d942feecSAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 447d942feecSAlberto Garcia 448d942feecSAlberto Garcia b->avg = 1; 449d942feecSAlberto Garcia b->max = THROTTLE_VALUE_MAX; 450d942feecSAlberto Garcia b->burst_length = 1; 451d942feecSAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 452d942feecSAlberto Garcia 453d942feecSAlberto Garcia b->avg = 1; 454d942feecSAlberto Garcia b->max = THROTTLE_VALUE_MAX; 455d942feecSAlberto Garcia b->burst_length = 2; 456d942feecSAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 457d942feecSAlberto Garcia } 458d942feecSAlberto Garcia } 459d942feecSAlberto Garcia 46092e11a17SStefan Hajnoczi static void test_max_is_missing_limit(void) 46192e11a17SStefan Hajnoczi { 46292e11a17SStefan Hajnoczi int i; 46392e11a17SStefan Hajnoczi 46492e11a17SStefan Hajnoczi for (i = 0; i < BUCKETS_COUNT; i++) { 4651588ab5dSAlberto Garcia throttle_config_init(&cfg); 46692e11a17SStefan Hajnoczi cfg.buckets[i].max = 100; 46792e11a17SStefan Hajnoczi cfg.buckets[i].avg = 0; 468d5851089SAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 46992e11a17SStefan Hajnoczi 47092e11a17SStefan Hajnoczi cfg.buckets[i].max = 0; 47192e11a17SStefan Hajnoczi cfg.buckets[i].avg = 0; 472d5851089SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 47392e11a17SStefan Hajnoczi 47492e11a17SStefan Hajnoczi cfg.buckets[i].max = 0; 47592e11a17SStefan Hajnoczi cfg.buckets[i].avg = 100; 476d5851089SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 4775fc8c052SAlberto Garcia 4785fc8c052SAlberto Garcia cfg.buckets[i].max = 30; 4795fc8c052SAlberto Garcia cfg.buckets[i].avg = 100; 4805fc8c052SAlberto Garcia g_assert(!throttle_is_valid(&cfg, NULL)); 4815fc8c052SAlberto Garcia 4825fc8c052SAlberto Garcia cfg.buckets[i].max = 100; 4835fc8c052SAlberto Garcia cfg.buckets[i].avg = 100; 4845fc8c052SAlberto Garcia g_assert(throttle_is_valid(&cfg, NULL)); 48592e11a17SStefan Hajnoczi } 48692e11a17SStefan Hajnoczi } 48792e11a17SStefan Hajnoczi 4888860eabdSStefan Hajnoczi static void test_iops_size_is_missing_limit(void) 4898860eabdSStefan Hajnoczi { 4908860eabdSStefan Hajnoczi /* A total/read/write iops limit is required */ 4918860eabdSStefan Hajnoczi throttle_config_init(&cfg); 4928860eabdSStefan Hajnoczi cfg.op_size = 4096; 4938860eabdSStefan Hajnoczi g_assert(!throttle_is_valid(&cfg, NULL)); 4948860eabdSStefan Hajnoczi } 4958860eabdSStefan Hajnoczi 496f17cfe81SBenoît Canet static void test_have_timer(void) 497f17cfe81SBenoît Canet { 4980e5b0a2dSBenoît Canet /* zero structures */ 499f17cfe81SBenoît Canet memset(&ts, 0, sizeof(ts)); 500c61791fcSManos Pitsidianakis memset(tt, 0, sizeof(*tt)); 501f17cfe81SBenoît Canet 50273f395faSStefan Weil /* no timer set should return false */ 503c61791fcSManos Pitsidianakis g_assert(!throttle_timers_are_initialized(tt)); 504f17cfe81SBenoît Canet 5050e5b0a2dSBenoît Canet /* init structures */ 5060e5b0a2dSBenoît Canet throttle_init(&ts); 507c61791fcSManos Pitsidianakis throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL, 50813af91ebSStefan Hajnoczi read_timer_cb, write_timer_cb, &ts); 509f17cfe81SBenoît Canet 510f17cfe81SBenoît Canet /* timer set by init should return true */ 511c61791fcSManos Pitsidianakis g_assert(throttle_timers_are_initialized(tt)); 512f17cfe81SBenoît Canet 513c61791fcSManos Pitsidianakis throttle_timers_destroy(tt); 514f17cfe81SBenoît Canet } 515f17cfe81SBenoît Canet 51622524f72SStefan Hajnoczi static void test_detach_attach(void) 51722524f72SStefan Hajnoczi { 5180e5b0a2dSBenoît Canet /* zero structures */ 51922524f72SStefan Hajnoczi memset(&ts, 0, sizeof(ts)); 520c61791fcSManos Pitsidianakis memset(tt, 0, sizeof(*tt)); 52122524f72SStefan Hajnoczi 52222524f72SStefan Hajnoczi /* init the structure */ 5230e5b0a2dSBenoît Canet throttle_init(&ts); 524c61791fcSManos Pitsidianakis throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL, 52522524f72SStefan Hajnoczi read_timer_cb, write_timer_cb, &ts); 52622524f72SStefan Hajnoczi 52722524f72SStefan Hajnoczi /* timer set by init should return true */ 528c61791fcSManos Pitsidianakis g_assert(throttle_timers_are_initialized(tt)); 52922524f72SStefan Hajnoczi 53022524f72SStefan Hajnoczi /* timer should no longer exist after detaching */ 531c61791fcSManos Pitsidianakis throttle_timers_detach_aio_context(tt); 532c61791fcSManos Pitsidianakis g_assert(!throttle_timers_are_initialized(tt)); 53322524f72SStefan Hajnoczi 53422524f72SStefan Hajnoczi /* timer should exist again after attaching */ 535c61791fcSManos Pitsidianakis throttle_timers_attach_aio_context(tt, ctx); 536c61791fcSManos Pitsidianakis g_assert(throttle_timers_are_initialized(tt)); 53722524f72SStefan Hajnoczi 538c61791fcSManos Pitsidianakis throttle_timers_destroy(tt); 53922524f72SStefan Hajnoczi } 54022524f72SStefan Hajnoczi 541f17cfe81SBenoît Canet static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */ 542f17cfe81SBenoît Canet int size, /* size of the operation to do */ 543f17cfe81SBenoît Canet double avg, /* io limit */ 544f17cfe81SBenoît Canet uint64_t op_size, /* ideal size of an io */ 545f17cfe81SBenoît Canet double total_result, 546f17cfe81SBenoît Canet double read_result, 547f17cfe81SBenoît Canet double write_result) 548f17cfe81SBenoît Canet { 549f17cfe81SBenoît Canet BucketType to_test[2][3] = { { THROTTLE_BPS_TOTAL, 550f17cfe81SBenoît Canet THROTTLE_BPS_READ, 551f17cfe81SBenoît Canet THROTTLE_BPS_WRITE, }, 552f17cfe81SBenoît Canet { THROTTLE_OPS_TOTAL, 553f17cfe81SBenoît Canet THROTTLE_OPS_READ, 554f17cfe81SBenoît Canet THROTTLE_OPS_WRITE, } }; 555f17cfe81SBenoît Canet ThrottleConfig cfg; 556f17cfe81SBenoît Canet BucketType index; 557f17cfe81SBenoît Canet int i; 558f17cfe81SBenoît Canet 559f17cfe81SBenoît Canet for (i = 0; i < 3; i++) { 560f17cfe81SBenoît Canet BucketType index = to_test[is_ops][i]; 561f17cfe81SBenoît Canet cfg.buckets[index].avg = avg; 562f17cfe81SBenoît Canet } 563f17cfe81SBenoît Canet 564f17cfe81SBenoît Canet cfg.op_size = op_size; 565f17cfe81SBenoît Canet 5660e5b0a2dSBenoît Canet throttle_init(&ts); 567c61791fcSManos Pitsidianakis throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL, 56813af91ebSStefan Hajnoczi read_timer_cb, write_timer_cb, &ts); 56927e4cf13SManos Pitsidianakis throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &cfg); 570f17cfe81SBenoît Canet 571f17cfe81SBenoît Canet /* account a read */ 572f17cfe81SBenoît Canet throttle_account(&ts, false, size); 573f17cfe81SBenoît Canet /* account a write */ 574f17cfe81SBenoît Canet throttle_account(&ts, true, size); 575f17cfe81SBenoît Canet 576f17cfe81SBenoît Canet /* check total result */ 577f17cfe81SBenoît Canet index = to_test[is_ops][0]; 578f17cfe81SBenoît Canet if (!double_cmp(ts.cfg.buckets[index].level, total_result)) { 579f17cfe81SBenoît Canet return false; 580f17cfe81SBenoît Canet } 581f17cfe81SBenoît Canet 582f17cfe81SBenoît Canet /* check read result */ 583f17cfe81SBenoît Canet index = to_test[is_ops][1]; 584f17cfe81SBenoît Canet if (!double_cmp(ts.cfg.buckets[index].level, read_result)) { 585f17cfe81SBenoît Canet return false; 586f17cfe81SBenoît Canet } 587f17cfe81SBenoît Canet 588f17cfe81SBenoît Canet /* check write result */ 589f17cfe81SBenoît Canet index = to_test[is_ops][2]; 590f17cfe81SBenoît Canet if (!double_cmp(ts.cfg.buckets[index].level, write_result)) { 591f17cfe81SBenoît Canet return false; 592f17cfe81SBenoît Canet } 593f17cfe81SBenoît Canet 594c61791fcSManos Pitsidianakis throttle_timers_destroy(tt); 595f17cfe81SBenoît Canet 596f17cfe81SBenoît Canet return true; 597f17cfe81SBenoît Canet } 598f17cfe81SBenoît Canet 599f17cfe81SBenoît Canet static void test_accounting(void) 600f17cfe81SBenoît Canet { 601f17cfe81SBenoît Canet /* tests for bps */ 602f17cfe81SBenoît Canet 603f17cfe81SBenoît Canet /* op of size 1 */ 604f17cfe81SBenoît Canet g_assert(do_test_accounting(false, 605f17cfe81SBenoît Canet 1 * 512, 606f17cfe81SBenoît Canet 150, 607f17cfe81SBenoît Canet 0, 608f17cfe81SBenoît Canet 1024, 609f17cfe81SBenoît Canet 512, 610f17cfe81SBenoît Canet 512)); 611f17cfe81SBenoît Canet 612f17cfe81SBenoît Canet /* op of size 2 */ 613f17cfe81SBenoît Canet g_assert(do_test_accounting(false, 614f17cfe81SBenoît Canet 2 * 512, 615f17cfe81SBenoît Canet 150, 616f17cfe81SBenoît Canet 0, 617f17cfe81SBenoît Canet 2048, 618f17cfe81SBenoît Canet 1024, 619f17cfe81SBenoît Canet 1024)); 620f17cfe81SBenoît Canet 621f17cfe81SBenoît Canet /* op of size 2 and orthogonal parameter change */ 622f17cfe81SBenoît Canet g_assert(do_test_accounting(false, 623f17cfe81SBenoît Canet 2 * 512, 624f17cfe81SBenoît Canet 150, 625f17cfe81SBenoît Canet 17, 626f17cfe81SBenoît Canet 2048, 627f17cfe81SBenoît Canet 1024, 628f17cfe81SBenoît Canet 1024)); 629f17cfe81SBenoît Canet 630f17cfe81SBenoît Canet 631f17cfe81SBenoît Canet /* tests for ops */ 632f17cfe81SBenoît Canet 633f17cfe81SBenoît Canet /* op of size 1 */ 634f17cfe81SBenoît Canet g_assert(do_test_accounting(true, 635f17cfe81SBenoît Canet 1 * 512, 636f17cfe81SBenoît Canet 150, 637f17cfe81SBenoît Canet 0, 638f17cfe81SBenoît Canet 2, 639f17cfe81SBenoît Canet 1, 640f17cfe81SBenoît Canet 1)); 641f17cfe81SBenoît Canet 642f17cfe81SBenoît Canet /* op of size 2 */ 643f17cfe81SBenoît Canet g_assert(do_test_accounting(true, 644f17cfe81SBenoît Canet 2 * 512, 645f17cfe81SBenoît Canet 150, 646f17cfe81SBenoît Canet 0, 647f17cfe81SBenoît Canet 2, 648f17cfe81SBenoît Canet 1, 649f17cfe81SBenoît Canet 1)); 650f17cfe81SBenoît Canet 651f17cfe81SBenoît Canet /* jumbo op accounting fragmentation : size 64 with op size of 13 units */ 652f17cfe81SBenoît Canet g_assert(do_test_accounting(true, 653f17cfe81SBenoît Canet 64 * 512, 654f17cfe81SBenoît Canet 150, 655f17cfe81SBenoît Canet 13 * 512, 656f17cfe81SBenoît Canet (64.0 * 2) / 13, 657f17cfe81SBenoît Canet (64.0 / 13), 658f17cfe81SBenoît Canet (64.0 / 13))); 659f17cfe81SBenoît Canet 660f17cfe81SBenoît Canet /* same with orthogonal parameters changes */ 661f17cfe81SBenoît Canet g_assert(do_test_accounting(true, 662f17cfe81SBenoît Canet 64 * 512, 663f17cfe81SBenoît Canet 300, 664f17cfe81SBenoît Canet 13 * 512, 665f17cfe81SBenoît Canet (64.0 * 2) / 13, 666f17cfe81SBenoît Canet (64.0 / 13), 667f17cfe81SBenoît Canet (64.0 / 13))); 668f17cfe81SBenoît Canet } 669f17cfe81SBenoît Canet 6701fee955fSAlberto Garcia static void test_groups(void) 6711fee955fSAlberto Garcia { 6721fee955fSAlberto Garcia ThrottleConfig cfg1, cfg2; 673a5614993SKevin Wolf BlockBackend *blk1, *blk2, *blk3; 67427ccdd52SKevin Wolf BlockBackendPublic *blkp1, *blkp2, *blkp3; 675022cdc9fSManos Pitsidianakis ThrottleGroupMember *tgm1, *tgm2, *tgm3; 6761fee955fSAlberto Garcia 6772807c0cdSKevin Wolf /* No actual I/O is performed on these devices */ 678*d861ab3aSKevin Wolf blk1 = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); 679*d861ab3aSKevin Wolf blk2 = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); 680*d861ab3aSKevin Wolf blk3 = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL); 681a5614993SKevin Wolf 68227ccdd52SKevin Wolf blkp1 = blk_get_public(blk1); 68327ccdd52SKevin Wolf blkp2 = blk_get_public(blk2); 68427ccdd52SKevin Wolf blkp3 = blk_get_public(blk3); 68527ccdd52SKevin Wolf 686022cdc9fSManos Pitsidianakis tgm1 = &blkp1->throttle_group_member; 687022cdc9fSManos Pitsidianakis tgm2 = &blkp2->throttle_group_member; 688022cdc9fSManos Pitsidianakis tgm3 = &blkp3->throttle_group_member; 6891fee955fSAlberto Garcia 690022cdc9fSManos Pitsidianakis g_assert(tgm1->throttle_state == NULL); 691022cdc9fSManos Pitsidianakis g_assert(tgm2->throttle_state == NULL); 692022cdc9fSManos Pitsidianakis g_assert(tgm3->throttle_state == NULL); 6931fee955fSAlberto Garcia 694c61791fcSManos Pitsidianakis throttle_group_register_tgm(tgm1, "bar", blk_get_aio_context(blk1)); 695c61791fcSManos Pitsidianakis throttle_group_register_tgm(tgm2, "foo", blk_get_aio_context(blk2)); 696c61791fcSManos Pitsidianakis throttle_group_register_tgm(tgm3, "bar", blk_get_aio_context(blk3)); 6971fee955fSAlberto Garcia 698022cdc9fSManos Pitsidianakis g_assert(tgm1->throttle_state != NULL); 699022cdc9fSManos Pitsidianakis g_assert(tgm2->throttle_state != NULL); 700022cdc9fSManos Pitsidianakis g_assert(tgm3->throttle_state != NULL); 701022cdc9fSManos Pitsidianakis 702022cdc9fSManos Pitsidianakis g_assert(!strcmp(throttle_group_get_name(tgm1), "bar")); 703022cdc9fSManos Pitsidianakis g_assert(!strcmp(throttle_group_get_name(tgm2), "foo")); 704022cdc9fSManos Pitsidianakis g_assert(tgm1->throttle_state == tgm3->throttle_state); 7051fee955fSAlberto Garcia 7061fee955fSAlberto Garcia /* Setting the config of a group member affects the whole group */ 7071588ab5dSAlberto Garcia throttle_config_init(&cfg1); 7081fee955fSAlberto Garcia cfg1.buckets[THROTTLE_BPS_READ].avg = 500000; 7091fee955fSAlberto Garcia cfg1.buckets[THROTTLE_BPS_WRITE].avg = 285000; 7101fee955fSAlberto Garcia cfg1.buckets[THROTTLE_OPS_READ].avg = 20000; 7111fee955fSAlberto Garcia cfg1.buckets[THROTTLE_OPS_WRITE].avg = 12000; 712022cdc9fSManos Pitsidianakis throttle_group_config(tgm1, &cfg1); 7131fee955fSAlberto Garcia 714022cdc9fSManos Pitsidianakis throttle_group_get_config(tgm1, &cfg1); 715022cdc9fSManos Pitsidianakis throttle_group_get_config(tgm3, &cfg2); 7161fee955fSAlberto Garcia g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1))); 7171fee955fSAlberto Garcia 7181fee955fSAlberto Garcia cfg2.buckets[THROTTLE_BPS_READ].avg = 4547; 7191fee955fSAlberto Garcia cfg2.buckets[THROTTLE_BPS_WRITE].avg = 1349; 7201fee955fSAlberto Garcia cfg2.buckets[THROTTLE_OPS_READ].avg = 123; 7211fee955fSAlberto Garcia cfg2.buckets[THROTTLE_OPS_WRITE].avg = 86; 722022cdc9fSManos Pitsidianakis throttle_group_config(tgm3, &cfg1); 7231fee955fSAlberto Garcia 724022cdc9fSManos Pitsidianakis throttle_group_get_config(tgm1, &cfg1); 725022cdc9fSManos Pitsidianakis throttle_group_get_config(tgm3, &cfg2); 7261fee955fSAlberto Garcia g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1))); 7271fee955fSAlberto Garcia 728022cdc9fSManos Pitsidianakis throttle_group_unregister_tgm(tgm1); 729022cdc9fSManos Pitsidianakis throttle_group_unregister_tgm(tgm2); 730022cdc9fSManos Pitsidianakis throttle_group_unregister_tgm(tgm3); 7311fee955fSAlberto Garcia 732022cdc9fSManos Pitsidianakis g_assert(tgm1->throttle_state == NULL); 733022cdc9fSManos Pitsidianakis g_assert(tgm2->throttle_state == NULL); 734022cdc9fSManos Pitsidianakis g_assert(tgm3->throttle_state == NULL); 7351fee955fSAlberto Garcia } 7361fee955fSAlberto Garcia 737f17cfe81SBenoît Canet int main(int argc, char **argv) 738f17cfe81SBenoît Canet { 73973eaa047SMarkus Armbruster qemu_init_main_loop(&error_fatal); 7401fee955fSAlberto Garcia ctx = qemu_get_aio_context(); 7411fee955fSAlberto Garcia bdrv_init(); 742432d889eSManos Pitsidianakis module_call_init(MODULE_INIT_QOM); 74313af91ebSStefan Hajnoczi 744f17cfe81SBenoît Canet do {} while (g_main_context_iteration(NULL, false)); 745f17cfe81SBenoît Canet 746f17cfe81SBenoît Canet /* tests in the same order as the header function declarations */ 747f17cfe81SBenoît Canet g_test_init(&argc, &argv, NULL); 748f17cfe81SBenoît Canet g_test_add_func("/throttle/leak_bucket", test_leak_bucket); 749f17cfe81SBenoît Canet g_test_add_func("/throttle/compute_wait", test_compute_wait); 750f17cfe81SBenoît Canet g_test_add_func("/throttle/init", test_init); 751f17cfe81SBenoît Canet g_test_add_func("/throttle/destroy", test_destroy); 752f17cfe81SBenoît Canet g_test_add_func("/throttle/have_timer", test_have_timer); 75322524f72SStefan Hajnoczi g_test_add_func("/throttle/detach_attach", test_detach_attach); 754f17cfe81SBenoît Canet g_test_add_func("/throttle/config/enabled", test_enabled); 755f17cfe81SBenoît Canet g_test_add_func("/throttle/config/conflicting", test_conflicting_config); 756f17cfe81SBenoît Canet g_test_add_func("/throttle/config/is_valid", test_is_valid); 757d942feecSAlberto Garcia g_test_add_func("/throttle/config/ranges", test_ranges); 75892e11a17SStefan Hajnoczi g_test_add_func("/throttle/config/max", test_max_is_missing_limit); 7598860eabdSStefan Hajnoczi g_test_add_func("/throttle/config/iops_size", 7608860eabdSStefan Hajnoczi test_iops_size_is_missing_limit); 761f17cfe81SBenoît Canet g_test_add_func("/throttle/config_functions", test_config_functions); 762f17cfe81SBenoît Canet g_test_add_func("/throttle/accounting", test_accounting); 7631fee955fSAlberto Garcia g_test_add_func("/throttle/groups", test_groups); 764f17cfe81SBenoît Canet return g_test_run(); 765f17cfe81SBenoît Canet } 766f17cfe81SBenoît Canet 767