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