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