summaryrefslogtreecommitdiffstats
path: root/chrome/installer/util/duplicate_tree_detector_unittest.cc
blob: c9b50e8679a79e4f891f323adf4f76e1a9665fbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// 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 <fstream>

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "chrome/installer/util/duplicate_tree_detector.h"
#include "chrome/installer/util/installer_util_test_common.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class DuplicateTreeDetectorTest : public testing::Test {
 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_source_dir_.CreateUniqueTempDir());
    ASSERT_TRUE(temp_dest_dir_.CreateUniqueTempDir());
  }

  // Simple function to dump some text into a new file.
  void CreateTextFile(const std::string& filename,
                      const base::string16& contents) {
    std::wofstream file;
    file.open(filename.c_str());
    ASSERT_TRUE(file.is_open());
    file << contents;
    file.close();
  }

  // Creates a two level deep source dir with a file in each in |first_root| and
  // copy it (files properties will be identical) in |second_root|.
  void CreateTwoIdenticalHierarchies(const base::FilePath& first_root,
                                     const base::FilePath& second_root) {
    base::FilePath d1(first_root);
    d1 = d1.AppendASCII("D1");
    base::CreateDirectory(d1);
    ASSERT_TRUE(base::PathExists(d1));

    base::FilePath f1(d1);
    f1 = f1.AppendASCII("F1");
    CreateTextFile(f1.MaybeAsASCII(), text_content_1_);
    ASSERT_TRUE(base::PathExists(f1));

    base::FilePath d2(d1);
    d2 = d2.AppendASCII("D2");
    base::CreateDirectory(d2);
    ASSERT_TRUE(base::PathExists(d2));

    base::FilePath f2(d2);
    f2 = f2.AppendASCII("F2");
    CreateTextFile(f2.MaybeAsASCII(), text_content_2_);
    ASSERT_TRUE(base::PathExists(f2));

    ASSERT_TRUE(installer::test::CopyFileHierarchy(d1, second_root));
  }

  base::ScopedTempDir temp_source_dir_;
  base::ScopedTempDir temp_dest_dir_;

  static const wchar_t text_content_1_[];
  static const wchar_t text_content_2_[];
  static const wchar_t text_content_3_[];
};

const wchar_t DuplicateTreeDetectorTest::text_content_1_[] =
    L"Gooooooooooooooooooooogle";
const wchar_t DuplicateTreeDetectorTest::text_content_2_[] =
    L"Overwrite Me";
const wchar_t DuplicateTreeDetectorTest::text_content_3_[] =
    L"I'd rather see your watermelon and raise you ham and a half.";

};  // namespace

// Test the DuplicateTreeChecker's definition of identity on two identical
// directory structures.
TEST_F(DuplicateTreeDetectorTest, TestIdenticalDirs) {
  CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());

  EXPECT_TRUE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
                                                  temp_dest_dir_.path()));
}

// Test when source entirely contains dest but contains other files as well.
// IsIdenticalTo should return false in this case.
TEST_F(DuplicateTreeDetectorTest, TestSourceContainsDest) {
  CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());

  base::FilePath new_file(temp_source_dir_.path());
  new_file = new_file.AppendASCII("FNew");
  CreateTextFile(new_file.MaybeAsASCII(), text_content_1_);
  ASSERT_TRUE(base::PathExists(new_file));

  EXPECT_FALSE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
                                                   temp_dest_dir_.path()));
}

// Test when dest entirely contains source but contains other files as well.
// IsIdenticalTo should return true in this case.
TEST_F(DuplicateTreeDetectorTest, TestDestContainsSource) {
  CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());

  base::FilePath new_file(temp_dest_dir_.path());
  new_file = new_file.AppendASCII("FNew");
  CreateTextFile(new_file.MaybeAsASCII(), text_content_1_);
  ASSERT_TRUE(base::PathExists(new_file));

  EXPECT_TRUE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
                                                  temp_dest_dir_.path()));
}

// Test when the file hierarchies are the same but one of the files is changed.
TEST_F(DuplicateTreeDetectorTest, TestIdenticalDirsDifferentFiles) {
  CreateTwoIdenticalHierarchies(temp_source_dir_.path(), temp_dest_dir_.path());

  base::FilePath existing_file(temp_dest_dir_.path());
  existing_file = existing_file.AppendASCII("D1")
                               .AppendASCII("D2")
                               .AppendASCII("F2");
  CreateTextFile(existing_file.MaybeAsASCII(), text_content_3_);

  EXPECT_FALSE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
                                                   temp_dest_dir_.path()));
}

// Test when both file hierarchies are empty.
TEST_F(DuplicateTreeDetectorTest, TestEmptyDirs) {
  EXPECT_TRUE(installer::IsIdenticalFileHierarchy(temp_source_dir_.path(),
                                                  temp_dest_dir_.path()));
}

// Test on single files.
TEST_F(DuplicateTreeDetectorTest, TestSingleFiles) {
  // Create a source file.
  base::FilePath source_file(temp_source_dir_.path());
  source_file = source_file.AppendASCII("F1");
  CreateTextFile(source_file.MaybeAsASCII(), text_content_1_);

  // This file should be the same.
  base::FilePath dest_file(temp_dest_dir_.path());
  dest_file = dest_file.AppendASCII("F1");
  ASSERT_TRUE(installer::test::CopyFileHierarchy(source_file, dest_file));

  // This file should be different.
  base::FilePath other_file(temp_dest_dir_.path());
  other_file = other_file.AppendASCII("F2");
  CreateTextFile(other_file.MaybeAsASCII(), text_content_2_);

  EXPECT_TRUE(installer::IsIdenticalFileHierarchy(source_file, dest_file));
  EXPECT_FALSE(installer::IsIdenticalFileHierarchy(source_file, other_file));
}