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

Side by Side Diff: util/file/file_io_test.cc

Issue 1001673002: Add Locking calls to file_io.h plus implementations and test (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: ws Created 5 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "util/file/file_io.h"
16
17 #include "base/atomicops.h"
18 #include "base/basictypes.h"
19 #include "base/files/file_path.h"
20 #include "gtest/gtest.h"
21 #include "util/test/errors.h"
22 #include "util/test/scoped_temp_dir.h"
23 #include "util/test/thread.h"
24
25 namespace crashpad {
26 namespace test {
27 namespace {
28
29 enum class ReadOrWrite : bool {
30 Read,
Mark Mentovai 2015/03/20 22:11:37 I’m digging these enum classes! kRead, kWrite to m
scottmg 2015/03/20 22:32:53 Done.
31 Write,
32 };
33
34 void FileShareModeTest(ReadOrWrite first, ReadOrWrite second) {
Mark Mentovai 2015/03/20 22:11:36 These were good tests to add!
35 ScopedTempDir temp_dir;
36 base::FilePath shared_file =
37 temp_dir.path().Append(FILE_PATH_LITERAL("shared_file"));
38 {
39 // Create an empty file to work on.
40 ScopedFileHandle create(
41 LoggingOpenFileForWrite(shared_file,
42 FileWriteMode::kCreateOrFail,
43 FilePermissions::kOwnerOnly));
44 }
45
46 auto handle1 = ScopedFileHandle(
47 (first == ReadOrWrite::Read)
48 ? LoggingOpenFileForRead(shared_file)
49 : LoggingOpenFileForWrite(shared_file,
50 FileWriteMode::kReuseOrCreate,
51 FilePermissions::kOwnerOnly));
52 ASSERT_NE(handle1, kInvalidFileHandle);
53 auto handle2 = ScopedFileHandle(
54 (second == ReadOrWrite::Read)
55 ? LoggingOpenFileForRead(shared_file)
56 : LoggingOpenFileForWrite(shared_file,
57 FileWriteMode::kReuseOrCreate,
58 FilePermissions::kOwnerOnly));
59 EXPECT_NE(handle2, kInvalidFileHandle);
Mark Mentovai 2015/03/20 22:11:36 EXPECT_NE(handle1, handle2) also, because we’re ki
scottmg 2015/03/20 22:32:53 Done.
60 }
61
62 TEST(FileIO, FileShareModes) {
Mark Mentovai 2015/03/20 22:11:37 Can you have a separate TEST for each of these? Li
scottmg 2015/03/20 22:32:53 Done.
63 FileShareModeTest(ReadOrWrite::Read, ReadOrWrite::Read);
64 FileShareModeTest(ReadOrWrite::Read, ReadOrWrite::Write);
65 FileShareModeTest(ReadOrWrite::Write, ReadOrWrite::Read);
66 FileShareModeTest(ReadOrWrite::Write, ReadOrWrite::Write);
67 }
68
69 TEST(FileIO, MultipleSharedLocks) {
70 ScopedTempDir temp_dir;
71 base::FilePath shared_file =
72 temp_dir.path().Append(FILE_PATH_LITERAL("file_to_lock"));
73
74 {
75 // Create an empty file to lock.
76 ScopedFileHandle create(
77 LoggingOpenFileForWrite(shared_file,
78 FileWriteMode::kCreateOrFail,
79 FilePermissions::kOwnerOnly));
80 }
81
82 auto handle1 = ScopedFileHandle(LoggingOpenFileForRead(shared_file));
83 ASSERT_NE(handle1, kInvalidFileHandle);
84 EXPECT_TRUE(LoggingLockFile(handle1.get(), FileLocking::kShared));
85
86 auto handle2 = ScopedFileHandle(LoggingOpenFileForRead(shared_file));
87 ASSERT_NE(handle1, kInvalidFileHandle);
88 EXPECT_TRUE(LoggingLockFile(handle2.get(), FileLocking::kShared));
89
90 EXPECT_TRUE(LoggingUnlockFile(handle1.get()));
91 EXPECT_TRUE(LoggingUnlockFile(handle2.get()));
92 }
93
94 class LockingTestThread : public Thread {
95 public:
96 void Main() override {
Mark Mentovai 2015/03/20 22:11:37 Doesn’t need to be public. private’s fine. There’s
scottmg 2015/03/20 22:32:53 Done.
97 for (int i = 0; i < iterations; ++i) {
98 EXPECT_TRUE(LoggingLockFile(file.get(), lock_type));
99 base::subtle::NoBarrier_AtomicIncrement(actual_iterations, 1);
100 EXPECT_TRUE(LoggingUnlockFile(file.get()));
101 }
102 }
103
104 ScopedFileHandle file;
Mark Mentovai 2015/03/20 22:11:37 private, trailing underscores, DISALLOW_COPY_AND_A
scottmg 2015/03/20 22:32:53 Done.
105 FileLocking lock_type;
106 int iterations;
107 base::subtle::Atomic32* actual_iterations;
108 };
109
110 void LockingTest(FileLocking main_lock, FileLocking other_locks) {
111 ScopedTempDir temp_dir;
112 base::FilePath shared_file =
113 temp_dir.path().Append(FILE_PATH_LITERAL("file_to_lock"));
114
115 {
116 // Create an empty file to lock.
117 ScopedFileHandle create(
118 LoggingOpenFileForWrite(shared_file,
119 FileWriteMode::kCreateOrFail,
120 FilePermissions::kOwnerOnly));
121 }
122
123 auto initial = ScopedFileHandle(
124 (main_lock == FileLocking::kShared)
125 ? LoggingOpenFileForRead(shared_file)
126 : LoggingOpenFileForWrite(shared_file,
127 FileWriteMode::kReuseOrCreate,
128 FilePermissions::kOwnerOnly));
129 ASSERT_NE(initial, kInvalidFileHandle);
130 ASSERT_TRUE(LoggingLockFile(initial.get(), main_lock));
131
132 base::subtle::Atomic32 actual_iterations = 0;
133
134 LockingTestThread threads[20];
135 int expected_iterations = 0;
136 for (size_t index = 0; index < arraysize(threads); ++index) {
137 threads[index].file = ScopedFileHandle(
138 (other_locks == FileLocking::kShared)
139 ? LoggingOpenFileForRead(shared_file)
140 : LoggingOpenFileForWrite(shared_file,
141 FileWriteMode::kReuseOrCreate,
142 FilePermissions::kOwnerOnly));
143 ASSERT_NE(threads[index].file, kInvalidFileHandle);
144 threads[index].lock_type = other_locks;
145 threads[index].iterations = static_cast<int>(index * 10);
146 threads[index].actual_iterations = &actual_iterations;
147 expected_iterations += threads[index].iterations;
148
149 ASSERT_NO_FATAL_FAILURE(threads[index].Start());
150 }
151
152 base::subtle::Atomic32 result =
153 base::subtle::Release_Load(&actual_iterations);
154 EXPECT_EQ(0, result);
155
156 ASSERT_TRUE(LoggingUnlockFile(initial.get()));
157
158 for (auto& t : threads)
159 t.Join();
160
161 EXPECT_EQ(expected_iterations, actual_iterations);
162 }
163
164 TEST(FileIO, ExclusiveVsExclusives) {
165 LockingTest(FileLocking::kExclusive, FileLocking::kExclusive);
166 }
167
168 TEST(FileIO, ExclusiveVsShareds) {
169 LockingTest(FileLocking::kExclusive, FileLocking::kShared);
170 }
171
172 TEST(FileIO, SharedVsExclusives) {
173 LockingTest(FileLocking::kShared, FileLocking::kExclusive);
174 }
175
176 } // namespace
177 } // namespace test
178 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698