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