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

Side by Side Diff: services/preferences/tracked/registry_hash_store_contents_win_unittest.cc

Issue 2926453002: Fix a race condition in ~RegistryHashStoreContentsWin (Closed)
Patch Set: Add temp_scoped_dir_cleaner to a build file Created 3 years, 6 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
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 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 "services/preferences/tracked/registry_hash_store_contents_win.h" 5 #include "services/preferences/tracked/registry_hash_store_contents_win.h"
6 6
7 #include "base/bind.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/ptr_util.h"
7 #include "base/strings/string16.h" 10 #include "base/strings/string16.h"
8 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
9 #include "base/test/test_reg_util_win.h" 12 #include "base/test/test_reg_util_win.h"
13 #include "base/threading/thread.h"
10 #include "base/values.h" 14 #include "base/values.h"
11 #include "base/win/registry.h" 15 #include "base/win/registry.h"
12 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
13 17
14 namespace { 18 namespace {
15 19
16 constexpr base::char16 kRegistryPath[] = L"Foo\\TestStore"; 20 constexpr base::char16 kRegistryPath[] = L"Foo\\TestStore";
17 constexpr base::char16 kStoreKey[] = L"test_store_key"; 21 constexpr base::char16 kStoreKey[] = L"test_store_key";
18 22
19 // Hex-encoded MACs are 64 characters long. 23 // Hex-encoded MACs are 64 characters long.
20 constexpr char kTestStringA[] = 24 constexpr char kTestStringA[] =
21 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 25 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
22 constexpr char kTestStringB[] = 26 constexpr char kTestStringB[] =
23 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; 27 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
24 28
25 constexpr char kAtomicPrefPath[] = "path1"; 29 constexpr char kAtomicPrefPath[] = "path1";
26 constexpr char kSplitPrefPath[] = "extension"; 30 constexpr char kSplitPrefPath[] = "extension";
27 31
28 class RegistryHashStoreContentsWinTest : public testing::Test { 32 class RegistryHashStoreContentsWinTest : public testing::Test {
29 protected: 33 protected:
30 RegistryHashStoreContentsWinTest() {} 34 RegistryHashStoreContentsWinTest() {}
31 35
32 void SetUp() override { 36 void SetUp() override {
33 ASSERT_NO_FATAL_FAILURE( 37 ASSERT_NO_FATAL_FAILURE(
34 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER)); 38 registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));
35 39
36 contents.reset(new RegistryHashStoreContentsWin(kRegistryPath, kStoreKey)); 40 contents.reset(
41 new RegistryHashStoreContentsWin(kRegistryPath, kStoreKey, nullptr));
37 } 42 }
38 43
39 std::unique_ptr<HashStoreContents> contents; 44 std::unique_ptr<HashStoreContents> contents;
40 45
41 private: 46 private:
42 registry_util::RegistryOverrideManager registry_override_manager_; 47 registry_util::RegistryOverrideManager registry_override_manager_;
43 48
44 DISALLOW_COPY_AND_ASSIGN(RegistryHashStoreContentsWinTest); 49 DISALLOW_COPY_AND_ASSIGN(RegistryHashStoreContentsWinTest);
45 }; 50 };
46 51
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 contents->Reset(); 116 contents->Reset();
112 117
113 stored_mac.clear(); 118 stored_mac.clear();
114 EXPECT_FALSE(contents->GetMac(kAtomicPrefPath, &stored_mac)); 119 EXPECT_FALSE(contents->GetMac(kAtomicPrefPath, &stored_mac));
115 EXPECT_TRUE(stored_mac.empty()); 120 EXPECT_TRUE(stored_mac.empty());
116 121
117 split_macs.clear(); 122 split_macs.clear();
118 EXPECT_FALSE(contents->GetSplitMacs(kSplitPrefPath, &split_macs)); 123 EXPECT_FALSE(contents->GetSplitMacs(kSplitPrefPath, &split_macs));
119 EXPECT_EQ(0U, split_macs.size()); 124 EXPECT_EQ(0U, split_macs.size());
120 } 125 }
126
127 TEST(RegistryHashStoreContentsWinScopedTest, TestScopedDirsCleared) {
128 std::string stored_mac;
129
130 base::ScopedTempDir temp_dir;
131 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
132 const base::string16 registry_path =
133 temp_dir.GetPath().DirName().BaseName().LossyDisplayName();
134
135 RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey,
136 nullptr);
137
138 scoped_refptr<TempScopedDirRegistryCleaner> temp_scoped_dir_cleaner =
139 base::MakeRefCounted<TempScopedDirRegistryCleaner>();
140 std::unique_ptr<RegistryHashStoreContentsWin> contentsA =
141 base::MakeUnique<RegistryHashStoreContentsWin>(registry_path, kStoreKey,
142 temp_scoped_dir_cleaner);
143 std::unique_ptr<RegistryHashStoreContentsWin> contentsB =
144 base::MakeUnique<RegistryHashStoreContentsWin>(registry_path, kStoreKey,
145 temp_scoped_dir_cleaner);
146
147 contentsA->SetMac(kAtomicPrefPath, kTestStringA);
148 contentsB->SetMac(kAtomicPrefPath, kTestStringB);
149
150 temp_scoped_dir_cleaner = nullptr;
151 EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
152 EXPECT_EQ(kTestStringB, stored_mac);
153
154 contentsB.reset();
155 EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
156 EXPECT_EQ(kTestStringB, stored_mac);
157
158 contentsA.reset();
159 EXPECT_FALSE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
160 }
161
162 void OffThreadTempScopedDirDestructor(
163 base::string16 registry_path,
164 std::unique_ptr<HashStoreContents> contents) {
165 std::string stored_mac;
166
167 RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey,
168 nullptr);
169
170 contents->SetMac(kAtomicPrefPath, kTestStringB);
171 EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
172 EXPECT_EQ(kTestStringB, stored_mac);
173
174 contents.reset();
175 EXPECT_FALSE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
176 }
177
178 TEST(RegistryHashStoreContentsWinScopedTest, TestScopedDirsClearedMultiThread) {
179 std::string stored_mac;
180
181 base::ScopedTempDir temp_dir;
182 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
183 const base::string16 registry_path =
184 temp_dir.GetPath().DirName().BaseName().LossyDisplayName();
185
186 RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey,
187 nullptr);
188
189 base::Thread test_thread("scoped_dir_cleaner_test_thread");
190 test_thread.StartAndWaitForTesting();
191
192 scoped_refptr<TempScopedDirRegistryCleaner> temp_scoped_dir_cleaner =
193 base::MakeRefCounted<TempScopedDirRegistryCleaner>();
194 std::unique_ptr<RegistryHashStoreContentsWin> contents =
195 base::MakeUnique<RegistryHashStoreContentsWin>(
196 registry_path, kStoreKey, std::move(temp_scoped_dir_cleaner));
197 base::OnceClosure other_thread_closure =
198 base::BindOnce(&OffThreadTempScopedDirDestructor, registry_path,
199 base::Passed(contents->MakeCopy()));
200
201 contents->SetMac(kAtomicPrefPath, kTestStringA);
202 contents.reset();
203
204 EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
205 EXPECT_EQ(kTestStringA, stored_mac);
206
207 test_thread.task_runner()->PostTask(FROM_HERE,
208 std::move(other_thread_closure));
209 test_thread.FlushForTesting();
210
211 EXPECT_FALSE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
212 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698