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

Side by Side Diff: chrome/common/multi_process_lock_unittest.cc

Issue 4721001: Add multi_process_lock to chrome/common (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more clean up for mento Created 10 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/basictypes.h"
6 #include "base/logging.h"
7 #include "base/rand_util.h"
8 #include "base/scoped_ptr.h"
9 #include "base/stringprintf.h"
10 #include "base/test/multiprocess_test.h"
11 #include "base/time.h"
12 #include "chrome/common/multi_process_lock.h"
13 #include "testing/multiprocess_func_list.h"
14
15 #if defined(OS_WIN)
16 #include <windows.h>
17 #else // !defined(OS_WIN)
18 #include <stdlib.h>
19 #endif // defined(OS_WIN)
20
21 class MultiProcessLockTest : public base::MultiProcessTest {
22 public:
23 static const char kLockEnviromentVarName[];
24
25 // TODO(dmaclach): Move to process_utils.
26 class ScopedEnvironmentVariable {
27 public:
28 ScopedEnvironmentVariable(const std::string &name,
29 const std::string &value) : name_(name) {
30 setenv(name_, value);
31 }
32 ~ScopedEnvironmentVariable() {
33 setenv(name_, "");
34 }
35 private:
36 std::string name_;
37 DISALLOW_COPY_AND_ASSIGN(ScopedEnvironmentVariable);
38 };
39
40 // TODO(dmaclach): Move setenv and getenv to process_utils.
41 static bool setenv(const std::string &name, const std::string &value);
42 static bool getenv(const std::string &name, std::string *value);
43
44 std::string GenerateLockName();
45 void ExpectLockIsLocked(const std::string &name);
46 void ExpectLockIsUnlocked(const std::string &name);
47 };
48
49 const char MultiProcessLockTest::kLockEnviromentVarName[]
50 = "MULTI_PROCESS_TEST_LOCK_NAME";
51
52 bool MultiProcessLockTest::setenv(const std::string &name,
Mark Mentovai 2010/11/16 18:55:15 Does base/environmenth.h help here?
53 const std::string &value) {
54 #if defined(OS_WIN)
55 return _putenv_s(name.c_str(), value.c_str()) == 0;
56 #else // !defined(OS_WIN)
57 if (value.length()) {
58 return ::setenv(name.c_str(), value.c_str(), true) == 0;
59 } else {
60 return unsetenv(name.c_str());
61 }
62 #endif //defined(OS_WIN)
63 }
64
65 bool MultiProcessLockTest::getenv(const std::string &name, std::string *value) {
66 bool ret = false;
67 #if defined(OS_WIN)
68 size_t requiredSize = 0;
69 errno_t err = getenv_s(&requiredSize, NULL, 0, name.c_str());
70 if (err == 0 && requiredSize > 0) {
71 ret = true;
72 if (value) {
73 scoped_array<char> c_value(new char[requiredSize]);
74 err = getenv_s(&requiredSize, c_value.get(), requiredSize, name.c_str());
75 if (err == 0) {
76 *value = c_value.get();
77 } else {
78 ret = false;
79 *value = "";
80 }
81 }
82 }
83 #else // !defined(OS_WIN)
84 const char *c_value = ::getenv(name.c_str());
85 if (c_value) {
86 ret = true;
87 if (value) {
88 *value = c_value;
89 }
90 }
91 #endif //defined(OS_WIN)
92 return ret;
93 }
94
95 std::string MultiProcessLockTest::GenerateLockName() {
96 base::Time now = base::Time::NowFromSystemTime();
97 return base::StringPrintf("multi_process_test_lock %lf%lf",
98 now.ToDoubleT(), base::RandDouble());
99 }
100
101 void MultiProcessLockTest::ExpectLockIsLocked(const std::string &name) {
102 ScopedEnvironmentVariable var(kLockEnviromentVarName, name);
103 base::ProcessHandle handle = SpawnChild("MultiProcessLockTryFailMain", false);
104 ASSERT_TRUE(handle);
105 int exit_code = 0;
106 EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
107 EXPECT_EQ(exit_code, 0);
108 }
109
110 void MultiProcessLockTest::ExpectLockIsUnlocked(
111 const std::string &name) {
112 ScopedEnvironmentVariable var(kLockEnviromentVarName, name);
113 base::ProcessHandle handle = SpawnChild("MultiProcessLockTrySucceedMain",
114 false);
115 ASSERT_TRUE(handle);
116 int exit_code = 0;
117 EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
118 EXPECT_EQ(exit_code, 0);
119 }
120
121 TEST_F(MultiProcessLockTest, BasicCreationTest) {
122 // Test basic creation/destruction with no lock taken
123 std::string name = GenerateLockName();
124 scoped_ptr<MultiProcessLock> scoped(MultiProcessLock::Create(name));
125 ExpectLockIsUnlocked(name);
126 scoped.reset(NULL);
127 }
128
129 TEST_F(MultiProcessLockTest, LongNameTest) {
130 // Linux has a max path name of 108 characters.
131 // http://lxr.linux.no/linux+v2.6.36/include/linux/un.h
132 // This is enforced on all platforms.
133 LOG(INFO) << "Following error log due to long name is expected";
134 std::string name("This is a name that is longer than one hundred and eight "
135 "characters to make sure that we fail appropriately on linux when we "
136 "have a path that is to long for linux to handle");
137 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
138 EXPECT_FALSE(test_lock->TryLock());
139 }
140
141 TEST_F(MultiProcessLockTest, SimpleLock) {
142 std::string name = GenerateLockName();
143 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
144 EXPECT_TRUE(test_lock->TryLock());
145 ExpectLockIsLocked(name);
146 test_lock->Unlock();
147 ExpectLockIsUnlocked(name);
148 }
149
150 TEST_F(MultiProcessLockTest, RecursiveLock) {
151 std::string name = GenerateLockName();
152 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
153 EXPECT_TRUE(test_lock->TryLock());
154 ExpectLockIsLocked(name);
155 LOG(INFO) << "Following error log "
156 << "'MultiProcessLock is already locked' is expected";
157 EXPECT_TRUE(test_lock->TryLock());
158 ExpectLockIsLocked(name);
159 test_lock->Unlock();
160 ExpectLockIsUnlocked(name);
161 LOG(INFO) << "Following error log "
162 << "'Over-unlocked MultiProcessLock' is expected";
163 test_lock->Unlock();
164 ExpectLockIsUnlocked(name);
165 test_lock.reset();
166 }
167
168 TEST_F(MultiProcessLockTest, LockScope) {
169 // Check to see that lock is released when it goes out of scope.
170 std::string name = GenerateLockName();
171 {
172 scoped_ptr<MultiProcessLock> test_lock(MultiProcessLock::Create(name));
173 EXPECT_TRUE(test_lock->TryLock());
174 ExpectLockIsLocked(name);
175 }
176 ExpectLockIsUnlocked(name);
177 }
178
179 MULTIPROCESS_TEST_MAIN(MultiProcessLockTryFailMain) {
180 std::string name;
181 EXPECT_TRUE(MultiProcessLockTest::getenv(
182 MultiProcessLockTest::kLockEnviromentVarName, &name));
183 #if defined(OS_MACOSX)
184 // OS X sends out a log if a lock fails.
185 // Hopefully this will keep people from panicking about it when they
186 // are perusing thge build logs.
avi_google.com 2010/11/16 22:07:30 drive-by typo: thge
187 LOG(INFO) << "Following error log "
188 << "\"CFMessagePort: bootstrap_register(): failed 1100 (0x44c) "
189 << "'Permission denied'\" is expected";
190 #endif // defined(OS_MACOSX)
191 scoped_ptr<MultiProcessLock> test_lock(
192 MultiProcessLock::Create(name));
193 EXPECT_FALSE(test_lock->TryLock());
194 return 0;
195 }
196
197 MULTIPROCESS_TEST_MAIN(MultiProcessLockTrySucceedMain) {
198 std::string name;
199 EXPECT_TRUE(MultiProcessLockTest::getenv(
200 MultiProcessLockTest::kLockEnviromentVarName, &name));
201 scoped_ptr<MultiProcessLock> test_lock(
202 MultiProcessLock::Create(name));
203 EXPECT_TRUE(test_lock->TryLock());
204 return 0;
205 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698