OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/process_singleton.h" | 5 #include "chrome/browser/process_singleton.h" |
6 | 6 |
7 #include <sys/types.h> | 7 #include <sys/types.h> |
8 #include <sys/wait.h> | 8 #include <sys/wait.h> |
9 #include <signal.h> | 9 #include <signal.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "chrome/test/ui/ui_test.h" | 25 #include "chrome/test/ui/ui_test.h" |
26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 typedef UITest ProcessSingletonLinuxTest; | 30 typedef UITest ProcessSingletonLinuxTest; |
31 | 31 |
32 // A helper method to call ProcessSingleton::NotifyOtherProcess(). | 32 // A helper method to call ProcessSingleton::NotifyOtherProcess(). |
33 // |url| will be added to CommandLine for current process, so that it can be | 33 // |url| will be added to CommandLine for current process, so that it can be |
34 // sent to browser process by ProcessSingleton::NotifyOtherProcess(). | 34 // sent to browser process by ProcessSingleton::NotifyOtherProcess(). |
35 ProcessSingleton::NotifyResult NotifyOtherProcess(const std::string& url) { | 35 ProcessSingleton::NotifyResult NotifyOtherProcess(const std::string& url, |
| 36 int timeout_ms) { |
36 FilePath user_data_dir; | 37 FilePath user_data_dir; |
37 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); | 38 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
38 | 39 |
39 // Hack: mutate the current process's command line so we don't show a dialog. | 40 // Hack: mutate the current process's command line so we don't show a dialog. |
40 // Note that this only works if we have no loose values on the command line, | 41 // Note that this only works if we have no loose values on the command line, |
41 // but that's fine for unit tests. In a UI test we disable error dialogs | 42 // but that's fine for unit tests. In a UI test we disable error dialogs |
42 // when spawning Chrome, but this test hits the ProcessSingleton directly. | 43 // when spawning Chrome, but this test hits the ProcessSingleton directly. |
43 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); | 44 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
44 if (!cmd_line->HasSwitch(switches::kNoProcessSingletonDialog)) | 45 if (!cmd_line->HasSwitch(switches::kNoProcessSingletonDialog)) |
45 cmd_line->AppendSwitch(switches::kNoProcessSingletonDialog); | 46 cmd_line->AppendSwitch(switches::kNoProcessSingletonDialog); |
46 | 47 |
47 CommandLine new_cmd_line(*cmd_line); | 48 CommandLine new_cmd_line(*cmd_line); |
48 new_cmd_line.AppendLooseValue(ASCIIToWide(url)); | 49 new_cmd_line.AppendLooseValue(ASCIIToWide(url)); |
49 | 50 |
50 ProcessSingleton process_singleton(user_data_dir); | 51 ProcessSingleton process_singleton(user_data_dir); |
51 | 52 |
52 // Use a short timeout to keep tests fast. | 53 return process_singleton.NotifyOtherProcessWithTimeout( |
53 const int kTimeoutSeconds = 3; | 54 new_cmd_line, timeout_ms / 1000); |
54 return process_singleton.NotifyOtherProcessWithTimeout(new_cmd_line, | |
55 kTimeoutSeconds); | |
56 } | 55 } |
57 | 56 |
58 } // namespace | 57 } // namespace |
59 | 58 |
60 // Test if the socket file and symbol link created by ProcessSingletonLinux | 59 // Test if the socket file and symbol link created by ProcessSingletonLinux |
61 // are valid. When running this test, the ProcessSingleton object is already | 60 // are valid. When running this test, the ProcessSingleton object is already |
62 // initiated by UITest. So we just test against this existing object. | 61 // initiated by UITest. So we just test against this existing object. |
63 TEST_F(ProcessSingletonLinuxTest, CheckSocketFile) { | 62 TEST_F(ProcessSingletonLinuxTest, CheckSocketFile) { |
64 FilePath user_data_dir; | 63 FilePath user_data_dir; |
65 FilePath socket_path; | 64 FilePath socket_path; |
(...skipping 22 matching lines...) Expand all Loading... |
88 #define NotifyOtherProcessSuccess FLAKY_NotifyOtherProcessSuccess | 87 #define NotifyOtherProcessSuccess FLAKY_NotifyOtherProcessSuccess |
89 #define NotifyOtherProcessHostChanged FLAKY_NotifyOtherProcessHostChanged | 88 #define NotifyOtherProcessHostChanged FLAKY_NotifyOtherProcessHostChanged |
90 #endif | 89 #endif |
91 | 90 |
92 // TODO(james.su@gmail.com): port following tests to Windows. | 91 // TODO(james.su@gmail.com): port following tests to Windows. |
93 // Test success case of NotifyOtherProcess(). | 92 // Test success case of NotifyOtherProcess(). |
94 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) { | 93 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) { |
95 std::string url("about:blank"); | 94 std::string url("about:blank"); |
96 int original_tab_count = GetTabCount(); | 95 int original_tab_count = GetTabCount(); |
97 | 96 |
98 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, NotifyOtherProcess(url)); | 97 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, |
| 98 NotifyOtherProcess(url, action_timeout_ms())); |
99 EXPECT_EQ(original_tab_count + 1, GetTabCount()); | 99 EXPECT_EQ(original_tab_count + 1, GetTabCount()); |
100 EXPECT_EQ(url, GetActiveTabURL().spec()); | 100 EXPECT_EQ(url, GetActiveTabURL().spec()); |
101 } | 101 } |
102 | 102 |
103 // Test failure case of NotifyOtherProcess(). | 103 // Test failure case of NotifyOtherProcess(). |
104 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) { | 104 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) { |
105 base::ProcessId pid = browser_process_id(); | 105 base::ProcessId pid = browser_process_id(); |
106 | 106 |
107 ASSERT_GE(pid, 1); | 107 ASSERT_GE(pid, 1); |
108 | 108 |
109 // Block the browser process, then it'll be killed by | 109 // Block the browser process, then it'll be killed by |
110 // ProcessSingleton::NotifyOtherProcess(). | 110 // ProcessSingleton::NotifyOtherProcess(). |
111 kill(pid, SIGSTOP); | 111 kill(pid, SIGSTOP); |
112 | 112 |
113 // Wait to make sure the browser process is actually stopped. | 113 // Wait to make sure the browser process is actually stopped. |
114 // It's necessary when running with valgrind. | 114 // It's necessary when running with valgrind. |
115 HANDLE_EINTR(waitpid(pid, 0, WUNTRACED)); | 115 HANDLE_EINTR(waitpid(pid, 0, WUNTRACED)); |
116 | 116 |
117 std::string url("about:blank"); | 117 std::string url("about:blank"); |
118 EXPECT_EQ(ProcessSingleton::PROCESS_NONE, NotifyOtherProcess(url)); | 118 EXPECT_EQ(ProcessSingleton::PROCESS_NONE, |
| 119 NotifyOtherProcess(url, action_timeout_ms())); |
119 | 120 |
120 // Wait for a while to make sure the browser process is actually killed. | 121 // Wait for a while to make sure the browser process is actually killed. |
121 EXPECT_FALSE(CrashAwareSleep(1000)); | 122 EXPECT_FALSE(CrashAwareSleep(sleep_timeout_ms())); |
122 } | 123 } |
123 | 124 |
124 // Test that we can still notify a process on the same host even after the | 125 // Test that we can still notify a process on the same host even after the |
125 // hostname changed. | 126 // hostname changed. |
126 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) { | 127 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) { |
127 FilePath lock_path = user_data_dir().Append(chrome::kSingletonLockFilename); | 128 FilePath lock_path = user_data_dir().Append(chrome::kSingletonLockFilename); |
128 EXPECT_EQ(0, unlink(lock_path.value().c_str())); | 129 EXPECT_EQ(0, unlink(lock_path.value().c_str())); |
129 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path.value().c_str())); | 130 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path.value().c_str())); |
130 | 131 |
131 int original_tab_count = GetTabCount(); | 132 int original_tab_count = GetTabCount(); |
132 | 133 |
133 std::string url("about:blank"); | 134 std::string url("about:blank"); |
134 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, NotifyOtherProcess(url)); | 135 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, |
| 136 NotifyOtherProcess(url, action_timeout_ms())); |
135 EXPECT_EQ(original_tab_count + 1, GetTabCount()); | 137 EXPECT_EQ(original_tab_count + 1, GetTabCount()); |
136 EXPECT_EQ(url, GetActiveTabURL().spec()); | 138 EXPECT_EQ(url, GetActiveTabURL().spec()); |
137 } | 139 } |
138 | 140 |
139 // Test that we fail when lock says process is on another host and we can't | 141 // Test that we fail when lock says process is on another host and we can't |
140 // notify it over the socket. | 142 // notify it over the socket. |
141 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessDifferingHost) { | 143 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessDifferingHost) { |
142 base::ProcessId pid = browser_process_id(); | 144 base::ProcessId pid = browser_process_id(); |
143 | 145 |
144 ASSERT_GE(pid, 1); | 146 ASSERT_GE(pid, 1); |
145 | 147 |
146 // Kill the browser process, so that it does not respond on the socket. | 148 // Kill the browser process, so that it does not respond on the socket. |
147 kill(pid, SIGKILL); | 149 kill(pid, SIGKILL); |
148 // Wait for a while to make sure the browser process is actually killed. | 150 // Wait for a while to make sure the browser process is actually killed. |
149 EXPECT_FALSE(CrashAwareSleep(1000)); | 151 EXPECT_FALSE(CrashAwareSleep(sleep_timeout_ms())); |
150 | 152 |
151 FilePath lock_path = user_data_dir().Append(chrome::kSingletonLockFilename); | 153 FilePath lock_path = user_data_dir().Append(chrome::kSingletonLockFilename); |
152 EXPECT_EQ(0, unlink(lock_path.value().c_str())); | 154 EXPECT_EQ(0, unlink(lock_path.value().c_str())); |
153 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path.value().c_str())); | 155 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path.value().c_str())); |
154 | 156 |
155 std::string url("about:blank"); | 157 std::string url("about:blank"); |
156 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, NotifyOtherProcess(url)); | 158 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, |
| 159 NotifyOtherProcess(url, action_timeout_ms())); |
157 } | 160 } |
OLD | NEW |