Upstream version 7.35.136.0
[platform/framework/web/crosswalk.git] / src / apps / saved_files_service_unittest.cc
1 // Copyright 2013 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 <algorithm>
6
7 #include "apps/saved_files_service.h"
8 #include "base/files/file_path.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/test/values_test_util.h"
11 #include "base/values.h"
12 #include "chrome/browser/extensions/test_extension_environment.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "extensions/browser/extension_prefs.h"
15 #include "extensions/browser/extension_system.h"
16 #include "extensions/common/extension.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 #if !defined(OS_ANDROID)
20
21 #define TRACE_CALL(expression) \
22   do {                         \
23     SCOPED_TRACE(#expression); \
24     expression;                \
25   } while (0)
26
27 using apps::SavedFileEntry;
28 using apps::SavedFilesService;
29
30 namespace {
31
32 std::string GenerateId(int i) {
33   return base::IntToString(i) + ":filename.ext";
34 }
35
36 }  // namespace
37
38 class SavedFilesServiceUnitTest : public testing::Test {
39  protected:
40   virtual void SetUp() OVERRIDE {
41     testing::Test::SetUp();
42     extension_ = env_.MakeExtension(*base::test::ParseJson(
43         "{"
44         "  \"app\": {"
45         "    \"background\": {"
46         "      \"scripts\": [\"background.js\"]"
47         "    }"
48         "  },"
49         "  \"permissions\": ["
50         "    {\"fileSystem\": [\"retainEntries\"]}"
51         "  ]"
52         "}"));
53     service_ = SavedFilesService::Get(env_.profile());
54     path_ = base::FilePath(FILE_PATH_LITERAL("filename.ext"));
55   }
56
57   virtual void TearDown() OVERRIDE {
58     SavedFilesService::ClearMaxSequenceNumberForTest();
59     SavedFilesService::ClearLruSizeForTest();
60     testing::Test::TearDown();
61   }
62
63   // Check that a registered file entry has the correct value.
64   void CheckEntrySequenceNumber(int id, int sequence_number) {
65     std::string id_string = GenerateId(id);
66     SCOPED_TRACE(id_string);
67     EXPECT_TRUE(service_->IsRegistered(extension_->id(), id_string));
68     const SavedFileEntry* entry =
69         service_->GetFileEntry(extension_->id(), id_string);
70     ASSERT_TRUE(entry);
71     EXPECT_EQ(id_string, entry->id);
72     EXPECT_EQ(path_, entry->path);
73     EXPECT_TRUE(entry->is_directory);
74     EXPECT_EQ(sequence_number, entry->sequence_number);
75   }
76
77   // Check that a range of registered file entries have the correct values.
78   void CheckRangeEnqueuedInOrder(int start, int end) {
79     SavedFileEntry entry;
80     for (int i = start; i < end; i++) {
81       CheckEntrySequenceNumber(i, i + 1);
82     }
83   }
84
85   extensions::TestExtensionEnvironment env_;
86   const extensions::Extension* extension_;
87   SavedFilesService* service_;
88   base::FilePath path_;
89 };
90
91 TEST_F(SavedFilesServiceUnitTest, RetainTwoFilesTest) {
92   service_->RegisterFileEntry(extension_->id(), GenerateId(1), path_, true);
93   service_->RegisterFileEntry(extension_->id(), GenerateId(2), path_, true);
94   service_->RegisterFileEntry(extension_->id(), GenerateId(3), path_, true);
95
96   // Test that no entry has a sequence number.
97   TRACE_CALL(CheckEntrySequenceNumber(1, 0));
98   TRACE_CALL(CheckEntrySequenceNumber(2, 0));
99   TRACE_CALL(CheckEntrySequenceNumber(3, 0));
100
101   // Test that only entry #1 has a sequence number.
102   service_->EnqueueFileEntry(extension_->id(), GenerateId(1));
103   TRACE_CALL(CheckEntrySequenceNumber(1, 1));
104   TRACE_CALL(CheckEntrySequenceNumber(2, 0));
105
106   // Test that entry #1 has not changed sequence number because it is the most
107   // recently enqueued entry.
108   service_->EnqueueFileEntry(extension_->id(), GenerateId(1));
109   TRACE_CALL(CheckEntrySequenceNumber(1, 1));
110   TRACE_CALL(CheckEntrySequenceNumber(2, 0));
111
112   // Test that entry #1 is unchanged and entry #2 has been assigned the next
113   // sequence number.
114   service_->EnqueueFileEntry(extension_->id(), GenerateId(2));
115   TRACE_CALL(CheckEntrySequenceNumber(1, 1));
116   TRACE_CALL(CheckEntrySequenceNumber(2, 2));
117
118   // Test that both entries #1 and #2 are unchanged because #2 is the most
119   // recently enqueued entry.
120   service_->EnqueueFileEntry(extension_->id(), GenerateId(2));
121   TRACE_CALL(CheckEntrySequenceNumber(1, 1));
122   TRACE_CALL(CheckEntrySequenceNumber(2, 2));
123
124   // Test that entry #1 has been assigned the next sequence number.
125   service_->EnqueueFileEntry(extension_->id(), GenerateId(1));
126   TRACE_CALL(CheckEntrySequenceNumber(1, 3));
127   TRACE_CALL(CheckEntrySequenceNumber(2, 2));
128   TRACE_CALL(CheckEntrySequenceNumber(3, 0));
129
130   EXPECT_FALSE(service_->IsRegistered(extension_->id(), "another id"));
131   SavedFileEntry entry;
132   EXPECT_FALSE(service_->GetFileEntry(extension_->id(), "another id"));
133
134   // ClearQueueIfNoRetainPermission should be a no-op because the app has the
135   // fileSystem.retainEntries permission.
136   service_->ClearQueueIfNoRetainPermission(extension_);
137   TRACE_CALL(CheckEntrySequenceNumber(1, 3));
138   TRACE_CALL(CheckEntrySequenceNumber(2, 2));
139   TRACE_CALL(CheckEntrySequenceNumber(3, 0));
140
141   // Test that after a clear, retained file entries are unchanged, but file
142   // entries that have been registered but not retained are no longer
143   // registered.
144   service_->Clear(extension_->id());
145   TRACE_CALL(CheckEntrySequenceNumber(1, 3));
146   TRACE_CALL(CheckEntrySequenceNumber(2, 2));
147   EXPECT_FALSE(service_->IsRegistered(extension_->id(), GenerateId(3)));
148 }
149
150 TEST_F(SavedFilesServiceUnitTest, NoRetainEntriesPermissionTest) {
151   extension_ = env_.MakeExtension(*base::test::ParseJson(
152       "{\"app\": {\"background\": {\"scripts\": [\"background.js\"]}},"
153       "\"permissions\": [\"fileSystem\"]}"));
154   service_->RegisterFileEntry(extension_->id(), GenerateId(1), path_, true);
155   TRACE_CALL(CheckEntrySequenceNumber(1, 0));
156   SavedFileEntry entry;
157   service_->EnqueueFileEntry(extension_->id(), GenerateId(1));
158   TRACE_CALL(CheckEntrySequenceNumber(1, 1));
159   EXPECT_FALSE(service_->IsRegistered(extension_->id(), "another id"));
160   EXPECT_FALSE(service_->GetFileEntry(extension_->id(), "another id"));
161
162   // ClearQueueIfNoRetainPermission should clear the queue, since the app does
163   // not have the "retainEntries" permission.
164   service_->ClearQueueIfNoRetainPermission(extension_);
165   std::vector<SavedFileEntry> entries =
166       service_->GetAllFileEntries(extension_->id());
167   EXPECT_TRUE(entries.empty());
168 }
169
170 TEST_F(SavedFilesServiceUnitTest, EvictionTest) {
171   SavedFilesService::SetLruSizeForTest(10);
172   for (int i = 0; i < 10; i++) {
173     service_->RegisterFileEntry(extension_->id(), GenerateId(i), path_, true);
174     service_->EnqueueFileEntry(extension_->id(), GenerateId(i));
175   }
176   service_->RegisterFileEntry(extension_->id(), GenerateId(10), path_, true);
177
178   // Expect that entries 0 to 9 are in the queue, but 10 is not.
179   TRACE_CALL(CheckRangeEnqueuedInOrder(0, 10));
180   TRACE_CALL(CheckEntrySequenceNumber(10, 0));
181   service_->EnqueueFileEntry(extension_->id(), GenerateId(10));
182
183   // Expect that entries 1 to 10 are in the queue, but entry 0 is not.
184   TRACE_CALL(CheckEntrySequenceNumber(0, 0));
185   TRACE_CALL(CheckRangeEnqueuedInOrder(1, 11));
186
187   // Check that retained entries are unchanged after a clear.
188   service_->Clear(extension_->id());
189   SavedFileEntry entry;
190   EXPECT_FALSE(service_->GetFileEntry(extension_->id(), GenerateId(0)));
191   TRACE_CALL(CheckRangeEnqueuedInOrder(1, 11));
192
193   // Expect that entry 2 is now at the back of the queue, and no further entries
194   // have been evicted.
195   service_->EnqueueFileEntry(extension_->id(), GenerateId(2));
196   TRACE_CALL(CheckEntrySequenceNumber(2, 12));
197   TRACE_CALL(CheckRangeEnqueuedInOrder(1, 1));
198   TRACE_CALL(CheckRangeEnqueuedInOrder(3, 11));
199
200   // Check that retained entries are unchanged after a clear.
201   service_->Clear(extension_->id());
202   TRACE_CALL(CheckEntrySequenceNumber(2, 12));
203   TRACE_CALL(CheckRangeEnqueuedInOrder(1, 1));
204   TRACE_CALL(CheckRangeEnqueuedInOrder(3, 11));
205 }
206
207 TEST_F(SavedFilesServiceUnitTest, SequenceNumberCompactionTest) {
208   SavedFilesService::SetMaxSequenceNumberForTest(8);
209   SavedFilesService::SetLruSizeForTest(8);
210   for (int i = 0; i < 4; i++) {
211     service_->RegisterFileEntry(extension_->id(), GenerateId(i), path_, true);
212     service_->EnqueueFileEntry(extension_->id(), GenerateId(i));
213   }
214   service_->EnqueueFileEntry(extension_->id(), GenerateId(2));
215   service_->EnqueueFileEntry(extension_->id(), GenerateId(3));
216   service_->EnqueueFileEntry(extension_->id(), GenerateId(2));
217
218   // The sequence numbers should be sparse, as they have not gone over the
219   // limit.
220   TRACE_CALL(CheckEntrySequenceNumber(0, 1));
221   TRACE_CALL(CheckEntrySequenceNumber(1, 2));
222   TRACE_CALL(CheckEntrySequenceNumber(2, 7));
223   TRACE_CALL(CheckEntrySequenceNumber(3, 6));
224   service_->Clear(extension_->id());
225   TRACE_CALL(CheckEntrySequenceNumber(0, 1));
226   TRACE_CALL(CheckEntrySequenceNumber(1, 2));
227   TRACE_CALL(CheckEntrySequenceNumber(2, 7));
228   TRACE_CALL(CheckEntrySequenceNumber(3, 6));
229
230   // This should push the sequence number to the limit of 8, and trigger a
231   // sequence number compaction. Expect that the sequence numbers are
232   // contiguous from 1 to 4.
233   service_->EnqueueFileEntry(extension_->id(), GenerateId(3));
234   TRACE_CALL(CheckRangeEnqueuedInOrder(0, 4));
235   service_->Clear(extension_->id());
236   TRACE_CALL(CheckRangeEnqueuedInOrder(0, 4));
237 }
238 #endif