remove CAP_MAC_OVERRIDE from app2sd-server
[platform/core/appfw/app2sd.git] / test / src / test_app2ext.c
1 /*
2  * test_app2ext
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <assert.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <malloc.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <errno.h>
28 #include <sys/wait.h>
29 #include <sys/types.h>
30 #include <getopt.h>
31 #include <unzip.h>
32
33 #include "app2ext_interface.h"
34 #include "app2ext_utils.h"
35
36 #define SUCCESS 0
37 #define FAIL 1
38 #define CMD_LEN 256
39 #define TEST_PKGNAME "org.example.basicuiapplication"
40 #define TEST_PKGNAME_PATH "/tmp/org.example.basicuiapplication-1.0.0-arm.tpk"
41
42 app2ext_handle *handle = NULL;
43
44 char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
45
46 #define COUNT_OF_ERROR_LIST APP2EXT_ERROR_ENUM_MAX
47 char error_list[COUNT_OF_ERROR_LIST][100] = {
48         "SUCCESS",
49         "APP2EXT_ERROR_UNKNOWN",
50         "APP2EXT_ERROR_INVALID_ARGUMENTS",
51         "APP2EXT_ERROR_MOVE",
52         "APP2EXT_ERROR_PRE_UNINSTALL",
53         "APP2EXT_ERROR_MMC_STATUS",
54         "APP2EXT_ERROR_DB_INITIALIZE",
55         "APP2EXT_ERROR_SQLITE_REGISTRY",
56         "APP2EXT_ERROR_PASSWD_GENERATION",
57         "APP2EXT_ERROR_MMC_INFORMATION",
58         "APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY",
59         "APP2EXT_ERROR_DELETE_DIRECTORY",
60         "APP2EXT_ERROR_CREATE_SYMLINK",
61         "APP2EXT_ERROR_CREATE_DIRECTORY",
62         "APP2EXT_ERROR_DELETE_LINK_FILE",
63         "APP2EXT_ERROR_PKG_EXISTS",
64         "APP2EXT_ERROR_ACCESS_FILE",
65         "APP2EXT_ERROR_OPEN_DIR",
66         "APP2EXT_ERROR_ALREADY_FILE_PRESENT",
67         "APP2EXT_ERROR_FILE_ABSENT",
68         "APP2EXT_ERROR_STRCMP_FAILED",
69         "APP2EXT_ERROR_INVALID_PACKAGE",
70         "APP2EXT_ERROR_CREATE_DIR_ENTRY",
71         "APP2EXT_ERROR_COPY_DIRECTORY",
72         "APP2EXT_ERROR_INVALID_CASE",
73         "APP2EXT_ERROR_SYMLINK_ALREADY_EXISTS",
74         "APP2EXT_ERROR_APPEND_HASH_TO_FILE",
75         "APP2EXT_ERROR_CREATE_DEVICE",
76         "APP2EXT_ERROR_DO_LOSETUP",
77         "APP2EXT_ERROR_CREATE_FS",
78         "APP2EXT_ERROR_MOUNT_PATH",
79         "APP2EXT_ERROR_CLEANUP",
80         "APP2EXT_ERROR_MOUNT",
81         "APP2EXT_ERROR_REMOUNT",
82         "APP2EXT_ERROR_PIPE_CREATION",
83         "APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE",
84         "APP2EXT_ERROR_VCONF_REGISTRY",
85         "APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE",
86         "APP2EXT_ERROR_UNMOUNT",
87         "APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE",
88         "APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE",
89         "APP2EXT_ERROR_ALREADY_MOUNTED",
90         "APP2EXT_ERROR_PLUGIN_INIT_FAILED",
91         "APP2EXT_ERROR_PLUGIN_DEINIT_FAILED",
92         "APP2EXT_ERROR_DBUS_FAILED",
93         "APP2EXT_ERROR_MEMORY_ALLOC_FAILED",
94         "APP2EXT_ERROR_OPERATION_NOT_PERMITTED",
95         "APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS",
96         "APP2EXT_ERROR_PKGMGR_ERROR",
97 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
98         "APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE",
99         "APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE",
100         "APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE",
101         "APP2EXT_ERROR_FIND_ASSOCIATED_DMCRYPT_DEVICE_NODE",
102         "APP2EXT_ERROR_DMCRYPT_DEVICE_UNAVAILABLE",
103 #endif
104 };
105
106 static void usage(void)
107 {
108         printf("\n");
109         printf("*************************************************\n");
110         printf("app2sd test usage:\n");
111         printf("pre-condition: /tmp/org.example.basicuiapplication-1.0.0-arm.tpk\n");
112         printf("\n");
113         printf("<INSTALL>\n");
114         printf("1.(at target_user)$test_app2ext --pre-install\n");
115         printf("2.(at target_user)$pkgcmd -it tpk {pkg-path}\n");
116         printf("3.(at target_user)$test_app2ext --post-install\n");
117         printf("------------------------------------------------\n");
118         printf("\n");
119         printf("<UPGRADE>\n");
120         printf("1.(at target_user)$test_app2ext --pre-upgrade\n");
121         printf("2.(at target_user)$pkgcmd -it tpk {pkg-path}\n");
122         printf("3.(at target_user)$test_app2ext --post-upgrade\n");
123         printf("------------------------------------------------\n");
124         printf("\n");
125         printf("<INSTALL>\n");
126         printf("1.(at target_user)$test_app2ext --pre-uninstall\n");
127         printf("2.(at target_user)$pkgcmd -un {pkg-id}\n");
128         printf("3.(at target_user)$test_app2ext --post-uninstall\n");
129         printf("------------------------------------------------\n");
130         printf("\n");
131         printf("<MOVE PKG TEST>\n");
132         printf("(at target_user)$test_app2ext --move\n");
133         printf("------------------------------------------------\n");
134         printf("\n");
135         printf("<GET INSTALLED LOCATION (Ext/Internal)>\n");
136         printf("(at target_user)$test_app2ext --getlocation\n");
137         printf("------------------------------------------------\n");
138         printf("\n");
139         printf("<ENABLE(mount)/DISABLE(umount) TEST W/ Installed PKG>\n");
140         printf("(at target_user)$test_app2ext --enable\n");
141         printf("(at target_user)$test_app2ext --disable\n");
142         printf("(at target_user)$test_app2ext --enable-full\n");
143         printf("(at target_user)$test_app2ext --disable-full\n");
144         printf("------------------------------------------------\n");
145         printf("**************************************************\n");
146         printf("\n");
147 }
148
149 #define OPTVAL_PRE_INSTALL              1000
150 #define OPTVAL_POST_INSTALL             1001
151 #define OPTVAL_PRE_UNINSTALL            1002
152 #define OPTVAL_POST_UNINSTALL           1003
153 #define OPTVAL_PRE_UPGRADE              1004
154 #define OPTVAL_POST_UPGRADE             1005
155 #define OPTVAL_MOVE                     1006
156 #define OPTVAL_GET_LOCATION             1007
157 #define OPTVAL_ENABLE_APP               1008
158 #define OPTVAL_DISABLE_APP              1009
159 #define OPTVAL_ENABLE_FULL              1010
160 #define OPTVAL_DISABLE_FULL             1011
161 #define OPTVAL_USAGE                    1012
162
163 /* Supported options */
164 const struct option long_opts[] = {
165         { "pre-install", 0, NULL, OPTVAL_PRE_INSTALL },
166         { "post-install", 0, NULL, OPTVAL_POST_INSTALL },
167         { "pre-uninstall", 0, NULL, OPTVAL_PRE_UNINSTALL },
168         { "post-uninstall", 0, NULL, OPTVAL_POST_UNINSTALL },
169         { "pre-upgrade", 0, NULL, OPTVAL_PRE_UPGRADE },
170         { "post-upgrade", 0, NULL, OPTVAL_POST_UPGRADE },
171         { "move", 0, NULL, OPTVAL_MOVE },
172         { "getlocation", 0, NULL, OPTVAL_GET_LOCATION },
173         { "enable", 0, NULL, OPTVAL_ENABLE_APP },
174         { "disable", 0, NULL, OPTVAL_DISABLE_APP },
175         { "enable-full", 0, NULL, OPTVAL_ENABLE_FULL },
176         { "disable-full", 0, NULL, OPTVAL_DISABLE_FULL },
177         { "help", 0, NULL, OPTVAL_USAGE },
178         { "usage", 0, NULL, OPTVAL_USAGE },
179         { 0, 0, 0, 0 }  /* sentinel */
180 };
181
182 void clear_dir_list(GList *dir_list)
183 {
184         GList *list = NULL;
185         app2ext_dir_details *dir_detail = NULL;
186
187         if (dir_list) {
188                 list = g_list_first(dir_list);
189                 while (list) {
190                         dir_detail = (app2ext_dir_details *)list->data;
191                         if (dir_detail && dir_detail->name)
192                                 free(dir_detail->name);
193
194                         list = g_list_next(list);
195                 }
196                 g_list_free(dir_list);
197         }
198 }
199
200 GList *populate_dir_details()
201 {
202         GList *dir_list = NULL;
203         GList *list = NULL;
204         app2ext_dir_details *dir_detail = NULL;
205         int i;
206
207         for (i = 0; i < 3; i++) {
208                 dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
209                 if (dir_detail == NULL) {
210                         printf("memory allocation failed\n");
211                         goto FINISH_OFF;
212                 }
213
214                 dir_detail->name = (char *)calloc(1, sizeof(char) * (strlen(pkg_ro_content_rpm[i]) + 2));
215                 if (dir_detail->name == NULL) {
216                         printf("memory allocation failed\n");
217                         free(dir_detail);
218                         goto FINISH_OFF;
219                 }
220                 snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i]) + 1), "%s", pkg_ro_content_rpm[i]);
221                 dir_detail->type = APP2EXT_DIR_RO;
222                 dir_list = g_list_append(dir_list, dir_detail);
223         }
224
225         if (dir_list) {
226                 list = g_list_first(dir_list);
227                 while (list) {
228                         dir_detail = (app2ext_dir_details *)list->data;
229                         list = g_list_next(list);
230                 }
231         }
232
233         return dir_list;
234
235 FINISH_OFF:
236
237         clear_dir_list(dir_list);
238
239         return NULL;
240 }
241
242 static int get_unzip_size(const char *item, unsigned long long *size)
243 {
244         int ret = 0;
245         unzFile uzf = NULL;
246         char *filename = NULL;
247         unz_file_info fileInfo = { 0 };
248
249         if (!item || !size) {
250                 printf("get size : invalid argument\n");
251                 return -1;
252         }
253         uzf = unzOpen64(item);
254         if (uzf == NULL) {
255                 printf("get size : failed to open item : [%s]\n", item);
256                 *size = 0;
257                 return -1;
258         } else {
259                 ret = unzGoToFirstFile(uzf);
260                 if (ret != UNZ_OK) {
261                         printf("get size : error get first zip file\n");
262                         unzClose(uzf);
263                         *size = 0;
264                         return -1;
265                 } else {
266                         do {
267                                 ret = unzOpenCurrentFile(uzf);
268                                 if (ret != UNZ_OK) {
269                                         printf("get size : error unzOpenCurrentFile\n");
270                                         unzClose(uzf);
271                                         *size = 0;
272                                         return -1;
273                                 }
274
275                                 filename = (char *)calloc(1, 4096);
276                                 ret = unzGetCurrentFileInfo(uzf, &fileInfo, filename, (4096 - 1), NULL, 0, NULL, 0);
277                                 *size = (unsigned long long)fileInfo.uncompressed_size + *size;
278                                 if (ret != UNZ_OK) {
279                                         printf("get size : error get current file info\n");
280                                         unzCloseCurrentFile(uzf);
281                                         *size = 0;
282                                         free(filename);
283                                         filename = NULL;
284                                         break;
285                                 }
286
287                                 free(filename);
288                                 filename = NULL;
289                         } while (unzGoToNextFile(uzf) == UNZ_OK);
290                 }
291         }
292         unzClose(uzf);
293
294         return 0;
295 }
296
297 static void print_error_code(const char *func_name, int ret)
298 {
299         if (ret < 0 || ret > COUNT_OF_ERROR_LIST - 1)
300                 printf("%s failed : unknown error(%d)\n", func_name, ret);
301         else
302                 printf("%s return(%s)\n", func_name, error_list[ret]);
303 }
304
305 static int pre_app_install()
306 {
307         GList *dir_list = NULL;
308         int ret = -1;
309         unsigned long long size_byte = 0;
310         int size_mega = 0;
311
312         printf("pre_app_install for [%s]\n", TEST_PKGNAME_PATH);
313
314         dir_list = populate_dir_details();
315         if (dir_list == NULL) {
316                 printf("error in populating the directory list\n");
317                 return -1;
318         }
319
320         /* size : in MB */
321         ret = get_unzip_size(TEST_PKGNAME_PATH, &size_byte);
322         if (ret < 0 || size_byte == 0)
323                 printf("wrong pkg size, ret(%d), size_byte(%llu)\n", ret, size_byte);
324
325         size_mega = size_byte / (1024 * 1024) + 1;
326         printf("get pkg size : (%d)MB\n", size_mega);
327
328         ret = handle->interface.client_pre_install(TEST_PKGNAME,
329                 dir_list, size_mega);
330         print_error_code(__func__, ret);
331
332         clear_dir_list(dir_list);
333
334         return ret;
335 }
336
337 static int post_app_install()
338 {
339         int ret = -1;
340
341         ret = handle->interface.client_post_install(TEST_PKGNAME,
342                 APP2EXT_STATUS_SUCCESS);
343         print_error_code(__func__, ret);
344
345         return ret;
346 }
347
348 static int app_enable()
349 {
350         int ret = -1;
351
352         ret = handle->interface.client_enable(TEST_PKGNAME);
353         print_error_code(__func__, ret);
354
355         return ret;
356 }
357
358 static int app_disable()
359 {
360         int ret = -1;
361
362         ret = handle->interface.client_disable(TEST_PKGNAME);
363         print_error_code(__func__, ret);
364
365         return ret;
366 }
367
368 static int fullpkg_enable()
369 {
370         int ret = -1;
371
372         ret = handle->interface.client_enable_full_pkg();
373         print_error_code(__func__, ret);
374
375         return ret;
376 }
377
378 static int fullpkg_disable()
379 {
380         int ret = -1;
381
382         ret = handle->interface.client_disable_full_pkg();
383         print_error_code(__func__, ret);
384
385         return ret;
386 }
387
388 static int pre_app_uninstall()
389 {
390         int ret = -1;
391
392         printf("pre_app_uninstall for [%s]\n", TEST_PKGNAME);
393
394         ret = handle->interface.client_pre_uninstall(TEST_PKGNAME);
395         print_error_code(__func__, ret);
396
397         return ret;
398 }
399
400 static int post_app_uninstall()
401 {
402         int ret = -1;
403
404         ret = handle->interface.client_post_uninstall(TEST_PKGNAME);
405         print_error_code(__func__, ret);
406
407         return ret;
408 }
409
410 static int pre_app_upgrade()
411 {
412         GList *dir_list = NULL;
413         int ret = -1;
414         unsigned long long size_byte = 0;
415         int size_mega = 0;
416
417         printf("pre_app_upgrade for [%s]\n", TEST_PKGNAME);
418
419         dir_list = populate_dir_details();
420         if (dir_list == NULL) {
421                 printf("Error in populating the directory list\n");
422                 return -1;
423         }
424
425         /* size : in MB */
426         ret = get_unzip_size(TEST_PKGNAME_PATH, &size_byte);
427         if (ret < 0 || size_byte == 0)
428                 printf("wrong pkg size, ret(%d), size_byte(%llu)\n", ret, size_byte);
429
430         size_mega = size_byte / (1024 * 1024) + 1;
431         printf("get pkg size : (%d)MB\n", size_mega);
432
433         ret = handle->interface.client_pre_upgrade(TEST_PKGNAME, dir_list,
434                 size_mega);
435         print_error_code(__func__, ret);
436
437         clear_dir_list(dir_list);
438
439         return ret;
440 }
441
442 static int post_app_upgrade()
443 {
444         int ret = -1;
445
446         ret = handle->interface.client_post_upgrade(TEST_PKGNAME,
447                 APP2EXT_STATUS_SUCCESS);
448         print_error_code(__func__, ret);
449
450         return ret;
451 }
452
453 static int app_move()
454 {
455         GList *dir_list = NULL;
456         int ret = -1;
457         int ret_check = -1;
458
459         printf("app_move  %s\n", TEST_PKGNAME);
460
461         dir_list = populate_dir_details();
462         if (dir_list == NULL) {
463                 printf("Error in populating the directory list\n");
464                 return -1;
465         }
466
467         ret = app2ext_usr_get_app_location(TEST_PKGNAME, getuid());
468         printf("return value = (%d)\n", ret);
469         if (ret == APP2EXT_SD_CARD) {
470                 printf("pkg %s is in sd card\n", TEST_PKGNAME);
471                 printf("pkg %s will be moved to internal memory\n", TEST_PKGNAME);
472                 ret = handle->interface.client_pre_move(TEST_PKGNAME,
473                         dir_list, APP2EXT_MOVE_TO_PHONE);
474                 print_error_code(__func__, ret);
475                 ret = handle->interface.client_post_move(TEST_PKGNAME,
476                         APP2EXT_MOVE_TO_PHONE);
477                 print_error_code(__func__, ret);
478                 ret_check = app2ext_usr_get_app_location(TEST_PKGNAME, getuid());
479                 if (ret_check == APP2EXT_INTERNAL_MEM)
480                         printf("pkg %s is moved to internal memory\n", TEST_PKGNAME);
481         } else if (ret == APP2EXT_INTERNAL_MEM) {
482                 printf("pkg %s is in internal memory\n", TEST_PKGNAME);
483                 printf("pkg %s will be moved to sd card\n", TEST_PKGNAME);
484                 ret = handle->interface.client_pre_move(TEST_PKGNAME,
485                         dir_list, APP2EXT_MOVE_TO_EXT);
486                 print_error_code(__func__, ret);
487                 ret = handle->interface.client_post_move(TEST_PKGNAME,
488                         APP2EXT_MOVE_TO_EXT);
489                 print_error_code(__func__, ret);
490                 ret_check = app2ext_usr_get_app_location(TEST_PKGNAME, getuid());
491                 if (ret_check == APP2EXT_SD_CARD)
492                         printf("pkg %s is moved to sd card\n", TEST_PKGNAME);
493         }  else {
494                 ret = APP2EXT_ERROR_INVALID_PACKAGE;
495                 printf("app_move failed (%s)\n", error_list[ret]);
496         }
497
498         clear_dir_list(dir_list);
499
500         return ret;
501 }
502
503 static void app_get_location()
504 {
505         printf("app_get_location for pkg(%s)\n", TEST_PKGNAME);
506         int ret = -1;
507
508         ret = app2ext_usr_get_app_location(TEST_PKGNAME, getuid());
509         if (ret == APP2EXT_SD_CARD)
510                 printf("pkg is in sd card\n");
511          else if (ret == APP2EXT_INTERNAL_MEM)
512                 printf("pkg is in internal memory\n");
513          else
514                 printf("pkg is not installed\n");
515 }
516
517 int main(int argc, char **argv)
518 {
519         int ret = 0;
520         int opt_idx = 0;
521         int c;
522         uid_t uid = getuid();
523
524         /* check user */
525         if (uid == GLOBAL_USER) {
526                 printf("test for global app\n");
527         } else if (uid == OWNER_ROOT) {
528                 printf("for root user, a test isn't supproted yet\n");
529                 return 0;
530         } else {
531                 printf("test for user(%d) app\n", uid);
532         }
533
534         handle = app2ext_init(APP2EXT_SD_CARD);
535         if (handle == NULL) {
536                 ret = APP2EXT_ERROR_PLUGIN_INIT_FAILED;
537                 printf("app2ext_init failed (%s)\n", error_list[ret]);
538                 return -1;
539         }
540
541         /* Parse argv */
542         optind = 1;  /* Initialize optind to clear prev. index */
543         while (1) {
544                 c = getopt_long(argc, argv, "", long_opts, &opt_idx);
545                 if (-1 == c) {
546                         usage();
547                         break;  /* Parse is end */
548                 }
549                 switch (c) {
550                 case OPTVAL_PRE_INSTALL:
551                         pre_app_install();
552                         break;
553                 case OPTVAL_POST_INSTALL:
554                         post_app_install();
555                         break;
556                 case OPTVAL_PRE_UNINSTALL:
557                         pre_app_uninstall();
558                         break;
559                 case OPTVAL_POST_UNINSTALL:
560                         post_app_uninstall();
561                         break;
562                 case OPTVAL_PRE_UPGRADE:
563                         pre_app_upgrade();
564                         break;
565                 case OPTVAL_POST_UPGRADE:
566                         post_app_upgrade();
567                         break;
568                 case OPTVAL_MOVE:
569                         app_move();
570                         break;
571                 case OPTVAL_GET_LOCATION:
572                         app_get_location();
573                         break;
574                 case OPTVAL_ENABLE_APP:
575                         app_enable();
576                         break;
577                 case OPTVAL_DISABLE_APP:
578                         app_disable();
579                         break;
580                 case OPTVAL_ENABLE_FULL:
581                         fullpkg_enable();
582                         break;
583                 case OPTVAL_DISABLE_FULL:
584                         fullpkg_disable();
585                         break;
586                 case OPTVAL_USAGE:
587                 default:
588                         usage();
589                         break;
590                 }
591
592                 break;
593         }
594
595         app2ext_deinit(handle);
596
597         return 0;
598 }