2 * virbitmaptest.c: Test the bitmap code
4 * Copyright (C) 2013 Red Hat, Inc.
5 * Copyright (C) 2012 Fujitsu.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
25 #include "testutils.h"
27 #include "virbitmap.h"
31 checkBitmap(virBitmap
*map
,
35 g_autofree
char *actual
= virBitmapFormat(map
);
37 if (expectedSize
!= -1 &&
38 virBitmapSize(map
) != expectedSize
) {
39 fprintf(stderr
, "\n expected bitmap size: '%zd' actual size: "
40 "'%zu'\n", expectedSize
, virBitmapSize(map
));
44 if (STRNEQ_NULLABLE(expect
, actual
)) {
45 fprintf(stderr
, "\n expected bitmap contents '%s' actual contents "\
46 "'%s'\n", NULLSTR(expect
), NULLSTR(actual
));
55 test1(const void *data G_GNUC_UNUSED
)
57 g_autoptr(virBitmap
) bitmap
= NULL
;
64 bitmap
= virBitmapNew(size
);
66 if (virBitmapSetBit(bitmap
, bit
) < 0)
69 if (virBitmapGetBit(bitmap
, bit
, &result
) < 0)
75 if (virBitmapGetBit(bitmap
, bit
+ 1, &result
) < 0)
85 testBit(virBitmap
*bitmap
,
93 for (i
= start
; i
<= end
; i
++) {
94 if (virBitmapGetBit(bitmap
, i
, &result
) < 0)
96 if (result
!= expected
)
104 test2(const void *data G_GNUC_UNUSED
)
106 const char *bitsString1
= "1-32,50,88-99,1021-1023";
107 g_autofree
char *bitsString2
= NULL
;
108 g_autoptr(virBitmap
) bitmap
= NULL
;
111 if (virBitmapParse(bitsString1
, &bitmap
, size
) < 0)
114 if (testBit(bitmap
, 1, 32, true) < 0)
116 if (testBit(bitmap
, 50, 50, true) < 0)
118 if (testBit(bitmap
, 88, 99, true) < 0)
120 if (testBit(bitmap
, 1021, 1023, true) < 0)
123 if (testBit(bitmap
, 0, 0, false) < 0)
125 if (testBit(bitmap
, 33, 49, false) < 0)
127 if (testBit(bitmap
, 51, 87, false) < 0)
129 if (testBit(bitmap
, 100, 1020, false) < 0)
132 if (virBitmapCountBits(bitmap
) != 48)
135 if (!(bitsString2
= virBitmapFormat(bitmap
)))
137 if (strcmp(bitsString1
, bitsString2
))
140 virBitmapSetAll(bitmap
);
141 if (testBit(bitmap
, 0, size
- 1, true) < 0)
143 if (virBitmapCountBits(bitmap
) != size
)
146 if (!virBitmapIsAllSet(bitmap
))
149 virBitmapClearAll(bitmap
);
150 if (!virBitmapIsAllClear(bitmap
))
152 if (testBit(bitmap
, 0, size
- 1, false) < 0)
154 if (virBitmapCountBits(bitmap
) != 0)
161 test3(const void *data G_GNUC_UNUSED
)
163 g_autoptr(virBitmap
) bitmap
= NULL
;
167 bitmap
= virBitmapNew(size
);
169 for (i
= 0; i
< size
; i
++)
170 ignore_value(virBitmapSetBit(bitmap
, i
));
172 if (!virBitmapIsAllSet(bitmap
))
175 virBitmapClearAll(bitmap
);
176 if (!virBitmapIsAllClear(bitmap
))
182 /* test for virBitmapNextSetBit, virBitmapLastSetBit, virBitmapNextClearBit */
184 test4a(const void *data G_GNUC_UNUSED
)
186 g_autoptr(virBitmap
) bitmap
= NULL
;
190 bitmap
= virBitmapNew(0);
192 if (virBitmapNextSetBit(bitmap
, -1) != -1)
195 if (virBitmapLastSetBit(bitmap
) != -1)
198 if (virBitmapNextClearBit(bitmap
, -1) != -1)
206 test4b(const void *data G_GNUC_UNUSED
)
208 g_autoptr(virBitmap
) bitmap
= NULL
;
214 bitmap
= virBitmapNew(size
);
216 if (virBitmapNextSetBit(bitmap
, -1) != -1)
219 if (virBitmapLastSetBit(bitmap
) != -1)
222 for (i
= 0; i
< size
; i
++) {
223 if (virBitmapNextClearBit(bitmap
, i
- 1) != i
)
226 if (virBitmapNextClearBit(bitmap
, i
) != -1)
229 if (!virBitmapIsAllClear(bitmap
))
237 test4c(const void *data G_GNUC_UNUSED
)
239 const char *bitsString
= "0, 2-4, 6-10, 12, 14-18, 20, 22, 25";
242 0, 2, 3, 4, 6, 7, 8, 9, 10, 12,
243 14, 15, 16, 17, 18, 20, 22, 25
246 1, 5, 11, 13, 19, 21, 23, 24, 26, 27,
247 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39
249 g_autoptr(virBitmap
) bitmap
= NULL
;
252 if (G_N_ELEMENTS(bitsPos
) + G_N_ELEMENTS(bitsPosInv
) != size
)
257 if (virBitmapParse(bitsString
, &bitmap
, size
) < 0)
265 while (j
< G_N_ELEMENTS(bitsPos
)) {
266 i
= virBitmapNextSetBit(bitmap
, i
);
267 if (i
!= bitsPos
[j
++])
271 if (virBitmapNextSetBit(bitmap
, i
) != -1)
274 j
= G_N_ELEMENTS(bitsPos
) - 1;
276 if (virBitmapLastSetBit(bitmap
) != bitsPos
[j
])
282 while (j
< G_N_ELEMENTS(bitsPosInv
)) {
283 i
= virBitmapNextClearBit(bitmap
, i
);
284 if (i
!= bitsPosInv
[j
++])
288 if (virBitmapNextClearBit(bitmap
, i
) != -1)
293 virBitmapSetAll(bitmap
);
295 for (i
= 0; i
< size
; i
++) {
296 if (virBitmapNextSetBit(bitmap
, i
- 1) != i
)
299 if (virBitmapNextSetBit(bitmap
, i
) != -1)
302 if (virBitmapLastSetBit(bitmap
) != size
- 1)
305 if (virBitmapNextClearBit(bitmap
, -1) != -1)
311 /* test for virBitmapNewData/ToData/DataFormat */
313 test5(const void *v G_GNUC_UNUSED
)
315 char data
[] = {0x01, 0x02, 0x00, 0x00, 0x04};
316 g_autofree
unsigned char *data2
= NULL
;
318 int bits
[] = {0, 9, 34};
319 g_autoptr(virBitmap
) bitmap
= NULL
;
322 g_autofree
char *actual1
= NULL
;
323 g_autofree
char *actual2
= NULL
;
325 bitmap
= virBitmapNewData(data
, sizeof(data
));
331 while (i
< G_N_ELEMENTS(bits
) &&
332 (j
= virBitmapNextSetBit(bitmap
, j
)) >= 0) {
336 if (virBitmapNextSetBit(bitmap
, j
) > 0)
339 ignore_value(virBitmapSetBit(bitmap
, 2));
340 ignore_value(virBitmapSetBit(bitmap
, 15));
342 if (virBitmapToData(bitmap
, &data2
, &len2
) < 0)
345 if (len2
!= sizeof(data
) ||
353 if (!(actual1
= virBitmapDataFormat(data
, sizeof(data
))))
355 if (STRNEQ(actual1
, "0,9,34"))
357 if (!(actual2
= virBitmapDataFormat(data2
, len2
)))
359 if (STRNEQ(actual2
, "0,2,9,15,34"))
366 /* test for virBitmapFormat */
368 test6(const void *v G_GNUC_UNUSED
)
370 g_autoptr(virBitmap
) bitmap
= NULL
;
373 bitmap
= virBitmapNew(size
);
375 if (checkBitmap(bitmap
, "", -1) < 0)
378 ignore_value(virBitmapSetBit(bitmap
, 0));
380 if (checkBitmap(bitmap
, "0", -1) < 0)
383 ignore_value(virBitmapSetBit(bitmap
, 4));
384 ignore_value(virBitmapSetBit(bitmap
, 5));
386 if (checkBitmap(bitmap
, "0,4-5", -1) < 0)
389 ignore_value(virBitmapSetBit(bitmap
, 6));
391 if (checkBitmap(bitmap
, "0,4-6", -1) < 0)
394 ignore_value(virBitmapSetBit(bitmap
, 13));
395 ignore_value(virBitmapSetBit(bitmap
, 14));
396 ignore_value(virBitmapSetBit(bitmap
, 15));
397 ignore_value(virBitmapSetBit(bitmap
, 16));
399 if (checkBitmap(bitmap
, "0,4-6,13-16", -1) < 0)
402 ignore_value(virBitmapSetBit(bitmap
, 62));
403 ignore_value(virBitmapSetBit(bitmap
, 63));
405 if (checkBitmap(bitmap
, "0,4-6,13-16,62-63", -1) < 0)
412 test7(const void *v G_GNUC_UNUSED
)
416 1, 8, 31, 32, 63, 64, 95, 96, 127, 128, 159, 160
420 for (i
= 0; i
< nmaxBit
; i
++) {
421 g_autoptr(virBitmap
) bitmap
= virBitmapNew(maxBit
[i
]);
423 if (virBitmapIsAllSet(bitmap
))
426 ignore_value(virBitmapSetBit(bitmap
, 1));
427 if (virBitmapIsAllSet(bitmap
))
430 virBitmapSetAll(bitmap
);
431 if (!virBitmapIsAllSet(bitmap
))
434 virBitmapClearAll(bitmap
);
435 if (!virBitmapIsAllClear(bitmap
))
443 test8(const void *v G_GNUC_UNUSED
)
445 g_autoptr(virBitmap
) bitmap
= NULL
;
446 char data
[108] = {0x00,};
448 bitmap
= virBitmapNewData(data
, sizeof(data
));
452 if (!virBitmapIsAllClear(bitmap
))
455 if (virBitmapSetBit(bitmap
, 11) < 0)
458 if (virBitmapIsAllClear(bitmap
))
465 /* test out of bounds conditions on virBitmapParse */
467 test9(const void *opaque G_GNUC_UNUSED
)
469 g_autoptr(virBitmap
) bitmap
= NULL
;
471 if (virBitmapParse("100000000", &bitmap
, 20) != -1)
477 if (virBitmapParse("1-1000000000", &bitmap
, 20) != -1)
483 if (virBitmapParse("1-10^10000000000", &bitmap
, 20) != -1)
493 test10(const void *opaque G_GNUC_UNUSED
)
495 g_autoptr(virBitmap
) b1
= NULL
;
496 g_autoptr(virBitmap
) b2
= NULL
;
497 g_autoptr(virBitmap
) b3
= NULL
;
498 g_autoptr(virBitmap
) b4
= NULL
;
500 if (virBitmapParse("0-3,5-8,11-15", &b1
, 20) < 0 ||
501 virBitmapParse("4,9,10,16-19", &b2
, 20) < 0 ||
502 virBitmapParse("15", &b3
, 20) < 0 ||
503 virBitmapParse("0,^0", &b4
, 20) < 0)
506 if (!virBitmapIsAllClear(b4
))
509 if (virBitmapOverlaps(b1
, b2
) ||
510 virBitmapOverlaps(b1
, b4
) ||
511 virBitmapOverlaps(b2
, b3
) ||
512 virBitmapOverlaps(b2
, b4
) ||
513 !virBitmapOverlaps(b1
, b3
) ||
514 virBitmapOverlaps(b3
, b4
))
520 struct testBinaryOpData
{
527 test11(const void *opaque
)
529 const struct testBinaryOpData
*data
= opaque
;
530 g_autoptr(virBitmap
) amap
= NULL
;
531 g_autoptr(virBitmap
) bmap
= NULL
;
532 g_autoptr(virBitmap
) resmap
= NULL
;
534 if (virBitmapParse(data
->a
, &amap
, 256) < 0 ||
535 virBitmapParse(data
->b
, &bmap
, 256) < 0 ||
536 virBitmapParse(data
->res
, &resmap
, 256) < 0)
539 virBitmapIntersect(amap
, bmap
);
541 if (!virBitmapEqual(amap
, resmap
)) {
543 "\n bitmap intersection failed: intersect('%s','%s') !='%s'\n",
544 data
->a
, data
->b
, data
->res
);
552 /* test self-expanding bitmap APIs */
554 test12a(const void *opaque G_GNUC_UNUSED
)
556 g_autoptr(virBitmap
) map
= virBitmapNew(0);
558 if (checkBitmap(map
, "", 0) < 0)
561 virBitmapSetBitExpand(map
, 128);
563 if (checkBitmap(map
, "128", 129) < 0)
566 virBitmapClearBitExpand(map
, 150);
568 if (checkBitmap(map
, "128", 151) < 0)
576 test12b(const void *opaque G_GNUC_UNUSED
)
578 g_autoptr(virBitmap
) map
= NULL
;
580 if (!(map
= virBitmapParseUnlimited("31,32,63,64,1023")))
583 if (checkBitmap(map
, "31-32,63-64,1023", 1024) < 0)
586 /* no shrink at full alloc */
587 virBitmapShrink(map
, 1025);
588 if (checkBitmap(map
, "31-32,63-64,1023", 1024) < 0)
591 /* shrink at the end */
592 virBitmapShrink(map
, 1023);
593 if (checkBitmap(map
, "31-32,63-64", 1023) < 0)
596 /* extend back to see whether tail was cleared */
597 virBitmapSetBitExpand(map
, 1022);
598 if (checkBitmap(map
, "31-32,63-64,1022", 1023) < 0)
601 virBitmapShrink(map
, 64);
602 if (checkBitmap(map
, "31-32,63", 64) < 0)
605 virBitmapShrink(map
, 65);
606 if (checkBitmap(map
, "31-32,63", 64) < 0)
609 virBitmapShrink(map
, 63);
610 if (checkBitmap(map
, "31-32", 63) < 0)
613 virBitmapShrink(map
, 32);
614 if (checkBitmap(map
, "31", 32) < 0)
617 virBitmapShrink(map
, 31);
618 if (checkBitmap(map
, "", 31) < 0)
625 /* virBitmap(New/To)String */
627 test13(const void *opaque G_GNUC_UNUSED
)
629 const char *strings
[] = { "1234feebee", "000c0fefe", "0", "" };
632 for (i
= 0; i
< G_N_ELEMENTS(strings
); i
++) {
633 g_autoptr(virBitmap
) map
= NULL
;
634 g_autofree
char *str
= NULL
;
636 if (!(map
= virBitmapNewString(strings
[i
])))
639 if (!(str
= virBitmapToString(map
)))
642 if (STRNEQ(strings
[i
], str
)) {
643 fprintf(stderr
, "\n expected bitmap string '%s' actual string "
644 "'%s'\n", strings
[i
], str
);
654 test14(const void *opaque
)
656 const struct testBinaryOpData
*data
= opaque
;
657 g_autoptr(virBitmap
) amap
= NULL
;
658 g_autoptr(virBitmap
) bmap
= NULL
;
659 g_autoptr(virBitmap
) resmap
= NULL
;
661 if (virBitmapParse(data
->a
, &amap
, 256) < 0 ||
662 virBitmapParse(data
->b
, &bmap
, 256) < 0 ||
663 virBitmapParse(data
->res
, &resmap
, 256) < 0)
666 virBitmapSubtract(amap
, bmap
);
668 if (!virBitmapEqual(amap
, resmap
)) {
670 "\n bitmap subtraction failed: '%s' - '%s' != '%s'\n",
671 data
->a
, data
->b
, data
->res
);
678 /* virBitmapUnion() */
680 test15(const void *opaque
)
682 const struct testBinaryOpData
*data
= opaque
;
683 g_autoptr(virBitmap
) amap
= NULL
;
684 g_autoptr(virBitmap
) bmap
= NULL
;
685 g_autoptr(virBitmap
) resmap
= NULL
;
687 if (!(amap
= virBitmapParseUnlimited(data
->a
)) ||
688 !(bmap
= virBitmapParseUnlimited(data
->b
)) ||
689 !(resmap
= virBitmapParseUnlimited(data
->res
))) {
693 virBitmapUnion(amap
, bmap
);
695 if (!virBitmapEqual(amap
, resmap
)) {
697 "\n bitmap union failed: union('%s', '%s') != '%s'\n",
698 data
->a
, data
->b
, data
->res
);
706 /* virBitmapNew(0) + virBitmapToString */
708 test16(const void *opaque G_GNUC_UNUSED
)
710 g_autoptr(virBitmap
) map
= virBitmapNew(0);
711 g_autofree
char *res_empty
= NULL
;
712 g_autofree
char *res_set
= NULL
;
714 if (!(res_empty
= virBitmapToString(map
)) ||
715 STRNEQ_NULLABLE(res_empty
, "")) {
716 fprintf(stderr
, "\n expected bitmap string '%s' actual string '%s'\n",
717 "", NULLSTR(res_empty
));
721 virBitmapSetBitExpand(map
, 2);
722 virBitmapSetBitExpand(map
, 11);
724 if (!(res_set
= virBitmapToString(map
)) ||
725 STRNEQ_NULLABLE(res_set
, "804")) {
726 fprintf(stderr
, "\n expected bitmap string '%s' actual string '%s'\n",
727 "804", NULLSTR(res_set
));
735 /* virBitmapParseUnlimitedAllowEmpty */
737 test17(const void *opaque G_GNUC_UNUSED
)
739 g_autoptr(virBitmap
) map1
= NULL
;
740 g_autoptr(virBitmap
) map2
= NULL
;
741 g_autofree
char *map1_str
= NULL
;
742 g_autofree
char *map2_str
= NULL
;
744 if (!(map1
= virBitmapParseUnlimitedAllowEmpty(NULL
))) {
745 fprintf(stderr
, "Expected success, got failure\n");
749 if (!(map2
= virBitmapParseUnlimitedAllowEmpty(" "))) {
750 fprintf(stderr
, "Expected success, got failure\n");
754 if (!virBitmapIsAllClear(map1
) ||
755 !virBitmapIsAllClear(map2
) ||
756 !virBitmapEqual(map1
, map2
)) {
757 fprintf(stderr
, "empty maps should equal\n");
761 if (!(map1_str
= virBitmapFormat(map1
)) ||
762 !(map2_str
= virBitmapFormat(map2
)) ||
763 STRNEQ(map1_str
, map2_str
)) {
764 fprintf(stderr
, "maps don't equal after format to string\n");
772 #define TESTBINARYOP(A, B, RES, FUNC) \
773 testBinaryOpData.a = A; \
774 testBinaryOpData.b = B; \
775 testBinaryOpData.res = RES; \
776 if (virTestRun(virTestCounterNext(), FUNC, &testBinaryOpData) < 0) \
782 struct testBinaryOpData testBinaryOpData
;
785 if (virTestRun("test1", test1
, NULL
) < 0)
787 if (virTestRun("test2", test2
, NULL
) < 0)
789 if (virTestRun("test3", test3
, NULL
) < 0)
791 if (virTestRun("test4a", test4a
, NULL
) < 0)
793 if (virTestRun("test4b", test4b
, NULL
) < 0)
795 if (virTestRun("test4c", test4c
, NULL
) < 0)
797 if (virTestRun("test5", test5
, NULL
) < 0)
799 if (virTestRun("test6", test6
, NULL
) < 0)
801 if (virTestRun("test7", test7
, NULL
) < 0)
803 if (virTestRun("test8", test8
, NULL
) < 0)
805 if (virTestRun("test9", test9
, NULL
) < 0)
807 if (virTestRun("test10", test10
, NULL
) < 0)
810 virTestCounterReset("test11-");
811 TESTBINARYOP("0", "0", "0", test11
);
812 TESTBINARYOP("0-3", "0", "0", test11
);
813 TESTBINARYOP("0-3", "0,3", "0,3", test11
);
814 TESTBINARYOP("0,^0", "0", "0,^0", test11
);
815 TESTBINARYOP("0-3", "0-3", "0-3", test11
);
816 TESTBINARYOP("0-3", "0,^0", "0,^0", test11
);
817 TESTBINARYOP("0,2", "1,3", "0,^0", test11
);
819 if (virTestRun("test12a", test12a
, NULL
) < 0)
821 if (virTestRun("test12b", test12b
, NULL
) < 0)
823 if (virTestRun("test13", test13
, NULL
) < 0)
826 virTestCounterReset("test14-");
827 TESTBINARYOP("0", "0", "0,^0", test14
);
828 TESTBINARYOP("0-3", "0", "1-3", test14
);
829 TESTBINARYOP("0-3", "0,3", "1-2", test14
);
830 TESTBINARYOP("0,^0", "0", "0,^0", test14
);
831 TESTBINARYOP("0-3", "0-3", "0,^0", test14
);
832 TESTBINARYOP("0-3", "0,^0", "0-3", test14
);
833 TESTBINARYOP("0,2", "1,3", "0,2", test14
);
835 /* virBitmapUnion() */
836 virTestCounterReset("test15-");
837 TESTBINARYOP("0-1", "0-1", "0-1", test15
);
838 TESTBINARYOP("0", "1", "0-1", test15
);
839 TESTBINARYOP("0-1", "2-3", "0-3", test15
);
840 TESTBINARYOP("0-3", "1-2", "0-3", test15
);
841 TESTBINARYOP("0,^0", "12345", "12345", test15
);
842 TESTBINARYOP("12345", "0,^0", "12345", test15
);
843 TESTBINARYOP("0,^0", "0,^0", "0,^0", test15
);
845 if (virTestRun("test16", test16
, NULL
) < 0)
848 if (virTestRun("test17", test17
, NULL
) < 0)
851 return ret
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
854 VIR_TEST_MAIN(mymain
)