File: setup_unittest.mm

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (256 lines) | stat: -rw-r--r-- 10,556 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/apple/foundation_util.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/no_destructor.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/strcat.h"
#include "base/strings/sys_string_conversions.h"
#include "base/test/task_environment.h"
#include "base/test/test_timeouts.h"
#include "base/time/time.h"
#include "base/version.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/updater/mac/install_from_archive.h"
#include "chrome/updater/updater_scope.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace updater_setup {

namespace {

constexpr char kTestAppNameWithExtension[] = "InstallerTest.app";
constexpr char kTestAppFrameworkName[] = "InstallerTest Framework.framework";
constexpr char kTestAppVersion[] = "0";
constexpr char kTestBundleId[] = "com.install.test";
constexpr char kTestDirName[] = "InstallerTestDir";
constexpr char kUpdaterTestDMGName[] = "updater_setup_test_dmg.dmg";

void CreateTestApp(const base::FilePath& test_dir) {
  // Create file paths for each part of the app we want to create.
  base::FilePath test_app_path =
      test_dir.Append(FILE_PATH_LITERAL(kTestAppNameWithExtension));
  base::FilePath test_app_info_plist_path =
      test_app_path.Append(FILE_PATH_LITERAL("Contents"))
          .Append(FILE_PATH_LITERAL("Info.plist"));
  base::FilePath test_app_frameworks_path =
      test_app_path.Append(FILE_PATH_LITERAL("Contents"))
          .Append(FILE_PATH_LITERAL("Frameworks"))
          .Append(FILE_PATH_LITERAL(kTestAppFrameworkName));
  base::FilePath test_app_versions_path =
      test_app_frameworks_path.Append(FILE_PATH_LITERAL("Versions"));
  base::FilePath test_app_current_path =
      test_app_versions_path.Append(FILE_PATH_LITERAL("Current"));
  base::FilePath test_app_versioned_path =
      test_app_versions_path.Append(FILE_PATH_LITERAL(kTestAppVersion));
  base::FilePath test_app_versioned_resources_path =
      test_app_versioned_path.Append(FILE_PATH_LITERAL("Resources"));

  // First create the directory all the way up to Resources. We only need to do
  // this once because it'll create everything recursively.
  ASSERT_FALSE(base::PathExists(test_app_versioned_resources_path));
  ASSERT_TRUE(base::CreateDirectory(test_app_versioned_resources_path));

  // Now we should also create the Current dir to prepare for symlinks.
  ASSERT_FALSE(base::PathExists(test_app_current_path));
  ASSERT_TRUE(base::CreateDirectory(test_app_current_path));

  // Now to create some symlinks. We need to create one from versioned directory
  // to Frameworks, and one from versioned directory to the Current directory.
  ASSERT_TRUE(base::CreateSymbolicLink(
      test_app_versioned_resources_path,
      test_app_current_path.Append(FILE_PATH_LITERAL("Resources"))));

  ASSERT_TRUE(base::CreateSymbolicLink(
      test_app_versioned_resources_path,
      test_app_frameworks_path.Append(FILE_PATH_LITERAL("Resources"))));

  // Now to create the info plist.
  NSDictionary* launchd_plist = @{
    @"CFBundleShortVersionString" : base::SysUTF8ToNSString(kTestAppVersion),
    @"CFBundleIdentifier" : base::SysUTF8ToNSString(kTestBundleId)
  };

  ASSERT_TRUE([launchd_plist
      writeToURL:base::apple::FilePathToNSURL(test_app_info_plist_path)
           error:nil]);
}

void CreateTestSuiteTestDir(const base::FilePath& test_dir) {
  // Now lets copy the dmg into the test directory.
  // Get test data path.
  base::FilePath test_data_path;
  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_path));

  // Get path to the dmg.
  base::FilePath dmg_path = test_data_path.Append(FILE_PATH_LITERAL("updater"))
                                .Append(FILE_PATH_LITERAL(kUpdaterTestDMGName));
  ASSERT_TRUE(base::PathExists(dmg_path));

  // Copy the dmg over to the test directory.
  base::FilePath dest_path =
      test_dir.Append(FILE_PATH_LITERAL(kUpdaterTestDMGName));
  ASSERT_TRUE(base::CopyFile(dmg_path, dest_path));

  // Now to create a fake test app.
  CreateTestApp(test_dir);
}

base::ScopedTempDir& GetTestSuiteScopedTempDir() {
  static base::NoDestructor<base::ScopedTempDir> test_suite_dir_;
  return *test_suite_dir_;
}

const base::FilePath& GetTestSuiteDirPath() {
  return GetTestSuiteScopedTempDir().GetPath();
}

}  // namespace

class ChromeUpdaterMacSetupTest : public testing::Test {
 protected:
  static void SetUpTestSuite() {
    // SetUpTestSuite will run a script (install_test_helper.sh), which will set
    // up all the necessary things for running the mac installer test. This will
    // include creating dummy *.app to test the update and a sample dmg that
    // will be used as well.
    ASSERT_TRUE(GetTestSuiteScopedTempDir().CreateUniqueTempDir());
    CreateTestSuiteTestDir(GetTestSuiteDirPath());
  }

  static void TearDownTestSuite() {
    // TearDownTestSuite will run a script (install_test_helper.sh), to clean up
    // anything remaining from the test. This will need to be run with an arg
    // "clean" after the normal args.
    ASSERT_TRUE(GetTestSuiteScopedTempDir().Delete());
  }

  void SetUp() override {
    // Copies the directory created in set up test suite corresponding to each
    // test case name. This way, we have unique directories that we can set up
    // and clean up per test.
    base::FilePath temp_dir;
    ASSERT_TRUE(base::PathService::Get(base::DIR_TEMP, &temp_dir));

    test_dir_ = temp_dir.Append(
        FILE_PATH_LITERAL(base::StrCat({kTestDirName, "-",
                                        ::testing::UnitTest::GetInstance()
                                            ->current_test_info()
                                            ->test_suite_name()})));
    ASSERT_TRUE(base::CopyDirectory(GetTestSuiteDirPath(), test_dir_, true));
  }

  void TearDown() override {
    ASSERT_TRUE(base::DeletePathRecursively(test_dir_));
  }

  base::FilePath GetTestDir() { return test_dir_; }

 private:
  base::FilePath test_dir_;
};

TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveNoArgs) {
  // Get the path of the dmg based on the test directory path and validate it
  // exists.
  const base::FilePath dmg_file_path =
      GetTestDir().Append(FILE_PATH_LITERAL(kUpdaterTestDMGName));
  ASSERT_TRUE(base::PathExists(dmg_file_path));
  ASSERT_NE(updater::InstallFromArchive(dmg_file_path, {}, {},
                                        updater::UpdaterScope::kUser,
                                        base::Version("0"), {}, {}, false,
                                        TestTimeouts::action_timeout()),
            0);
}

TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveWithArgsFail) {
  // Get the path of the dmg based on the test directory path and validate it
  // exists.
  const base::FilePath dmg_file_path =
      GetTestDir().Append(FILE_PATH_LITERAL(kUpdaterTestDMGName));
  ASSERT_TRUE(base::PathExists(dmg_file_path));
  ASSERT_NE(updater::InstallFromArchive(dmg_file_path, {}, {},
                                        updater::UpdaterScope::kUser,
                                        base::Version("0"), "arg2", {}, false,
                                        TestTimeouts::action_timeout()),
            0);
}

TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveWithArgsPass) {
  // Get the path of the dmg based on the test directory path and validate it
  // exists.
  const base::FilePath dmg_file_path =
      GetTestDir().Append(FILE_PATH_LITERAL(kUpdaterTestDMGName));
  ASSERT_TRUE(base::PathExists(dmg_file_path));

  const base::FilePath installed_app_path =
      GetTestDir().Append(FILE_PATH_LITERAL(kTestAppNameWithExtension));
  ASSERT_TRUE(base::PathExists(installed_app_path));

  ASSERT_EQ(updater::InstallFromArchive(dmg_file_path, installed_app_path, {},
                                        updater::UpdaterScope::kUser,
                                        base::Version(kTestAppVersion), {}, {},
                                        false, TestTimeouts::action_timeout()),
            0);
}

TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveWithExtraneousArgsPass) {
  // Get the path of the dmg based on the test directory path and validate it
  // exists.
  const base::FilePath dmg_file_path =
      GetTestDir().Append(FILE_PATH_LITERAL(kUpdaterTestDMGName));
  ASSERT_TRUE(base::PathExists(dmg_file_path));

  // Get the path of the installed app and then validate it exists.
  const base::FilePath installed_app_path =
      GetTestDir().Append(FILE_PATH_LITERAL(kTestAppNameWithExtension));
  ASSERT_TRUE(base::PathExists(installed_app_path));

  std::string args = base::StrCat({kTestAppVersion, " arg1 arg2"});
  ASSERT_EQ(updater::InstallFromArchive(dmg_file_path, installed_app_path, {},
                                        updater::UpdaterScope::kUser,
                                        base::Version("0"), args, {}, false,
                                        TestTimeouts::action_timeout()),
            0);
}

TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchivePreinstallPostinstall) {
  base::FilePath test_dir;
  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
  test_dir = test_dir.Append("updater");

  ASSERT_EQ(updater::InstallFromArchive(
                test_dir.Append("setup_test_envcheck").Append("marker.app"),
                base::FilePath().Append("xc_path"), "ap",
                updater::UpdaterScope::kUser, base::Version("0"), "arg1 arg2",
                {}, false, TestTimeouts::action_timeout()),
            0);

  ASSERT_EQ(
      updater::InstallFromArchive(
          test_dir.Append("setup_test_preinstallfailure").Append("marker.app"),
          {}, {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {},
          false, TestTimeouts::action_timeout()),
      1);

  ASSERT_EQ(
      updater::InstallFromArchive(
          test_dir.Append("setup_test_installfailure").Append("marker.app"), {},
          {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {}, false,
          TestTimeouts::action_timeout()),
      2);

  ASSERT_EQ(
      updater::InstallFromArchive(
          test_dir.Append("setup_test_postinstallfailure").Append("marker.app"),
          {}, {}, updater::UpdaterScope::kUser, base::Version("0"), {}, {},
          false, TestTimeouts::action_timeout()),
      3);
}

}  // namespace updater_setup