Fix smoketest
[platform/core/appfw/wgt-backend.git] / src / unit_tests / smoke_test.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
4
5 #include <boost/filesystem/operations.hpp>
6 #include <boost/filesystem/path.hpp>
7 #include <boost/range/iterator_range.hpp>
8 #include <boost/system/error_code.hpp>
9
10 #include <common/paths.h>
11 #include <common/pkgmgr_interface.h>
12 #include <common/pkgmgr_query.h>
13 #include <common/request.h>
14 #include <common/step/configuration/step_fail.h>
15 #include <common/tzip_interface.h>
16 #include <common/utils/file_util.h>
17 #include <common/utils/subprocess.h>
18 #include <common/utils/user_util.h>
19
20 #include <gtest/gtest.h>
21 #include <gtest/gtest-death-test.h>
22 #include <pkgmgr-info.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <tzplatform_config.h>
26
27 #include <array>
28 #include <cstdio>
29 #include <cstdlib>
30 #include <vector>
31
32 #include "hybrid/hybrid_installer.h"
33 #include "wgt/wgt_app_query_interface.h"
34 #include "wgt/wgt_installer.h"
35
36 #define SIZEOFARRAY(ARR)                                                       \
37   sizeof(ARR) / sizeof(ARR[0])                                                 \
38
39 namespace bf = boost::filesystem;
40 namespace bs = boost::system;
41 namespace ci = common_installer;
42
43 namespace {
44
45 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
46 const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
47 const uid_t kTestUserId = kGlobalUserUid;
48 const gid_t kTestGroupId = kGlobalUserGid;
49 const char kSystemShareGroupName[] = "system_share";
50 const std::string kTestUserIdStr =
51     std::to_string(kTestUserId);
52
53 const bf::path kSmokePackagesDirectory =
54     "/usr/share/wgt-backend-ut/test_samples/smoke/";
55
56 // common entries
57 const std::vector<std::string> kDBEntries = {
58   {".pkgmgr_parser.db"},
59   {".pkgmgr_parser.db-journal"},
60   {".pkgmgr_cert.db"},
61   {".pkgmgr_cert.db-journal"},
62 };
63 // globaluser entries
64 const char kGlobalManifestDir[] = "/opt/share/packages";
65 const char kSkelDir[] = "/etc/skel/apps_rw";
66
67 enum class RequestResult {
68   NORMAL,
69   FAIL
70 };
71
72 class ScopedTzipInterface {
73  public:
74   explicit ScopedTzipInterface(const std::string& pkgid)
75       : pkg_path_(bf::path(ci::GetRootAppPath(false,
76             kTestUserId)) / pkgid),
77         interface_(ci::GetMountLocation(pkg_path_)),
78         mounted_(true) {
79     interface_.MountZip(ci::GetZipPackageLocation(pkg_path_, pkgid));
80   }
81
82   void Release() {
83     if (mounted_) {
84       interface_.UnmountZip();
85       mounted_ = false;
86     }
87   }
88
89   ~ScopedTzipInterface() {
90     Release();
91   }
92
93  private:
94   bf::path pkg_path_;
95   ci::TzipInterface interface_;
96   bool mounted_;
97 };
98
99 class TestPkgmgrInstaller : public ci::PkgmgrInstallerInterface {
100  public:
101   bool CreatePkgMgrInstaller(pkgmgr_installer** installer,
102                              ci::InstallationMode* mode) {
103     *installer = pkgmgr_installer_offline_new();
104     if (!*installer)
105       return false;
106     *mode = ci::InstallationMode::ONLINE;
107     return true;
108   }
109
110   bool ShouldCreateSignal() const {
111     return false;
112   }
113 };
114
115 enum class PackageType {
116   WGT,
117   HYBRID
118 };
119
120 bool TouchFile(const bf::path& path) {
121   FILE* f = fopen(path.c_str(), "w+");
122   if (!f)
123     return false;
124   fclose(f);
125   return true;
126 }
127
128 void RemoveAllRecoveryFiles() {
129   bf::path root_path = ci::GetRootAppPath(false,
130       kTestUserId);
131   if (!bf::exists(root_path))
132     return;
133   for (auto& dir_entry : boost::make_iterator_range(
134          bf::directory_iterator(root_path), bf::directory_iterator())) {
135     if (bf::is_regular_file(dir_entry)) {
136       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
137         bs::error_code error;
138         bf::remove(dir_entry.path(), error);
139       }
140     }
141   }
142 }
143
144 bf::path FindRecoveryFile() {
145   bf::path root_path = ci::GetRootAppPath(false,
146       kTestUserId);
147   for (auto& dir_entry : boost::make_iterator_range(
148          bf::directory_iterator(root_path), bf::directory_iterator())) {
149     if (bf::is_regular_file(dir_entry)) {
150       if (dir_entry.path().string().find("/recovery") != std::string::npos) {
151         return dir_entry.path();
152       }
153     }
154   }
155   return {};
156 }
157
158 bf::path GetPackageRoot(const std::string& pkgid, uid_t uid) {
159   bf::path root_path = ci::GetRootAppPath(false, uid);
160   return root_path / pkgid;
161 }
162
163 bool ValidateFileContentInPackage(const std::string& pkgid,
164                                   const std::string& relative,
165                                   const std::string& expected) {
166   bf::path file_path = GetPackageRoot(pkgid, kTestUserId) / relative;
167   if (!bf::exists(file_path)) {
168     LOG(ERROR) << file_path << " doesn't exist";
169     return false;
170   }
171   FILE* handle = fopen(file_path.c_str(), "r");
172   if (!handle) {
173     LOG(ERROR) << file_path << " cannot  be open";
174     return false;
175   }
176   std::string content;
177   std::array<char, 200> buffer;
178   while (fgets(buffer.data(), buffer.size(), handle)) {
179     content += buffer.data();
180   }
181   fclose(handle);
182   return content == expected;
183 }
184
185 void AddDataFiles(const std::string& pkgid, uid_t uid) {
186   if (uid == kGlobalUserUid) {
187     ci::UserList list = ci::GetUserList();
188     for (auto l : list) {
189       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
190       ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
191       ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
192     }
193   } else {
194     auto pkg_path = GetPackageRoot(pkgid, uid);
195     ASSERT_TRUE(TouchFile(pkg_path / "data" / "file1.txt"));
196     ASSERT_TRUE(TouchFile(pkg_path / "data" / "file2.txt"));
197   }
198 }
199
200 void ValidateDataFiles(const std::string& pkgid, uid_t uid) {
201   if (uid == kGlobalUserUid) {
202     ci::UserList list = ci::GetUserList();
203     for (auto l : list) {
204       auto pkg_path = GetPackageRoot(pkgid, std::get<0>(l));
205       ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
206       ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
207     }
208   } else {
209     auto pkg_path = GetPackageRoot(pkgid, uid);
210     ASSERT_TRUE(bf::exists(pkg_path / "data" / "file1.txt"));
211     ASSERT_TRUE(bf::exists(pkg_path / "data" / "file2.txt"));
212   }
213 }
214
215 void ValidatePackageRWFS(const std::string& pkgid, uid_t uid, gid_t gid) {
216   bf::path root_path = ci::GetRootAppPath(false, uid);
217   bf::path package_path = root_path / pkgid;
218   bf::path data_path = package_path / "data";
219   bf::path cache_path = package_path / "cache";
220   bf::path shared_data_path = package_path / "shared" / "data";
221
222   ASSERT_TRUE(bf::exists(data_path));
223   ASSERT_TRUE(bf::exists(cache_path));
224
225   struct stat stats;
226   stat(data_path.c_str(), &stats);
227   // gid of data, and shared/data should be system_share
228   boost::optional<gid_t> system_share =
229     ci::GetGidByGroupName(kSystemShareGroupName);
230   ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << data_path;
231   ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: " << data_path;
232   if (bf::exists(shared_data_path)) {
233     stat(shared_data_path.c_str(), &stats);
234     ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << shared_data_path;
235     ASSERT_EQ(*system_share, stats.st_gid) << "Invalid gid: "
236       << shared_data_path;
237   }
238
239   stat(cache_path.c_str(), &stats);
240   ASSERT_EQ(uid, stats.st_uid) << "Invalid gid: " << cache_path;
241   ASSERT_EQ(gid, stats.st_gid) << "Invalid gid: " << cache_path;
242 }
243
244 void ValidatePackageFS(const std::string& pkgid,
245                        const std::vector<std::string>& appids,
246                        uid_t uid, gid_t gid) {
247   bf::path root_path = ci::GetRootAppPath(false, uid);
248   bf::path package_path = GetPackageRoot(pkgid, uid);
249   bf::path shared_path = package_path / "shared";
250   ASSERT_TRUE(bf::exists(root_path));
251   ASSERT_TRUE(bf::exists(package_path));
252   ASSERT_TRUE(bf::exists(shared_path));
253
254   bf::path manifest_path =
255       bf::path(getUserManifestPath(uid, false)) / (pkgid + ".xml");
256   ASSERT_TRUE(bf::exists(manifest_path));
257
258   for (auto& appid : appids) {
259     bf::path binary_path = package_path / "bin" / appid;
260     ASSERT_TRUE(bf::exists(binary_path));
261   }
262
263   bf::path widget_root_path = package_path / "res" / "wgt";
264   bf::path config_path = widget_root_path / "config.xml";
265   ASSERT_TRUE(bf::exists(widget_root_path));
266   ASSERT_TRUE(bf::exists(config_path));
267
268   bf::path private_tmp_path = package_path / "tmp";
269   ASSERT_TRUE(bf::exists(private_tmp_path));
270
271   // backups should not exist
272   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
273   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
274   ASSERT_FALSE(bf::exists(package_backup));
275   ASSERT_FALSE(bf::exists(manifest_backup));
276
277   for (bf::recursive_directory_iterator iter(package_path);
278       iter != bf::recursive_directory_iterator(); ++iter) {
279     if (bf::is_symlink(symlink_status(iter->path())))
280       continue;
281     if (iter->path().filename() == "data")
282       continue;
283     struct stat stats;
284     stat(iter->path().c_str(), &stats);
285     ASSERT_EQ(uid, stats.st_uid) << "Invalid uid: " << iter->path();
286     ASSERT_EQ(gid, stats.st_gid) << "Invalid gid: " << iter->path();
287   }
288 }
289
290 void PackageCheckCleanup(const std::string& pkgid,
291                          const std::vector<std::string>&) {
292   bf::path package_path = GetPackageRoot(pkgid, kTestUserId);
293   ASSERT_FALSE(bf::exists(package_path));
294
295   bf::path manifest_path =
296       bf::path(getUserManifestPath(
297           kTestUserId, false)) / (pkgid + ".xml");
298   ASSERT_FALSE(bf::exists(manifest_path));
299
300   // backups should not exist
301   bf::path package_backup = ci::GetBackupPathForPackagePath(package_path);
302   bf::path manifest_backup = ci::GetBackupPathForManifestFile(manifest_path);
303   ASSERT_FALSE(bf::exists(package_backup));
304   ASSERT_FALSE(bf::exists(manifest_backup));
305 }
306
307 void ValidatePackage(const std::string& pkgid,
308                      const std::vector<std::string>& appids) {
309   ASSERT_TRUE(ci::QueryIsPackageInstalled(
310       pkgid, ci::GetRequestMode(kTestUserId),
311       kTestUserId));
312   ValidatePackageFS(pkgid, appids, kTestUserId, kTestGroupId);
313   if (kTestUserId == kGlobalUserUid) {
314     ci::UserList list = ci::GetUserList();
315     for (auto& l : list)
316       ValidatePackageRWFS(pkgid, std::get<0>(l), std::get<1>(l));
317   } else {
318     ValidatePackageRWFS(pkgid, kTestUserId, kTestGroupId);
319   }
320 }
321
322 void CheckPackageNonExistance(const std::string& pkgid,
323                               const std::vector<std::string>& appids) {
324   ASSERT_FALSE(ci::QueryIsPackageInstalled(
325       pkgid, ci::GetRequestMode(kTestUserId),
326       kTestUserId));
327   PackageCheckCleanup(pkgid, appids);
328 }
329
330 std::unique_ptr<ci::AppQueryInterface> CreateQueryInterface() {
331   std::unique_ptr<ci::AppQueryInterface> query_interface(
332       new wgt::WgtAppQueryInterface());
333   return query_interface;
334 }
335
336 std::unique_ptr<ci::AppInstaller> CreateInstaller(ci::PkgMgrPtr pkgmgr,
337                                                   PackageType type) {
338   switch (type) {
339     case PackageType::WGT:
340       return std::unique_ptr<ci::AppInstaller>(new wgt::WgtInstaller(pkgmgr));
341     case PackageType::HYBRID:
342       return std::unique_ptr<ci::AppInstaller>(
343           new hybrid::HybridInstaller(pkgmgr));
344     default:
345       LOG(ERROR) << "Unknown installer type";
346       return nullptr;
347   }
348 }
349
350 ci::AppInstaller::Result RunInstallerWithPkgrmgr(ci::PkgMgrPtr pkgmgr,
351                                                  PackageType type,
352                                                  RequestResult mode) {
353   std::unique_ptr<ci::AppInstaller> installer = CreateInstaller(pkgmgr, type);
354   switch (mode) {
355   case RequestResult::FAIL:
356     installer->AddStep<ci::configuration::StepFail>();
357     break;
358   default:
359     break;
360   }
361   return installer->Run();
362 }
363 ci::AppInstaller::Result CallBackend(int argc,
364                                      const char* argv[],
365                                      PackageType type,
366                                      RequestResult mode = RequestResult::NORMAL
367                                      ) {
368   TestPkgmgrInstaller pkgmgr_installer;
369   std::unique_ptr<ci::AppQueryInterface> query_interface =
370       CreateQueryInterface();
371   auto pkgmgr =
372       ci::PkgMgrInterface::Create(argc, const_cast<char**>(argv),
373                                   &pkgmgr_installer, query_interface.get());
374   if (!pkgmgr) {
375     LOG(ERROR) << "Failed to initialize pkgmgr interface";
376     return ci::AppInstaller::Result::UNKNOWN;
377   }
378   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
379 }
380
381 ci::AppInstaller::Result Install(const bf::path& path,
382                                  PackageType type,
383                                  RequestResult mode = RequestResult::NORMAL) {
384   const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
385   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
386 }
387
388 ci::AppInstaller::Result MountInstall(const bf::path& path,
389     PackageType type, RequestResult mode = RequestResult::NORMAL) {
390   const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()};
391   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
392 }
393
394 ci::AppInstaller::Result Uninstall(const std::string& pkgid,
395                                    PackageType type,
396                                    RequestResult mode = RequestResult::NORMAL) {
397   const char* argv[] = {"", "-d", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
398   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
399 }
400
401 ci::AppInstaller::Result RDSUpdate(const bf::path& path,
402                                    const std::string& pkgid,
403                                    PackageType type,
404                                    RequestResult mode = RequestResult::NORMAL) {
405   if (Install(path, type) != ci::AppInstaller::Result::OK) {
406     LOG(ERROR) << "Failed to install application. Cannot perform RDS";
407     return ci::AppInstaller::Result::UNKNOWN;
408   }
409   const char* argv[] = {"", "-r", pkgid.c_str(), "-u",
410                         kTestUserIdStr.c_str()};
411   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
412 }
413
414 ci::AppInstaller::Result DeltaInstall(const bf::path& path,
415     const bf::path& delta_package, PackageType type) {
416   if (Install(path, type) != ci::AppInstaller::Result::OK) {
417     LOG(ERROR) << "Failed to install application. Cannot perform delta update";
418     return ci::AppInstaller::Result::UNKNOWN;
419   }
420   return Install(delta_package, type);
421 }
422
423 ci::AppInstaller::Result EnablePackage(const std::string& pkgid,
424                                   PackageType type,
425                                   RequestResult mode = RequestResult::NORMAL) {
426   const char* argv[] = {"", "-A", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
427   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
428 }
429
430 ci::AppInstaller::Result DisablePackage(const std::string& pkgid,
431                                   PackageType type,
432                                   RequestResult mode = RequestResult::NORMAL) {
433   const char* argv[] = {"", "-D", pkgid.c_str(), "-u", kTestUserIdStr.c_str()};
434   return CallBackend(SIZEOFARRAY(argv), argv, type, mode);
435 }
436
437 ci::AppInstaller::Result Recover(const bf::path& recovery_file,
438                                  PackageType type,
439                                  RequestResult mode = RequestResult::NORMAL) {
440   const char* argv[] = {"", "-b", recovery_file.c_str(), "-u",
441                         kTestUserIdStr.c_str()};
442   TestPkgmgrInstaller pkgmgr_installer;
443   std::unique_ptr<ci::AppQueryInterface> query_interface =
444       CreateQueryInterface();
445   auto pkgmgr =
446       ci::PkgMgrInterface::Create(SIZEOFARRAY(argv), const_cast<char**>(argv),
447                                   &pkgmgr_installer, query_interface.get());
448   if (!pkgmgr) {
449     LOG(ERROR) << "Failed to initialize pkgmgr interface";
450     return ci::AppInstaller::Result::UNKNOWN;
451   }
452   return RunInstallerWithPkgrmgr(pkgmgr, type, mode);
453 }
454
455 void BackupPath(const bf::path& path) {
456   bf::path backup_path = path.string() + ".bck";
457   std::cout << "Backup path: " << path << " to " << backup_path << std::endl;
458   bs::error_code error;
459   bf::remove_all(backup_path, error);
460   if (error)
461     LOG(ERROR) << "Remove failed: " << backup_path
462                << " (" << error.message() << ")";
463   if (bf::exists(path)) {
464     bf::rename(path, backup_path, error);
465     if (error)
466       LOG(ERROR) << "Failed to setup test environment. Does some previous"
467                  << " test crashed? Path: "
468                  << backup_path << " should not exist.";
469     assert(!error);
470   }
471 }
472
473 void RestorePath(const bf::path& path) {
474   bf::path backup_path = path.string() + ".bck";
475   std::cout << "Restore path: " << path << " from " << backup_path << std::endl;
476   bs::error_code error;
477   bf::remove_all(path, error);
478   if (error)
479     LOG(ERROR) << "Remove failed: " << path
480                << " (" << error.message() << ")";
481   if (bf::exists(backup_path)) {
482     bf::rename(backup_path, path, error);
483     if (error)
484       LOG(ERROR) << "Failed to restore backup path: " << backup_path
485                  << " (" << error.message() << ")";
486   }
487 }
488
489 std::vector<bf::path> SetupBackupDirectories(uid_t uid) {
490   std::vector<bf::path> entries;
491   bf::path db_dir = bf::path("/opt/dbspace");
492   if (uid != kGlobalUserUid)
493     db_dir = db_dir / "user" / std::to_string(uid);
494   for (auto e : kDBEntries) {
495     bf::path path = db_dir / e;
496     entries.emplace_back(path);
497   }
498
499   if (uid == kGlobalUserUid) {
500     entries.emplace_back(kSkelDir);
501     entries.emplace_back(kGlobalManifestDir);
502     ci::UserList list = ci::GetUserList();
503     for (auto l : list) {
504       bf::path apps = std::get<2>(l) / "apps_rw";
505       entries.emplace_back(apps);
506     }
507   } else {
508     tzplatform_set_user(uid);
509     bf::path approot = tzplatform_getenv(TZ_USER_APPROOT);
510     tzplatform_reset_user();
511     entries.emplace_back(approot);
512   }
513
514   bf::path apps_rw = ci::GetRootAppPath(false, uid);
515   entries.emplace_back(apps_rw);
516
517   return entries;
518 }
519
520 }  // namespace
521
522 namespace common_installer {
523
524 class SmokeEnvironment : public testing::Environment {
525  public:
526   explicit SmokeEnvironment(uid_t uid) : uid_(uid) {
527   }
528   void SetUp() override {
529     backups_ = SetupBackupDirectories(uid_);
530     for (auto& path : backups_)
531       BackupPath(path);
532   }
533   void TearDown() override {
534     // TODO(s89.jang): Uninstall smoke packages to clear security context
535     for (auto& path : backups_)
536       RestorePath(path);
537   }
538
539  private:
540   uid_t uid_;
541   std::vector<bf::path> backups_;
542 };
543
544 class SmokeTest : public testing::Test {
545 };
546
547 TEST_F(SmokeTest, InstallationMode) {
548   bf::path path = kSmokePackagesDirectory / "InstallationMode.wgt";
549   std::string pkgid = "smokeapp03";
550   std::string appid = "smokeapp03.InstallationMode";
551   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
552   ValidatePackage(pkgid, {appid});
553 }
554
555 TEST_F(SmokeTest, UpdateMode) {
556   bf::path path_old = kSmokePackagesDirectory / "UpdateMode.wgt";
557   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_2.wgt";
558   std::string pkgid = "smokeapp04";
559   std::string appid = "smokeapp04.UpdateMode";
560   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
561   AddDataFiles(pkgid, kTestUserId);
562   ASSERT_EQ(Install(path_new, PackageType::WGT), ci::AppInstaller::Result::OK);
563   ValidatePackage(pkgid, {appid});
564
565   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
566   ValidateDataFiles(pkgid, kTestUserId);
567 }
568
569 TEST_F(SmokeTest, DeinstallationMode) {
570   bf::path path = kSmokePackagesDirectory / "DeinstallationMode.wgt";
571   std::string pkgid = "smokeapp05";
572   std::string appid = "smokeapp05.DeinstallationMode";
573   ASSERT_EQ(Install(path, PackageType::WGT),
574             ci::AppInstaller::Result::OK);
575   ASSERT_EQ(Uninstall(pkgid, PackageType::WGT), ci::AppInstaller::Result::OK);
576   CheckPackageNonExistance(pkgid, {appid});
577 }
578
579 TEST_F(SmokeTest, RDSMode) {
580   bf::path path = kSmokePackagesDirectory / "RDSMode.wgt";
581   std::string pkgid = "smokeapp11";
582   std::string appid = "smokeapp11.RDSMode";
583   bf::path delta_directory = kSmokePackagesDirectory / "delta_dir/";
584   bf::path sdk_expected_directory =
585       bf::path(ci::GetRootAppPath(false, kTestUserId)) / "tmp" / pkgid;
586   bs::error_code error;
587   bf::create_directories(sdk_expected_directory.parent_path(), error);
588   ASSERT_FALSE(error);
589   ASSERT_TRUE(CopyDir(delta_directory, sdk_expected_directory));
590   ASSERT_EQ(RDSUpdate(path, pkgid, PackageType::WGT),
591             ci::AppInstaller::Result::OK);
592   ValidatePackage(pkgid, {appid});
593
594   // Check delta modifications
595   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / "res" / "wgt" / "DELETED"));
596   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) / "res" / "wgt" / "ADDED"));
597   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n"));
598 }
599
600 TEST_F(SmokeTest, EnablePkg) {
601   bf::path path = kSmokePackagesDirectory / "EnablePkg.wgt";
602   std::string pkgid = "smokeapp22";
603   ASSERT_EQ(Install(path, PackageType::WGT),
604             ci::AppInstaller::Result::OK);
605   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
606             ci::AppInstaller::Result::OK);
607   ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT),
608             ci::AppInstaller::Result::OK);
609
610   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid,
611       ci::GetRequestMode(kTestUserId),
612       kTestUserId));
613 }
614
615 TEST_F(SmokeTest, DisablePkg) {
616   bf::path path = kSmokePackagesDirectory / "DisablePkg.wgt";
617   std::string pkgid = "smokeapp21";
618   std::string appid = "smokeapp21.DisablePkg";
619   ASSERT_EQ(Install(path, PackageType::WGT),
620             ci::AppInstaller::Result::OK);
621   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
622             ci::AppInstaller::Result::OK);
623   ASSERT_TRUE(ci::QueryIsDisabledPackage(pkgid, kTestUserId));
624   ValidatePackage(pkgid, {appid});
625 }
626
627 TEST_F(SmokeTest, DeltaMode) {
628   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
629   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
630   std::string pkgid = "smokeapp17";
631   std::string appid = "smokeapp17.DeltaMode";
632   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
633             ci::AppInstaller::Result::OK);
634   ValidatePackage(pkgid, {appid});
635
636   // Check delta modifications
637   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
638         "res" / "wgt" / "DELETED"));
639   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
640         "res" / "wgt" / "ADDED"));
641   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
642         "res" / "wgt" / "css" / "style.css"));  // NOLINT
643   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
644         "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
645   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
646         "res" / "wgt" / "js" / "main.js"));  // NOLINT
647   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
648 }
649
650 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
651   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
652   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
653   backend_crash.Run("-i", path.string(), "-u", kTestUserIdStr.c_str());
654   ASSERT_NE(backend_crash.Wait(), 0);
655
656   std::string pkgid = "smokeapp09";
657   std::string appid = "smokeapp09.RecoveryModeForInstallation";
658   bf::path recovery_file = FindRecoveryFile();
659   ASSERT_FALSE(recovery_file.empty());
660   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
661       ci::AppInstaller::Result::OK);
662   CheckPackageNonExistance(pkgid, {appid});
663 }
664
665 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
666   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
667   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
668   RemoveAllRecoveryFiles();
669   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
670   std::string pkgid = "smokeapp10";
671   std::string appid = "smokeapp10.RecoveryModeForUpdate";
672   AddDataFiles(pkgid, kTestUserId);
673   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
674   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
675   ASSERT_NE(backend_crash.Wait(), 0);
676
677   bf::path recovery_file = FindRecoveryFile();
678   ASSERT_FALSE(recovery_file.empty());
679   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
680             ci::AppInstaller::Result::OK);
681   ValidatePackage(pkgid, {appid});
682
683   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
684   ValidateDataFiles(pkgid, kTestUserId);
685 }
686
687 TEST_F(SmokeTest, RecoveryMode_ForDelta) {
688   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForDelta.wgt";
689   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForDelta.delta";
690   RemoveAllRecoveryFiles();
691   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
692   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
693   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
694   ASSERT_NE(backend_crash.Wait(), 0);
695
696   std::string pkgid = "smokeapp30";
697   std::string appid = "smokeapp30.RecoveryModeForDelta";
698   bf::path recovery_file = FindRecoveryFile();
699   ASSERT_FALSE(recovery_file.empty());
700   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
701             ci::AppInstaller::Result::OK);
702   ValidatePackage(pkgid, {appid});
703
704   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
705 }
706
707 TEST_F(SmokeTest, RecoveryMode_ForMountInstall) {
708   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForMountInstall.wgt";
709   RemoveAllRecoveryFiles();
710   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
711   backend_crash.Run("-w", path.string(), "-u", kTestUserIdStr.c_str());
712   ASSERT_NE(backend_crash.Wait(), 0);
713
714   std::string pkgid = "smokeapp31";
715   std::string appid = "smokeapp31.RecoveryModeForMountInstall";
716   bf::path recovery_file = FindRecoveryFile();
717   ASSERT_FALSE(recovery_file.empty());
718   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
719             ci::AppInstaller::Result::OK);
720   CheckPackageNonExistance(pkgid, {appid});
721 }
722
723 TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) {
724   bf::path path_old =
725       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate.wgt";
726   bf::path path_new =
727       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate_2.wgt";
728   std::string pkgid = "smokeapp32";
729   std::string appid = "smokeapp32.RecoveryModeForMountUpdate";
730   RemoveAllRecoveryFiles();
731   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
732             ci::AppInstaller::Result::OK);
733   AddDataFiles(pkgid, kTestUserId);
734   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
735   backend_crash.Run("-w", path_new.string(), "-u", kTestUserIdStr.c_str());
736   ASSERT_NE(backend_crash.Wait(), 0);
737
738   // Filesystem may be mounted after crash
739   ScopedTzipInterface poweroff_unmount_interface(pkgid);
740   poweroff_unmount_interface.Release();
741
742   bf::path recovery_file = FindRecoveryFile();
743   ASSERT_FALSE(recovery_file.empty());
744   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
745             ci::AppInstaller::Result::OK);
746
747   ScopedTzipInterface interface(pkgid);
748   ValidatePackage(pkgid, {appid});
749   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
750   ValidateDataFiles(pkgid, kTestUserId);
751 }
752
753 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
754   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
755   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
756 }
757
758 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
759   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
760   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
761 }
762
763 TEST_F(SmokeTest, InstallationMode_Rollback) {
764   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
765   std::string pkgid = "smokeapp06";
766   std::string appid = "smokeapp06.InstallationModeRollback";
767   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
768             ci::AppInstaller::Result::ERROR);
769   CheckPackageNonExistance(pkgid, {appid});
770 }
771
772 TEST_F(SmokeTest, UpdateMode_Rollback) {
773   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
774   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
775   std::string pkgid = "smokeapp07";
776   std::string appid = "smokeapp07.UpdateModeRollback";
777   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
778   AddDataFiles(pkgid, kTestUserId);
779   ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL),
780                     ci::AppInstaller::Result::ERROR);
781   ValidatePackage(pkgid, {appid});
782
783   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
784   ValidateDataFiles(pkgid, kTestUserId);
785 }
786
787 TEST_F(SmokeTest, InstallationMode_Hybrid) {
788   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
789   std::string pkgid = "smokehyb01";
790   // Excutable for native app doesn't create symlink
791   std::string appid1 = "smokehyb01.Web";
792   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
793   ValidatePackage(pkgid, {appid1});
794 }
795
796 TEST_F(SmokeTest, UpdateMode_Hybrid) {
797   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
798   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
799   std::string pkgid = "smokehyb02";
800   std::string appid1 = "smokehyb02.Web";
801   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
802             ci::AppInstaller::Result::OK);
803 //  AddDataFiles(pkgid, kTestUserId);
804   ASSERT_EQ(Install(path_new, PackageType::HYBRID),
805             ci::AppInstaller::Result::OK);
806   ValidatePackage(pkgid, {appid1});
807
808   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
809   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
810 //  ValidateDataFiles(pkgid, kTestUserId);
811 }
812
813 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
814   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
815   std::string pkgid = "smokehyb03";
816   std::string appid1 = "smokehyb03.Web";
817   ASSERT_EQ(Install(path, PackageType::HYBRID),
818             ci::AppInstaller::Result::OK);
819   ASSERT_EQ(Uninstall(pkgid, PackageType::HYBRID),
820             ci::AppInstaller::Result::OK);
821   CheckPackageNonExistance(pkgid, {appid1});
822 }
823
824 TEST_F(SmokeTest, DeltaMode_Hybrid) {
825   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
826   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
827   std::string pkgid = "smokehyb04";
828   std::string appid1 = "smokehyb04.Web";
829   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
830             ci::AppInstaller::Result::OK);
831   ValidatePackage(pkgid, {appid1});
832
833   // Check delta modifications
834   bf::path root_path = ci::GetRootAppPath(false,
835       kTestUserId);
836   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
837   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
838   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
839   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
840   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
841   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
842   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
843   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
844   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n"));  // NOLINT
845 }
846
847 TEST_F(SmokeTest, MountInstallationMode_Hybrid) {
848   bf::path path = kSmokePackagesDirectory / "MountInstallationMode_Hybrid.wgt";
849   std::string pkgid = "smokehyb05";
850   std::string appid1 = "smokehyb05.web";
851   ASSERT_EQ(MountInstall(path, PackageType::HYBRID),
852             ci::AppInstaller::Result::OK);
853   ScopedTzipInterface interface(pkgid);
854   ValidatePackage(pkgid, {appid1});
855 }
856
857 TEST_F(SmokeTest, MountUpdateMode_Hybrid) {
858   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Hybrid.wgt";
859   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_Hybrid_2.wgt";
860   std::string pkgid = "smokehyb06";
861   std::string appid1 = "smokehyb06.web";
862   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
863             ci::AppInstaller::Result::OK);
864   AddDataFiles(pkgid, kTestUserId);
865   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID),
866             ci::AppInstaller::Result::OK);
867   ScopedTzipInterface interface(pkgid);
868   ValidatePackage(pkgid, {appid1});
869
870   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
871   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "2\n"));
872   ValidateDataFiles(pkgid, kTestUserId);
873 }
874
875 TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) {
876   bf::path path = kSmokePackagesDirectory /
877       "InstallationMode_Rollback_Hybrid.wgt";
878   std::string pkgid = "smokehyb07";
879   std::string appid1 = "smokehyb07.web";
880   ASSERT_EQ(Install(path, PackageType::HYBRID, RequestResult::FAIL),
881             ci::AppInstaller::Result::ERROR);
882   CheckPackageNonExistance(pkgid, {appid1});
883 }
884
885 TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) {
886   bf::path path_old = kSmokePackagesDirectory /
887       "UpdateMode_Rollback_Hybrid.wgt";
888   bf::path path_new = kSmokePackagesDirectory /
889       "UpdateMode_Rollback_Hybrid_2.wgt";
890   std::string pkgid = "smokehyb08";
891   std::string appid1 = "smokehyb08.web";
892   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
893             ci::AppInstaller::Result::OK);
894   AddDataFiles(pkgid, kTestUserId);
895   ASSERT_EQ(Install(path_new, PackageType::HYBRID,
896       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
897   ValidatePackage(pkgid, {appid1});
898
899   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
900   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
901   ValidateDataFiles(pkgid, kTestUserId);
902 }
903
904 TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) {
905   bf::path path = kSmokePackagesDirectory /
906       "MountInstallationMode_Rollback_Hybrid.wgt";
907   std::string pkgid = "smokehyb09";
908   std::string appid1 = "smokehyb09.web";
909   ASSERT_EQ(MountInstall(path, PackageType::HYBRID, RequestResult::FAIL),
910       ci::AppInstaller::Result::ERROR);
911   ScopedTzipInterface interface(pkgid);
912   CheckPackageNonExistance(pkgid, {appid1});
913 }
914
915 TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) {
916   bf::path path_old = kSmokePackagesDirectory /
917       "MountUpdateMode_Rollback_Hybrid.wgt";
918   bf::path path_new = kSmokePackagesDirectory /
919       "MountUpdateMode_Rollback_Hybrid_2.wgt";
920   std::string pkgid = "smokehyb10";
921   std::string appid1 = "smokehyb10.web";
922   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
923             ci::AppInstaller::Result::OK);
924   AddDataFiles(pkgid, kTestUserId);
925   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID,
926       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
927   ScopedTzipInterface interface(pkgid);
928   ValidatePackage(pkgid, {appid1});
929
930   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
931   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
932   ValidateDataFiles(pkgid, kTestUserId);
933 }
934
935 TEST_F(SmokeTest, MountInstallationMode) {
936   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
937   std::string pkgid = "smokeapp28";
938   std::string appid = "smokeapp28.InstallationMode";
939   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
940   ScopedTzipInterface interface(pkgid);
941   ValidatePackage(pkgid, {appid});
942 }
943
944 TEST_F(SmokeTest, MountUpdateMode) {
945   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
946   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
947   std::string pkgid = "smokeapp29";
948   std::string appid = "smokeapp29.UpdateMode";
949   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
950             ci::AppInstaller::Result::OK);
951   AddDataFiles(pkgid, kTestUserId);
952   ASSERT_EQ(MountInstall(path_new, PackageType::WGT),
953             ci::AppInstaller::Result::OK);
954   ScopedTzipInterface interface(pkgid);
955   ValidatePackage(pkgid, {appid});
956
957   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
958   ValidateDataFiles(pkgid, kTestUserId);
959 }
960
961 TEST_F(SmokeTest, MountInstallationMode_Rollback) {
962   bf::path path =
963       kSmokePackagesDirectory / "MountInstallationMode_Rollback.wgt";
964   std::string pkgid = "smokeapp33";
965   std::string appid = "smokeapp33.web";
966   ASSERT_EQ(MountInstall(path, PackageType::WGT, RequestResult::FAIL),
967             ci::AppInstaller::Result::ERROR);
968   ScopedTzipInterface interface(pkgid);
969   CheckPackageNonExistance(pkgid, {appid});
970 }
971
972 TEST_F(SmokeTest, MountUpdateMode_Rollback) {
973   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Rollback.wgt";
974   bf::path path_new =
975       kSmokePackagesDirectory / "MountUpdateMode_Rollback_2.wgt";
976   std::string pkgid = "smokeapp34";
977   std::string appid = "smokeapp34.web";
978   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
979             ci::AppInstaller::Result::OK);
980   AddDataFiles(pkgid, kTestUserId);
981   ASSERT_EQ(MountInstall(path_new, PackageType::WGT,
982       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
983   ScopedTzipInterface interface(pkgid);
984   ValidatePackage(pkgid, {appid});
985
986   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
987   ValidateDataFiles(pkgid, kTestUserId);
988 }
989
990 TEST_F(SmokeTest, UserDefinedPlugins) {
991   bf::path path = kSmokePackagesDirectory / "SimpleEchoPrivilege.wgt";
992   std::string pkgid = "0CSPVhKmRk";
993   std::string appid = "0CSPVhKmRk.SimpleEcho";
994   std::string call_privilege = "http://tizen.org/privilege/call";
995   std::string location_privilege = "http://tizen.org/privilege/location";
996   std::string power_privilege = "http://tizen.org/privilege/power";
997
998   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
999   ValidatePackage(pkgid, {appid});
1000   std::vector<std::string> res;
1001   ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res));
1002   ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end());
1003   ASSERT_TRUE(std::find(res.begin(), res.end(), location_privilege)
1004           != res.end());
1005   ASSERT_TRUE(std::find(res.begin(), res.end(), power_privilege) != res.end());
1006 }
1007
1008 }  // namespace common_installer
1009
1010 int main(int argc,  char** argv) {
1011   testing::InitGoogleTest(&argc, argv);
1012   testing::AddGlobalTestEnvironment(
1013       new common_installer::SmokeEnvironment(kGlobalUserUid));
1014   return RUN_ALL_TESTS();
1015 }