1// Copyright 2014 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 "base/basictypes.h"
6#include "base/files/file_util.h"
7#include "base/files/scoped_temp_dir.h"
8#include "storage/browser/fileapi/sandbox_origin_database.h"
9#include "storage/browser/fileapi/sandbox_prioritized_origin_database.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12using storage::SandboxOriginDatabase;
13using storage::SandboxOriginDatabaseInterface;
14using storage::SandboxPrioritizedOriginDatabase;
15
16namespace content {
17
18TEST(SandboxPrioritizedOriginDatabaseTest, BasicTest) {
19  base::ScopedTempDir dir;
20  base::FilePath path;
21  ASSERT_TRUE(dir.CreateUniqueTempDir());
22
23  const std::string kOrigin1("origin1");
24  const std::string kOrigin2("origin2");
25
26  SandboxPrioritizedOriginDatabase database(dir.path(), NULL);
27
28  // Set the kOrigin1 as a parimary origin.
29  EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1));
30
31  // Add two origins.
32  EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path));
33  EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path));
34
35  // Verify them.
36  EXPECT_TRUE(database.HasOriginPath(kOrigin1));
37  EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path));
38  EXPECT_FALSE(path.empty());
39  EXPECT_TRUE(database.HasOriginPath(kOrigin2));
40  EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path));
41  EXPECT_FALSE(path.empty());
42
43  std::vector<SandboxOriginDatabaseInterface::OriginRecord> origins;
44  database.ListAllOrigins(&origins);
45  ASSERT_EQ(2U, origins.size());
46  EXPECT_TRUE(origins[0].origin == kOrigin1 ||
47              origins[1].origin == kOrigin1);
48  EXPECT_TRUE(origins[0].origin == kOrigin2 ||
49              origins[1].origin == kOrigin2);
50  EXPECT_NE(origins[0].path, origins[1].path);
51
52  // Try remove path for kOrigin1.
53  database.RemovePathForOrigin(kOrigin1);
54
55  // Verify the removal.
56  EXPECT_FALSE(database.HasOriginPath(kOrigin1));
57  EXPECT_TRUE(database.HasOriginPath(kOrigin2));
58  database.ListAllOrigins(&origins);
59  ASSERT_EQ(1U, origins.size());
60  EXPECT_EQ(kOrigin2, origins[0].origin);
61
62  // Try remove path for kOrigin2.
63  database.RemovePathForOrigin(kOrigin2);
64
65  // Verify the removal.
66  EXPECT_FALSE(database.HasOriginPath(kOrigin1));
67  EXPECT_FALSE(database.HasOriginPath(kOrigin2));
68  database.ListAllOrigins(&origins);
69  EXPECT_TRUE(origins.empty());
70}
71
72TEST(SandboxPrioritizedOriginDatabaseTest, SetPrimaryLaterTest) {
73  base::ScopedTempDir dir;
74  base::FilePath path;
75  ASSERT_TRUE(dir.CreateUniqueTempDir());
76
77  const std::string kOrigin1("origin1");
78  const std::string kOrigin2("origin2");
79
80  SandboxPrioritizedOriginDatabase database(dir.path(), NULL);
81
82  EXPECT_TRUE(database.GetPrimaryOrigin().empty());
83
84  EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path));
85  EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path));
86
87  // Set the kOrigin1 as a parimary origin.
88  EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1));
89  EXPECT_EQ(kOrigin1, database.GetPrimaryOrigin());
90
91  // Regardless of whether it is initialized as primary or not
92  // they should just work.
93  EXPECT_TRUE(database.HasOriginPath(kOrigin1));
94  EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path));
95  EXPECT_FALSE(path.empty());
96  EXPECT_TRUE(database.HasOriginPath(kOrigin2));
97  EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path));
98  EXPECT_FALSE(path.empty());
99}
100
101TEST(SandboxPrioritizedOriginDatabaseTest, LostPrimaryOriginFileTest) {
102  base::ScopedTempDir dir;
103  base::FilePath path;
104  ASSERT_TRUE(dir.CreateUniqueTempDir());
105
106  const std::string kOrigin1("origin1");
107  const std::string kData("foo");
108
109  SandboxPrioritizedOriginDatabase database(dir.path(), NULL);
110
111  EXPECT_TRUE(database.GetPrimaryOrigin().empty());
112
113  // Set the kOrigin1 as a parimary origin.
114  EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1));
115  EXPECT_EQ(kOrigin1, database.GetPrimaryOrigin());
116
117  // Make sure it works.
118  EXPECT_TRUE(database.HasOriginPath(kOrigin1));
119  EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path));
120
121  // Reset the database.
122  database.DropDatabase();
123
124  // kOrigin1 should still be marked as primary.
125  EXPECT_TRUE(database.HasOriginPath(kOrigin1));
126  EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path));
127
128  // Corrupt the primary origin file.
129  base::WriteFile(database.primary_origin_file(), kData.data(), kData.size());
130
131  // Reset the database.
132  database.DropDatabase();
133
134  // kOrigin1 is no longer marked as primary, and unfortunately we fail
135  // to find the data for the origin.
136  EXPECT_FALSE(database.HasOriginPath(kOrigin1));
137}
138
139TEST(SandboxPrioritizedOriginDatabaseTest, MigrationTest) {
140  base::ScopedTempDir dir;
141  ASSERT_TRUE(dir.CreateUniqueTempDir());
142
143  const std::string kOrigin1("origin1");
144  const std::string kOrigin2("origin2");
145  const std::string kFakeDirectoryData1("0123456789");
146  const std::string kFakeDirectoryData2("abcde");
147  base::FilePath old_dir_db_path1, old_dir_db_path2;
148  base::FilePath path1, path2;
149
150  // Initialize the directory with two origins using the regular
151  // SandboxOriginDatabase.
152  {
153    SandboxOriginDatabase database_old(dir.path(), NULL);
154    base::FilePath old_db_path = database_old.GetDatabasePath();
155    EXPECT_FALSE(base::PathExists(old_db_path));
156
157    // Initialize paths for kOrigin1 and kOrigin2.
158    EXPECT_TRUE(database_old.GetPathForOrigin(kOrigin1, &path1));
159    EXPECT_FALSE(path1.empty());
160    EXPECT_TRUE(database_old.GetPathForOrigin(kOrigin2, &path2));
161    EXPECT_FALSE(path2.empty());
162
163    EXPECT_TRUE(base::DirectoryExists(old_db_path));
164
165    // Populate the origin directory with some fake data.
166    old_dir_db_path1 = dir.path().Append(path1);
167    ASSERT_TRUE(base::CreateDirectory(old_dir_db_path1));
168    EXPECT_EQ(static_cast<int>(kFakeDirectoryData1.size()),
169              base::WriteFile(old_dir_db_path1.AppendASCII("dummy"),
170                              kFakeDirectoryData1.data(),
171                              kFakeDirectoryData1.size()));
172    old_dir_db_path2 = dir.path().Append(path2);
173    ASSERT_TRUE(base::CreateDirectory(old_dir_db_path2));
174    EXPECT_EQ(static_cast<int>(kFakeDirectoryData2.size()),
175              base::WriteFile(old_dir_db_path2.AppendASCII("dummy"),
176                              kFakeDirectoryData2.data(),
177                              kFakeDirectoryData2.size()));
178  }
179
180  // Re-open the directory using sandboxPrioritizedOriginDatabase.
181  SandboxPrioritizedOriginDatabase database(dir.path(), NULL);
182
183  // Set the kOrigin1 as a parimary origin.
184  // (Trying to initialize another origin should fail).
185  EXPECT_TRUE(database.InitializePrimaryOrigin(kOrigin1));
186  EXPECT_FALSE(database.InitializePrimaryOrigin(kOrigin2));
187
188  EXPECT_EQ(kOrigin1, database.GetPrimaryOrigin());
189
190  // Regardless of whether the origin is registered as primary or not
191  // it should just work.
192  EXPECT_TRUE(database.HasOriginPath(kOrigin1));
193  EXPECT_TRUE(database.GetPathForOrigin(kOrigin1, &path1));
194  EXPECT_TRUE(database.HasOriginPath(kOrigin2));
195  EXPECT_TRUE(database.GetPathForOrigin(kOrigin2, &path2));
196
197  // The directory content must be kept (or migrated if necessary) as well.
198  std::string origin_db_data;
199  base::FilePath dir_db_path = dir.path().Append(path1);
200  EXPECT_TRUE(base::PathExists(dir_db_path.AppendASCII("dummy")));
201  EXPECT_TRUE(base::ReadFileToString(
202      dir_db_path.AppendASCII("dummy"), &origin_db_data));
203  EXPECT_EQ(kFakeDirectoryData1, origin_db_data);
204
205  origin_db_data.clear();
206  dir_db_path = dir.path().Append(path2);
207  EXPECT_TRUE(base::PathExists(dir_db_path.AppendASCII("dummy")));
208  EXPECT_TRUE(base::ReadFileToString(
209      dir_db_path.AppendASCII("dummy"), &origin_db_data));
210  EXPECT_EQ(kFakeDirectoryData2, origin_db_data);
211
212  // After the migration the kOrigin1 directory database path must be gone.
213  EXPECT_FALSE(base::PathExists(old_dir_db_path1));
214  EXPECT_TRUE(base::PathExists(old_dir_db_path2));
215}
216
217}  // namespace content
218