OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/common/multi_process_lock.h" |
| 6 |
| 7 #include <memory> |
| 8 |
5 #include "base/environment.h" | 9 #include "base/environment.h" |
6 #include "base/logging.h" | 10 #include "base/logging.h" |
7 #include "base/macros.h" | 11 #include "base/macros.h" |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "base/process/kill.h" | 12 #include "base/process/kill.h" |
10 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
11 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
12 #include "base/test/multiprocess_test.h" | 15 #include "base/test/multiprocess_test.h" |
13 #include "base/time/time.h" | 16 #include "base/time/time.h" |
14 #include "build/build_config.h" | 17 #include "build/build_config.h" |
15 #include "chrome/common/multi_process_lock.h" | |
16 #include "testing/multiprocess_func_list.h" | 18 #include "testing/multiprocess_func_list.h" |
17 | 19 |
18 class MultiProcessLockTest : public base::MultiProcessTest { | 20 class MultiProcessLockTest : public base::MultiProcessTest { |
19 public: | 21 public: |
20 static const char kLockEnviromentVarName[]; | 22 static const char kLockEnviromentVarName[]; |
21 | 23 |
22 class ScopedEnvironmentVariable { | 24 class ScopedEnvironmentVariable { |
23 public: | 25 public: |
24 ScopedEnvironmentVariable(const std::string &name, | 26 ScopedEnvironmentVariable(const std::string &name, |
25 const std::string &value) | 27 const std::string &value) |
26 : name_(name), environment_(base::Environment::Create()) { | 28 : name_(name), environment_(base::Environment::Create()) { |
27 environment_->SetVar(name_.c_str(), value); | 29 environment_->SetVar(name_.c_str(), value); |
28 } | 30 } |
29 ~ScopedEnvironmentVariable() { | 31 ~ScopedEnvironmentVariable() { |
30 environment_->UnSetVar(name_.c_str()); | 32 environment_->UnSetVar(name_.c_str()); |
31 } | 33 } |
32 | 34 |
33 private: | 35 private: |
34 std::string name_; | 36 std::string name_; |
35 scoped_ptr<base::Environment> environment_; | 37 std::unique_ptr<base::Environment> environment_; |
36 DISALLOW_COPY_AND_ASSIGN(ScopedEnvironmentVariable); | 38 DISALLOW_COPY_AND_ASSIGN(ScopedEnvironmentVariable); |
37 }; | 39 }; |
38 | 40 |
39 std::string GenerateLockName(); | 41 std::string GenerateLockName(); |
40 void ExpectLockIsLocked(const std::string &name); | 42 void ExpectLockIsLocked(const std::string &name); |
41 void ExpectLockIsUnlocked(const std::string &name); | 43 void ExpectLockIsUnlocked(const std::string &name); |
42 }; | 44 }; |
43 | 45 |
44 const char MultiProcessLockTest::kLockEnviromentVarName[] | 46 const char MultiProcessLockTest::kLockEnviromentVarName[] |
45 = "MULTI_PROCESS_TEST_LOCK_NAME"; | 47 = "MULTI_PROCESS_TEST_LOCK_NAME"; |
(...skipping 19 matching lines...) Expand all Loading... |
65 base::Process process = SpawnChild("MultiProcessLockTrySucceedMain"); | 67 base::Process process = SpawnChild("MultiProcessLockTrySucceedMain"); |
66 ASSERT_TRUE(process.IsValid()); | 68 ASSERT_TRUE(process.IsValid()); |
67 int exit_code = -1; | 69 int exit_code = -1; |
68 EXPECT_TRUE(process.WaitForExit(&exit_code)); | 70 EXPECT_TRUE(process.WaitForExit(&exit_code)); |
69 EXPECT_EQ(0, exit_code); | 71 EXPECT_EQ(0, exit_code); |
70 } | 72 } |
71 | 73 |
72 TEST_F(MultiProcessLockTest, BasicCreationTest) { | 74 TEST_F(MultiProcessLockTest, BasicCreationTest) { |
73 // Test basic creation/destruction with no lock taken | 75 // Test basic creation/destruction with no lock taken |
74 std::string name = GenerateLockName(); | 76 std::string name = GenerateLockName(); |
75 scoped_ptr<MultiProcessLock> scoped(MultiProcessLock::Create(name)); | 77 std::unique_ptr<MultiProcessLock> scoped(MultiProcessLock::Create(name)); |
76 ExpectLockIsUnlocked(name); | 78 ExpectLockIsUnlocked(name); |
77 scoped.reset(NULL); | 79 scoped.reset(NULL); |
78 } | 80 } |
79 | 81 |
80 TEST_F(MultiProcessLockTest, LongNameTest) { | 82 TEST_F(MultiProcessLockTest, LongNameTest) { |
81 // Every platform has has it's own max path name size, | 83 // Every platform has has it's own max path name size, |
82 // so different checks are needed for them. | 84 // so different checks are needed for them. |
83 // POSIX: sizeof(address.sun_path) - 2 | 85 // POSIX: sizeof(address.sun_path) - 2 |
84 // Mac OS X: BOOTSTRAP_MAX_NAME_LEN | 86 // Mac OS X: BOOTSTRAP_MAX_NAME_LEN |
85 // Windows: MAX_PATH | 87 // Windows: MAX_PATH |
86 LOG(INFO) << "Following error log due to long name is expected"; | 88 LOG(INFO) << "Following error log due to long name is expected"; |
87 #if defined(OS_MACOSX) | 89 #if defined(OS_MACOSX) |
88 std::string name("This is a name that is longer than one hundred and " | 90 std::string name("This is a name that is longer than one hundred and " |
89 "twenty-eight characters to make sure that we fail appropriately on " | 91 "twenty-eight characters to make sure that we fail appropriately on " |
90 "Mac OS X when we have a path that is too long for Mac OS X to handle"); | 92 "Mac OS X when we have a path that is too long for Mac OS X to handle"); |
91 #elif defined(OS_POSIX) | 93 #elif defined(OS_POSIX) |
92 std::string name("This is a name that is longer than one hundred and eight " | 94 std::string name("This is a name that is longer than one hundred and eight " |
93 "characters to make sure that we fail appropriately on POSIX systems " | 95 "characters to make sure that we fail appropriately on POSIX systems " |
94 "when we have a path that is too long for the system to handle"); | 96 "when we have a path that is too long for the system to handle"); |
95 #elif defined(OS_WIN) | 97 #elif defined(OS_WIN) |
96 std::string name("This is a name that is longer than two hundred and sixty " | 98 std::string name("This is a name that is longer than two hundred and sixty " |
97 "characters to make sure that we fail appropriately on Windows when we " | 99 "characters to make sure that we fail appropriately on Windows when we " |
98 "have a path that is too long for Windows to handle " | 100 "have a path that is too long for Windows to handle " |
99 "This limitation comes from the MAX_PATH definition which is obviously " | 101 "This limitation comes from the MAX_PATH definition which is obviously " |
100 "defined to be a maximum of two hundred and sixty characters "); | 102 "defined to be a maximum of two hundred and sixty characters "); |
101 #endif | 103 #endif |
102 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); | 104 std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); |
103 EXPECT_FALSE(test_lock->TryLock()); | 105 EXPECT_FALSE(test_lock->TryLock()); |
104 } | 106 } |
105 | 107 |
106 TEST_F(MultiProcessLockTest, SimpleLock) { | 108 TEST_F(MultiProcessLockTest, SimpleLock) { |
107 std::string name = GenerateLockName(); | 109 std::string name = GenerateLockName(); |
108 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); | 110 std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); |
109 EXPECT_TRUE(test_lock->TryLock()); | 111 EXPECT_TRUE(test_lock->TryLock()); |
110 ExpectLockIsLocked(name); | 112 ExpectLockIsLocked(name); |
111 test_lock->Unlock(); | 113 test_lock->Unlock(); |
112 ExpectLockIsUnlocked(name); | 114 ExpectLockIsUnlocked(name); |
113 } | 115 } |
114 | 116 |
115 TEST_F(MultiProcessLockTest, RecursiveLock) { | 117 TEST_F(MultiProcessLockTest, RecursiveLock) { |
116 std::string name = GenerateLockName(); | 118 std::string name = GenerateLockName(); |
117 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); | 119 std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); |
118 EXPECT_TRUE(test_lock->TryLock()); | 120 EXPECT_TRUE(test_lock->TryLock()); |
119 ExpectLockIsLocked(name); | 121 ExpectLockIsLocked(name); |
120 LOG(INFO) << "Following error log " | 122 LOG(INFO) << "Following error log " |
121 << "'MultiProcessLock is already locked' is expected"; | 123 << "'MultiProcessLock is already locked' is expected"; |
122 EXPECT_TRUE(test_lock->TryLock()); | 124 EXPECT_TRUE(test_lock->TryLock()); |
123 ExpectLockIsLocked(name); | 125 ExpectLockIsLocked(name); |
124 test_lock->Unlock(); | 126 test_lock->Unlock(); |
125 ExpectLockIsUnlocked(name); | 127 ExpectLockIsUnlocked(name); |
126 LOG(INFO) << "Following error log " | 128 LOG(INFO) << "Following error log " |
127 << "'Over-unlocked MultiProcessLock' is expected"; | 129 << "'Over-unlocked MultiProcessLock' is expected"; |
128 test_lock->Unlock(); | 130 test_lock->Unlock(); |
129 ExpectLockIsUnlocked(name); | 131 ExpectLockIsUnlocked(name); |
130 test_lock.reset(); | 132 test_lock.reset(); |
131 } | 133 } |
132 | 134 |
133 TEST_F(MultiProcessLockTest, LockScope) { | 135 TEST_F(MultiProcessLockTest, LockScope) { |
134 // Check to see that lock is released when it goes out of scope. | 136 // Check to see that lock is released when it goes out of scope. |
135 std::string name = GenerateLockName(); | 137 std::string name = GenerateLockName(); |
136 { | 138 { |
137 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); | 139 std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); |
138 EXPECT_TRUE(test_lock->TryLock()); | 140 EXPECT_TRUE(test_lock->TryLock()); |
139 ExpectLockIsLocked(name); | 141 ExpectLockIsLocked(name); |
140 } | 142 } |
141 ExpectLockIsUnlocked(name); | 143 ExpectLockIsUnlocked(name); |
142 } | 144 } |
143 | 145 |
144 MULTIPROCESS_TEST_MAIN(MultiProcessLockTryFailMain) { | 146 MULTIPROCESS_TEST_MAIN(MultiProcessLockTryFailMain) { |
145 std::string name; | 147 std::string name; |
146 scoped_ptr<base::Environment> environment(base::Environment::Create()); | 148 std::unique_ptr<base::Environment> environment(base::Environment::Create()); |
147 EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName, | 149 EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName, |
148 &name)); | 150 &name)); |
149 #if defined(OS_MACOSX) | 151 #if defined(OS_MACOSX) |
150 // OS X sends out a log if a lock fails. | 152 // OS X sends out a log if a lock fails. |
151 // Hopefully this will keep people from panicking about it when they | 153 // Hopefully this will keep people from panicking about it when they |
152 // are perusing the build logs. | 154 // are perusing the build logs. |
153 LOG(INFO) << "Following error log " | 155 LOG(INFO) << "Following error log " |
154 << "\"CFMessagePort: bootstrap_register(): failed 1100 (0x44c) " | 156 << "\"CFMessagePort: bootstrap_register(): failed 1100 (0x44c) " |
155 << "'Permission denied'\" is expected"; | 157 << "'Permission denied'\" is expected"; |
156 #endif // defined(OS_MACOSX) | 158 #endif // defined(OS_MACOSX) |
157 scoped_ptr<MultiProcessLock> test_lock( | 159 std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); |
158 MultiProcessLock::Create(name)); | |
159 | 160 |
160 // Expect locking to fail because it is claimed by another process. | 161 // Expect locking to fail because it is claimed by another process. |
161 bool locked_successfully = test_lock->TryLock(); | 162 bool locked_successfully = test_lock->TryLock(); |
162 EXPECT_FALSE(locked_successfully); | 163 EXPECT_FALSE(locked_successfully); |
163 return locked_successfully; | 164 return locked_successfully; |
164 } | 165 } |
165 | 166 |
166 MULTIPROCESS_TEST_MAIN(MultiProcessLockTrySucceedMain) { | 167 MULTIPROCESS_TEST_MAIN(MultiProcessLockTrySucceedMain) { |
167 std::string name; | 168 std::string name; |
168 scoped_ptr<base::Environment> environment(base::Environment::Create()); | 169 std::unique_ptr<base::Environment> environment(base::Environment::Create()); |
169 EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName, | 170 EXPECT_TRUE(environment->GetVar(MultiProcessLockTest::kLockEnviromentVarName, |
170 &name)); | 171 &name)); |
171 scoped_ptr<MultiProcessLock> test_lock( | 172 std::unique_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name)); |
172 MultiProcessLock::Create(name)); | |
173 | 173 |
174 // Expect locking to succeed because it is not claimed yet. | 174 // Expect locking to succeed because it is not claimed yet. |
175 bool locked_successfully = test_lock->TryLock(); | 175 bool locked_successfully = test_lock->TryLock(); |
176 EXPECT_TRUE(locked_successfully); | 176 EXPECT_TRUE(locked_successfully); |
177 return !locked_successfully; | 177 return !locked_successfully; |
178 } | 178 } |
OLD | NEW |