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

Unified Diff: chrome/browser/profiles/profile_manager_browsertest.cc

Issue 2021253002: Skip profiles in GetLastOpenedProfiles that fail to initialize (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add test, fix nits Created 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/profiles/profile_manager.cc ('k') | chrome/browser/ui/startup/startup_browser_creator.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/profiles/profile_manager_browsertest.cc
diff --git a/chrome/browser/profiles/profile_manager_browsertest.cc b/chrome/browser/profiles/profile_manager_browsertest.cc
index 06f06dc2d8fa4b9e2843c2751ce1d1f706ab6001..d7d160d1b8fff85897353e3f7f62a19cd7e48ede 100644
--- a/chrome/browser/profiles/profile_manager_browsertest.cc
+++ b/chrome/browser/profiles/profile_manager_browsertest.cc
@@ -36,6 +36,16 @@
#include "testing/gtest/include/gtest/gtest.h"
#endif
+#if defined(OS_WIN)
+#include <AccCtrl.h>
+#include <Aclapi.h>
+#include "base/callback_forward.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#endif
Peter Kasting 2016/06/04 01:24:25 Nit: There's a lot of stuff in this block and adde
WC Leung 2016/06/04 04:55:22 SGTM
+
namespace {
const ProfileManager::CreateCallback kOnProfileSwitchDoNothing;
@@ -499,3 +509,139 @@ IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTest, IncognitoProfile) {
->GetFilePath(prefs::kSaveFileDefaultDirectory)
.empty());
}
+
+#if defined(OS_WIN)
+
+bool AddAceToObjectsSecurityDescriptor(LPTSTR filename, LPTSTR trustee,
brettw 2016/06/03 21:47:24 I'm OK duplicating this code. It's a bit yucky but
Peter Kasting 2016/06/04 01:24:25 It looks to me as if these two are so close that j
WC Leung 2016/06/04 04:55:22 I see. Then I'll do the deduplication.
+ DWORD access_rights, ACCESS_MODE access_mode, DWORD inheritance) {
Peter Kasting 2016/06/04 01:24:25 Nit: All lines of args must be indented the same.
WC Leung 2016/06/04 04:55:21 Acknowledged. Anyway, if that deduplication succee
+ // Get a pointer to the existing DACL.
+ ACL* old_dacl = nullptr;
+ PSECURITY_DESCRIPTOR security_descriptor = nullptr;
+ DWORD result = GetNamedSecurityInfo(filename, SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION,
+ nullptr, nullptr, &old_dacl, nullptr,
+ &security_descriptor);
+ if (result != ERROR_SUCCESS) {
+ LOG(WARNING) << "GetNamedSecurityInfo Error " << result;
Peter Kasting 2016/06/04 01:24:25 Are you going to collect and analyze this log data
+ } else {
+ // Initialize an EXPLICIT_ACCESS structure for the new ACE.
+ EXPLICIT_ACCESS explicit_access;
+ ZeroMemory(&explicit_access, sizeof(EXPLICIT_ACCESS));
+ explicit_access.grfAccessPermissions = access_rights;
+ explicit_access.grfAccessMode = access_mode;
+ explicit_access.grfInheritance = inheritance;
+ explicit_access.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
+ explicit_access.Trustee.ptstrName = trustee;
Peter Kasting 2016/06/04 01:24:25 Nit: Try to use initializer values if possible, e.
+
+ // Create a new ACL that merges the new ACE into the existing DACL.
+ ACL* new_dacl = nullptr;
+ result = SetEntriesInAcl(1, &explicit_access, old_dacl, &new_dacl);
+ if (result != ERROR_SUCCESS) {
+ LOG(WARNING) << "SetEntriesInAcl Error " << result;
+ } else {
+ // Attach the new ACL as the object's DACL.
+ result = SetNamedSecurityInfo(filename, SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION,
+ nullptr, nullptr, new_dacl, nullptr);
+ if (result != ERROR_SUCCESS)
+ LOG(WARNING) << "SetNamedSecurityInfo Error " << result;
+ }
+
+ if (new_dacl)
Peter Kasting 2016/06/04 01:24:25 Don't conditionalize these LocalFree() calls; it s
WC Leung 2016/06/04 04:55:22 Noted and thanks. https://msdn.microsoft.com/en-us
+ LocalFree((HLOCAL)new_dacl);
Peter Kasting 2016/06/04 01:24:25 Consider creating a scoping object that frees thes
WC Leung 2016/06/04 04:55:22 Acknowledged.
+ }
+
+ if (security_descriptor)
+ LocalFree((HLOCAL)security_descriptor);
+
+ return result == ERROR_SUCCESS;
+}
+
+bool RemoveCreateDirectoryPermission(const base::FilePath& path) {
+ return AddAceToObjectsSecurityDescriptor(
+ const_cast<wchar_t*>(path.value().c_str()), L"EVERYONE",
+ FILE_ADD_SUBDIRECTORY, DENY_ACCESS, NO_INHERITANCE);
+}
+
+class ProfileManagerWinBrowserTest : public ProfileManagerBrowserTest {
+ public:
+ // Tests may be reported as PASS even if the test has never been run. To
Peter Kasting 2016/06/04 01:24:25 I have no idea what this is talking about :(.
WC Leung 2016/06/04 04:55:22 You've stumpled on a bug in the browser test. :-)
Peter Kasting 2016/06/04 08:01:39 Please understand this bug completely before proce
WC Leung 2016/06/04 15:48:33 Agree that the bug needs more investigation. The p
+ // mitigate the issue, a "red flag" is raised for suspectable tests. These
Peter Kasting 2016/06/04 01:24:25 Do you mean "susceptible" or "suspicious"?
WC Leung 2016/06/04 04:55:22 Susceptble. Sorry for wrong spelling.
WC Leung 2016/06/04 17:34:43 Done.
+ // tests need to call DropRedFlag() to pass the test.
+ void DropRedFlag() { red_flag_ = false; }
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ command_line->AppendSwitch(switches::kRestoreLastSession);
+ }
+
+ bool SetUpUserDataDirectory() override {
+ std::string testname(
+ testing::UnitTest::GetInstance()->current_test_info()->name());
+ if (testname == "LastOpenedProfileMissing") {
brettw 2016/06/03 21:47:24 This seems potentially very confusing since people
WC Leung 2016/06/04 04:55:22 We need to do remove a profile directory and set t
+ red_flag_ = true;
+
+ base::FilePath user_data_dir;
+ if (!PathService::Get(chrome::DIR_USER_DATA, &user_data_dir))
+ return false;
+
+ base::FilePath dir_to_delete = user_data_dir.AppendASCII("Profile 1");
+ return base::DirectoryExists(dir_to_delete) &&
+ DeleteFile(dir_to_delete, true) &&
+ RemoveCreateDirectoryPermission(user_data_dir);
+ }
+ return true;
+ }
+
+ void TearDown() override {
+ EXPECT_FALSE(red_flag_);
+ ProfileManagerBrowserTest::TearDown();
+ }
+
+ private:
+ bool red_flag_ = false;
+};
Peter Kasting 2016/06/04 01:24:25 Nit: DISALLOW_COPY_AND_ASSIGN
WC Leung 2016/06/04 04:55:22 Acknowledged.
WC Leung 2016/06/04 17:34:43 Unable to do this in test fixtures, because compil
Peter Kasting 2016/06/04 18:12:31 Why?
WC Leung 2016/06/05 03:04:48 Here's the compiler log: f:\chromium\src\chrome\b
+
+IN_PROC_BROWSER_TEST_F(ProfileManagerWinBrowserTest,
+ PRE_LastOpenedProfileMissing) {
Peter Kasting 2016/06/04 01:24:25 I'm not terribly familiar with using PRE_ in tests
WC Leung 2016/06/04 04:55:22 The test (PRE_ and non-PRE_ as a whole) do the fol
Peter Kasting 2016/06/04 08:01:39 That didn't really answer my question. Are you sa
WC Leung 2016/06/04 15:48:33 Oh sorry for my bad explanation. What you're sayin
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
+ ASSERT_TRUE(profile_manager);
+
+ std::vector<base::FilePath> profile_paths;
+ // Create two additional profile.
+ for (int i = 0; i < 2; ++i) {
+ base::FilePath path = profile_manager->GenerateNextProfileDirectoryPath();
+ profile_paths.push_back(path);
+
+ base::RunLoop run_loop;
+ profile_manager->CreateProfileAsync(
+ path, base::Bind(&OnUnblockOnProfileCreation, &run_loop),
+ base::string16(), std::string(), std::string());
+
+ // Run the message loop to allow profile creation to take place; the loop is
+ // terminated by OnUnblockOnProfileCreation when the profile is created.
+ run_loop.Run();
+
+ profiles::SwitchToProfile(path, false, kOnProfileSwitchDoNothing,
+ ProfileMetrics::SWITCH_PROFILE_ICON);
+ }
+
+ ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("Profile 1")),
+ profile_paths[0].BaseName());
+}
+
+IN_PROC_BROWSER_TEST_F(ProfileManagerWinBrowserTest,
+ LastOpenedProfileMissing) {
+ DropRedFlag();
+
+ ProfileManager* profile_manager = g_browser_process->profile_manager();
Peter Kasting 2016/06/04 01:24:25 Why do you need this variable?
WC Leung 2016/06/04 04:55:21 I don't need it, sorry for that. Forgot to remove
+ ASSERT_TRUE(profile_manager);
+
+ BrowserList* browser_list = BrowserList::GetInstance();
+ EXPECT_EQ(2u, browser_list->size());
+ for (const Browser* browser : *browser_list) {
+ EXPECT_NE(base::FilePath(FILE_PATH_LITERAL("Profile 1")),
+ browser->profile()->GetPath().BaseName());
+ }
+}
+#endif // defined(OS_WIN)
Peter Kasting 2016/06/04 01:24:25 Nit: Blank line above this, or no blank below the
WC Leung 2016/06/04 04:55:22 Acknowledged.
« no previous file with comments | « chrome/browser/profiles/profile_manager.cc ('k') | chrome/browser/ui/startup/startup_browser_creator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698