Assertion changed for added test malware file
[platform/upstream/csr-framework.git] / test / test-api-content-screening-async.cpp
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /*
17  * @file        test-api-content-screening-async.cpp
18  * @author      Kyungwook Tak (k.tak@samsung.com)
19  * @version     1.0
20  * @brief       CSR Content screening async API test
21  */
22 #include <csr-content-screening.h>
23
24 #include <condition_variable>
25 #include <thread>
26 #include <mutex>
27 #include <vector>
28 #include <boost/test/unit_test.hpp>
29
30 #include "test-common.h"
31 #include "test-helper.h"
32 #include "test-resource.h"
33
34 #define ASSERT_CALLBACK(actual, scan, detect, complete, cancel, error)                  \
35         do {                                                                                \
36                 std::unique_lock<std::mutex> l(actual.m);                                       \
37                 if (!actual.isDone()) {                                                         \
38                         actual.cv.wait(l);                                                          \
39                         l.unlock();                                                                 \
40                 }                                                                               \
41                 if (scan >= 0)                                                                  \
42                         ASSERT_IF_MSG(actual.scannedCnt, scan, "scanned count mismatch.");          \
43                 if (detect >= 0)                                                                \
44                         ASSERT_IF_MSG(actual.detectedCnt, detect, "detected count mismatch.");      \
45                 if (complete >= 0)                                                              \
46                         ASSERT_IF_MSG(actual.completedCnt, complete, "completed count mismatch.");  \
47                 if (cancel >= 0)                                                                \
48                         ASSERT_IF_MSG(actual.cancelledCnt, cancel, "cancelled count mismatch.");    \
49                 if (error >= 0)                                                                 \
50                         ASSERT_IF_MSG(actual.errorCnt, error, "error count mismatch.");             \
51                 break;                                                                          \
52         } while (false)
53
54 namespace {
55
56 struct AsyncTestContext {
57         std::mutex m;
58         std::mutex m_vec;
59         std::condition_variable cv;
60         int scannedCnt;
61         int detectedCnt;
62         int completedCnt;
63         int cancelledCnt;
64         int errorCnt;
65         std::vector<std::string> scannedList;
66         std::vector<csr_cs_malware_h> detectedList;
67         int errorCode;
68         bool apiReturned;
69
70         AsyncTestContext(bool raceTest = false) :
71                 scannedCnt(0),
72                 detectedCnt(0),
73                 completedCnt(0),
74                 cancelledCnt(0),
75                 errorCnt(0),
76                 apiReturned(!raceTest) {}
77
78         bool isDone(void) const {
79                 return this->completedCnt != 0 || this->cancelledCnt != 0 || this->errorCnt != 0;
80         }
81 };
82
83 void on_scanned(const char *file, void *userdata)
84 {
85         auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
86
87         BOOST_REQUIRE_MESSAGE(ctx->apiReturned,
88                 "API not returned yet but scanned callback called on file: " << file);
89
90         BOOST_MESSAGE("on_scanned. file[" << file << "] scanned!");
91
92         std::lock_guard<std::mutex> l(ctx->m_vec);
93
94         ctx->scannedCnt++;
95         ctx->scannedList.push_back(file);
96 }
97
98 void on_detected(csr_cs_malware_h detected, void *userdata)
99 {
100         auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
101
102         BOOST_REQUIRE_MESSAGE(ctx->apiReturned,
103                 "API not returned yet but detected callback called");
104
105         Test::ScopedCstr file_name;
106         ASSERT_SUCCESS(csr_cs_malware_get_file_name(detected, &file_name.ptr));
107         BOOST_MESSAGE("on_detected. file[" << file_name.ptr << "] detected!");
108
109         std::lock_guard<std::mutex> l(ctx->m_vec);
110
111         ctx->detectedCnt++;
112         ctx->detectedList.push_back(detected);
113 }
114
115 void on_error(int ec, void *userdata)
116 {
117         auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
118
119         BOOST_REQUIRE_MESSAGE(ctx->apiReturned,
120                 "API not returned yet but error callback called with error: " <<
121                 Test::capi_ec_to_string(ec));
122
123         BOOST_MESSAGE("on_error. async request done with error: " <<
124                                   Test::capi_ec_to_string(ec));
125
126         ctx->errorCnt++;
127         ctx->errorCode = ec;
128         ctx->cv.notify_one();
129 }
130
131 void on_completed(void *userdata)
132 {
133         auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
134
135         BOOST_REQUIRE_MESSAGE(ctx->apiReturned,
136                 "API not returned yet but completed callback called");
137
138         BOOST_MESSAGE("on_completed. async request completed succesfully.");
139         ctx->completedCnt++;
140         ctx->cv.notify_one();
141 }
142
143 void on_cancelled(void *userdata)
144 {
145         auto ctx = reinterpret_cast<AsyncTestContext *>(userdata);
146
147         BOOST_REQUIRE_MESSAGE(ctx->apiReturned,
148                 "API not returned yet but cancelled callback called");
149
150         BOOST_MESSAGE("on_cancelled. async request canceled!");
151         ctx->cancelledCnt++;
152         ctx->cv.notify_one();
153 }
154
155 void set_default_callback(csr_cs_context_h context)
156 {
157         ASSERT_SUCCESS(csr_cs_set_detected_cb(context, on_detected));
158         ASSERT_SUCCESS(csr_cs_set_completed_cb(context, on_completed));
159         ASSERT_SUCCESS(csr_cs_set_cancelled_cb(context, on_cancelled));
160         ASSERT_SUCCESS(csr_cs_set_error_cb(context, on_error));
161         ASSERT_SUCCESS(csr_cs_set_file_scanned_cb(context, on_scanned));
162 }
163
164 void install_test_files()
165 {
166         Test::copy_file(TEST_FILE_HIGH, TEST_FILE_MEDIA());
167         Test::copy_file(TEST_FILE_HIGH, TEST_FILE_TMP);
168
169         Test::make_dir(TEST_FAKE_APP_ROOT());
170         Test::copy_file(TEST_FILE_HIGH, TEST_FAKE_APP_FILE());
171 }
172
173 void uninstall_test_files()
174 {
175         Test::remove_file(TEST_FILE_MEDIA());
176         Test::remove_file(TEST_FILE_TMP);
177         Test::remove_file(TEST_FAKE_APP_FILE());
178         Test::remove_file(TEST_FAKE_APP_ROOT());
179 }
180
181 void uninstall_test_apps()
182 {
183         Test::uninstall_app(TEST_WGT_PKG_ID);
184         Test::uninstall_app(TEST_TPK_PKG_ID);
185         Test::uninstall_app(TEST_SAFE_WGT_PKG_ID);
186 }
187
188 void install_test_apps()
189 {
190         uninstall_test_apps();
191
192         ASSERT_INSTALL_APP(TEST_WGT_PATH, TEST_WGT_TYPE);
193         ASSERT_INSTALL_APP(TEST_TPK_PATH, TEST_TPK_TYPE);
194         ASSERT_INSTALL_APP(TEST_SAFE_WGT_PATH, TEST_SAFE_WGT_TYPE);
195 }
196
197 } // end of namespace
198
199 BOOST_AUTO_TEST_SUITE(API_CONTENT_SCREENING_ASYNC)
200
201 BOOST_AUTO_TEST_CASE(set_callbacks_positive)
202 {
203         EXCEPTION_GUARD_START
204
205         auto c = Test::Context<csr_cs_context_h>();
206         auto context = c.get();
207
208         set_default_callback(context);
209
210         EXCEPTION_GUARD_END
211 }
212
213 BOOST_AUTO_TEST_CASE(set_callbacks_negative)
214 {
215         EXCEPTION_GUARD_START
216
217         auto c = Test::Context<csr_cs_context_h>();
218         auto context = c.get();
219
220         ASSERT_IF(csr_cs_set_detected_cb(nullptr, on_detected), CSR_ERROR_INVALID_HANDLE);
221         ASSERT_IF(csr_cs_set_detected_cb(context, nullptr), CSR_ERROR_INVALID_PARAMETER);
222         ASSERT_IF(csr_cs_set_completed_cb(nullptr, on_completed), CSR_ERROR_INVALID_HANDLE);
223         ASSERT_IF(csr_cs_set_completed_cb(context, nullptr), CSR_ERROR_INVALID_PARAMETER);
224         ASSERT_IF(csr_cs_set_cancelled_cb(nullptr, on_cancelled), CSR_ERROR_INVALID_HANDLE);
225         ASSERT_IF(csr_cs_set_cancelled_cb(context, nullptr), CSR_ERROR_INVALID_PARAMETER);
226         ASSERT_IF(csr_cs_set_error_cb(nullptr, on_error), CSR_ERROR_INVALID_HANDLE);
227         ASSERT_IF(csr_cs_set_error_cb(context, nullptr), CSR_ERROR_INVALID_PARAMETER);
228         ASSERT_IF(csr_cs_set_file_scanned_cb(nullptr, on_scanned), CSR_ERROR_INVALID_HANDLE);
229         ASSERT_IF(csr_cs_set_file_scanned_cb(context, nullptr), CSR_ERROR_INVALID_PARAMETER);
230
231         EXCEPTION_GUARD_END
232 }
233
234 BOOST_AUTO_TEST_CASE(scan_files_async_positive)
235 {
236         EXCEPTION_GUARD_START
237
238         auto c = Test::Context<csr_cs_context_h>();
239         auto context = c.get();
240
241         set_default_callback(context);
242
243         const char *files[4] = {
244                 TEST_FILE_HIGH,
245                 TEST_FILE_MEDIUM,
246                 TEST_FILE_LOW,
247                 TEST_FILE_NORMAL
248         };
249
250         AsyncTestContext testCtx;
251
252         ASSERT_SUCCESS(csr_cs_scan_files_async(context, files, 4, &testCtx));
253
254         ASSERT_CALLBACK(testCtx, -1, 3, 1, 0, 0);
255
256         ASSERT_DETECTED_IN_LIST(testCtx.detectedList,
257                 TEST_FILE_HIGH, MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
258         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_HIGH, false, "");
259
260         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_MEDIUM, MALWARE_MEDIUM_NAME,
261                                                         MALWARE_MEDIUM_SEVERITY, MALWARE_MEDIUM_DETAILED_URL);
262         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_MEDIUM, false, "");
263
264         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_LOW, MALWARE_LOW_NAME,
265                                                         MALWARE_LOW_SEVERITY, MALWARE_LOW_DETAILED_URL);
266         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_LOW, false, "");
267
268         EXCEPTION_GUARD_END
269 }
270
271 BOOST_AUTO_TEST_CASE(scan_files_async_negative)
272 {
273         EXCEPTION_GUARD_START
274
275         auto c = Test::Context<csr_cs_context_h>();
276         auto context = c.get();
277
278         const char *files[3] = {
279                 TEST_FILE_HIGH,
280                 TEST_FILE_NORMAL,
281                 TEST_FILE_MEDIUM
282         };
283
284         AsyncTestContext testCtx;
285
286         ASSERT_IF(csr_cs_scan_files_async(nullptr, files, 3, nullptr), CSR_ERROR_INVALID_HANDLE);
287         ASSERT_IF(csr_cs_scan_files_async(context, nullptr, 3, nullptr), CSR_ERROR_INVALID_PARAMETER);
288
289         EXCEPTION_GUARD_END
290 }
291
292 BOOST_AUTO_TEST_CASE(scan_dir_positive)
293 {
294         EXCEPTION_GUARD_START
295
296         auto c = Test::Context<csr_cs_context_h>();
297         auto context = c.get();
298
299         set_default_callback(context);
300
301         AsyncTestContext testCtx;
302
303         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_MALWARES, &testCtx));
304
305         //scanned, detected, completed, cancelled, error
306         ASSERT_CALLBACK(testCtx, -1, -1, 1, 0, 0);
307         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_UNREMOVABLE,
308                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
309                                                         MALWARE_HIGH_DETAILED_URL);
310         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_UNREMOVABLE, false, "");
311
312         EXCEPTION_GUARD_END
313 }
314
315 BOOST_AUTO_TEST_CASE(scan_dir_negative)
316 {
317         EXCEPTION_GUARD_START
318
319         auto c = Test::Context<csr_cs_context_h>();
320         auto context = c.get();
321
322         AsyncTestContext testCtx;
323
324         ASSERT_IF(csr_cs_scan_dir_async(nullptr, TEST_DIR_MALWARES, nullptr), CSR_ERROR_INVALID_HANDLE);
325         ASSERT_IF(csr_cs_scan_dir_async(context, nullptr, nullptr), CSR_ERROR_INVALID_PARAMETER);
326
327         EXCEPTION_GUARD_END
328 }
329
330 BOOST_AUTO_TEST_CASE(scan_dir_root)
331 {
332         EXCEPTION_GUARD_START
333
334         auto c = Test::Context<csr_cs_context_h>();
335         auto context = c.get();
336
337         install_test_files();
338         install_test_apps();
339
340         set_default_callback(context);
341
342         AsyncTestContext testCtx;
343
344         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_ROOT, &testCtx));
345
346         //scanned, detected, completed, cancelled, error
347         ASSERT_CALLBACK(testCtx, -1, -1, 1, 0, 0);
348
349         Test::uninstall_app(TEST_WGT_PKG_ID);
350         Test::uninstall_app(TEST_TPK_PKG_ID);
351
352         std::string homeDirPrefix;
353 #ifdef PLATFORM_VERSION_3
354         // "/home" is symlinked of "/opt/home" so in root directory scanning,
355         // user directory prefix("/opt") is additionally needed to check file_name field
356         // in malware handle
357         homeDirPrefix = "/opt";
358 #endif
359
360         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_HIGH, MALWARE_HIGH_NAME,
361                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
362         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_HIGH, false, "");
363
364         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, homeDirPrefix + TEST_FILE_MEDIA(),
365                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
366                                                         MALWARE_HIGH_DETAILED_URL);
367         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, homeDirPrefix + TEST_FILE_MEDIA(),
368                                                                 false, "");
369
370         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_TMP, MALWARE_HIGH_NAME,
371                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
372         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_TMP, false, "");
373
374         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, homeDirPrefix + TEST_WGT_APP_ROOT(),
375                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
376                                                         MALWARE_HIGH_DETAILED_URL);
377         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, homeDirPrefix + TEST_WGT_APP_ROOT(),
378                                                                 true, TEST_WGT_PKG_ID);
379
380         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, homeDirPrefix + TEST_TPK_APP_ROOT(),
381                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
382                                                         MALWARE_HIGH_DETAILED_URL);
383         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, homeDirPrefix + TEST_TPK_APP_ROOT(),
384                                                                 true, TEST_TPK_PKG_ID);
385
386         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, homeDirPrefix + TEST_FAKE_APP_FILE(),
387                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
388                                                         MALWARE_HIGH_DETAILED_URL);
389         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, homeDirPrefix + TEST_FAKE_APP_FILE(),
390                                                                 false, "");
391
392         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_MEDIUM, MALWARE_MEDIUM_NAME,
393                                                         MALWARE_MEDIUM_SEVERITY, MALWARE_MEDIUM_DETAILED_URL);
394         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_MEDIUM, false, "");
395
396         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_LOW, MALWARE_LOW_NAME,
397                                                         MALWARE_LOW_SEVERITY, MALWARE_LOW_DETAILED_URL);
398         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_LOW, false, "");
399
400         EXCEPTION_GUARD_END
401 }
402
403 BOOST_AUTO_TEST_CASE(scan_dir_media)
404 {
405         EXCEPTION_GUARD_START
406
407         auto c = Test::Context<csr_cs_context_h>();
408         auto context = c.get();
409
410         install_test_files();
411
412         set_default_callback(context);
413
414         AsyncTestContext testCtx;
415
416         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_MEDIA(), &testCtx));
417
418         // scanned, detected, completed, cancelled, error
419         ASSERT_CALLBACK(testCtx, -1, 1, 1, 0, 0);
420
421         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_MEDIA(), MALWARE_HIGH_NAME,
422                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
423         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_MEDIA(), false, "");
424
425         EXCEPTION_GUARD_END
426 }
427
428 BOOST_AUTO_TEST_CASE(scan_dir_tmp)
429 {
430         EXCEPTION_GUARD_START
431
432         auto c = Test::Context<csr_cs_context_h>();
433         auto context = c.get();
434
435         install_test_files();
436
437         set_default_callback(context);
438
439         AsyncTestContext testCtx;
440
441         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_TMP, &testCtx));
442
443         //scanned, detected, completed, cancelled, error
444         ASSERT_CALLBACK(testCtx, -1, 1, 1, 0, 0);
445
446         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_TMP, MALWARE_HIGH_NAME,
447                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
448         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_TMP, false, "");
449
450         EXCEPTION_GUARD_END
451 }
452
453 BOOST_AUTO_TEST_CASE(scan_dir_apps)
454 {
455         EXCEPTION_GUARD_START
456
457         auto c = Test::Context<csr_cs_context_h>();
458         auto context = c.get();
459
460         install_test_files();
461         install_test_apps();
462
463         set_default_callback(context);
464
465         AsyncTestContext testCtx;
466
467         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testCtx));
468
469         //scanned, detected, completed, cancelled, error
470         ASSERT_CALLBACK(testCtx, -1, 3, 1, 0, 0);
471
472         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_WGT_APP_ROOT(), MALWARE_HIGH_NAME,
473                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
474         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_WGT_APP_ROOT(), true,
475                                                                 TEST_WGT_PKG_ID);
476
477         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_TPK_APP_ROOT(), MALWARE_HIGH_NAME,
478                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
479         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_TPK_APP_ROOT(), true,
480                                                                 TEST_TPK_PKG_ID);
481
482         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FAKE_APP_FILE(), MALWARE_HIGH_NAME,
483                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
484         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FAKE_APP_FILE(), false, "");
485
486         uninstall_test_apps();
487
488         EXCEPTION_GUARD_END
489 }
490
491 BOOST_AUTO_TEST_CASE(scan_dir_wgt)
492 {
493         EXCEPTION_GUARD_START
494
495         auto c = Test::Context<csr_cs_context_h>();
496         auto context = c.get();
497
498         Test::uninstall_app(TEST_WGT_PKG_ID);
499         ASSERT_INSTALL_APP(TEST_WGT_PATH, TEST_WGT_TYPE);
500
501         set_default_callback(context);
502
503         AsyncTestContext testCtx;
504
505         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_WGT_APP_ROOT(), &testCtx));
506
507         //scanned, detected, completed, cancelled, error
508         ASSERT_CALLBACK(testCtx, -1, 1, 1, 0, 0);
509
510         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_WGT_APP_ROOT(), MALWARE_HIGH_NAME,
511                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
512         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_WGT_APP_ROOT(), true,
513                                                                 TEST_WGT_PKG_ID);
514
515         Test::uninstall_app(TEST_WGT_PKG_ID);
516
517         EXCEPTION_GUARD_END
518 }
519
520 BOOST_AUTO_TEST_CASE(scan_dir_tpk)
521 {
522         EXCEPTION_GUARD_START
523
524         auto c = Test::Context<csr_cs_context_h>();
525         auto context = c.get();
526
527         Test::uninstall_app(TEST_TPK_PKG_ID);
528         ASSERT_INSTALL_APP(TEST_TPK_PATH, TEST_TPK_TYPE);
529
530         set_default_callback(context);
531
532         AsyncTestContext testCtx;
533
534         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_TPK_APP_ROOT(), &testCtx));
535
536         //scanned, detected, completed, cancelled, error
537         ASSERT_CALLBACK(testCtx, -1, 1, 1, 0, 0);
538
539         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_TPK_APP_ROOT(), MALWARE_HIGH_NAME,
540                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
541         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_TPK_APP_ROOT(), true,
542                                                                 TEST_TPK_PKG_ID);
543
544         Test::uninstall_app(TEST_TPK_PKG_ID);
545
546         EXCEPTION_GUARD_END
547 }
548
549 BOOST_AUTO_TEST_CASE(scan_dirs_positive)
550 {
551         EXCEPTION_GUARD_START
552
553         auto c = Test::Context<csr_cs_context_h>();
554         auto context = c.get();
555
556         set_default_callback(context);
557
558         AsyncTestContext testCtx;
559
560         const char *dirs[1] = {
561                 TEST_DIR_MALWARES
562         };
563
564         ASSERT_SUCCESS(csr_cs_scan_dirs_async(context, dirs, 1, &testCtx));
565
566         //scanned, detected, completed, cancelled, error
567         ASSERT_CALLBACK(testCtx, -1, -1, 1, 0, 0);
568         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FILE_UNREMOVABLE,
569                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
570                                                         MALWARE_HIGH_DETAILED_URL);
571         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FILE_UNREMOVABLE, false, "");
572
573         EXCEPTION_GUARD_END
574 }
575
576 BOOST_AUTO_TEST_CASE(scan_dirs_negative)
577 {
578         EXCEPTION_GUARD_START
579
580         auto c = Test::Context<csr_cs_context_h>();
581         auto context = c.get();
582
583         const char *dirs[1] = {
584                 TEST_DIR_MALWARES
585         };
586
587         ASSERT_IF(csr_cs_scan_dirs_async(nullptr, dirs, 1, nullptr), CSR_ERROR_INVALID_HANDLE);
588         ASSERT_IF(csr_cs_scan_dirs_async(context, nullptr, 1, nullptr), CSR_ERROR_INVALID_PARAMETER);
589
590         EXCEPTION_GUARD_END
591 }
592
593
594 BOOST_AUTO_TEST_CASE(scan_cancel_positiive)
595 {
596         EXCEPTION_GUARD_START
597
598         auto c = Test::Context<csr_cs_context_h>();
599         auto context = c.get();
600
601         set_default_callback(context);
602
603         AsyncTestContext testCtx;
604
605         const char *dirs[1] = {
606                 "/"
607         };
608
609         // touch a file : in case of no target file to scan, we cannot cancel to scan.
610         Test::touch_file(TEST_FILE_HIGH);
611
612         ASSERT_SUCCESS(csr_cs_scan_dirs_async(context, dirs, 1, &testCtx));
613         ASSERT_SUCCESS(csr_cs_cancel_scanning(context));
614
615         //scanned, detected, completed, cancelled, error
616         ASSERT_CALLBACK(testCtx, -1, -1, 0, 1, 0);
617
618         EXCEPTION_GUARD_END
619 }
620
621 BOOST_AUTO_TEST_CASE(scan_cancel_negative)
622 {
623         EXCEPTION_GUARD_START
624
625         auto c = Test::Context<csr_cs_context_h>();
626         auto context = c.get();
627
628         ASSERT_IF(csr_cs_cancel_scanning(nullptr), CSR_ERROR_INVALID_HANDLE);
629         ASSERT_IF(csr_cs_cancel_scanning(context), CSR_ERROR_NO_TASK);
630
631         EXCEPTION_GUARD_END
632 }
633
634 BOOST_AUTO_TEST_CASE(delta_scan_basic)
635 {
636         EXCEPTION_GUARD_START
637
638         Test::initialize_db();
639
640         auto c = Test::Context<csr_cs_context_h>();
641         auto context = c.get();
642
643         install_test_files();
644         install_test_apps();
645
646         set_default_callback(context);
647
648         // Base Scan
649         AsyncTestContext testBaseCtx;
650
651         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testBaseCtx));
652
653         // scanned, detected, completed, cancelled, error
654         ASSERT_CALLBACK(testBaseCtx, -1, -1, 1, 0, 0);
655         BOOST_REQUIRE_MESSAGE(testBaseCtx.scannedCnt > 0,
656                         "Base Scan count should not be zero");
657
658         ASSERT_DETECTED_IN_LIST(testBaseCtx.detectedList, TEST_WGT_APP_ROOT(),
659                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
660                                                         MALWARE_HIGH_DETAILED_URL);
661         ASSERT_DETECTED_IN_LIST_EXT(testBaseCtx.detectedList, TEST_WGT_APP_ROOT(), true,
662                                                                 TEST_WGT_PKG_ID);
663
664         ASSERT_DETECTED_IN_LIST(testBaseCtx.detectedList, TEST_TPK_APP_ROOT(),
665                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
666                                                         MALWARE_HIGH_DETAILED_URL);
667         ASSERT_DETECTED_IN_LIST_EXT(testBaseCtx.detectedList, TEST_TPK_APP_ROOT(), true,
668                                                                 TEST_TPK_PKG_ID);
669
670         ASSERT_DETECTED_IN_LIST(testBaseCtx.detectedList, TEST_FAKE_APP_FILE(),
671                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
672                                                         MALWARE_HIGH_DETAILED_URL);
673         ASSERT_DETECTED_IN_LIST_EXT(testBaseCtx.detectedList, TEST_FAKE_APP_FILE(), false, "");
674
675         // Rescan the same dir
676         AsyncTestContext testRescanCtx;
677
678         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testRescanCtx));
679
680         // scanned, detected, completed, cancelled, error
681         ASSERT_CALLBACK(testRescanCtx, -1, -1, 1, 0, 0);
682         BOOST_REQUIRE_MESSAGE(testBaseCtx.scannedCnt > testRescanCtx.scannedCnt,
683                         "Scan count of the base[" << testBaseCtx.scannedCnt <<
684                         "] should be bigger than the delta-scan[" << testRescanCtx.scannedCnt << "]");
685
686         ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_WGT_APP_ROOT(),
687                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
688                                                         MALWARE_HIGH_DETAILED_URL);
689         ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_WGT_APP_ROOT(), true,
690                                                                 TEST_WGT_PKG_ID);
691
692         ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_TPK_APP_ROOT(),
693                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
694                                                         MALWARE_HIGH_DETAILED_URL);
695         ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_TPK_APP_ROOT(), true,
696                                                                 TEST_TPK_PKG_ID);
697
698         ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_FAKE_APP_FILE(),
699                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
700                                                         MALWARE_HIGH_DETAILED_URL);
701         ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_FAKE_APP_FILE(), false,
702                                                                 "");
703
704         // Rescan the sub dir
705         AsyncTestContext testRescanSubCtx;
706
707         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_WGT_APP_ROOT(), &testRescanSubCtx));
708
709         // scanned, detected, completed, cancelled, error
710         ASSERT_CALLBACK(testRescanSubCtx, 0, 1, 1, 0, 0);
711
712         ASSERT_DETECTED_IN_LIST(testRescanSubCtx.detectedList, TEST_WGT_APP_ROOT(),
713                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
714                                                         MALWARE_HIGH_DETAILED_URL);
715         ASSERT_DETECTED_IN_LIST_EXT(testRescanSubCtx.detectedList, TEST_WGT_APP_ROOT(), true,
716                                                                 TEST_WGT_PKG_ID);
717
718         uninstall_test_apps();
719
720         EXCEPTION_GUARD_END
721 }
722
723 BOOST_AUTO_TEST_CASE(delta_scan_changed_after_scan)
724 {
725         EXCEPTION_GUARD_START
726
727         Test::initialize_db();
728
729         auto c = Test::Context<csr_cs_context_h>();
730         auto context = c.get();
731
732         install_test_files();
733         install_test_apps();
734
735         set_default_callback(context);
736
737         // Base Scan
738         AsyncTestContext testBaseCtx;
739
740         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testBaseCtx));
741
742         // scanned, detected, completed, cancelled, error
743         ASSERT_CALLBACK(testBaseCtx, -1, 3, 1, 0, 0);
744         BOOST_REQUIRE_MESSAGE(testBaseCtx.scannedCnt != 0,
745                         "Base Scan count should not be zero");
746
747         // changed
748         Test::uninstall_app(TEST_SAFE_WGT_PKG_ID);
749         ASSERT_INSTALL_APP(TEST_SAFE_WGT_PATH, TEST_SAFE_WGT_TYPE);
750
751         // Rescan the same dir
752         AsyncTestContext testRescanCtx;
753
754         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testRescanCtx));
755
756         // scanned, detected, completed, cancelled, error
757         ASSERT_CALLBACK(testRescanCtx, -1, -1, 1, 0, 0);
758         BOOST_REQUIRE_MESSAGE(testRescanCtx.scannedCnt >= 1,
759                         "reinstalled app(non-malicious wgt) should be counted in scanned.");
760
761         ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_WGT_APP_ROOT(),
762                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
763                                                         MALWARE_HIGH_DETAILED_URL);
764         ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_WGT_APP_ROOT(), true,
765                                                                 TEST_WGT_PKG_ID);
766
767         ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_TPK_APP_ROOT(),
768                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
769                                                         MALWARE_HIGH_DETAILED_URL);
770         ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_TPK_APP_ROOT(), true,
771                                                                 TEST_TPK_PKG_ID);
772
773         ASSERT_DETECTED_IN_LIST(testRescanCtx.detectedList, TEST_FAKE_APP_FILE(),
774                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
775                                                         MALWARE_HIGH_DETAILED_URL);
776         ASSERT_DETECTED_IN_LIST_EXT(testRescanCtx.detectedList, TEST_FAKE_APP_FILE(), false,
777                                                                 "");
778
779         uninstall_test_apps();
780
781         EXCEPTION_GUARD_END
782 }
783
784 BOOST_AUTO_TEST_CASE(canonicalize_files_absolute_path)
785 {
786         EXCEPTION_GUARD_START
787
788         Test::initialize_db();
789
790         auto c = Test::Context<csr_cs_context_h>();
791         auto context = c.get();
792
793         install_test_files();
794
795         set_default_callback(context);
796
797         // four files are all same as realpath.
798         const char *files[4] = {
799                 TEST_FILE_NORMAL,
800                 TEST_DIR "/./test_normal_file",
801                 TEST_DIR "/.././././csr-test/test_normal_file",
802                 TEST_DIR "/././.././csr-test/test_normal_file"
803         };
804
805         AsyncTestContext testCtx;
806
807         ASSERT_SUCCESS(csr_cs_scan_files_async(context, files, 4, &testCtx));
808
809         ASSERT_CALLBACK(testCtx, 1, 0, 1, 0, 0);
810         ASSERT_IF(testCtx.scannedList.size(), static_cast<std::size_t>(1));
811         ASSERT_IF(testCtx.scannedList.front(), static_cast<const char *>(TEST_FILE_NORMAL));
812
813         EXCEPTION_GUARD_END
814 }
815
816 BOOST_AUTO_TEST_CASE(canonicalize_files_relative_path)
817 {
818         EXCEPTION_GUARD_START
819
820         Test::initialize_db();
821
822         auto c = Test::Context<csr_cs_context_h>();
823         auto context = c.get();
824
825         install_test_files();
826
827         set_default_callback(context);
828
829         // four files are all same as realpath.
830         const char *files[4] = {
831                 "test_normal_file",
832                 "./test_normal_file",
833                 ".././././csr-test/test_normal_file",
834                 "././.././csr-test/test_normal_file"
835         };
836
837         AsyncTestContext testCtx;
838
839         Test::ScopedChDir scopedCd(TEST_DIR);
840
841         ASSERT_SUCCESS(csr_cs_scan_files_async(context, files, 4, &testCtx));
842
843         ASSERT_CALLBACK(testCtx, 1, 0, 1, 0, 0);
844         ASSERT_IF(testCtx.scannedList.size(), static_cast<std::size_t>(1));
845         ASSERT_IF(testCtx.scannedList.front(), static_cast<const char *>(TEST_FILE_NORMAL));
846
847         EXCEPTION_GUARD_END
848 }
849
850 BOOST_AUTO_TEST_CASE(multiple_async_dispatch_negative)
851 {
852         EXCEPTION_GUARD_START
853
854         Test::initialize_db();
855
856         auto c = Test::Context<csr_cs_context_h>();
857         auto context = c.get();
858
859         install_test_files();
860         install_test_apps();
861
862         set_default_callback(context);
863
864         AsyncTestContext testCtx;
865
866         // first call. it'll running in background asynchronously.
867         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testCtx));
868
869         AsyncTestContext testCtx2;
870
871         // second call while first call is running in background. It should blocked because
872         // only one operation can be running asynchronously on one handle.
873         ASSERT_IF(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testCtx2), CSR_ERROR_BUSY);
874
875         ASSERT_CALLBACK(testCtx, -1, 3, 1, 0, 0);
876
877         EXCEPTION_GUARD_END
878 }
879
880 BOOST_AUTO_TEST_CASE(get_malware_after_async)
881 {
882         EXCEPTION_GUARD_START
883
884         auto c = Test::Context<csr_cs_context_h>();
885         auto context = c.get();
886
887         set_default_callback(context);
888
889         const char *dirs[4] = {
890                 "/opt/usr/media/",
891                 "/opt/usr/apps/",
892                 "/tmp/",
893                 "/sdcard/"
894         };
895
896         csr_cs_malware_list_h malwares = nullptr;
897         csr_cs_malware_h malware = nullptr;
898         size_t count = 0;
899
900         ASSERT_SUCCESS(csr_cs_get_detected_malwares(context, dirs, 4, &malwares, &count));
901         BOOST_MESSAGE("detected malware exist count before scanning: " << count);
902
903         AsyncTestContext testCtx;
904
905         ASSERT_SUCCESS(csr_cs_scan_dirs_async(context, dirs, 4, &testCtx));
906
907         ASSERT_CALLBACK(testCtx, -1, -1, -1, -1, -1);
908
909         BOOST_MESSAGE("scanned count: " << testCtx.scannedCnt);
910         BOOST_MESSAGE("detected count: " << testCtx.detectedCnt);
911         BOOST_MESSAGE("completed count: " << testCtx.completedCnt);
912         BOOST_MESSAGE("cancelled count: " << testCtx.cancelledCnt);
913         BOOST_MESSAGE("error count: " << testCtx.errorCnt);
914
915         ASSERT_SUCCESS(csr_cs_get_detected_malwares(context, dirs, 4, &malwares, &count));
916
917         CHECK_IS_NOT_NULL(malwares);
918
919         for (size_t i = 0; i < count; ++i) {
920                 malware = nullptr;
921                 Test::ScopedCstr filepath;
922                 ASSERT_SUCCESS(csr_cs_malware_list_get_malware(malwares, i, &malware));
923                 CHECK_IS_NOT_NULL(malware);
924                 ASSERT_SUCCESS(csr_cs_malware_get_file_name(malware, &filepath.ptr));
925                 CHECK_IS_NOT_NULL(filepath.ptr);
926                 BOOST_MESSAGE("detect malware from file: " << filepath.ptr);
927         }
928
929         EXCEPTION_GUARD_END
930 }
931
932 BOOST_AUTO_TEST_CASE(async_api_returning_and_callback_race)
933 {
934         EXCEPTION_GUARD_START
935
936         auto c = Test::Context<csr_cs_context_h>();
937         auto context = c.get();
938
939         install_test_files();
940
941         set_default_callback(context);
942
943         const char *files[2] = {
944                 TEST_FILE_NORMAL,
945                 TEST_FILE_HIGH
946         };
947
948         AsyncTestContext testCtx(true);
949
950         ASSERT_SUCCESS(csr_cs_scan_files_async(context, files, 2, &testCtx));
951         testCtx.apiReturned = true;
952
953         ASSERT_CALLBACK(testCtx, -1, -1, -1, -1, -1);
954
955         EXCEPTION_GUARD_END
956 }
957
958 BOOST_AUTO_TEST_CASE(scan_app_on_cloud)
959 {
960         EXCEPTION_GUARD_START
961
962         BOOST_MESSAGE("Only valid for engines which supports scan on cloud feature");
963
964         auto c = Test::Context<csr_cs_context_h>();
965         auto context = c.get();
966
967         install_test_files();
968         install_test_apps();
969
970         set_default_callback(context);
971         ASSERT_SUCCESS(csr_cs_set_scan_on_cloud(context, true));
972
973         AsyncTestContext testCtx;
974
975         ASSERT_SUCCESS(csr_cs_scan_dir_async(context, TEST_DIR_APPS(), &testCtx));
976
977         ASSERT_CALLBACK(testCtx, -1, -1, 1, 0, 0);
978
979         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_WGT_APP_ROOT(),
980                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
981                                                         MALWARE_HIGH_DETAILED_URL);
982         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_WGT_APP_ROOT(), true,
983                                                                 TEST_WGT_PKG_ID);
984
985         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_TPK_APP_ROOT(),
986                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
987                                                         MALWARE_HIGH_DETAILED_URL);
988         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_TPK_APP_ROOT(), true,
989                                                                 TEST_TPK_PKG_ID);
990
991         ASSERT_DETECTED_IN_LIST(testCtx.detectedList, TEST_FAKE_APP_FILE(),
992                                                         MALWARE_HIGH_NAME, MALWARE_HIGH_SEVERITY,
993                                                         MALWARE_HIGH_DETAILED_URL);
994         ASSERT_DETECTED_IN_LIST_EXT(testCtx.detectedList, TEST_FAKE_APP_FILE(), false, "");
995
996         const char *dirs[1] = {
997                 TEST_DIR_APPS()
998         };
999         csr_cs_malware_list_h malwares = nullptr;
1000         size_t count = 0;
1001
1002         ASSERT_SUCCESS(csr_cs_get_detected_malwares(context, dirs, 1, &malwares, &count));
1003         CHECK_IS_NOT_NULL(malwares);
1004
1005         std::vector<csr_cs_malware_h> malware_vec;
1006         for (size_t i = 0; i < count; ++i) {
1007                 csr_cs_malware_h malware = nullptr;
1008                 ASSERT_SUCCESS(csr_cs_malware_list_get_malware(malwares, i, &malware));
1009
1010                 malware_vec.push_back(malware);
1011         }
1012
1013         ASSERT_DETECTED_IN_LIST(malware_vec, TEST_WGT_APP_ROOT(), MALWARE_HIGH_NAME,
1014                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
1015         ASSERT_DETECTED_IN_LIST_EXT(malware_vec, TEST_WGT_APP_ROOT(), true, TEST_WGT_PKG_ID);
1016
1017         ASSERT_DETECTED_IN_LIST(malware_vec, TEST_TPK_APP_ROOT(), MALWARE_HIGH_NAME,
1018                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
1019         ASSERT_DETECTED_IN_LIST_EXT(malware_vec, TEST_TPK_APP_ROOT(), true, TEST_TPK_PKG_ID);
1020
1021         ASSERT_DETECTED_IN_LIST(malware_vec, TEST_FAKE_APP_FILE(), MALWARE_HIGH_NAME,
1022                                                         MALWARE_HIGH_SEVERITY, MALWARE_HIGH_DETAILED_URL);
1023         ASSERT_DETECTED_IN_LIST_EXT(malware_vec, TEST_FAKE_APP_FILE(), false, "");
1024
1025         EXCEPTION_GUARD_END
1026 }
1027
1028 BOOST_AUTO_TEST_SUITE_END()