Fix code style
[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) /
596       "res" / "wgt" / "DELETED"));
597   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
598       "res" / "wgt" / "ADDED"));
599   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "2\n"));
600 }
601
602 TEST_F(SmokeTest, EnablePkg) {
603   bf::path path = kSmokePackagesDirectory / "EnablePkg.wgt";
604   std::string pkgid = "smokeapp22";
605   ASSERT_EQ(Install(path, PackageType::WGT),
606             ci::AppInstaller::Result::OK);
607   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
608             ci::AppInstaller::Result::OK);
609   ASSERT_EQ(EnablePackage(pkgid, PackageType::WGT),
610             ci::AppInstaller::Result::OK);
611
612   ASSERT_TRUE(ci::QueryIsPackageInstalled(pkgid,
613       ci::GetRequestMode(kTestUserId),
614       kTestUserId));
615 }
616
617 TEST_F(SmokeTest, DisablePkg) {
618   bf::path path = kSmokePackagesDirectory / "DisablePkg.wgt";
619   std::string pkgid = "smokeapp21";
620   std::string appid = "smokeapp21.DisablePkg";
621   ASSERT_EQ(Install(path, PackageType::WGT),
622             ci::AppInstaller::Result::OK);
623   ASSERT_EQ(DisablePackage(pkgid, PackageType::WGT),
624             ci::AppInstaller::Result::OK);
625   ASSERT_TRUE(ci::QueryIsDisabledPackage(pkgid, kTestUserId));
626   ValidatePackage(pkgid, {appid});
627 }
628
629 TEST_F(SmokeTest, DeltaMode) {
630   bf::path path = kSmokePackagesDirectory / "DeltaMode.wgt";
631   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode.delta";
632   std::string pkgid = "smokeapp17";
633   std::string appid = "smokeapp17.DeltaMode";
634   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::WGT),
635             ci::AppInstaller::Result::OK);
636   ValidatePackage(pkgid, {appid});
637
638   // Check delta modifications
639   ASSERT_FALSE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
640       "res" / "wgt" / "DELETED"));
641   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
642       "res" / "wgt" / "ADDED"));
643   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
644       "res" / "wgt" / "css" / "style.css"));
645   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
646       "res" / "wgt" / "images" / "tizen_32.png"));
647   ASSERT_TRUE(bf::exists(GetPackageRoot(pkgid, kTestUserId) /
648       "res" / "wgt" / "js" / "main.js"));
649   ASSERT_TRUE(ValidateFileContentInPackage(
650       pkgid, "res/wgt/MODIFIED", "version 2\n"));
651 }
652
653 TEST_F(SmokeTest, RecoveryMode_ForInstallation) {
654   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForInstallation.wgt";
655   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
656   backend_crash.Run("-i", path.string(), "-u", kTestUserIdStr.c_str());
657   ASSERT_NE(backend_crash.Wait(), 0);
658
659   std::string pkgid = "smokeapp09";
660   std::string appid = "smokeapp09.RecoveryModeForInstallation";
661   bf::path recovery_file = FindRecoveryFile();
662   ASSERT_FALSE(recovery_file.empty());
663   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
664       ci::AppInstaller::Result::OK);
665   CheckPackageNonExistance(pkgid, {appid});
666 }
667
668 TEST_F(SmokeTest, RecoveryMode_ForUpdate) {
669   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForUpdate.wgt";
670   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForUpdate_2.wgt";
671   RemoveAllRecoveryFiles();
672   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
673   std::string pkgid = "smokeapp10";
674   std::string appid = "smokeapp10.RecoveryModeForUpdate";
675   AddDataFiles(pkgid, kTestUserId);
676   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
677   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
678   ASSERT_NE(backend_crash.Wait(), 0);
679
680   bf::path recovery_file = FindRecoveryFile();
681   ASSERT_FALSE(recovery_file.empty());
682   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
683             ci::AppInstaller::Result::OK);
684   ValidatePackage(pkgid, {appid});
685
686   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
687   ValidateDataFiles(pkgid, kTestUserId);
688 }
689
690 TEST_F(SmokeTest, RecoveryMode_ForDelta) {
691   bf::path path_old = kSmokePackagesDirectory / "RecoveryMode_ForDelta.wgt";
692   bf::path path_new = kSmokePackagesDirectory / "RecoveryMode_ForDelta.delta";
693   RemoveAllRecoveryFiles();
694   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
695   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
696   backend_crash.Run("-i", path_new.string(), "-u", kTestUserIdStr.c_str());
697   ASSERT_NE(backend_crash.Wait(), 0);
698
699   std::string pkgid = "smokeapp30";
700   std::string appid = "smokeapp30.RecoveryModeForDelta";
701   bf::path recovery_file = FindRecoveryFile();
702   ASSERT_FALSE(recovery_file.empty());
703   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
704             ci::AppInstaller::Result::OK);
705   ValidatePackage(pkgid, {appid});
706
707   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
708 }
709
710 TEST_F(SmokeTest, RecoveryMode_ForMountInstall) {
711   bf::path path = kSmokePackagesDirectory / "RecoveryMode_ForMountInstall.wgt";
712   RemoveAllRecoveryFiles();
713   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
714   backend_crash.Run("-w", path.string(), "-u", kTestUserIdStr.c_str());
715   ASSERT_NE(backend_crash.Wait(), 0);
716
717   std::string pkgid = "smokeapp31";
718   std::string appid = "smokeapp31.RecoveryModeForMountInstall";
719   bf::path recovery_file = FindRecoveryFile();
720   ASSERT_FALSE(recovery_file.empty());
721   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
722             ci::AppInstaller::Result::OK);
723   CheckPackageNonExistance(pkgid, {appid});
724 }
725
726 TEST_F(SmokeTest, RecoveryMode_ForMountUpdate) {
727   bf::path path_old =
728       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate.wgt";
729   bf::path path_new =
730       kSmokePackagesDirectory / "RecoveryMode_ForMountUpdate_2.wgt";
731   std::string pkgid = "smokeapp32";
732   std::string appid = "smokeapp32.RecoveryModeForMountUpdate";
733   RemoveAllRecoveryFiles();
734   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
735             ci::AppInstaller::Result::OK);
736   AddDataFiles(pkgid, kTestUserId);
737   Subprocess backend_crash("/usr/bin/wgt-backend-ut/smoke-test-helper");
738   backend_crash.Run("-w", path_new.string(), "-u", kTestUserIdStr.c_str());
739   ASSERT_NE(backend_crash.Wait(), 0);
740
741   // Filesystem may be mounted after crash
742   ScopedTzipInterface poweroff_unmount_interface(pkgid);
743   poweroff_unmount_interface.Release();
744
745   bf::path recovery_file = FindRecoveryFile();
746   ASSERT_FALSE(recovery_file.empty());
747   ASSERT_EQ(Recover(recovery_file, PackageType::WGT),
748             ci::AppInstaller::Result::OK);
749
750   ScopedTzipInterface interface(pkgid);
751   ValidatePackage(pkgid, {appid});
752   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
753   ValidateDataFiles(pkgid, kTestUserId);
754 }
755
756 TEST_F(SmokeTest, InstallationMode_GoodSignature) {
757   bf::path path = kSmokePackagesDirectory / "InstallationMode_GoodSignature.wgt";  // NOLINT
758   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
759 }
760
761 TEST_F(SmokeTest, InstallationMode_WrongSignature) {
762   bf::path path = kSmokePackagesDirectory / "InstallationMode_WrongSignature.wgt";  // NOLINT
763   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::ERROR);
764 }
765
766 TEST_F(SmokeTest, InstallationMode_Rollback) {
767   bf::path path = kSmokePackagesDirectory / "InstallationMode_Rollback.wgt";
768   std::string pkgid = "smokeapp06";
769   std::string appid = "smokeapp06.InstallationModeRollback";
770   ASSERT_EQ(Install(path, PackageType::WGT, RequestResult::FAIL),
771             ci::AppInstaller::Result::ERROR);
772   CheckPackageNonExistance(pkgid, {appid});
773 }
774
775 TEST_F(SmokeTest, UpdateMode_Rollback) {
776   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Rollback.wgt";
777   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Rollback_2.wgt";
778   std::string pkgid = "smokeapp07";
779   std::string appid = "smokeapp07.UpdateModeRollback";
780   ASSERT_EQ(Install(path_old, PackageType::WGT), ci::AppInstaller::Result::OK);
781   AddDataFiles(pkgid, kTestUserId);
782   ASSERT_EQ(Install(path_new, PackageType::WGT, RequestResult::FAIL),
783                     ci::AppInstaller::Result::ERROR);
784   ValidatePackage(pkgid, {appid});
785
786   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
787   ValidateDataFiles(pkgid, kTestUserId);
788 }
789
790 TEST_F(SmokeTest, InstallationMode_Hybrid) {
791   bf::path path = kSmokePackagesDirectory / "InstallationMode_Hybrid.wgt";
792   std::string pkgid = "smokehyb01";
793   // Excutable for native app doesn't create symlink
794   std::string appid1 = "smokehyb01.Web";
795   ASSERT_EQ(Install(path, PackageType::HYBRID), ci::AppInstaller::Result::OK);
796   ValidatePackage(pkgid, {appid1});
797 }
798
799 TEST_F(SmokeTest, UpdateMode_Hybrid) {
800   bf::path path_old = kSmokePackagesDirectory / "UpdateMode_Hybrid.wgt";
801   bf::path path_new = kSmokePackagesDirectory / "UpdateMode_Hybrid_2.wgt";
802   std::string pkgid = "smokehyb02";
803   std::string appid1 = "smokehyb02.Web";
804   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
805             ci::AppInstaller::Result::OK);
806 //  AddDataFiles(pkgid, kTestUserId);
807   ASSERT_EQ(Install(path_new, PackageType::HYBRID),
808             ci::AppInstaller::Result::OK);
809   ValidatePackage(pkgid, {appid1});
810
811   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
812   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "VERSION", "2\n"));
813 //  ValidateDataFiles(pkgid, kTestUserId);
814 }
815
816 TEST_F(SmokeTest, DeinstallationMode_Hybrid) {
817   bf::path path = kSmokePackagesDirectory / "DeinstallationMode_Hybrid.wgt";
818   std::string pkgid = "smokehyb03";
819   std::string appid1 = "smokehyb03.Web";
820   ASSERT_EQ(Install(path, PackageType::HYBRID),
821             ci::AppInstaller::Result::OK);
822   ASSERT_EQ(Uninstall(pkgid, PackageType::HYBRID),
823             ci::AppInstaller::Result::OK);
824   CheckPackageNonExistance(pkgid, {appid1});
825 }
826
827 TEST_F(SmokeTest, DeltaMode_Hybrid) {
828   bf::path path = kSmokePackagesDirectory / "DeltaMode_Hybrid.wgt";
829   bf::path delta_package = kSmokePackagesDirectory / "DeltaMode_Hybrid.delta";
830   std::string pkgid = "smokehyb04";
831   std::string appid1 = "smokehyb04.Web";
832   ASSERT_EQ(DeltaInstall(path, delta_package, PackageType::HYBRID),
833             ci::AppInstaller::Result::OK);
834   ValidatePackage(pkgid, {appid1});
835
836   // Check delta modifications
837   bf::path root_path = ci::GetRootAppPath(false,
838       kTestUserId);
839   ASSERT_FALSE(bf::exists(root_path / pkgid / "res" / "wgt" / "DELETED"));
840   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "ADDED"));
841   ASSERT_FALSE(bf::exists(root_path / pkgid / "lib" / "DELETED"));
842   ASSERT_TRUE(bf::exists(root_path / pkgid / "lib" / "ADDED"));
843   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "css" / "style.css"));  // NOLINT
844   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "images" / "tizen_32.png"));  // NOLINT
845   ASSERT_TRUE(bf::exists(root_path / pkgid / "res" / "wgt" / "js" / "main.js"));
846   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/MODIFIED", "version 2\n"));  // NOLINT
847   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/MODIFIED", "version 2\n"));  // NOLINT
848 }
849
850 TEST_F(SmokeTest, MountInstallationMode_Hybrid) {
851   bf::path path = kSmokePackagesDirectory / "MountInstallationMode_Hybrid.wgt";
852   std::string pkgid = "smokehyb05";
853   std::string appid1 = "smokehyb05.web";
854   ASSERT_EQ(MountInstall(path, PackageType::HYBRID),
855             ci::AppInstaller::Result::OK);
856   ScopedTzipInterface interface(pkgid);
857   ValidatePackage(pkgid, {appid1});
858 }
859
860 TEST_F(SmokeTest, MountUpdateMode_Hybrid) {
861   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Hybrid.wgt";
862   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_Hybrid_2.wgt";
863   std::string pkgid = "smokehyb06";
864   std::string appid1 = "smokehyb06.web";
865   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
866             ci::AppInstaller::Result::OK);
867   AddDataFiles(pkgid, kTestUserId);
868   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID),
869             ci::AppInstaller::Result::OK);
870   ScopedTzipInterface interface(pkgid);
871   ValidatePackage(pkgid, {appid1});
872
873   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
874   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "2\n"));
875   ValidateDataFiles(pkgid, kTestUserId);
876 }
877
878 TEST_F(SmokeTest, InstallationMode_Rollback_Hybrid) {
879   bf::path path = kSmokePackagesDirectory /
880       "InstallationMode_Rollback_Hybrid.wgt";
881   std::string pkgid = "smokehyb07";
882   std::string appid1 = "smokehyb07.web";
883   ASSERT_EQ(Install(path, PackageType::HYBRID, RequestResult::FAIL),
884             ci::AppInstaller::Result::ERROR);
885   CheckPackageNonExistance(pkgid, {appid1});
886 }
887
888 TEST_F(SmokeTest, UpdateMode_Rollback_Hybrid) {
889   bf::path path_old = kSmokePackagesDirectory /
890       "UpdateMode_Rollback_Hybrid.wgt";
891   bf::path path_new = kSmokePackagesDirectory /
892       "UpdateMode_Rollback_Hybrid_2.wgt";
893   std::string pkgid = "smokehyb08";
894   std::string appid1 = "smokehyb08.web";
895   ASSERT_EQ(Install(path_old, PackageType::HYBRID),
896             ci::AppInstaller::Result::OK);
897   AddDataFiles(pkgid, kTestUserId);
898   ASSERT_EQ(Install(path_new, PackageType::HYBRID,
899       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
900   ValidatePackage(pkgid, {appid1});
901
902   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
903   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
904   ValidateDataFiles(pkgid, kTestUserId);
905 }
906
907 TEST_F(SmokeTest, MountInstallationMode_Rollback_Hybrid) {
908   bf::path path = kSmokePackagesDirectory /
909       "MountInstallationMode_Rollback_Hybrid.wgt";
910   std::string pkgid = "smokehyb09";
911   std::string appid1 = "smokehyb09.web";
912   ASSERT_EQ(MountInstall(path, PackageType::HYBRID, RequestResult::FAIL),
913       ci::AppInstaller::Result::ERROR);
914   ScopedTzipInterface interface(pkgid);
915   CheckPackageNonExistance(pkgid, {appid1});
916 }
917
918 TEST_F(SmokeTest, MountUpdateMode_Rollback_Hybrid) {
919   bf::path path_old = kSmokePackagesDirectory /
920       "MountUpdateMode_Rollback_Hybrid.wgt";
921   bf::path path_new = kSmokePackagesDirectory /
922       "MountUpdateMode_Rollback_Hybrid_2.wgt";
923   std::string pkgid = "smokehyb10";
924   std::string appid1 = "smokehyb10.web";
925   ASSERT_EQ(MountInstall(path_old, PackageType::HYBRID),
926             ci::AppInstaller::Result::OK);
927   AddDataFiles(pkgid, kTestUserId);
928   ASSERT_EQ(MountInstall(path_new, PackageType::HYBRID,
929       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
930   ScopedTzipInterface interface(pkgid);
931   ValidatePackage(pkgid, {appid1});
932
933   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
934   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "lib/VERSION", "1\n"));
935   ValidateDataFiles(pkgid, kTestUserId);
936 }
937
938 TEST_F(SmokeTest, MountInstallationMode) {
939   bf::path path = kSmokePackagesDirectory / "MountInstallationMode.wgt";
940   std::string pkgid = "smokeapp28";
941   std::string appid = "smokeapp28.InstallationMode";
942   ASSERT_EQ(MountInstall(path, PackageType::WGT), ci::AppInstaller::Result::OK);
943   ScopedTzipInterface interface(pkgid);
944   ValidatePackage(pkgid, {appid});
945 }
946
947 TEST_F(SmokeTest, MountUpdateMode) {
948   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode.wgt";
949   bf::path path_new = kSmokePackagesDirectory / "MountUpdateMode_2.wgt";
950   std::string pkgid = "smokeapp29";
951   std::string appid = "smokeapp29.UpdateMode";
952   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
953             ci::AppInstaller::Result::OK);
954   AddDataFiles(pkgid, kTestUserId);
955   ASSERT_EQ(MountInstall(path_new, PackageType::WGT),
956             ci::AppInstaller::Result::OK);
957   ScopedTzipInterface interface(pkgid);
958   ValidatePackage(pkgid, {appid});
959
960   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "2\n"));
961   ValidateDataFiles(pkgid, kTestUserId);
962 }
963
964 TEST_F(SmokeTest, MountInstallationMode_Rollback) {
965   bf::path path =
966       kSmokePackagesDirectory / "MountInstallationMode_Rollback.wgt";
967   std::string pkgid = "smokeapp33";
968   std::string appid = "smokeapp33.web";
969   ASSERT_EQ(MountInstall(path, PackageType::WGT, RequestResult::FAIL),
970             ci::AppInstaller::Result::ERROR);
971   ScopedTzipInterface interface(pkgid);
972   CheckPackageNonExistance(pkgid, {appid});
973 }
974
975 TEST_F(SmokeTest, MountUpdateMode_Rollback) {
976   bf::path path_old = kSmokePackagesDirectory / "MountUpdateMode_Rollback.wgt";
977   bf::path path_new =
978       kSmokePackagesDirectory / "MountUpdateMode_Rollback_2.wgt";
979   std::string pkgid = "smokeapp34";
980   std::string appid = "smokeapp34.web";
981   ASSERT_EQ(MountInstall(path_old, PackageType::WGT),
982             ci::AppInstaller::Result::OK);
983   AddDataFiles(pkgid, kTestUserId);
984   ASSERT_EQ(MountInstall(path_new, PackageType::WGT,
985       RequestResult::FAIL), ci::AppInstaller::Result::ERROR);
986   ScopedTzipInterface interface(pkgid);
987   ValidatePackage(pkgid, {appid});
988
989   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/wgt/VERSION", "1\n"));
990   ValidateDataFiles(pkgid, kTestUserId);
991 }
992
993 TEST_F(SmokeTest, UserDefinedPlugins) {
994   bf::path path = kSmokePackagesDirectory / "SimpleEchoPrivilege.wgt";
995   std::string pkgid = "0CSPVhKmRk";
996   std::string appid = "0CSPVhKmRk.SimpleEcho";
997   std::string call_privilege = "http://tizen.org/privilege/call";
998   std::string location_privilege = "http://tizen.org/privilege/location";
999   std::string power_privilege = "http://tizen.org/privilege/power";
1000
1001   ASSERT_EQ(Install(path, PackageType::WGT), ci::AppInstaller::Result::OK);
1002   ValidatePackage(pkgid, {appid});
1003   std::vector<std::string> res;
1004   ASSERT_TRUE(ci::QueryPrivilegesForPkgId(pkgid, kTestUserId, &res));
1005   ASSERT_TRUE(std::find(res.begin(), res.end(), call_privilege) != res.end());
1006   ASSERT_TRUE(std::find(res.begin(), res.end(), location_privilege)
1007           != res.end());
1008   ASSERT_TRUE(std::find(res.begin(), res.end(), power_privilege) != res.end());
1009 }
1010
1011 }  // namespace common_installer
1012
1013 int main(int argc,  char** argv) {
1014   testing::InitGoogleTest(&argc, argv);
1015   testing::AddGlobalTestEnvironment(
1016       new common_installer::SmokeEnvironment(kGlobalUserUid));
1017   return RUN_ALL_TESTS();
1018 }