Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / content / browser / indexed_db / indexed_db_backing_store_unittest.cc
1 // Copyright (c) 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 "content/browser/indexed_db/indexed_db_backing_store.h"
6
7 #include "base/logging.h"
8 #include "base/strings/string16.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
11 #include "content/browser/indexed_db/indexed_db_value.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/platform/WebIDBTypes.h"
14
15 using base::ASCIIToUTF16;
16
17 namespace content {
18
19 namespace {
20
21 class IndexedDBBackingStoreTest : public testing::Test {
22  public:
23   IndexedDBBackingStoreTest() {}
24   virtual void SetUp() {
25     const GURL origin("http://localhost:81");
26     backing_store_ = IndexedDBBackingStore::OpenInMemory(origin);
27
28     // useful keys and values during tests
29     m_value1 = IndexedDBValue("value1", std::vector<IndexedDBBlobInfo>());
30     m_value2 = IndexedDBValue("value2", std::vector<IndexedDBBlobInfo>());
31
32     m_key1 = IndexedDBKey(99, blink::WebIDBKeyTypeNumber);
33     m_key2 = IndexedDBKey(ASCIIToUTF16("key2"));
34   }
35
36  protected:
37   scoped_refptr<IndexedDBBackingStore> backing_store_;
38
39   // Sample keys and values that are consistent.
40   IndexedDBKey m_key1;
41   IndexedDBKey m_key2;
42   IndexedDBValue m_value1;
43   IndexedDBValue m_value2;
44
45  private:
46   DISALLOW_COPY_AND_ASSIGN(IndexedDBBackingStoreTest);
47 };
48
49 TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
50   {
51     IndexedDBBackingStore::Transaction transaction1(backing_store_);
52     transaction1.Begin();
53     IndexedDBBackingStore::RecordIdentifier record;
54     leveldb::Status s = backing_store_->PutRecord(
55         &transaction1, 1, 1, m_key1, m_value1, &record);
56     EXPECT_TRUE(s.ok());
57     transaction1.Commit();
58   }
59
60   {
61     IndexedDBBackingStore::Transaction transaction2(backing_store_);
62     transaction2.Begin();
63     IndexedDBValue result_value;
64     leveldb::Status s =
65         backing_store_->GetRecord(&transaction2, 1, 1, m_key1, &result_value);
66     transaction2.Commit();
67     EXPECT_TRUE(s.ok());
68     EXPECT_EQ(m_value1.bits, result_value.bits);
69   }
70 }
71
72 // Make sure that using very high ( more than 32 bit ) values for database_id
73 // and object_store_id still work.
74 TEST_F(IndexedDBBackingStoreTest, HighIds) {
75   const int64 high_database_id = 1ULL << 35;
76   const int64 high_object_store_id = 1ULL << 39;
77   // index_ids are capped at 32 bits for storage purposes.
78   const int64 high_index_id = 1ULL << 29;
79
80   const int64 invalid_high_index_id = 1ULL << 37;
81
82   const IndexedDBKey& index_key = m_key2;
83   std::string index_key_raw;
84   EncodeIDBKey(index_key, &index_key_raw);
85   {
86     IndexedDBBackingStore::Transaction transaction1(backing_store_);
87     transaction1.Begin();
88     IndexedDBBackingStore::RecordIdentifier record;
89     leveldb::Status s = backing_store_->PutRecord(&transaction1,
90                                                   high_database_id,
91                                                   high_object_store_id,
92                                                   m_key1,
93                                                   m_value1,
94                                                   &record);
95     EXPECT_TRUE(s.ok());
96
97     s = backing_store_->PutIndexDataForRecord(&transaction1,
98                                               high_database_id,
99                                               high_object_store_id,
100                                               invalid_high_index_id,
101                                               index_key,
102                                               record);
103     EXPECT_FALSE(s.ok());
104
105     s = backing_store_->PutIndexDataForRecord(&transaction1,
106                                               high_database_id,
107                                               high_object_store_id,
108                                               high_index_id,
109                                               index_key,
110                                               record);
111     EXPECT_TRUE(s.ok());
112
113     s = transaction1.Commit();
114     EXPECT_TRUE(s.ok());
115   }
116
117   {
118     IndexedDBBackingStore::Transaction transaction2(backing_store_);
119     transaction2.Begin();
120     IndexedDBValue result_value;
121     leveldb::Status s = backing_store_->GetRecord(&transaction2,
122                                                   high_database_id,
123                                                   high_object_store_id,
124                                                   m_key1,
125                                                   &result_value);
126     EXPECT_TRUE(s.ok());
127     EXPECT_EQ(m_value1.bits, result_value.bits);
128
129     scoped_ptr<IndexedDBKey> new_primary_key;
130     s = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
131                                               high_database_id,
132                                               high_object_store_id,
133                                               invalid_high_index_id,
134                                               index_key,
135                                               &new_primary_key);
136     EXPECT_FALSE(s.ok());
137
138     s = backing_store_->GetPrimaryKeyViaIndex(&transaction2,
139                                               high_database_id,
140                                               high_object_store_id,
141                                               high_index_id,
142                                               index_key,
143                                               &new_primary_key);
144     EXPECT_TRUE(s.ok());
145     EXPECT_TRUE(new_primary_key->Equals(m_key1));
146
147     s = transaction2.Commit();
148     EXPECT_TRUE(s.ok());
149   }
150 }
151
152 // Make sure that other invalid ids do not crash.
153 TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
154   // valid ids for use when testing invalid ids
155   const int64 database_id = 1;
156   const int64 object_store_id = 1;
157   const int64 index_id = kMinimumIndexId;
158   const int64 invalid_low_index_id = 19;  // index_ids must be > kMinimumIndexId
159
160   IndexedDBValue result_value;
161
162   IndexedDBBackingStore::Transaction transaction1(backing_store_);
163   transaction1.Begin();
164
165   IndexedDBBackingStore::RecordIdentifier record;
166   leveldb::Status s = backing_store_->PutRecord(&transaction1,
167                                                 database_id,
168                                                 KeyPrefix::kInvalidId,
169                                                 m_key1,
170                                                 m_value1,
171                                                 &record);
172   EXPECT_FALSE(s.ok());
173   s = backing_store_->PutRecord(
174       &transaction1, database_id, 0, m_key1, m_value1, &record);
175   EXPECT_FALSE(s.ok());
176   s = backing_store_->PutRecord(&transaction1,
177                                 KeyPrefix::kInvalidId,
178                                 object_store_id,
179                                 m_key1,
180                                 m_value1,
181                                 &record);
182   EXPECT_FALSE(s.ok());
183   s = backing_store_->PutRecord(
184       &transaction1, 0, object_store_id, m_key1, m_value1, &record);
185   EXPECT_FALSE(s.ok());
186
187   s = backing_store_->GetRecord(
188       &transaction1, database_id, KeyPrefix::kInvalidId, m_key1, &result_value);
189   EXPECT_FALSE(s.ok());
190   s = backing_store_->GetRecord(
191       &transaction1, database_id, 0, m_key1, &result_value);
192   EXPECT_FALSE(s.ok());
193   s = backing_store_->GetRecord(&transaction1,
194                                 KeyPrefix::kInvalidId,
195                                 object_store_id,
196                                 m_key1,
197                                 &result_value);
198   EXPECT_FALSE(s.ok());
199   s = backing_store_->GetRecord(
200       &transaction1, 0, object_store_id, m_key1, &result_value);
201   EXPECT_FALSE(s.ok());
202
203   scoped_ptr<IndexedDBKey> new_primary_key;
204   s = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
205                                             database_id,
206                                             object_store_id,
207                                             KeyPrefix::kInvalidId,
208                                             m_key1,
209                                             &new_primary_key);
210   EXPECT_FALSE(s.ok());
211   s = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
212                                             database_id,
213                                             object_store_id,
214                                             invalid_low_index_id,
215                                             m_key1,
216                                             &new_primary_key);
217   EXPECT_FALSE(s.ok());
218   s = backing_store_->GetPrimaryKeyViaIndex(
219       &transaction1, database_id, object_store_id, 0, m_key1, &new_primary_key);
220   EXPECT_FALSE(s.ok());
221
222   s = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
223                                             KeyPrefix::kInvalidId,
224                                             object_store_id,
225                                             index_id,
226                                             m_key1,
227                                             &new_primary_key);
228   EXPECT_FALSE(s.ok());
229   s = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
230                                             database_id,
231                                             KeyPrefix::kInvalidId,
232                                             index_id,
233                                             m_key1,
234                                             &new_primary_key);
235   EXPECT_FALSE(s.ok());
236 }
237
238 TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
239   const base::string16 database_name(ASCIIToUTF16("db1"));
240   int64 database_id;
241   const base::string16 version(ASCIIToUTF16("old_string_version"));
242   const int64 int_version = 9;
243
244   const int64 object_store_id = 99;
245   const base::string16 object_store_name(ASCIIToUTF16("object_store1"));
246   const bool auto_increment = true;
247   const IndexedDBKeyPath object_store_key_path(
248       ASCIIToUTF16("object_store_key"));
249
250   const int64 index_id = 999;
251   const base::string16 index_name(ASCIIToUTF16("index1"));
252   const bool unique = true;
253   const bool multi_entry = true;
254   const IndexedDBKeyPath index_key_path(ASCIIToUTF16("index_key"));
255
256   {
257     leveldb::Status s = backing_store_->CreateIDBDatabaseMetaData(
258         database_name, version, int_version, &database_id);
259     EXPECT_TRUE(s.ok());
260     EXPECT_GT(database_id, 0);
261
262     IndexedDBBackingStore::Transaction transaction(backing_store_);
263     transaction.Begin();
264
265     s = backing_store_->CreateObjectStore(&transaction,
266                                           database_id,
267                                           object_store_id,
268                                           object_store_name,
269                                           object_store_key_path,
270                                           auto_increment);
271     EXPECT_TRUE(s.ok());
272
273     s = backing_store_->CreateIndex(&transaction,
274                                     database_id,
275                                     object_store_id,
276                                     index_id,
277                                     index_name,
278                                     index_key_path,
279                                     unique,
280                                     multi_entry);
281     EXPECT_TRUE(s.ok());
282
283     s = transaction.Commit();
284     EXPECT_TRUE(s.ok());
285   }
286
287   {
288     IndexedDBDatabaseMetadata database;
289     bool found;
290     leveldb::Status s = backing_store_->GetIDBDatabaseMetaData(
291         database_name, &database, &found);
292     EXPECT_TRUE(s.ok());
293     EXPECT_TRUE(found);
294
295     // database.name is not filled in by the implementation.
296     EXPECT_EQ(version, database.version);
297     EXPECT_EQ(int_version, database.int_version);
298     EXPECT_EQ(database_id, database.id);
299
300     s = backing_store_->GetObjectStores(database.id, &database.object_stores);
301     EXPECT_TRUE(s.ok());
302
303     EXPECT_EQ(1UL, database.object_stores.size());
304     IndexedDBObjectStoreMetadata object_store =
305         database.object_stores[object_store_id];
306     EXPECT_EQ(object_store_name, object_store.name);
307     EXPECT_EQ(object_store_key_path, object_store.key_path);
308     EXPECT_EQ(auto_increment, object_store.auto_increment);
309
310     EXPECT_EQ(1UL, object_store.indexes.size());
311     IndexedDBIndexMetadata index = object_store.indexes[index_id];
312     EXPECT_EQ(index_name, index.name);
313     EXPECT_EQ(index_key_path, index.key_path);
314     EXPECT_EQ(unique, index.unique);
315     EXPECT_EQ(multi_entry, index.multi_entry);
316   }
317 }
318
319 }  // namespace
320
321 }  // namespace content