- add sources.
[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 "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/WebKit/public/platform/WebIDBTypes.h"
13
14 namespace content {
15
16 namespace {
17
18 class IndexedDBBackingStoreTest : public testing::Test {
19  public:
20   IndexedDBBackingStoreTest() {}
21   virtual void SetUp() {
22     const GURL origin("http://localhost:81");
23     backing_store_ = IndexedDBBackingStore::OpenInMemory(origin);
24
25     // useful keys and values during tests
26     m_value1 = "value1";
27     m_value2 = "value2";
28     m_value3 = "value3";
29     m_key1 = IndexedDBKey(99, WebKit::WebIDBKeyTypeNumber);
30     m_key2 = IndexedDBKey(ASCIIToUTF16("key2"));
31     m_key3 = IndexedDBKey(ASCIIToUTF16("key3"));
32   }
33
34  protected:
35   scoped_refptr<IndexedDBBackingStore> backing_store_;
36
37   // Sample keys and values that are consistent.
38   IndexedDBKey m_key1;
39   IndexedDBKey m_key2;
40   IndexedDBKey m_key3;
41   std::string m_value1;
42   std::string m_value2;
43   std::string m_value3;
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     bool ok = backing_store_->PutRecord(
55         &transaction1, 1, 1, m_key1, m_value1, &record);
56     EXPECT_TRUE(ok);
57     transaction1.Commit();
58   }
59
60   {
61     IndexedDBBackingStore::Transaction transaction2(backing_store_);
62     transaction2.Begin();
63     std::string result_value;
64     bool ok =
65         backing_store_->GetRecord(&transaction2, 1, 1, m_key1, &result_value);
66     transaction2.Commit();
67     EXPECT_TRUE(ok);
68     EXPECT_EQ(m_value1, result_value);
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     bool ok = backing_store_->PutRecord(&transaction1,
90                                         high_database_id,
91                                         high_object_store_id,
92                                         m_key1,
93                                         m_value1,
94                                         &record);
95     EXPECT_TRUE(ok);
96
97     ok = 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(ok);
104
105     ok = 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(ok);
112
113     ok = transaction1.Commit();
114     EXPECT_TRUE(ok);
115   }
116
117   {
118     IndexedDBBackingStore::Transaction transaction2(backing_store_);
119     transaction2.Begin();
120     std::string result_value;
121     bool ok = backing_store_->GetRecord(&transaction2,
122                                         high_database_id,
123                                         high_object_store_id,
124                                         m_key1,
125                                         &result_value);
126     EXPECT_TRUE(ok);
127     EXPECT_EQ(m_value1, result_value);
128
129     scoped_ptr<IndexedDBKey> new_primary_key;
130     ok = 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(ok);
137
138     ok = 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(ok);
145     EXPECT_TRUE(new_primary_key->IsEqual(m_key1));
146
147     ok = transaction2.Commit();
148     EXPECT_TRUE(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   std::string result_value;
161
162   IndexedDBBackingStore::Transaction transaction1(backing_store_);
163   transaction1.Begin();
164
165   IndexedDBBackingStore::RecordIdentifier record;
166   bool ok = backing_store_->PutRecord(&transaction1,
167                                       database_id,
168                                       KeyPrefix::kInvalidId,
169                                       m_key1,
170                                       m_value1,
171                                       &record);
172   EXPECT_FALSE(ok);
173   ok = backing_store_->PutRecord(
174       &transaction1, database_id, 0, m_key1, m_value1, &record);
175   EXPECT_FALSE(ok);
176   ok = backing_store_->PutRecord(&transaction1,
177                                  KeyPrefix::kInvalidId,
178                                  object_store_id,
179                                  m_key1,
180                                  m_value1,
181                                  &record);
182   EXPECT_FALSE(ok);
183   ok = backing_store_->PutRecord(
184       &transaction1, 0, object_store_id, m_key1, m_value1, &record);
185   EXPECT_FALSE(ok);
186
187   ok = backing_store_->GetRecord(
188       &transaction1, database_id, KeyPrefix::kInvalidId, m_key1, &result_value);
189   EXPECT_FALSE(ok);
190   ok = backing_store_->GetRecord(
191       &transaction1, database_id, 0, m_key1, &result_value);
192   EXPECT_FALSE(ok);
193   ok = backing_store_->GetRecord(&transaction1,
194                                  KeyPrefix::kInvalidId,
195                                  object_store_id,
196                                  m_key1,
197                                  &result_value);
198   EXPECT_FALSE(ok);
199   ok = backing_store_->GetRecord(
200       &transaction1, 0, object_store_id, m_key1, &result_value);
201   EXPECT_FALSE(ok);
202
203   scoped_ptr<IndexedDBKey> new_primary_key;
204   ok = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
205                                              database_id,
206                                              object_store_id,
207                                              KeyPrefix::kInvalidId,
208                                              m_key1,
209                                              &new_primary_key);
210   EXPECT_FALSE(ok);
211   ok = 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(ok);
218   ok = backing_store_->GetPrimaryKeyViaIndex(
219       &transaction1, database_id, object_store_id, 0, m_key1, &new_primary_key);
220   EXPECT_FALSE(ok);
221
222   ok = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
223                                              KeyPrefix::kInvalidId,
224                                              object_store_id,
225                                              index_id,
226                                              m_key1,
227                                              &new_primary_key);
228   EXPECT_FALSE(ok);
229   ok = backing_store_->GetPrimaryKeyViaIndex(&transaction1,
230                                              database_id,
231                                              KeyPrefix::kInvalidId,
232                                              index_id,
233                                              m_key1,
234                                              &new_primary_key);
235   EXPECT_FALSE(ok);
236 }
237
238 TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
239   const string16 database_name(ASCIIToUTF16("db1"));
240   int64 database_id;
241   const string16 version(ASCIIToUTF16("old_string_version"));
242   const int64 int_version = 9;
243
244   const int64 object_store_id = 99;
245   const 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 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     bool ok = backing_store_->CreateIDBDatabaseMetaData(
258         database_name, version, int_version, &database_id);
259     EXPECT_TRUE(ok);
260     EXPECT_GT(database_id, 0);
261
262     IndexedDBBackingStore::Transaction transaction(backing_store_);
263     transaction.Begin();
264
265     ok = 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(ok);
272
273     ok = 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(ok);
282
283     ok = transaction.Commit();
284     EXPECT_TRUE(ok);
285   }
286
287   {
288     IndexedDBDatabaseMetadata database;
289     bool found;
290     bool ok = backing_store_->GetIDBDatabaseMetaData(
291         database_name, &database, &found);
292     EXPECT_TRUE(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     ok = backing_store_->GetObjectStores(database.id, &database.object_stores);
301     EXPECT_TRUE(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