OSDN Git Service

test-qga: add trivial tests for some commands
[qmiga/qemu.git] / tests / test-throttle.c
1 /*
2  * Throttle infrastructure tests
3  *
4  * Copyright Nodalink, EURL. 2013-2014
5  * Copyright Igalia, S.L. 2015
6  *
7  * Authors:
8  *  BenoĆ®t Canet     <benoit.canet@nodalink.com>
9  *  Alberto Garcia   <berto@igalia.com>
10  *
11  * This work is licensed under the terms of the GNU LGPL, version 2 or later.
12  * See the COPYING.LIB file in the top-level directory.
13  */
14
15 #include "qemu/osdep.h"
16 #include <math.h>
17 #include "block/aio.h"
18 #include "qapi/error.h"
19 #include "qemu/throttle.h"
20 #include "qemu/error-report.h"
21 #include "block/throttle-groups.h"
22 #include "sysemu/block-backend.h"
23
24 static AioContext     *ctx;
25 static LeakyBucket    bkt;
26 static ThrottleConfig cfg;
27 static ThrottleGroupMember tgm;
28 static ThrottleState  ts;
29 static ThrottleTimers *tt;
30
31 /* useful function */
32 static bool double_cmp(double x, double y)
33 {
34     return fabsl(x - y) < 1e-6;
35 }
36
37 /* tests for single bucket operations */
38 static void test_leak_bucket(void)
39 {
40     throttle_config_init(&cfg);
41     bkt = cfg.buckets[THROTTLE_BPS_TOTAL];
42
43     /* set initial value */
44     bkt.avg = 150;
45     bkt.max = 15;
46     bkt.level = 1.5;
47
48     /* leak an op work of time */
49     throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150);
50     g_assert(bkt.avg == 150);
51     g_assert(bkt.max == 15);
52     g_assert(double_cmp(bkt.level, 0.5));
53
54     /* leak again emptying the bucket */
55     throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150);
56     g_assert(bkt.avg == 150);
57     g_assert(bkt.max == 15);
58     g_assert(double_cmp(bkt.level, 0));
59
60     /* check that the bucket level won't go lower */
61     throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150);
62     g_assert(bkt.avg == 150);
63     g_assert(bkt.max == 15);
64     g_assert(double_cmp(bkt.level, 0));
65
66     /* check that burst_level leaks correctly */
67     bkt.burst_level = 6;
68     bkt.max = 250;
69     bkt.burst_length = 2; /* otherwise burst_level will not leak */
70     throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100);
71     g_assert(double_cmp(bkt.burst_level, 3.5));
72
73     throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100);
74     g_assert(double_cmp(bkt.burst_level, 1));
75
76     throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100);
77     g_assert(double_cmp(bkt.burst_level, 0));
78
79     throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 100);
80     g_assert(double_cmp(bkt.burst_level, 0));
81 }
82
83 static void test_compute_wait(void)
84 {
85     unsigned i;
86     int64_t wait;
87     int64_t result;
88
89     throttle_config_init(&cfg);
90     bkt = cfg.buckets[THROTTLE_BPS_TOTAL];
91
92     /* no operation limit set */
93     bkt.avg = 0;
94     bkt.max = 15;
95     bkt.level = 1.5;
96     wait = throttle_compute_wait(&bkt);
97     g_assert(!wait);
98
99     /* zero delta */
100     bkt.avg = 150;
101     bkt.max = 15;
102     bkt.level = 15;
103     wait = throttle_compute_wait(&bkt);
104     g_assert(!wait);
105
106     /* below zero delta */
107     bkt.avg = 150;
108     bkt.max = 15;
109     bkt.level = 9;
110     wait = throttle_compute_wait(&bkt);
111     g_assert(!wait);
112
113     /* half an operation above max */
114     bkt.avg = 150;
115     bkt.max = 15;
116     bkt.level = 15.5;
117     wait = throttle_compute_wait(&bkt);
118     /* time required to do half an operation */
119     result = (int64_t)  NANOSECONDS_PER_SECOND / 150 / 2;
120     g_assert(wait == result);
121
122     /* Perform I/O for 2.2 seconds at a rate of bkt.max */
123     bkt.burst_length = 2;
124     bkt.level = 0;
125     bkt.avg = 10;
126     bkt.max = 200;
127     for (i = 0; i < 22; i++) {
128         double units = bkt.max / 10;
129         bkt.level += units;
130         bkt.burst_level += units;
131         throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 10);
132         wait = throttle_compute_wait(&bkt);
133         g_assert(double_cmp(bkt.burst_level, 0));
134         g_assert(double_cmp(bkt.level, (i + 1) * (bkt.max - bkt.avg) / 10));
135         /* We can do bursts for the 2 seconds we have configured in
136          * burst_length. We have 100 extra miliseconds of burst
137          * because bkt.level has been leaking during this time.
138          * After that, we have to wait. */
139         result = i < 21 ? 0 : 1.8 * NANOSECONDS_PER_SECOND;
140         g_assert(wait == result);
141     }
142 }
143
144 /* functions to test ThrottleState initialization/destroy methods */
145 static void read_timer_cb(void *opaque)
146 {
147 }
148
149 static void write_timer_cb(void *opaque)
150 {
151 }
152
153 static void test_init(void)
154 {
155     int i;
156
157     tt = &tgm.throttle_timers;
158
159     /* fill the structures with crap */
160     memset(&ts, 1, sizeof(ts));
161     memset(tt, 1, sizeof(*tt));
162
163     /* init structures */
164     throttle_init(&ts);
165     throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
166                          read_timer_cb, write_timer_cb, &ts);
167
168     /* check initialized fields */
169     g_assert(tt->clock_type == QEMU_CLOCK_VIRTUAL);
170     g_assert(tt->timers[0]);
171     g_assert(tt->timers[1]);
172
173     /* check other fields where cleared */
174     g_assert(!ts.previous_leak);
175     g_assert(!ts.cfg.op_size);
176     for (i = 0; i < BUCKETS_COUNT; i++) {
177         g_assert(!ts.cfg.buckets[i].avg);
178         g_assert(!ts.cfg.buckets[i].max);
179         g_assert(!ts.cfg.buckets[i].level);
180     }
181
182     throttle_timers_destroy(tt);
183 }
184
185 static void test_destroy(void)
186 {
187     int i;
188     throttle_init(&ts);
189     throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
190                          read_timer_cb, write_timer_cb, &ts);
191     throttle_timers_destroy(tt);
192     for (i = 0; i < 2; i++) {
193         g_assert(!tt->timers[i]);
194     }
195 }
196
197 /* function to test throttle_config and throttle_get_config */
198 static void test_config_functions(void)
199 {
200     int i;
201     ThrottleConfig orig_cfg, final_cfg;
202
203     orig_cfg.buckets[THROTTLE_BPS_TOTAL].avg = 153;
204     orig_cfg.buckets[THROTTLE_BPS_READ].avg  = 56;
205     orig_cfg.buckets[THROTTLE_BPS_WRITE].avg = 1;
206
207     orig_cfg.buckets[THROTTLE_OPS_TOTAL].avg = 150;
208     orig_cfg.buckets[THROTTLE_OPS_READ].avg  = 69;
209     orig_cfg.buckets[THROTTLE_OPS_WRITE].avg = 23;
210
211     orig_cfg.buckets[THROTTLE_BPS_TOTAL].max = 0;
212     orig_cfg.buckets[THROTTLE_BPS_READ].max  = 56;
213     orig_cfg.buckets[THROTTLE_BPS_WRITE].max = 120;
214
215     orig_cfg.buckets[THROTTLE_OPS_TOTAL].max = 150;
216     orig_cfg.buckets[THROTTLE_OPS_READ].max  = 400;
217     orig_cfg.buckets[THROTTLE_OPS_WRITE].max = 500;
218
219     orig_cfg.buckets[THROTTLE_BPS_TOTAL].level = 45;
220     orig_cfg.buckets[THROTTLE_BPS_READ].level  = 65;
221     orig_cfg.buckets[THROTTLE_BPS_WRITE].level = 23;
222
223     orig_cfg.buckets[THROTTLE_OPS_TOTAL].level = 1;
224     orig_cfg.buckets[THROTTLE_OPS_READ].level  = 90;
225     orig_cfg.buckets[THROTTLE_OPS_WRITE].level = 75;
226
227     orig_cfg.op_size = 1;
228
229     throttle_init(&ts);
230     throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
231                          read_timer_cb, write_timer_cb, &ts);
232     /* structure reset by throttle_init previous_leak should be null */
233     g_assert(!ts.previous_leak);
234     throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &orig_cfg);
235
236     /* has previous leak been initialized by throttle_config ? */
237     g_assert(ts.previous_leak);
238
239     /* get back the fixed configuration */
240     throttle_get_config(&ts, &final_cfg);
241
242     throttle_timers_destroy(tt);
243
244     g_assert(final_cfg.buckets[THROTTLE_BPS_TOTAL].avg == 153);
245     g_assert(final_cfg.buckets[THROTTLE_BPS_READ].avg  == 56);
246     g_assert(final_cfg.buckets[THROTTLE_BPS_WRITE].avg == 1);
247
248     g_assert(final_cfg.buckets[THROTTLE_OPS_TOTAL].avg == 150);
249     g_assert(final_cfg.buckets[THROTTLE_OPS_READ].avg  == 69);
250     g_assert(final_cfg.buckets[THROTTLE_OPS_WRITE].avg == 23);
251
252     g_assert(final_cfg.buckets[THROTTLE_BPS_TOTAL].max == 0);
253     g_assert(final_cfg.buckets[THROTTLE_BPS_READ].max  == 56);
254     g_assert(final_cfg.buckets[THROTTLE_BPS_WRITE].max == 120);
255
256     g_assert(final_cfg.buckets[THROTTLE_OPS_TOTAL].max == 150);
257     g_assert(final_cfg.buckets[THROTTLE_OPS_READ].max  == 400);
258     g_assert(final_cfg.buckets[THROTTLE_OPS_WRITE].max == 500);
259
260     g_assert(final_cfg.op_size == 1);
261
262     /* check bucket have been cleared */
263     for (i = 0; i < BUCKETS_COUNT; i++) {
264         g_assert(!final_cfg.buckets[i].level);
265     }
266 }
267
268 /* functions to test is throttle is enabled by a config */
269 static void set_cfg_value(bool is_max, int index, int value)
270 {
271     if (is_max) {
272         cfg.buckets[index].max = value;
273         /* If max is set, avg should never be 0 */
274         cfg.buckets[index].avg = MAX(cfg.buckets[index].avg, 1);
275     } else {
276         cfg.buckets[index].avg = value;
277     }
278 }
279
280 static void test_enabled(void)
281 {
282     int i;
283
284     throttle_config_init(&cfg);
285     g_assert(!throttle_enabled(&cfg));
286
287     for (i = 0; i < BUCKETS_COUNT; i++) {
288         throttle_config_init(&cfg);
289         set_cfg_value(false, i, 150);
290         g_assert(throttle_is_valid(&cfg, NULL));
291         g_assert(throttle_enabled(&cfg));
292     }
293
294     for (i = 0; i < BUCKETS_COUNT; i++) {
295         throttle_config_init(&cfg);
296         set_cfg_value(false, i, -150);
297         g_assert(!throttle_is_valid(&cfg, NULL));
298     }
299 }
300
301 /* tests functions for throttle_conflicting */
302
303 static void test_conflicts_for_one_set(bool is_max,
304                                        int total,
305                                        int read,
306                                        int write)
307 {
308     throttle_config_init(&cfg);
309     g_assert(throttle_is_valid(&cfg, NULL));
310
311     set_cfg_value(is_max, total, 1);
312     set_cfg_value(is_max, read,  1);
313     g_assert(!throttle_is_valid(&cfg, NULL));
314
315     throttle_config_init(&cfg);
316     set_cfg_value(is_max, total, 1);
317     set_cfg_value(is_max, write, 1);
318     g_assert(!throttle_is_valid(&cfg, NULL));
319
320     throttle_config_init(&cfg);
321     set_cfg_value(is_max, total, 1);
322     set_cfg_value(is_max, read,  1);
323     set_cfg_value(is_max, write, 1);
324     g_assert(!throttle_is_valid(&cfg, NULL));
325
326     throttle_config_init(&cfg);
327     set_cfg_value(is_max, total, 1);
328     g_assert(throttle_is_valid(&cfg, NULL));
329
330     throttle_config_init(&cfg);
331     set_cfg_value(is_max, read,  1);
332     set_cfg_value(is_max, write, 1);
333     g_assert(throttle_is_valid(&cfg, NULL));
334 }
335
336 static void test_conflicting_config(void)
337 {
338     /* bps average conflicts */
339     test_conflicts_for_one_set(false,
340                                THROTTLE_BPS_TOTAL,
341                                THROTTLE_BPS_READ,
342                                THROTTLE_BPS_WRITE);
343
344     /* ops average conflicts */
345     test_conflicts_for_one_set(false,
346                                THROTTLE_OPS_TOTAL,
347                                THROTTLE_OPS_READ,
348                                THROTTLE_OPS_WRITE);
349
350     /* bps average conflicts */
351     test_conflicts_for_one_set(true,
352                                THROTTLE_BPS_TOTAL,
353                                THROTTLE_BPS_READ,
354                                THROTTLE_BPS_WRITE);
355     /* ops average conflicts */
356     test_conflicts_for_one_set(true,
357                                THROTTLE_OPS_TOTAL,
358                                THROTTLE_OPS_READ,
359                                THROTTLE_OPS_WRITE);
360 }
361 /* functions to test the throttle_is_valid function */
362 static void test_is_valid_for_value(int value, bool should_be_valid)
363 {
364     int is_max, index;
365     for (is_max = 0; is_max < 2; is_max++) {
366         for (index = 0; index < BUCKETS_COUNT; index++) {
367             throttle_config_init(&cfg);
368             set_cfg_value(is_max, index, value);
369             g_assert(throttle_is_valid(&cfg, NULL) == should_be_valid);
370         }
371     }
372 }
373
374 static void test_is_valid(void)
375 {
376     /* negative number are invalid */
377     test_is_valid_for_value(-1, false);
378     /* zero are valids */
379     test_is_valid_for_value(0, true);
380     /* positives numers are valids */
381     test_is_valid_for_value(1, true);
382 }
383
384 static void test_ranges(void)
385 {
386     int i;
387
388     for (i = 0; i < BUCKETS_COUNT; i++) {
389         LeakyBucket *b = &cfg.buckets[i];
390         throttle_config_init(&cfg);
391
392         /* avg = 0 means throttling is disabled, but the config is valid */
393         b->avg = 0;
394         g_assert(throttle_is_valid(&cfg, NULL));
395         g_assert(!throttle_enabled(&cfg));
396
397         /* These are valid configurations (values <= THROTTLE_VALUE_MAX) */
398         b->avg = 1;
399         g_assert(throttle_is_valid(&cfg, NULL));
400
401         b->avg = THROTTLE_VALUE_MAX;
402         g_assert(throttle_is_valid(&cfg, NULL));
403
404         b->avg = THROTTLE_VALUE_MAX;
405         b->max = THROTTLE_VALUE_MAX;
406         g_assert(throttle_is_valid(&cfg, NULL));
407
408         /* Values over THROTTLE_VALUE_MAX are not allowed */
409         b->avg = THROTTLE_VALUE_MAX + 1;
410         g_assert(!throttle_is_valid(&cfg, NULL));
411
412         b->avg = THROTTLE_VALUE_MAX;
413         b->max = THROTTLE_VALUE_MAX + 1;
414         g_assert(!throttle_is_valid(&cfg, NULL));
415
416         /* burst_length must be between 1 and THROTTLE_VALUE_MAX */
417         b->avg = 1;
418         b->max = 1;
419         b->burst_length = 0;
420         g_assert(!throttle_is_valid(&cfg, NULL));
421
422         b->avg = 1;
423         b->max = 1;
424         b->burst_length = 1;
425         g_assert(throttle_is_valid(&cfg, NULL));
426
427         b->avg = 1;
428         b->max = 1;
429         b->burst_length = THROTTLE_VALUE_MAX;
430         g_assert(throttle_is_valid(&cfg, NULL));
431
432         b->avg = 1;
433         b->max = 1;
434         b->burst_length = THROTTLE_VALUE_MAX + 1;
435         g_assert(!throttle_is_valid(&cfg, NULL));
436
437         /* burst_length * max cannot exceed THROTTLE_VALUE_MAX */
438         b->avg = 1;
439         b->max = 2;
440         b->burst_length = THROTTLE_VALUE_MAX / 2;
441         g_assert(throttle_is_valid(&cfg, NULL));
442
443         b->avg = 1;
444         b->max = 3;
445         b->burst_length = THROTTLE_VALUE_MAX / 2;
446         g_assert(!throttle_is_valid(&cfg, NULL));
447
448         b->avg = 1;
449         b->max = THROTTLE_VALUE_MAX;
450         b->burst_length = 1;
451         g_assert(throttle_is_valid(&cfg, NULL));
452
453         b->avg = 1;
454         b->max = THROTTLE_VALUE_MAX;
455         b->burst_length = 2;
456         g_assert(!throttle_is_valid(&cfg, NULL));
457     }
458 }
459
460 static void test_max_is_missing_limit(void)
461 {
462     int i;
463
464     for (i = 0; i < BUCKETS_COUNT; i++) {
465         throttle_config_init(&cfg);
466         cfg.buckets[i].max = 100;
467         cfg.buckets[i].avg = 0;
468         g_assert(!throttle_is_valid(&cfg, NULL));
469
470         cfg.buckets[i].max = 0;
471         cfg.buckets[i].avg = 0;
472         g_assert(throttle_is_valid(&cfg, NULL));
473
474         cfg.buckets[i].max = 0;
475         cfg.buckets[i].avg = 100;
476         g_assert(throttle_is_valid(&cfg, NULL));
477
478         cfg.buckets[i].max = 30;
479         cfg.buckets[i].avg = 100;
480         g_assert(!throttle_is_valid(&cfg, NULL));
481
482         cfg.buckets[i].max = 100;
483         cfg.buckets[i].avg = 100;
484         g_assert(throttle_is_valid(&cfg, NULL));
485     }
486 }
487
488 static void test_iops_size_is_missing_limit(void)
489 {
490     /* A total/read/write iops limit is required */
491     throttle_config_init(&cfg);
492     cfg.op_size = 4096;
493     g_assert(!throttle_is_valid(&cfg, NULL));
494 }
495
496 static void test_have_timer(void)
497 {
498     /* zero structures */
499     memset(&ts, 0, sizeof(ts));
500     memset(tt, 0, sizeof(*tt));
501
502     /* no timer set should return false */
503     g_assert(!throttle_timers_are_initialized(tt));
504
505     /* init structures */
506     throttle_init(&ts);
507     throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
508                          read_timer_cb, write_timer_cb, &ts);
509
510     /* timer set by init should return true */
511     g_assert(throttle_timers_are_initialized(tt));
512
513     throttle_timers_destroy(tt);
514 }
515
516 static void test_detach_attach(void)
517 {
518     /* zero structures */
519     memset(&ts, 0, sizeof(ts));
520     memset(tt, 0, sizeof(*tt));
521
522     /* init the structure */
523     throttle_init(&ts);
524     throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
525                          read_timer_cb, write_timer_cb, &ts);
526
527     /* timer set by init should return true */
528     g_assert(throttle_timers_are_initialized(tt));
529
530     /* timer should no longer exist after detaching */
531     throttle_timers_detach_aio_context(tt);
532     g_assert(!throttle_timers_are_initialized(tt));
533
534     /* timer should exist again after attaching */
535     throttle_timers_attach_aio_context(tt, ctx);
536     g_assert(throttle_timers_are_initialized(tt));
537
538     throttle_timers_destroy(tt);
539 }
540
541 static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
542                 int size,                   /* size of the operation to do */
543                 double avg,                 /* io limit */
544                 uint64_t op_size,           /* ideal size of an io */
545                 double total_result,
546                 double read_result,
547                 double write_result)
548 {
549     BucketType to_test[2][3] = { { THROTTLE_BPS_TOTAL,
550                                    THROTTLE_BPS_READ,
551                                    THROTTLE_BPS_WRITE, },
552                                  { THROTTLE_OPS_TOTAL,
553                                    THROTTLE_OPS_READ,
554                                    THROTTLE_OPS_WRITE, } };
555     ThrottleConfig cfg;
556     BucketType index;
557     int i;
558
559     for (i = 0; i < 3; i++) {
560         BucketType index = to_test[is_ops][i];
561         cfg.buckets[index].avg = avg;
562     }
563
564     cfg.op_size = op_size;
565
566     throttle_init(&ts);
567     throttle_timers_init(tt, ctx, QEMU_CLOCK_VIRTUAL,
568                          read_timer_cb, write_timer_cb, &ts);
569     throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &cfg);
570
571     /* account a read */
572     throttle_account(&ts, false, size);
573     /* account a write */
574     throttle_account(&ts, true, size);
575
576     /* check total result */
577     index = to_test[is_ops][0];
578     if (!double_cmp(ts.cfg.buckets[index].level, total_result)) {
579         return false;
580     }
581
582     /* check read result */
583     index = to_test[is_ops][1];
584     if (!double_cmp(ts.cfg.buckets[index].level, read_result)) {
585         return false;
586     }
587
588     /* check write result */
589     index = to_test[is_ops][2];
590     if (!double_cmp(ts.cfg.buckets[index].level, write_result)) {
591         return false;
592     }
593
594     throttle_timers_destroy(tt);
595
596     return true;
597 }
598
599 static void test_accounting(void)
600 {
601     /* tests for bps */
602
603     /* op of size 1 */
604     g_assert(do_test_accounting(false,
605                                 1 * 512,
606                                 150,
607                                 0,
608                                 1024,
609                                 512,
610                                 512));
611
612     /* op of size 2 */
613     g_assert(do_test_accounting(false,
614                                 2 * 512,
615                                 150,
616                                 0,
617                                 2048,
618                                 1024,
619                                 1024));
620
621     /* op of size 2 and orthogonal parameter change */
622     g_assert(do_test_accounting(false,
623                                 2 * 512,
624                                 150,
625                                 17,
626                                 2048,
627                                 1024,
628                                 1024));
629
630
631     /* tests for ops */
632
633     /* op of size 1 */
634     g_assert(do_test_accounting(true,
635                                 1 * 512,
636                                 150,
637                                 0,
638                                 2,
639                                 1,
640                                 1));
641
642     /* op of size 2 */
643     g_assert(do_test_accounting(true,
644                                 2 *  512,
645                                 150,
646                                 0,
647                                 2,
648                                 1,
649                                 1));
650
651     /* jumbo op accounting fragmentation : size 64 with op size of 13 units */
652     g_assert(do_test_accounting(true,
653                                 64 * 512,
654                                 150,
655                                 13 * 512,
656                                 (64.0 * 2) / 13,
657                                 (64.0 / 13),
658                                 (64.0 / 13)));
659
660     /* same with orthogonal parameters changes */
661     g_assert(do_test_accounting(true,
662                                 64 * 512,
663                                 300,
664                                 13 * 512,
665                                 (64.0 * 2) / 13,
666                                 (64.0 / 13),
667                                 (64.0 / 13)));
668 }
669
670 static void test_groups(void)
671 {
672     ThrottleConfig cfg1, cfg2;
673     BlockBackend *blk1, *blk2, *blk3;
674     BlockBackendPublic *blkp1, *blkp2, *blkp3;
675     ThrottleGroupMember *tgm1, *tgm2, *tgm3;
676
677     /* No actual I/O is performed on these devices */
678     blk1 = blk_new(0, BLK_PERM_ALL);
679     blk2 = blk_new(0, BLK_PERM_ALL);
680     blk3 = blk_new(0, BLK_PERM_ALL);
681
682     blkp1 = blk_get_public(blk1);
683     blkp2 = blk_get_public(blk2);
684     blkp3 = blk_get_public(blk3);
685
686     tgm1 = &blkp1->throttle_group_member;
687     tgm2 = &blkp2->throttle_group_member;
688     tgm3 = &blkp3->throttle_group_member;
689
690     g_assert(tgm1->throttle_state == NULL);
691     g_assert(tgm2->throttle_state == NULL);
692     g_assert(tgm3->throttle_state == NULL);
693
694     throttle_group_register_tgm(tgm1, "bar", blk_get_aio_context(blk1));
695     throttle_group_register_tgm(tgm2, "foo", blk_get_aio_context(blk2));
696     throttle_group_register_tgm(tgm3, "bar", blk_get_aio_context(blk3));
697
698     g_assert(tgm1->throttle_state != NULL);
699     g_assert(tgm2->throttle_state != NULL);
700     g_assert(tgm3->throttle_state != NULL);
701
702     g_assert(!strcmp(throttle_group_get_name(tgm1), "bar"));
703     g_assert(!strcmp(throttle_group_get_name(tgm2), "foo"));
704     g_assert(tgm1->throttle_state == tgm3->throttle_state);
705
706     /* Setting the config of a group member affects the whole group */
707     throttle_config_init(&cfg1);
708     cfg1.buckets[THROTTLE_BPS_READ].avg  = 500000;
709     cfg1.buckets[THROTTLE_BPS_WRITE].avg = 285000;
710     cfg1.buckets[THROTTLE_OPS_READ].avg  = 20000;
711     cfg1.buckets[THROTTLE_OPS_WRITE].avg = 12000;
712     throttle_group_config(tgm1, &cfg1);
713
714     throttle_group_get_config(tgm1, &cfg1);
715     throttle_group_get_config(tgm3, &cfg2);
716     g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
717
718     cfg2.buckets[THROTTLE_BPS_READ].avg  = 4547;
719     cfg2.buckets[THROTTLE_BPS_WRITE].avg = 1349;
720     cfg2.buckets[THROTTLE_OPS_READ].avg  = 123;
721     cfg2.buckets[THROTTLE_OPS_WRITE].avg = 86;
722     throttle_group_config(tgm3, &cfg1);
723
724     throttle_group_get_config(tgm1, &cfg1);
725     throttle_group_get_config(tgm3, &cfg2);
726     g_assert(!memcmp(&cfg1, &cfg2, sizeof(cfg1)));
727
728     throttle_group_unregister_tgm(tgm1);
729     throttle_group_unregister_tgm(tgm2);
730     throttle_group_unregister_tgm(tgm3);
731
732     g_assert(tgm1->throttle_state == NULL);
733     g_assert(tgm2->throttle_state == NULL);
734     g_assert(tgm3->throttle_state == NULL);
735 }
736
737 int main(int argc, char **argv)
738 {
739     qemu_init_main_loop(&error_fatal);
740     ctx = qemu_get_aio_context();
741     bdrv_init();
742     module_call_init(MODULE_INIT_QOM);
743
744     do {} while (g_main_context_iteration(NULL, false));
745
746     /* tests in the same order as the header function declarations */
747     g_test_init(&argc, &argv, NULL);
748     g_test_add_func("/throttle/leak_bucket",        test_leak_bucket);
749     g_test_add_func("/throttle/compute_wait",       test_compute_wait);
750     g_test_add_func("/throttle/init",               test_init);
751     g_test_add_func("/throttle/destroy",            test_destroy);
752     g_test_add_func("/throttle/have_timer",         test_have_timer);
753     g_test_add_func("/throttle/detach_attach",      test_detach_attach);
754     g_test_add_func("/throttle/config/enabled",     test_enabled);
755     g_test_add_func("/throttle/config/conflicting", test_conflicting_config);
756     g_test_add_func("/throttle/config/is_valid",    test_is_valid);
757     g_test_add_func("/throttle/config/ranges",      test_ranges);
758     g_test_add_func("/throttle/config/max",         test_max_is_missing_limit);
759     g_test_add_func("/throttle/config/iops_size",
760                     test_iops_size_is_missing_limit);
761     g_test_add_func("/throttle/config_functions",   test_config_functions);
762     g_test_add_func("/throttle/accounting",         test_accounting);
763     g_test_add_func("/throttle/groups",             test_groups);
764     return g_test_run();
765 }
766