Home | History | Annotate | Download | only in util
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <windows.h>
      6 
      7 #include <fstream>
      8 
      9 #include "base/files/file_util.h"
     10 #include "base/files/scoped_temp_dir.h"
     11 #include "base/strings/string16.h"
     12 #include "base/strings/string_util.h"
     13 #include "chrome/installer/util/duplicate_tree_detector.h"
     14 #include "chrome/installer/util/installer_util_test_common.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace {
     18 
     19 class DuplicateTreeDetectorTest : public testing::Test {
     20  protected:
     21   virtual void SetUp() {
     22     ASSERT_TRUE(temp_source_dir_.CreateUniqueTempDir());
     23     ASSERT_TRUE(temp_dest_dir_.CreateUniqueTempDir());
     24   }
     25 
     26   // Simple function to dump some text into a new file.
     27   void CreateTextFile(const std::string& filename,
     28                       const base::string16& contents) {
     29     std::wofstream file;
     30     file.open(filename.c_str());
     31     ASSERT_TRUE(file.is_open());
     32     file << contents;
     33     file.close();
     34   }
     35 
     36   // Creates a two level deep source dir with a file in each in |first_root| and
     37   // copy it (files properties will be identical) in |second_root|.
     38   void CreateTwoIdenticalHierarchies(const base::FilePath& first_root,
     39                                      const base::FilePath& second_root) {
     40     base::FilePath d1(first_root);
     41     d1 = d1.AppendASCII("D1");
     42     base::CreateDirectory(d1);
     43     ASSERT_TRUE(base::PathExists(d1));
     44 
     45     base::FilePath f1(d1);
     46     f1 = f1.AppendASCII("F1");
     47     CreateTextFile(f1.MaybeAsASCII(), text_content_1_);
     48     ASSERT_TRUE(base::PathExists(f1));
     49 
     50     base::FilePath d2(d1);
     51     d2 = d2.AppendASCII("D2");
     52     base::CreateDirectory(d2);
     53     ASSERT_TRUE(base::PathExists(d2));
     54 
     55     base::FilePath f2(d2);
     56     f2 = f2.AppendASCII("F2");
     57     CreateTextFile(f2.MaybeAsASCII(), text_content_2_);
     58     ASSERT_TRUE(base::PathExists(f2));
     59 
     60     ASSERT_TRUE(installer::test::CopyFileHierarchy(d1, second_root));
     61   }
     62 
     63   base::ScopedTempDir temp_source_dir_;
     64   base::ScopedTempDir temp_dest_dir_;
     65 
     66   static const wchar_t text_content_1_[];
     67   static const wchar_t text_content_2_[];
     68   static const wchar_t text_content_3_[];
     69 };
     70 
     71 const wchar_t DuplicateTreeDetectorTest::text_content_1_[] =
     72     L"Gooooooooooooooooooooogle";
     73 const wchar_t DuplicateTreeDetectorTest::text_content_2_[] =
     74     L"Overwrite Me";
     75 const wchar_t DuplicateTreeDetectorTest::text_content_3_[] =
     76     L"I'd rather see your watermelon and raise you ham and a half.";
     77 
     78 };  // namespace
     79 
     80 // Test the DuplicateTreeChecker's definition of identity on two identical
     81 // directory structures.
     82 TEST_F(DuplicateTreeDetectorTest, TestIdenticalDirs) {
     83   CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());
     84 
     85   EXPECT_TRUE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
     86                                                   temp_dest_dir_.path()));
     87 }
     88 
     89 // Test when source entirely contains dest but contains other files as well.
     90 // IsIdenticalTo should return false in this case.
     91 TEST_F(DuplicateTreeDetectorTest, TestSourceContainsDest) {
     92   CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());
     93 
     94   base::FilePath new_file(temp_source_dir_.path());
     95   new_file = new_file.AppendASCII("FNew");
     96   CreateTextFile(new_file.MaybeAsASCII(), text_content_1_);
     97   ASSERT_TRUE(base::PathExists(new_file));
     98 
     99   EXPECT_FALSE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
    100                                                    temp_dest_dir_.path()));
    101 }
    102 
    103 // Test when dest entirely contains source but contains other files as well.
    104 // IsIdenticalTo should return true in this case.
    105 TEST_F(DuplicateTreeDetectorTest, TestDestContainsSource) {
    106   CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());
    107 
    108   base::FilePath new_file(temp_dest_dir_.path());
    109   new_file = new_file.AppendASCII("FNew");
    110   CreateTextFile(new_file.MaybeAsASCII(), text_content_1_);
    111   ASSERT_TRUE(base::PathExists(new_file));
    112 
    113   EXPECT_TRUE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
    114                                                   temp_dest_dir_.path()));
    115 }
    116 
    117 // Test when the file hierarchies are the same but one of the files is changed.
    118 TEST_F(DuplicateTreeDetectorTest, TestIdenticalDirsDifferentFiles) {
    119   CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());
    120 
    121   base::FilePath existing_file(temp_dest_dir_.path());
    122   existing_file = existing_file.AppendASCII("D1")
    123                                .AppendASCII("D2")
    124                                .AppendASCII("F2");
    125   CreateTextFile(existing_file.MaybeAsASCII(), text_content_3_);
    126 
    127   EXPECT_FALSE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
    128                                                    temp_dest_dir_.path()));
    129 }
    130 
    131 // Test when both file hierarchies are empty.
    132 TEST_F(DuplicateTreeDetectorTest, TestEmptyDirs) {
    133   EXPECT_TRUE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
    134                                                   temp_dest_dir_.path()));
    135 }
    136 
    137 // Test on single files.
    138 TEST_F(DuplicateTreeDetectorTest, TestSingleFiles) {
    139   // Create a source file.
    140   base::FilePath source_file(temp_source_dir_.path());
    141   source_file = source_file.AppendASCII("F1");
    142   CreateTextFile(source_file.MaybeAsASCII(), text_content_1_);
    143 
    144   // This file should be the same.
    145   base::FilePath dest_file(temp_dest_dir_.path());
    146   dest_file = dest_file.AppendASCII("F1");
    147   ASSERT_TRUE(installer::test::CopyFileHierarchy(source_file, dest_file));
    148 
    149   // This file should be different.
    150   base::FilePath other_file(temp_dest_dir_.path());
    151   other_file = other_file.AppendASCII("F2");
    152   CreateTextFile(other_file.MaybeAsASCII(), text_content_2_);
    153 
    154   EXPECT_TRUE(installer::IsIdenticalFileHierarchy(source_file, dest_file));
    155   EXPECT_FALSE(installer::IsIdenticalFileHierarchy(source_file, other_file));
    156 }
    157