1 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  *
3  * rollsum_test -- tests for the librsync rolling checksum.
4  *
5  * Copyright (C) 2003 by Donovan Baarda <abo@minkirri.apana.org.au>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * 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.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21 
22 /* Force DEBUG on so that tests can use assert(). */
23 #undef NDEBUG
24 #include "config.h"
25 #include <string.h>
26 #include <assert.h>
27 #include "librsync.h"
28 #include "sumset.h"
29 
30 /* Test driver for sumset.c. */
main(int argc,char ** argv)31 int main(int argc, char **argv)
32 {
33     rs_signature_t sig;
34     rs_result res;
35     rs_weak_sum_t weak = 0x12345678;
36     rs_strong_sum_t strong = "ABCDEF";
37     int i;
38     unsigned char buf[256];
39 
40     /* Initialize test buffer. */
41     for (i = 0; i < 256; i++)
42         buf[i] = (unsigned char)i;
43 
44     /* Test rs_sig_args() */
45     rs_magic_number magic;
46     size_t block_len, strong_len;
47 
48     /* old_fsize=unknown, all recommended. */
49     magic = 0;
50     block_len = 0;
51     strong_len = 0;
52     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
53     assert(res == RS_DONE);
54     assert(magic == RS_RK_BLAKE2_SIG_MAGIC);
55     assert(block_len == 2048);
56     assert(strong_len == 32);
57 
58     /* old_fsize=0, all recommended. */
59     magic = 0;
60     block_len = 0;
61     strong_len = 0;
62     res = rs_sig_args(0, &magic, &block_len, &strong_len);
63     assert(res == RS_DONE);
64     assert(magic == RS_RK_BLAKE2_SIG_MAGIC);
65     assert(block_len == 256);
66     assert(strong_len == 32);
67 
68     /* old_fsize=100000, magic=rs/md4, block_len=rec, strong_len=rec. */
69     magic = RS_MD4_SIG_MAGIC;
70     block_len = 0;
71     strong_len = 0;
72     res = rs_sig_args(1000000, &magic, &block_len, &strong_len);
73     assert(res == RS_DONE);
74     assert(magic == RS_MD4_SIG_MAGIC);
75     assert(block_len == 896);
76     assert(strong_len == 16);
77 
78     /* old_fsize=unknown, magic=rk/b2, block_len=rec, strong_len=min. */
79     magic = RS_RK_BLAKE2_SIG_MAGIC;
80     block_len = 0;
81     strong_len = -1;
82     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
83     assert(res == RS_DONE);
84     assert(magic == RS_RK_BLAKE2_SIG_MAGIC);
85     assert(block_len == 2048);
86     assert(strong_len == 12);
87 
88     /* old_fsize=unknown, magic=rs/b2, block_len=1000, strong_len=8. */
89     magic = RS_BLAKE2_SIG_MAGIC;
90     block_len = 1000;
91     strong_len = 8;
92     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
93     assert(res == RS_DONE);
94     assert(magic == RS_BLAKE2_SIG_MAGIC);
95     assert(block_len == 1000);
96     assert(strong_len == 8);
97 
98     /* old_fsize=0, magic=rs/md4, block_len=rec, strong_len=min. */
99     magic = RS_RK_MD4_SIG_MAGIC;
100     block_len = 0;
101     strong_len = -1;
102     res = rs_sig_args(0, &magic, &block_len, &strong_len);
103     assert(res == RS_DONE);
104     assert(magic == RS_RK_MD4_SIG_MAGIC);
105     assert(block_len == 256);
106     assert(strong_len == 5);
107 
108     /* old_fsize=0, magic=rs/md4, block_len=1000, strong_len=8. */
109     magic = RS_MD4_SIG_MAGIC;
110     block_len = 1000;
111     strong_len = 8;
112     res = rs_sig_args(0, &magic, &block_len, &strong_len);
113     assert(res == RS_DONE);
114     assert(magic == RS_MD4_SIG_MAGIC);
115     assert(block_len == 1000);
116     assert(strong_len == 8);
117 
118     /* old_fsize=100000, magic=rs/b2, block_len=rec, strong_len=min. */
119     magic = RS_BLAKE2_SIG_MAGIC;
120     block_len = 0;
121     strong_len = -1;
122     res = rs_sig_args(1000000, &magic, &block_len, &strong_len);
123     assert(res == RS_DONE);
124     assert(magic == RS_BLAKE2_SIG_MAGIC);
125     assert(block_len == 896);
126     assert(strong_len == 7);
127 
128     /* old_fsize=100000, magic=rk/md4, block_len=1000, strong_len=8. */
129     magic = RS_RK_MD4_SIG_MAGIC;
130     block_len = 1000;
131     strong_len = 8;
132     res = rs_sig_args(100000, &magic, &block_len, &strong_len);
133     assert(res == RS_DONE);
134     assert(magic == RS_RK_MD4_SIG_MAGIC);
135     assert(block_len == 1000);
136     assert(strong_len == 8);
137 
138     /* magic=bad. */
139     magic = 1;
140     block_len = 0;
141     strong_len = 0;
142     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
143     assert(res == RS_BAD_MAGIC);
144 
145     /* strong_len=bad. */
146     magic = RS_RK_BLAKE2_SIG_MAGIC;
147     block_len = 0;
148     strong_len = 33;
149     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
150     assert(res == RS_PARAM_ERROR);
151     magic = RS_BLAKE2_SIG_MAGIC;
152     block_len = 0;
153     strong_len = 33;
154     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
155     assert(res == RS_PARAM_ERROR);
156     magic = RS_RK_MD4_SIG_MAGIC;
157     block_len = 0;
158     strong_len = 17;
159     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
160     assert(res == RS_PARAM_ERROR);
161     magic = RS_MD4_SIG_MAGIC;
162     block_len = 0;
163     strong_len = 17;
164     res = rs_sig_args(-1, &magic, &block_len, &strong_len);
165     assert(res == RS_PARAM_ERROR);
166 
167     /* Test rs_signature_init() */
168     /* magic=rec, block_len=rec, strong_len=max. */
169     res = rs_signature_init(&sig, 0, 0, 0, -1);
170     assert(res == RS_DONE);
171     assert(sig.magic == RS_RK_BLAKE2_SIG_MAGIC);
172     assert(sig.block_len == 2048);
173     assert(sig.strong_sum_len == 32);
174     assert(sig.count == 0);
175     assert(sig.size == 0);
176     assert(sig.block_sigs == NULL);
177     assert(sig.hashtable == NULL);
178 #ifndef HASHTABLE_NSTATS
179     assert(sig.calc_strong_count == 0);
180 #endif
181 
182     /* Blake2 magic, block_len=rec, strong_len=max. */
183     res = rs_signature_init(&sig, RS_BLAKE2_SIG_MAGIC, 0, 0, -1);
184     assert(res == RS_DONE);
185     assert(sig.magic == RS_BLAKE2_SIG_MAGIC);
186     assert(sig.block_len == 2048);
187     assert(sig.strong_sum_len == 32);
188 
189     /* MD4 magic, block_len=rec, strong_len=max. */
190     res = rs_signature_init(&sig, RS_MD4_SIG_MAGIC, 0, 0, -1);
191     assert(res == RS_DONE);
192     assert(sig.magic == RS_MD4_SIG_MAGIC);
193     assert(sig.block_len == 2048);
194     assert(sig.strong_sum_len == 16);
195 
196     /* RabinKarp + Blake2 magic, block_len=16, strong_len=min. */
197     res = rs_signature_init(&sig, RS_RK_BLAKE2_SIG_MAGIC, 16, -1, -1);
198     assert(res == RS_DONE);
199     assert(sig.magic == RS_RK_BLAKE2_SIG_MAGIC);
200     assert(sig.block_len == 16);
201     assert(sig.strong_sum_len == 12);
202 
203     /* RabinKarp + MD4 magic, block_len=16, strong_len=6. */
204     res = rs_signature_init(&sig, RS_RK_MD4_SIG_MAGIC, 16, 6, -1);
205     assert(res == RS_DONE);
206     assert(sig.magic == RS_RK_MD4_SIG_MAGIC);
207     assert(sig.block_len == 16);
208     assert(sig.strong_sum_len == 6);
209 
210     /* Bad magic. */
211     res = rs_signature_init(&sig, 1, 16, 6, -1);
212     assert(res == RS_BAD_MAGIC);
213 
214     /* Bad strong_sum_len. */
215     res = rs_signature_init(&sig, RS_MD4_SIG_MAGIC, 16, 17, -1);
216     assert(res == RS_PARAM_ERROR);
217     res = rs_signature_init(&sig, RS_RK_MD4_SIG_MAGIC, 16, 17, -1);
218     assert(res == RS_PARAM_ERROR);
219     res = rs_signature_init(&sig, RS_BLAKE2_SIG_MAGIC, 16, 33, -1);
220     assert(res == RS_PARAM_ERROR);
221     res = rs_signature_init(&sig, RS_RK_BLAKE2_SIG_MAGIC, 16, 33, -1);
222     assert(res == RS_PARAM_ERROR);
223 
224     /* With sig_fsize provided. */
225     res = rs_signature_init(&sig, 0, 16, 6, 92);
226     assert(res == RS_DONE);
227     assert(sig.magic == RS_RK_BLAKE2_SIG_MAGIC);
228     assert(sig.block_len == 16);
229     assert(sig.strong_sum_len == 6);
230     assert(sig.count == 0);
231     assert(sig.size == 8);
232     assert(sig.block_sigs != NULL);
233 
234     /* Test rs_signature_done(). */
235     rs_signature_done(&sig);
236     assert(sig.size == 0);
237     assert(sig.block_sigs == NULL);
238 
239     /* Test rs_signature_calc_strong_sum(). */
240     res = rs_signature_init(&sig, RS_MD4_SIG_MAGIC, 16, 6, -1);
241     rs_signature_calc_strong_sum(&sig, &buf, 256, &strong);
242     assert(memcmp(&strong, "\x29\x8a\x05\xbc\x50\x6e", 6) == 0);
243 
244     res = rs_signature_init(&sig, RS_BLAKE2_SIG_MAGIC, 16, 6, -1);
245     rs_signature_calc_strong_sum(&sig, &buf, 256, &strong);
246     assert(memcmp(&strong, "\x39\xa7\xeb\x9f\xed\xc1", 6) == 0);
247 
248     /* Test rs_signature_add_block(). */
249     res = rs_signature_init(&sig, 0, 16, 6, -1);
250     rs_signature_add_block(&sig, weak, &strong);
251     assert(sig.count == 1);
252     assert(sig.size == 16);
253     assert(sig.block_sigs != NULL);
254     assert(((rs_block_sig_t *)sig.block_sigs)->weak_sum == 0x12345678);
255     assert(memcmp(((rs_block_sig_t *)sig.block_sigs)->strong_sum, &strong, 6)
256            == 0);
257     rs_signature_done(&sig);
258 
259     /* Prepare rs_build_hash_table() and rs_signature_find_match() tests. */
260     res = rs_signature_init(&sig, 0, 16, 6, -1);
261     for (i = 0; i < 256; i += 16) {
262         weak = rs_signature_calc_weak_sum(&sig, &buf[i], 16);
263         rs_signature_calc_strong_sum(&sig, &buf[i], 16, &strong);
264         rs_signature_add_block(&sig, weak, &strong);
265     }
266 
267     /* Test rs_build_hash_table(). */
268     rs_build_hash_table(&sig);
269     assert(sig.hashtable->count == 16);
270 
271     /* Test rs_signature_find_match(). */
272     /* different weak, different block. */
273     assert(rs_signature_find_match(&sig, 0x12345678, &buf[2], 16) == -1);
274     /* Matching weak, different block. */
275     assert(rs_signature_find_match(&sig, weak, &buf[2], 16) == -1);
276     /* Matching weak, matching block. */
277     assert(rs_signature_find_match(&sig, weak, &buf[15 * 16], 16) == 15 * 16);
278 #ifndef HASHTABLE_NSTATS
279     assert(sig.calc_strong_count == 2);
280 #endif
281     rs_signature_done(&sig);
282 
283     return 0;
284 }
285