1 /*
2 * This file Copyright (C) 2010-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 */
8
9 #include <string.h> /* strlen() */
10 #include "transmission.h"
11 #include "crypto-utils.h"
12 #include "bitfield.h"
13 #include "utils.h" /* tr_free */
14
15 #include "libtransmission-test.h"
16
test_bitfield_count_range(void)17 static int test_bitfield_count_range(void)
18 {
19 int begin;
20 int end;
21 int count1;
22 int count2;
23 int const bitCount = 100 + tr_rand_int_weak(1000);
24 tr_bitfield bf;
25
26 /* generate a random bitfield */
27 tr_bitfieldConstruct(&bf, bitCount);
28
29 for (int i = 0, n = tr_rand_int_weak(bitCount); i < n; ++i)
30 {
31 tr_bitfieldAdd(&bf, tr_rand_int_weak(bitCount));
32 }
33
34 begin = tr_rand_int_weak(bitCount);
35
36 do
37 {
38 end = tr_rand_int_weak(bitCount);
39 }
40 while (end == begin);
41
42 /* ensure end <= begin */
43 if (end < begin)
44 {
45 int const tmp = begin;
46 begin = end;
47 end = tmp;
48 }
49
50 /* test the bitfield */
51 count1 = 0;
52
53 for (int i = begin; i < end; ++i)
54 {
55 if (tr_bitfieldHas(&bf, i))
56 {
57 ++count1;
58 }
59 }
60
61 count2 = tr_bitfieldCountRange(&bf, begin, end);
62 check_int(count1, ==, count2);
63
64 /* cleanup */
65 tr_bitfieldDestruct(&bf);
66 return 0;
67 }
68
test_bitfields(void)69 static int test_bitfields(void)
70 {
71 unsigned int bitcount = 500;
72 tr_bitfield field;
73
74 tr_bitfieldConstruct(&field, bitcount);
75
76 /* test tr_bitfieldAdd */
77 for (unsigned int i = 0; i < bitcount; i++)
78 {
79 if (i % 7 == 0)
80 {
81 tr_bitfieldAdd(&field, i);
82 }
83 }
84
85 for (unsigned int i = 0; i < bitcount; i++)
86 {
87 check_bool(tr_bitfieldHas(&field, i), ==, (i % 7 == 0));
88 }
89
90 /* test tr_bitfieldAddRange */
91 tr_bitfieldAddRange(&field, 0, bitcount);
92
93 for (unsigned int i = 0; i < bitcount; i++)
94 {
95 check(tr_bitfieldHas(&field, i));
96 }
97
98 /* test tr_bitfieldRem */
99 for (unsigned int i = 0; i < bitcount; i++)
100 {
101 if (i % 7 != 0)
102 {
103 tr_bitfieldRem(&field, i);
104 }
105 }
106
107 for (unsigned int i = 0; i < bitcount; i++)
108 {
109 check_bool(tr_bitfieldHas(&field, i), ==, (i % 7 == 0));
110 }
111
112 /* test tr_bitfieldRemRange in the middle of a boundary */
113 tr_bitfieldAddRange(&field, 0, 64);
114 tr_bitfieldRemRange(&field, 4, 21);
115
116 for (unsigned int i = 0; i < 64; i++)
117 {
118 check_bool(tr_bitfieldHas(&field, i), ==, (i < 4 || i >= 21));
119 }
120
121 /* test tr_bitfieldRemRange on the boundaries */
122 tr_bitfieldAddRange(&field, 0, 64);
123 tr_bitfieldRemRange(&field, 8, 24);
124
125 for (unsigned int i = 0; i < 64; i++)
126 {
127 check_bool(tr_bitfieldHas(&field, i), ==, (i < 8 || i >= 24));
128 }
129
130 /* test tr_bitfieldRemRange when begin & end is on the same word */
131 tr_bitfieldAddRange(&field, 0, 64);
132 tr_bitfieldRemRange(&field, 4, 5);
133
134 for (unsigned int i = 0; i < 64; i++)
135 {
136 check_bool(tr_bitfieldHas(&field, i), ==, (i < 4 || i >= 5));
137 }
138
139 /* test tr_bitfieldAddRange */
140 tr_bitfieldRemRange(&field, 0, 64);
141 tr_bitfieldAddRange(&field, 4, 21);
142
143 for (unsigned int i = 0; i < 64; i++)
144 {
145 check_bool(tr_bitfieldHas(&field, i), ==, (4 <= i && i < 21));
146 }
147
148 /* test tr_bitfieldAddRange on the boundaries */
149 tr_bitfieldRemRange(&field, 0, 64);
150 tr_bitfieldAddRange(&field, 8, 24);
151
152 for (unsigned int i = 0; i < 64; i++)
153 {
154 check_bool(tr_bitfieldHas(&field, i), ==, (8 <= i && i < 24));
155 }
156
157 /* test tr_bitfieldAddRange when begin & end is on the same word */
158 tr_bitfieldRemRange(&field, 0, 64);
159 tr_bitfieldAddRange(&field, 4, 5);
160
161 for (unsigned int i = 0; i < 64; i++)
162 {
163 check_bool(tr_bitfieldHas(&field, i), ==, (4 <= i && i < 5));
164 }
165
166 tr_bitfieldDestruct(&field);
167 return 0;
168 }
169
test_bitfield_has_all_none(void)170 static int test_bitfield_has_all_none(void)
171 {
172 tr_bitfield field;
173
174 tr_bitfieldConstruct(&field, 3);
175
176 check(!tr_bitfieldHasAll(&field));
177 check(tr_bitfieldHasNone(&field));
178
179 tr_bitfieldAdd(&field, 0);
180 check(!tr_bitfieldHasAll(&field));
181 check(!tr_bitfieldHasNone(&field));
182
183 tr_bitfieldRem(&field, 0);
184 tr_bitfieldAdd(&field, 1);
185 check(!tr_bitfieldHasAll(&field));
186 check(!tr_bitfieldHasNone(&field));
187
188 tr_bitfieldRem(&field, 1);
189 tr_bitfieldAdd(&field, 2);
190 check(!tr_bitfieldHasAll(&field));
191 check(!tr_bitfieldHasNone(&field));
192
193 tr_bitfieldAdd(&field, 0);
194 tr_bitfieldAdd(&field, 1);
195 check(tr_bitfieldHasAll(&field));
196 check(!tr_bitfieldHasNone(&field));
197
198 tr_bitfieldSetHasNone(&field);
199 check(!tr_bitfieldHasAll(&field));
200 check(tr_bitfieldHasNone(&field));
201
202 tr_bitfieldSetHasAll(&field);
203 check(tr_bitfieldHasAll(&field));
204 check(!tr_bitfieldHasNone(&field));
205
206 tr_bitfieldDestruct(&field);
207 tr_bitfieldConstruct(&field, 0);
208
209 check(!tr_bitfieldHasAll(&field));
210 check(!tr_bitfieldHasNone(&field));
211
212 tr_bitfieldSetHasNone(&field);
213 check(!tr_bitfieldHasAll(&field));
214 check(tr_bitfieldHasNone(&field));
215
216 tr_bitfieldSetHasAll(&field);
217 check(tr_bitfieldHasAll(&field));
218 check(!tr_bitfieldHasNone(&field));
219
220 tr_bitfieldDestruct(&field);
221 return 0;
222 }
223
main(void)224 int main(void)
225 {
226 testFunc const tests[] =
227 {
228 test_bitfields,
229 test_bitfield_has_all_none
230 };
231
232 int ret = runTests(tests, NUM_TESTS(tests));
233
234 /* bitfield count range */
235 for (int l = 0; l < 10000; ++l)
236 {
237 if (test_bitfield_count_range() != 0)
238 {
239 ++ret;
240 }
241 }
242
243 return ret;
244 }
245