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 "base/base_paths.h"
8#include "base/files/file_util.h"
9#include "base/files/scoped_temp_dir.h"
10#include "base/memory/scoped_ptr.h"
11#include "base/path_service.h"
12#include "base/strings/string_util.h"
13#include "chrome/installer/util/create_dir_work_item.h"
14#include "chrome/installer/util/work_item.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace {
18  class CreateDirWorkItemTest : public testing::Test {
19   protected:
20    virtual void SetUp() {
21      ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
22    }
23
24    base::ScopedTempDir temp_dir_;
25  };
26};
27
28TEST_F(CreateDirWorkItemTest, CreatePath) {
29  base::FilePath parent_dir(temp_dir_.path());
30  parent_dir = parent_dir.AppendASCII("a");
31  base::CreateDirectory(parent_dir);
32  ASSERT_TRUE(base::PathExists(parent_dir));
33
34  base::FilePath top_dir_to_create(parent_dir);
35  top_dir_to_create = top_dir_to_create.AppendASCII("b");
36
37  base::FilePath dir_to_create(top_dir_to_create);
38  dir_to_create = dir_to_create.AppendASCII("c");
39  dir_to_create = dir_to_create.AppendASCII("d");
40
41  scoped_ptr<CreateDirWorkItem> work_item(
42      WorkItem::CreateCreateDirWorkItem(dir_to_create));
43
44  EXPECT_TRUE(work_item->Do());
45
46  EXPECT_TRUE(base::PathExists(dir_to_create));
47
48  work_item->Rollback();
49
50  // Rollback should delete all the paths up to top_dir_to_create.
51  EXPECT_FALSE(base::PathExists(top_dir_to_create));
52  EXPECT_TRUE(base::PathExists(parent_dir));
53}
54
55TEST_F(CreateDirWorkItemTest, CreateExistingPath) {
56  base::FilePath dir_to_create(temp_dir_.path());
57  dir_to_create = dir_to_create.AppendASCII("aa");
58  base::CreateDirectory(dir_to_create);
59  ASSERT_TRUE(base::PathExists(dir_to_create));
60
61  scoped_ptr<CreateDirWorkItem> work_item(
62      WorkItem::CreateCreateDirWorkItem(dir_to_create));
63
64  EXPECT_TRUE(work_item->Do());
65
66  EXPECT_TRUE(base::PathExists(dir_to_create));
67
68  work_item->Rollback();
69
70  // Rollback should not remove the path since it exists before
71  // the CreateDirWorkItem is called.
72  EXPECT_TRUE(base::PathExists(dir_to_create));
73}
74
75TEST_F(CreateDirWorkItemTest, CreateSharedPath) {
76  base::FilePath dir_to_create_1(temp_dir_.path());
77  dir_to_create_1 = dir_to_create_1.AppendASCII("aaa");
78
79  base::FilePath dir_to_create_2(dir_to_create_1);
80  dir_to_create_2 = dir_to_create_2.AppendASCII("bbb");
81
82  base::FilePath dir_to_create_3(dir_to_create_2);
83  dir_to_create_3 = dir_to_create_3.AppendASCII("ccc");
84
85  scoped_ptr<CreateDirWorkItem> work_item(
86      WorkItem::CreateCreateDirWorkItem(dir_to_create_3));
87
88  EXPECT_TRUE(work_item->Do());
89
90  EXPECT_TRUE(base::PathExists(dir_to_create_3));
91
92  // Create another directory under dir_to_create_2
93  base::FilePath dir_to_create_4(dir_to_create_2);
94  dir_to_create_4 = dir_to_create_4.AppendASCII("ddd");
95  base::CreateDirectory(dir_to_create_4);
96  ASSERT_TRUE(base::PathExists(dir_to_create_4));
97
98  work_item->Rollback();
99
100  // Rollback should delete dir_to_create_3.
101  EXPECT_FALSE(base::PathExists(dir_to_create_3));
102
103  // Rollback should not delete dir_to_create_2 as it is shared.
104  EXPECT_TRUE(base::PathExists(dir_to_create_2));
105  EXPECT_TRUE(base::PathExists(dir_to_create_4));
106}
107
108TEST_F(CreateDirWorkItemTest, RollbackWithMissingDir) {
109  base::FilePath dir_to_create_1(temp_dir_.path());
110  dir_to_create_1 = dir_to_create_1.AppendASCII("aaaa");
111
112  base::FilePath dir_to_create_2(dir_to_create_1);
113  dir_to_create_2 = dir_to_create_2.AppendASCII("bbbb");
114
115  base::FilePath dir_to_create_3(dir_to_create_2);
116  dir_to_create_3 = dir_to_create_3.AppendASCII("cccc");
117
118  scoped_ptr<CreateDirWorkItem> work_item(
119      WorkItem::CreateCreateDirWorkItem(dir_to_create_3));
120
121  EXPECT_TRUE(work_item->Do());
122
123  EXPECT_TRUE(base::PathExists(dir_to_create_3));
124
125  RemoveDirectory(dir_to_create_3.value().c_str());
126  ASSERT_FALSE(base::PathExists(dir_to_create_3));
127
128  work_item->Rollback();
129
130  // dir_to_create_3 has already been deleted, Rollback should delete
131  // the rest.
132  EXPECT_FALSE(base::PathExists(dir_to_create_1));
133}
134