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

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: parameterize test 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 TEST(FileIO, FileShareMode) {
30 ScopedTempDir temp_dir;
31 base::FilePath shared_file =
32 temp_dir.path().Append(FILE_PATH_LITERAL("shared_file"));
33 auto handle1 = ScopedFileHandle(LoggingOpenFileForWrite(
34 shared_file, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
35 ASSERT_NE(handle1, kInvalidFileHandle);
36 auto handle2 = ScopedFileHandle(LoggingOpenFileForWrite(
37 shared_file, FileWriteMode::kReuseOrCreate, FilePermissions::kOwnerOnly));
38 EXPECT_NE(handle2, kInvalidFileHandle);
39 }
40
41 TEST(FileIO, MultipleSharedLocks) {
42 ScopedTempDir temp_dir;
43 base::FilePath shared_file =
44 temp_dir.path().Append(FILE_PATH_LITERAL("file_to_lock"));
45
46 {
47 // Create an empty file to lock.
48 ScopedFileHandle create(
49 LoggingOpenFileForWrite(shared_file,
50 FileWriteMode::kCreateOrFail,
51 FilePermissions::kOwnerOnly));
52 }
53
54 auto handle1 = ScopedFileHandle(LoggingOpenFileForRead(shared_file));
55 ASSERT_NE(handle1, kInvalidFileHandle);
56 EXPECT_TRUE(LoggingLockFile(handle1.get(), FileLocking::kShared));
57
58 auto handle2 = ScopedFileHandle(LoggingOpenFileForRead(shared_file));
59 ASSERT_NE(handle1, kInvalidFileHandle);
60 EXPECT_TRUE(LoggingLockFile(handle2.get(), FileLocking::kShared));
61
62 EXPECT_TRUE(LoggingUnlockFile(handle1.get()));
63 EXPECT_TRUE(LoggingUnlockFile(handle2.get()));
64 }
65
66 struct ThreadData {
67 ScopedFileHandle file;
68 FileLocking lock_type;
69 int iterations;
70 base::subtle::Atomic32* actual_iterations;
71 };
72
73 void ThreadMain(ThreadData* info) {
74 for (int i = 0; i < info->iterations; ++i) {
75 EXPECT_TRUE(LoggingLockFile(info->file.get(), info->lock_type));
76 base::subtle::Barrier_AtomicIncrement(info->actual_iterations, 1);
Mark Mentovai 2015/03/20 15:03:55 I don’t think you need a memory barrier here.
scottmg 2015/03/20 21:07:34 Done.
77 EXPECT_TRUE(LoggingUnlockFile(info->file.get()));
78 }
79 }
80
81 void LockingTest(FileLocking main_lock, FileLocking other_locks) {
82 ScopedTempDir temp_dir;
83 base::FilePath shared_file =
84 temp_dir.path().Append(FILE_PATH_LITERAL("file_to_lock"));
85
86 {
87 // Create an empty file to lock.
88 ScopedFileHandle create(
89 LoggingOpenFileForWrite(shared_file,
90 FileWriteMode::kCreateOrFail,
91 FilePermissions::kOwnerOnly));
92 }
93
94 auto initial = ScopedFileHandle(
95 (main_lock == FileLocking::kShared)
96 ? LoggingOpenFileForRead(shared_file)
97 : LoggingOpenFileForWrite(shared_file,
98 FileWriteMode::kReuseOrCreate,
99 FilePermissions::kOwnerOnly));
100 ASSERT_NE(initial, kInvalidFileHandle);
101 ASSERT_TRUE(LoggingLockFile(initial.get(), main_lock));
102
103 base::subtle::Atomic32 actual_iterations = 0;
Mark Mentovai 2015/03/20 15:03:55 I’m not sure if the best practice for initializati
Robert Sesek 2015/03/20 16:31:35 Most instances in Chromium seem to initialize with
scottmg 2015/03/20 21:07:34 Left as direct assignment.
104
105 ThreadData info[20];
106 Thread<ThreadData> threads[arraysize(info)];
107 base::subtle::Atomic32 expected_iterations = 0;
Mark Mentovai 2015/03/20 15:03:56 This is not actually used for atomicity, it’s just
scottmg 2015/03/20 21:07:34 Right. I switched it back to int to make usage les
108 for (size_t index = 0; index < arraysize(info); ++index) {
109 info[index].file = ScopedFileHandle(
110 (other_locks == FileLocking::kShared)
111 ? LoggingOpenFileForRead(shared_file)
112 : LoggingOpenFileForWrite(shared_file,
113 FileWriteMode::kReuseOrCreate,
114 FilePermissions::kOwnerOnly));
115 ASSERT_NE(info[index].file, kInvalidFileHandle);
116 info[index].lock_type = other_locks;
117 info[index].iterations = index * 10;
118 info[index].actual_iterations = &actual_iterations;
119 expected_iterations += info[index].iterations;
120
121 ASSERT_NO_FATAL_FAILURE(threads[index].Start(&ThreadMain, &info[index]));
122 }
123
124 EXPECT_EQ(0, actual_iterations);
Mark Mentovai 2015/03/20 15:03:55 This one should have a barrier, so technically it
scottmg 2015/03/20 21:07:34 Done.
125
126 ASSERT_TRUE(LoggingUnlockFile(initial.get()));
127
128 for (auto& t : threads)
129 t.Join();
130
131 EXPECT_EQ(expected_iterations, actual_iterations);
132 }
133
134 TEST(FileIO, ExclusiveVsExclusives) {
135 LockingTest(FileLocking::kExclusive, FileLocking::kExclusive);
136 }
137
138 TEST(FileIO, ExclusiveVsShareds) {
139 LockingTest(FileLocking::kExclusive, FileLocking::kShared);
140 }
141
142 TEST(FileIO, SharedVsExclusives) {
143 LockingTest(FileLocking::kShared, FileLocking::kExclusive);
144 }
145
146 } // namespace
147 } // namespace test
148 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698