summaryrefslogtreecommitdiffstats
path: root/chrome/installer/util/self_cleaning_temp_dir_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/installer/util/self_cleaning_temp_dir_unittest.cc')
-rw-r--r--chrome/installer/util/self_cleaning_temp_dir_unittest.cc137
1 files changed, 137 insertions, 0 deletions
diff --git a/chrome/installer/util/self_cleaning_temp_dir_unittest.cc b/chrome/installer/util/self_cleaning_temp_dir_unittest.cc
new file mode 100644
index 0000000..5980575
--- /dev/null
+++ b/chrome/installer/util/self_cleaning_temp_dir_unittest.cc
@@ -0,0 +1,137 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <windows.h>
+#include <wincrypt.h>
+
+#include "base/file_util.h"
+#include "base/scoped_temp_dir.h"
+#include "base/string_number_conversions.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/installer/util/self_cleaning_temp_dir.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+// Returns a string of 8 characters consisting of the letter 'R' followed by
+// seven random hex digits.
+std::wstring GetRandomFilename() {
+ uint8 data[4];
+ HCRYPTPROV crypt_ctx = NULL;
+
+ // Get four bytes of randomness. Use CAPI rather than the CRT since I've
+ // seen the latter trivially repeat.
+ EXPECT_NE(FALSE, CryptAcquireContext(&crypt_ctx, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT));
+ EXPECT_NE(FALSE, CryptGenRandom(crypt_ctx, arraysize(data), &data[0]));
+ EXPECT_NE(FALSE, CryptReleaseContext(crypt_ctx, 0));
+
+ // Hexify the value.
+ std::string result(base::HexEncode(&data[0], arraysize(data)));
+ EXPECT_EQ(8, result.size());
+
+ // Replace the first digit with the letter 'R' (for "random", get it?).
+ result[0] = 'R';
+
+ return ASCIIToWide(result);
+}
+
+} // namespace
+
+namespace installer {
+
+class SelfCleaningTempDirTest : public testing::Test {
+};
+
+// Test the implementation of GetTopDirToCreate when given the root of a
+// volume.
+TEST_F(SelfCleaningTempDirTest, TopLevel) {
+ FilePath base_dir;
+ SelfCleaningTempDir::GetTopDirToCreate(FilePath(L"C:\\"), &base_dir);
+ EXPECT_TRUE(base_dir.empty());
+}
+
+// Test the implementation of GetTopDirToCreate when given a non-existant dir
+// under the root of a volume.
+TEST_F(SelfCleaningTempDirTest, TopLevelPlusOne) {
+ FilePath base_dir;
+ FilePath parent_dir(L"C:\\");
+ parent_dir = parent_dir.Append(GetRandomFilename());
+ SelfCleaningTempDir::GetTopDirToCreate(parent_dir, &base_dir);
+ EXPECT_EQ(parent_dir, base_dir);
+}
+
+// Test that all intermediate dirs are cleaned up if they're empty when
+// Delete() is called.
+TEST_F(SelfCleaningTempDirTest, RemoveUnusedOnDelete) {
+ // Make a directory in which we'll work.
+ ScopedTempDir work_dir;
+ EXPECT_TRUE(work_dir.CreateUniqueTempDir());
+
+ // Make up some path under the temp dir.
+ FilePath parent_temp_dir(work_dir.path().Append(L"One").Append(L"Two"));
+ SelfCleaningTempDir temp_dir;
+ EXPECT_TRUE(temp_dir.Initialize(parent_temp_dir, L"Three"));
+ EXPECT_EQ(parent_temp_dir.Append(L"Three"), temp_dir.path());
+ EXPECT_TRUE(file_util::DirectoryExists(temp_dir.path()));
+ EXPECT_TRUE(temp_dir.Delete());
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.Append(L"Three")));
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir));
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.DirName()));
+ EXPECT_TRUE(file_util::DirectoryExists(parent_temp_dir.DirName().DirName()));
+ EXPECT_TRUE(work_dir.Delete());
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.DirName().DirName()));
+}
+
+// Test that all intermediate dirs are cleaned up if they're empty when the
+// destructor is called.
+TEST_F(SelfCleaningTempDirTest, RemoveUnusedOnDestroy) {
+ // Make a directory in which we'll work.
+ ScopedTempDir work_dir;
+ EXPECT_TRUE(work_dir.CreateUniqueTempDir());
+
+ // Make up some path under the temp dir.
+ FilePath parent_temp_dir(work_dir.path().Append(L"One").Append(L"Two"));
+ {
+ SelfCleaningTempDir temp_dir;
+ EXPECT_TRUE(temp_dir.Initialize(parent_temp_dir, L"Three"));
+ EXPECT_EQ(parent_temp_dir.Append(L"Three"), temp_dir.path());
+ EXPECT_TRUE(file_util::DirectoryExists(temp_dir.path()));
+ }
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.Append(L"Three")));
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir));
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.DirName()));
+ EXPECT_TRUE(file_util::DirectoryExists(parent_temp_dir.DirName().DirName()));
+ EXPECT_TRUE(work_dir.Delete());
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.DirName().DirName()));
+}
+
+// Test that intermediate dirs are left behind if they're not empty when the
+// destructor is called.
+TEST_F(SelfCleaningTempDirTest, LeaveUsedOnDestroy) {
+ static const char kHiHon[] = "hi, hon";
+
+ // Make a directory in which we'll work.
+ ScopedTempDir work_dir;
+ EXPECT_TRUE(work_dir.CreateUniqueTempDir());
+
+ // Make up some path under the temp dir.
+ FilePath parent_temp_dir(work_dir.path().Append(L"One").Append(L"Two"));
+ {
+ SelfCleaningTempDir temp_dir;
+ EXPECT_TRUE(temp_dir.Initialize(parent_temp_dir, L"Three"));
+ EXPECT_EQ(parent_temp_dir.Append(L"Three"), temp_dir.path());
+ EXPECT_TRUE(file_util::DirectoryExists(temp_dir.path()));
+ // Drop a file somewhere.
+ EXPECT_EQ(arraysize(kHiHon) - 1,
+ file_util::WriteFile(parent_temp_dir.Append(GetRandomFilename()),
+ kHiHon, arraysize(kHiHon) - 1));
+ }
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.Append(L"Three")));
+ EXPECT_TRUE(file_util::DirectoryExists(parent_temp_dir));
+ EXPECT_TRUE(work_dir.Delete());
+ EXPECT_FALSE(file_util::DirectoryExists(parent_temp_dir.DirName().DirName()));
+}
+
+} // namespace installer