Browse code

unit tests for new fmap scan API

Török Edvin authored on 2011/06/15 04:35:03
Showing 6 changed files
... ...
@@ -35,6 +35,9 @@ CLAMAV_PUBLIC {
35 35
     cl_statinidir;
36 36
     cl_countsigs;
37 37
     cl_strerror;
38
+    cl_fmap_open_handle;
39
+    cl_fmap_open_memory;
40
+    cl_scanmap_callback;
38 41
 };
39 42
 CLAMAV_PRIVATE {
40 43
   global:
... ...
@@ -33,7 +33,7 @@ check_clamav_SOURCES = check_clamav.c checks.h checks_common.h $(top_builddir)/l
33 33
 		       check_jsnorm.c check_str.c check_regex.c\
34 34
 		       check_disasm.c check_uniq.c check_matchers.c\
35 35
 		       check_htmlnorm.c check_bytecode.c
36
-check_clamav_CPPFLAGS = -I$(top_srcdir) @CHECK_CPPFLAGS@ -DSRCDIR=\"$(abs_srcdir)\"
36
+check_clamav_CPPFLAGS = -I$(top_srcdir) @CHECK_CPPFLAGS@ -DSRCDIR=\"$(abs_srcdir)\" -DOBJDIR=\"$(abs_builddir)\"
37 37
 check_clamav_LDADD = $(top_builddir)/libclamav/libclamav.la @THREAD_LIBS@ @CHECK_LIBS@
38 38
 check_clamd_SOURCES = check_clamd.c checks_common.h
39 39
 check_clamd_CPPFLAGS = -I$(top_srcdir) @CHECK_CPPFLAGS@ -DSRCDIR=\"$(abs_srcdir)\" -DBUILDDIR=\"$(abs_builddir)\"
... ...
@@ -43,6 +43,11 @@ check_clamd_SOURCES = check_clamav_skip.c
43 43
 check_clamav_SOURCES = check_clamav_skip.c
44 44
 endif
45 45
 
46
+check_clamav.o: check_clamav.c $(top_builddir)/test/clam.exe clamav.hdb
47
+
48
+clamav.hdb: input/clamav.hdb
49
+	cp $< $@
50
+
46 51
 check_clamd.sh: $(top_builddir)/test/clam.exe check_clamd
47 52
 check_clamscan.sh: $(top_builddir)/test/clam.exe
48 53
 
... ...
@@ -387,7 +387,7 @@ AM_CFLAGS = @WERR_CFLAGS@
387 387
 @HAVE_LIBCHECK_TRUE@		       check_disasm.c check_uniq.c check_matchers.c\
388 388
 @HAVE_LIBCHECK_TRUE@		       check_htmlnorm.c check_bytecode.c
389 389
 
390
-@HAVE_LIBCHECK_TRUE@check_clamav_CPPFLAGS = -I$(top_srcdir) @CHECK_CPPFLAGS@ -DSRCDIR=\"$(abs_srcdir)\"
390
+@HAVE_LIBCHECK_TRUE@check_clamav_CPPFLAGS = -I$(top_srcdir) @CHECK_CPPFLAGS@ -DSRCDIR=\"$(abs_srcdir)\" -DOBJDIR=\"$(abs_builddir)\"
391 391
 @HAVE_LIBCHECK_TRUE@check_clamav_LDADD = $(top_builddir)/libclamav/libclamav.la @THREAD_LIBS@ @CHECK_LIBS@
392 392
 @HAVE_LIBCHECK_FALSE@check_clamd_SOURCES = check_clamav_skip.c
393 393
 @HAVE_LIBCHECK_TRUE@check_clamd_SOURCES = check_clamd.c checks_common.h
... ...
@@ -1097,6 +1097,11 @@ check10_clamd_hg.sh: $(FILES)
1097 1097
 $(FILES) :
1098 1098
 	cat $(SPLIT_DIR)/split.$@aa $(SPLIT_DIR)/split.$@ab > $@
1099 1099
 
1100
+check_clamav.o: check_clamav.c $(top_builddir)/test/clam.exe clamav.hdb
1101
+
1102
+clamav.hdb: input/clamav.hdb
1103
+	cp $< $@
1104
+
1100 1105
 check_clamd.sh: $(top_builddir)/test/clam.exe check_clamd
1101 1106
 check_clamscan.sh: $(top_builddir)/test/clam.exe
1102 1107
 
... ...
@@ -58,6 +58,7 @@ static void runtest(const char *file, uint64_t expected, int fail, int nojit,
58 58
     uint64_t v;
59 59
     struct cl_engine *engine;
60 60
     int fdin = -1;
61
+    char filestr[512];
61 62
 
62 63
     memset(&cctx, 0, sizeof(cctx));
63 64
     cctx.engine = engine = cl_engine_new();
... ...
@@ -103,7 +104,8 @@ static void runtest(const char *file, uint64_t expected, int fail, int nojit,
103 103
 
104 104
     ctx->ctx = &cctx;
105 105
     if (infile) {
106
-	fdin = open(infile, O_RDONLY);
106
+	snprintf(filestr, sizeof(filestr), OBJDIR"/%s", infile);
107
+	fdin = open(filestr, O_RDONLY);
107 108
 	if (fdin < 0 && errno == ENOENT)
108 109
 	    fdin = open_testfile(infile);
109 110
 	fail_unless(fdin >= 0, "failed to open infile");
... ...
@@ -9,6 +9,9 @@
9 9
 #include <fcntl.h>
10 10
 #include <string.h>
11 11
 #include <check.h>
12
+#include <sys/types.h>
13
+#include <dirent.h>
14
+#include <sys/mman.h>
12 15
 #include "../libclamav/clamav.h"
13 16
 #include "../libclamav/others.h"
14 17
 #include "../libclamav/matcher.h"
... ...
@@ -175,10 +178,135 @@ END_TEST
175 175
 START_TEST (test_cl_strerror)
176 176
 END_TEST
177 177
 
178
+static char **testfiles = NULL;
179
+static unsigned testfiles_n = 0;
180
+
181
+static void init_testfiles(void)
182
+{
183
+    struct dirent *dirent;
184
+    unsigned i = 0;
185
+
186
+    DIR *d = opendir(OBJDIR"/../test");
187
+    fail_unless(!!d, "opendir");
188
+    if (!d)
189
+	return;
190
+    while ((dirent = readdir(d))) {
191
+	if (strncmp(dirent->d_name, "clam", 4))
192
+	    continue;
193
+	i++;
194
+	testfiles = cli_realloc(testfiles, i*sizeof(*testfiles));
195
+	fail_unless(!!testfiles, "cli_realloc");
196
+	testfiles[i-1] = strdup(dirent->d_name);
197
+    }
198
+    testfiles_n = i;
199
+
200
+    closedir(d);
201
+}
202
+
203
+static void free_testfiles(void)
204
+{
205
+    unsigned i;
206
+    for (i=0;i<testfiles_n;i++) {
207
+	free(testfiles[i]);
208
+    }
209
+    free(testfiles);
210
+}
211
+
212
+static struct cl_engine *g_engine;
213
+
214
+static void engine_setup(void)
215
+{
216
+    unsigned int sigs = 0;
217
+
218
+    init_testfiles();
219
+    fail_unless(cl_init(CL_INIT_DEFAULT) == 0, "cl_init");
220
+    g_engine = cl_engine_new();
221
+    fail_unless(!!g_engine, "engine");
222
+    fail_unless(cl_load(OBJDIR"/clamav.hdb", g_engine, &sigs, CL_DB_STDOPT) == 0, "cl_load");
223
+    fail_unless(sigs == 1, "sigs");
224
+    fail_unless(cl_engine_compile(g_engine) == 0, "cl_engine_compile");
225
+}
226
+
227
+static void engine_teardown(void)
228
+{
229
+    free_testfiles();
230
+    cl_engine_free(g_engine);
231
+}
232
+
233
+static ssize_t pread_cb(void *handle, void *buf, size_t count, off_t offset)
234
+{
235
+    return pread(*((int*)handle), buf, count, offset);
236
+}
237
+
238
+START_TEST (test_cl_scanmap_callback_handle)
239
+{
240
+    int fd;
241
+    char file[256];
242
+    struct stat st;
243
+    const char *virname = NULL;
244
+    unsigned long int scanned;
245
+    cl_fmap_t *map;
246
+    int ret;
247
+
248
+    fail_unless(_i < testfiles_n);
249
+    snprintf(file, sizeof(file), OBJDIR"/../test/%s", testfiles[_i]);
250
+
251
+    fd = open(file, O_RDONLY);
252
+    fail_unless(fd > 0, "open");
253
+    fail_unless(fstat(fd, &st) == 0, "fstat");
254
+    /* intentionally use different way than scanners.c for testing */
255
+    map = cl_fmap_open_handle(&fd, 0, st.st_size, pread_cb, 1);
256
+    fail_unless(!!map, "cl_fmap_open_handle");
257
+
258
+    ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
259
+    fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret));
260
+    fail_unless(scanned > 0, "scanned");
261
+    fail_unless_fmt(!strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s", virname);
262
+    close(fd);
263
+}
264
+END_TEST
265
+
266
+START_TEST (test_cl_scanmap_callback_mem)
267
+{
268
+    int fd;
269
+    char file[256];
270
+    struct stat st;
271
+    const char *virname = NULL;
272
+    unsigned long int scanned;
273
+    cl_fmap_t *map;
274
+    int ret;
275
+    void *mem;
276
+
277
+    fail_unless(_i < testfiles_n);
278
+    snprintf(file, sizeof(file), OBJDIR"/../test/%s", testfiles[_i]);
279
+
280
+    fd = open(file, O_RDONLY);
281
+    fail_unless(fd > 0, "open");
282
+    fail_unless(fstat(fd, &st) == 0, "fstat");
283
+
284
+    mem = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
285
+    fail_unless(mem != MAP_FAILED, "mmap");
286
+
287
+    /* intentionally use different way than scanners.c for testing */
288
+    map = cl_fmap_open_memory(mem, st.st_size);
289
+    fail_unless(!!map, "cl_fmap_open_mem");
290
+
291
+    ret = cl_scanmap_callback(map, &virname, &scanned, g_engine, CL_SCAN_STDOPT, NULL);
292
+    fail_unless_fmt(ret == CL_VIRUS, "cl_scanmap_callback failed for %s: %s", file, cl_strerror(ret));
293
+    fail_unless(scanned > 0, "scanned %d for %s", scanned, virname);
294
+    fail_unless_fmt(!strcmp(virname, "ClamAV-Test-File.UNOFFICIAL"), "virusname: %s for %s", virname, file);
295
+    close(fd);
296
+
297
+    munmap(mem, st.st_size);
298
+}
299
+END_TEST
300
+
301
+
178 302
 static Suite *test_cl_suite(void)
179 303
 {
180 304
     Suite *s = suite_create("cl_api");
181 305
     TCase *tc_cl = tcase_create("cl_dup");
306
+    TCase *tc_cl_scan = tcase_create("cl_scan");
182 307
 
183 308
     suite_add_tcase (s, tc_cl);
184 309
     tcase_add_test(tc_cl, test_cl_free);
... ...
@@ -201,6 +329,11 @@ static Suite *test_cl_suite(void)
201 201
     tcase_add_test(tc_cl, test_cl_settempdir);
202 202
     tcase_add_test(tc_cl, test_cl_strerror);
203 203
 
204
+    suite_add_tcase(s, tc_cl_scan);
205
+    tcase_add_checked_fixture (tc_cl_scan, engine_setup, engine_teardown);
206
+    tcase_add_loop_test(tc_cl_scan, test_cl_scanmap_callback_handle, 0, 16);
207
+    tcase_add_loop_test(tc_cl_scan, test_cl_scanmap_callback_mem, 0, 16);
208
+
204 209
     return s;
205 210
 }
206 211
 
... ...
@@ -553,5 +686,6 @@ int main(void)
553 553
     srunner_run_all(sr, CK_NORMAL);
554 554
     nf = srunner_ntests_failed(sr);
555 555
     srunner_free(sr);
556
+
556 557
     return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
557 558
 }
558 559
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+aa15bcf478d165efd2065190eb473bcb:544:ClamAV-Test-File