Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Side by Side Diff: apps/app_shim/app_shim_host_manager_browsertest_mac.mm

Issue 66043003: Put app shim IPC socket in a temporary directory. (Mac) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync, rebase, git cl format Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | apps/app_shim/app_shim_host_manager_mac.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "apps/app_shim/app_shim_host_manager_mac.h" 5 #include "apps/app_shim/app_shim_host_manager_mac.h"
6 6
7 #include <unistd.h> 7 #include <unistd.h>
8 8
9 #include "apps/app_shim/app_shim_messages.h" 9 #include "apps/app_shim/app_shim_messages.h"
10 #include "apps/app_shim/test/app_shim_host_manager_test_api_mac.h" 10 #include "apps/app_shim/test/app_shim_host_manager_test_api_mac.h"
(...skipping 11 matching lines...) Expand all
22 #include "ipc/ipc_listener.h" 22 #include "ipc/ipc_listener.h"
23 #include "ipc/ipc_message.h" 23 #include "ipc/ipc_message.h"
24 24
25 namespace { 25 namespace {
26 26
27 const char kTestAppMode[] = "test_app"; 27 const char kTestAppMode[] = "test_app";
28 28
29 // A test version of the AppShimController IPC client in chrome_main_app_mode. 29 // A test version of the AppShimController IPC client in chrome_main_app_mode.
30 class TestShimClient : public IPC::Listener { 30 class TestShimClient : public IPC::Listener {
31 public: 31 public:
32 TestShimClient(const base::FilePath& socket_path); 32 TestShimClient();
33 virtual ~TestShimClient(); 33 virtual ~TestShimClient();
34 34
35 template <class T> 35 template <class T>
36 void Send(const T& message) { 36 void Send(const T& message) {
37 channel_->Send(message); 37 channel_->Send(message);
38 } 38 }
39 39
40 private: 40 private:
41 // IPC::Listener overrides: 41 // IPC::Listener overrides:
42 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 42 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
43 virtual void OnChannelError() OVERRIDE; 43 virtual void OnChannelError() OVERRIDE;
44 44
45 base::Thread io_thread_; 45 base::Thread io_thread_;
46 scoped_ptr<IPC::ChannelProxy> channel_; 46 scoped_ptr<IPC::ChannelProxy> channel_;
47 47
48 DISALLOW_COPY_AND_ASSIGN(TestShimClient); 48 DISALLOW_COPY_AND_ASSIGN(TestShimClient);
49 }; 49 };
50 50
51 TestShimClient::TestShimClient(const base::FilePath& socket_path) 51 TestShimClient::TestShimClient() : io_thread_("TestShimClientIO") {
52 : io_thread_("TestShimClientIO") {
53 base::Thread::Options io_thread_options; 52 base::Thread::Options io_thread_options;
54 io_thread_options.message_loop_type = base::MessageLoop::TYPE_IO; 53 io_thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
55 io_thread_.StartWithOptions(io_thread_options); 54 io_thread_.StartWithOptions(io_thread_options);
56 55
56 base::FilePath user_data_dir;
57 CHECK(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
58 base::FilePath symlink_path =
59 user_data_dir.Append(app_mode::kAppShimSocketSymlinkName);
60
61 base::FilePath socket_path;
62 CHECK(base::ReadSymbolicLink(symlink_path, &socket_path));
63 app_mode::VerifySocketPermissions(socket_path);
64
57 IPC::ChannelHandle handle(socket_path.value()); 65 IPC::ChannelHandle handle(socket_path.value());
58 channel_.reset(new IPC::ChannelProxy(handle, IPC::Channel::MODE_NAMED_CLIENT, 66 channel_.reset(new IPC::ChannelProxy(handle, IPC::Channel::MODE_NAMED_CLIENT,
59 this, io_thread_.message_loop_proxy().get())); 67 this, io_thread_.message_loop_proxy().get()));
60 } 68 }
61 69
62 TestShimClient::~TestShimClient() {} 70 TestShimClient::~TestShimClient() {}
63 71
64 bool TestShimClient::OnMessageReceived(const IPC::Message& message) { 72 bool TestShimClient::OnMessageReceived(const IPC::Message& message) {
65 return true; 73 return true;
66 } 74 }
(...skipping 12 matching lines...) Expand all
79 virtual ~AppShimHostManagerBrowserTest(); 87 virtual ~AppShimHostManagerBrowserTest();
80 88
81 protected: 89 protected:
82 // Wait for OnShimLaunch, then send a quit, and wait for the response. Used to 90 // Wait for OnShimLaunch, then send a quit, and wait for the response. Used to
83 // test launch behavior. 91 // test launch behavior.
84 void RunAndExitGracefully(); 92 void RunAndExitGracefully();
85 93
86 // InProcessBrowserTest overrides: 94 // InProcessBrowserTest overrides:
87 virtual void SetUpOnMainThread() OVERRIDE; 95 virtual void SetUpOnMainThread() OVERRIDE;
88 virtual void TearDownOnMainThread() OVERRIDE; 96 virtual void TearDownOnMainThread() OVERRIDE;
89 virtual bool SetUpUserDataDirectory() OVERRIDE;
90 97
91 // AppShimHandler overrides: 98 // AppShimHandler overrides:
92 virtual void OnShimLaunch(apps::AppShimHandler::Host* host, 99 virtual void OnShimLaunch(apps::AppShimHandler::Host* host,
93 apps::AppShimLaunchType launch_type, 100 apps::AppShimLaunchType launch_type,
94 const std::vector<base::FilePath>& files) OVERRIDE; 101 const std::vector<base::FilePath>& files) OVERRIDE;
95 virtual void OnShimClose(apps::AppShimHandler::Host* host) OVERRIDE {} 102 virtual void OnShimClose(apps::AppShimHandler::Host* host) OVERRIDE {}
96 virtual void OnShimFocus(apps::AppShimHandler::Host* host, 103 virtual void OnShimFocus(apps::AppShimHandler::Host* host,
97 apps::AppShimFocusType focus_type, 104 apps::AppShimFocusType focus_type,
98 const std::vector<base::FilePath>& files) OVERRIDE {} 105 const std::vector<base::FilePath>& files) OVERRIDE {}
99 virtual void OnShimSetHidden(apps::AppShimHandler::Host* host, 106 virtual void OnShimSetHidden(apps::AppShimHandler::Host* host,
100 bool hidden) OVERRIDE {} 107 bool hidden) OVERRIDE {}
101 virtual void OnShimQuit(apps::AppShimHandler::Host* host) OVERRIDE; 108 virtual void OnShimQuit(apps::AppShimHandler::Host* host) OVERRIDE;
102 109
103 scoped_ptr<TestShimClient> test_client_; 110 scoped_ptr<TestShimClient> test_client_;
104 base::FilePath short_socket_path_;
105 std::vector<base::FilePath> last_launch_files_; 111 std::vector<base::FilePath> last_launch_files_;
106 apps::AppShimLaunchType last_launch_type_; 112 apps::AppShimLaunchType last_launch_type_;
107 113
108 private: 114 private:
109 scoped_refptr<content::MessageLoopRunner> runner_; 115 scoped_refptr<content::MessageLoopRunner> runner_;
110 base::ScopedTempDir short_temp_dir_;
111 116
112 int launch_count_; 117 int launch_count_;
113 int quit_count_; 118 int quit_count_;
114 119
115 DISALLOW_COPY_AND_ASSIGN(AppShimHostManagerBrowserTest); 120 DISALLOW_COPY_AND_ASSIGN(AppShimHostManagerBrowserTest);
116 }; 121 };
117 122
118 AppShimHostManagerBrowserTest::AppShimHostManagerBrowserTest() 123 AppShimHostManagerBrowserTest::AppShimHostManagerBrowserTest()
119 : last_launch_type_(apps::APP_SHIM_LAUNCH_NUM_TYPES), 124 : last_launch_type_(apps::APP_SHIM_LAUNCH_NUM_TYPES),
120 launch_count_(0), 125 launch_count_(0),
(...skipping 20 matching lines...) Expand all
141 146
142 void AppShimHostManagerBrowserTest::SetUpOnMainThread() { 147 void AppShimHostManagerBrowserTest::SetUpOnMainThread() {
143 // Can't do this in the constructor, it needs a BrowserProcess. 148 // Can't do this in the constructor, it needs a BrowserProcess.
144 apps::AppShimHandler::RegisterHandler(kTestAppMode, this); 149 apps::AppShimHandler::RegisterHandler(kTestAppMode, this);
145 } 150 }
146 151
147 void AppShimHostManagerBrowserTest::TearDownOnMainThread() { 152 void AppShimHostManagerBrowserTest::TearDownOnMainThread() {
148 apps::AppShimHandler::RemoveHandler(kTestAppMode); 153 apps::AppShimHandler::RemoveHandler(kTestAppMode);
149 } 154 }
150 155
151 bool AppShimHostManagerBrowserTest::SetUpUserDataDirectory() {
152 // Create a symlink at /tmp/scoped_dir_XXXXXX/udd that points to the real user
153 // data dir, and use this as the domain socket path. This is required because
154 // there is a path length limit for named sockets that is exceeded in
155 // multi-process test spawning.
156 base::FilePath real_user_data_dir;
157 EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &real_user_data_dir));
158 EXPECT_TRUE(
159 short_temp_dir_.CreateUniqueTempDirUnderPath(base::FilePath("/tmp")));
160 base::FilePath shortened_user_data_dir = short_temp_dir_.path().Append("udd");
161 EXPECT_EQ(0, ::symlink(real_user_data_dir.AsUTF8Unsafe().c_str(),
162 shortened_user_data_dir.AsUTF8Unsafe().c_str()));
163
164 test::AppShimHostManagerTestApi::OverrideUserDataDir(shortened_user_data_dir);
165 short_socket_path_ =
166 shortened_user_data_dir.Append(app_mode::kAppShimSocketName);
167
168 return InProcessBrowserTest::SetUpUserDataDirectory();
169 }
170
171 void AppShimHostManagerBrowserTest::OnShimLaunch( 156 void AppShimHostManagerBrowserTest::OnShimLaunch(
172 apps::AppShimHandler::Host* host, 157 apps::AppShimHandler::Host* host,
173 apps::AppShimLaunchType launch_type, 158 apps::AppShimLaunchType launch_type,
174 const std::vector<base::FilePath>& files) { 159 const std::vector<base::FilePath>& files) {
175 host->OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_SUCCESS); 160 host->OnAppLaunchComplete(apps::APP_SHIM_LAUNCH_SUCCESS);
176 ++launch_count_; 161 ++launch_count_;
177 last_launch_type_ = launch_type; 162 last_launch_type_ = launch_type;
178 last_launch_files_ = files; 163 last_launch_files_ = files;
179 runner_->Quit(); 164 runner_->Quit();
180 } 165 }
181 166
182 void AppShimHostManagerBrowserTest::OnShimQuit( 167 void AppShimHostManagerBrowserTest::OnShimQuit(
183 apps::AppShimHandler::Host* host) { 168 apps::AppShimHandler::Host* host) {
184 ++quit_count_; 169 ++quit_count_;
185 runner_->Quit(); 170 runner_->Quit();
186 } 171 }
187 172
188 // Test regular launch, which would ask Chrome to launch the app. 173 // Test regular launch, which would ask Chrome to launch the app.
189 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, LaunchNormal) { 174 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, LaunchNormal) {
190 test_client_.reset(new TestShimClient(short_socket_path_)); 175 test_client_.reset(new TestShimClient());
191 test_client_->Send(new AppShimHostMsg_LaunchApp( 176 test_client_->Send(new AppShimHostMsg_LaunchApp(
192 browser()->profile()->GetPath(), 177 browser()->profile()->GetPath(),
193 kTestAppMode, 178 kTestAppMode,
194 apps::APP_SHIM_LAUNCH_NORMAL, 179 apps::APP_SHIM_LAUNCH_NORMAL,
195 std::vector<base::FilePath>())); 180 std::vector<base::FilePath>()));
196 181
197 RunAndExitGracefully(); 182 RunAndExitGracefully();
198 EXPECT_EQ(apps::APP_SHIM_LAUNCH_NORMAL, last_launch_type_); 183 EXPECT_EQ(apps::APP_SHIM_LAUNCH_NORMAL, last_launch_type_);
199 EXPECT_TRUE(last_launch_files_.empty()); 184 EXPECT_TRUE(last_launch_files_.empty());
200 } 185 }
201 186
202 // Test register-only launch, used when Chrome has already launched the app. 187 // Test register-only launch, used when Chrome has already launched the app.
203 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, LaunchRegisterOnly) { 188 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, LaunchRegisterOnly) {
204 test_client_.reset(new TestShimClient(short_socket_path_)); 189 test_client_.reset(new TestShimClient());
205 test_client_->Send(new AppShimHostMsg_LaunchApp( 190 test_client_->Send(new AppShimHostMsg_LaunchApp(
206 browser()->profile()->GetPath(), 191 browser()->profile()->GetPath(),
207 kTestAppMode, 192 kTestAppMode,
208 apps::APP_SHIM_LAUNCH_REGISTER_ONLY, 193 apps::APP_SHIM_LAUNCH_REGISTER_ONLY,
209 std::vector<base::FilePath>())); 194 std::vector<base::FilePath>()));
210 195
211 RunAndExitGracefully(); 196 RunAndExitGracefully();
212 EXPECT_EQ(apps::APP_SHIM_LAUNCH_REGISTER_ONLY, last_launch_type_); 197 EXPECT_EQ(apps::APP_SHIM_LAUNCH_REGISTER_ONLY, last_launch_type_);
213 EXPECT_TRUE(last_launch_files_.empty()); 198 EXPECT_TRUE(last_launch_files_.empty());
214 } 199 }
215 200
216 // Ensure the domain socket can be created in a fresh user data dir. 201 // Ensure the domain socket can be created in a fresh user data dir.
217 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, 202 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest,
218 PRE_ReCreate) { 203 PRE_ReCreate) {
219 test::AppShimHostManagerTestApi test_api( 204 test::AppShimHostManagerTestApi test_api(
220 g_browser_process->platform_part()->app_shim_host_manager()); 205 g_browser_process->platform_part()->app_shim_host_manager());
221 EXPECT_TRUE(test_api.factory()); 206 EXPECT_TRUE(test_api.factory());
222 } 207 }
223 208
224 // Ensure the domain socket can be re-created after a prior browser process has 209 // Ensure the domain socket can be re-created after a prior browser process has
225 // quit. 210 // quit.
226 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest, 211 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTest,
227 ReCreate) { 212 ReCreate) {
228 test::AppShimHostManagerTestApi test_api( 213 test::AppShimHostManagerTestApi test_api(
229 g_browser_process->platform_part()->app_shim_host_manager()); 214 g_browser_process->platform_part()->app_shim_host_manager());
230 EXPECT_TRUE(test_api.factory()); 215 EXPECT_TRUE(test_api.factory());
231 } 216 }
232 217
233 // Test for AppShimHostManager that fails to create the socket. 218 // Tests for the files created by AppShimHostManager.
234 class AppShimHostManagerBrowserTestFailsCreate : 219 class AppShimHostManagerBrowserTestSocketFiles
235 public AppShimHostManagerBrowserTest { 220 : public AppShimHostManagerBrowserTest {
236 public: 221 public:
237 AppShimHostManagerBrowserTestFailsCreate() {} 222 AppShimHostManagerBrowserTestSocketFiles() {}
223
224 protected:
225 base::FilePath directory_in_tmp_;
226 base::FilePath symlink_path_;
238 227
239 private: 228 private:
240 virtual bool SetUpUserDataDirectory() OVERRIDE; 229 virtual bool SetUpUserDataDirectory() OVERRIDE;
230 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;
241 231
242 base::ScopedTempDir barrier_dir_; 232 DISALLOW_COPY_AND_ASSIGN(AppShimHostManagerBrowserTestSocketFiles);
243
244 DISALLOW_COPY_AND_ASSIGN(AppShimHostManagerBrowserTestFailsCreate);
245 }; 233 };
246 234
247 bool AppShimHostManagerBrowserTestFailsCreate::SetUpUserDataDirectory() { 235 bool AppShimHostManagerBrowserTestSocketFiles::SetUpUserDataDirectory() {
236 // Create an existing symlink. It should be replaced by AppShimHostManager.
248 base::FilePath user_data_dir; 237 base::FilePath user_data_dir;
249 // Start in the "real" user data dir for this test. This is a meta-test for
250 // the symlinking steps used in the superclass. That is, by putting the
251 // clobber in the actual user data dir, the test will fail if the symlink
252 // does not actually point to the user data dir, since it won't be clobbered.
253 EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir)); 238 EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
254 base::FilePath socket_path = 239 symlink_path_ = user_data_dir.Append(app_mode::kAppShimSocketSymlinkName);
255 user_data_dir.Append(app_mode::kAppShimSocketName); 240 base::FilePath temp_dir;
256 // Create a "barrier" to forming the UNIX domain socket. This is just a 241 PathService::Get(base::DIR_TEMP, &temp_dir);
257 // pre-existing directory which can not be unlink()ed, in order to place a 242 EXPECT_TRUE(base::CreateSymbolicLink(temp_dir.Append("chrome-XXXXXX"),
258 // named socked there instead. 243 symlink_path_));
259 EXPECT_TRUE(barrier_dir_.Set(socket_path));
260 return AppShimHostManagerBrowserTest::SetUpUserDataDirectory(); 244 return AppShimHostManagerBrowserTest::SetUpUserDataDirectory();
261 } 245 }
262 246
263 // Test error handling. This is essentially testing for lifetime correctness 247 void AppShimHostManagerBrowserTestSocketFiles::
264 // during startup for unexpected failures. 248 TearDownInProcessBrowserTestFixture() {
265 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTestFailsCreate, 249 // Check that created files have been deleted.
266 SocketFailure) { 250 EXPECT_FALSE(base::PathExists(directory_in_tmp_));
251 EXPECT_FALSE(base::PathExists(symlink_path_));
252 }
253
254 IN_PROC_BROWSER_TEST_F(AppShimHostManagerBrowserTestSocketFiles,
255 ReplacesSymlinkAndCleansUpFiles) {
256 // Get the directory created by AppShimHostManager.
267 test::AppShimHostManagerTestApi test_api( 257 test::AppShimHostManagerTestApi test_api(
268 g_browser_process->platform_part()->app_shim_host_manager()); 258 g_browser_process->platform_part()->app_shim_host_manager());
269 EXPECT_FALSE(test_api.factory()); 259 directory_in_tmp_ = test_api.directory_in_tmp();
260
261 // Check that socket files have been created.
262 EXPECT_TRUE(base::PathExists(directory_in_tmp_));
263 EXPECT_TRUE(base::PathExists(symlink_path_));
264
265 // Check that the symlink has been replaced.
266 base::FilePath socket_path;
267 ASSERT_TRUE(base::ReadSymbolicLink(symlink_path_, &socket_path));
268 EXPECT_EQ(app_mode::kAppShimSocketShortName, socket_path.BaseName().value());
270 } 269 }
271 270
272 } // namespace 271 } // namespace
OLDNEW
« no previous file with comments | « no previous file | apps/app_shim/app_shim_host_manager_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698