Home | History | Annotate | Download | only in activity_log
      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 "base/files/scoped_temp_dir.h"
      6 #include "base/strings/stringprintf.h"
      7 #include "chrome/browser/extensions/activity_log/database_string_table.h"
      8 #include "sql/connection.h"
      9 #include "sql/statement.h"
     10 #include "sql/transaction.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 namespace extensions {
     14 
     15 class DatabaseStringTableTest : public testing::Test {
     16  protected:
     17   virtual void SetUp() OVERRIDE {
     18     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     19     base::FilePath db_file = temp_dir_.path().AppendASCII("StringTable.db");
     20 
     21     ASSERT_TRUE(db_.Open(db_file));
     22   }
     23 
     24   virtual void TearDown() OVERRIDE {
     25     db_.Close();
     26   }
     27 
     28   base::ScopedTempDir temp_dir_;
     29   sql::Connection db_;
     30 };
     31 
     32 // Check that initializing the database works.
     33 TEST_F(DatabaseStringTableTest, Init) {
     34   DatabaseStringTable table("test");
     35   table.Initialize(&db_);
     36   ASSERT_TRUE(db_.DoesTableExist("test"));
     37   ASSERT_TRUE(db_.DoesIndexExist("test_index"));
     38 }
     39 
     40 // Insert a new mapping into the table, then verify the table contents.
     41 TEST_F(DatabaseStringTableTest, Insert) {
     42   DatabaseStringTable table("test");
     43   table.Initialize(&db_);
     44   int64 id;
     45   ASSERT_TRUE(table.StringToInt(&db_, "abc", &id));
     46 
     47   sql::Statement query(
     48       db_.GetUniqueStatement("SELECT id FROM test WHERE value = 'abc'"));
     49   ASSERT_TRUE(query.Step());
     50   int64 raw_id = query.ColumnInt64(0);
     51   ASSERT_EQ(id, raw_id);
     52 }
     53 
     54 // Check that different strings are mapped to different values, and the same
     55 // string is mapped to the same value repeatably.
     56 TEST_F(DatabaseStringTableTest, InsertMultiple) {
     57   DatabaseStringTable table("test");
     58   table.Initialize(&db_);
     59 
     60   int64 id1;
     61   int64 id2;
     62   ASSERT_TRUE(table.StringToInt(&db_, "string1", &id1));
     63   ASSERT_TRUE(table.StringToInt(&db_, "string2", &id2));
     64   ASSERT_NE(id1, id2);
     65 
     66   int64 id1a;
     67   ASSERT_TRUE(table.StringToInt(&db_, "string1", &id1a));
     68   ASSERT_EQ(id1, id1a);
     69 }
     70 
     71 // Check that values can be read back from the database even after the
     72 // in-memory cache is cleared.
     73 TEST_F(DatabaseStringTableTest, CacheCleared) {
     74   DatabaseStringTable table("test");
     75   table.Initialize(&db_);
     76 
     77   int64 id1;
     78   ASSERT_TRUE(table.StringToInt(&db_, "string1", &id1));
     79 
     80   table.ClearCache();
     81 
     82   int64 id2;
     83   ASSERT_TRUE(table.StringToInt(&db_, "string1", &id2));
     84   ASSERT_EQ(id1, id2);
     85 }
     86 
     87 // Check that direct database modifications are picked up after the cache is
     88 // cleared.
     89 TEST_F(DatabaseStringTableTest, DatabaseModified) {
     90   DatabaseStringTable table("test");
     91   table.Initialize(&db_);
     92 
     93   int64 id1;
     94   ASSERT_TRUE(table.StringToInt(&db_, "modified", &id1));
     95 
     96   ASSERT_TRUE(
     97       db_.Execute("UPDATE test SET id = id + 1 WHERE value = 'modified'"));
     98 
     99   int64 id2;
    100   ASSERT_TRUE(table.StringToInt(&db_, "modified", &id2));
    101   ASSERT_EQ(id1, id2);
    102 
    103   table.ClearCache();
    104 
    105   int64 id3;
    106   ASSERT_TRUE(table.StringToInt(&db_, "modified", &id3));
    107   ASSERT_EQ(id1 + 1, id3);
    108 }
    109 
    110 // Check that looking up an unknown id returns an error.
    111 TEST_F(DatabaseStringTableTest, BadLookup) {
    112   DatabaseStringTable table("test");
    113   table.Initialize(&db_);
    114   std::string value;
    115   ASSERT_FALSE(table.IntToString(&db_, 1, &value));
    116 }
    117 
    118 // Check looking up an inserted value, both cached and not cached.
    119 TEST_F(DatabaseStringTableTest, Lookup) {
    120   DatabaseStringTable table("test");
    121   table.Initialize(&db_);
    122   int64 id;
    123   ASSERT_TRUE(table.StringToInt(&db_, "abc", &id));
    124 
    125   std::string value;
    126   ASSERT_TRUE(table.IntToString(&db_, id, &value));
    127   ASSERT_EQ("abc", value);
    128 
    129   table.ClearCache();
    130   value = "";
    131   ASSERT_TRUE(table.IntToString(&db_, id, &value));
    132   ASSERT_EQ("abc", value);
    133 }
    134 
    135 // Check that the in-memory cache for the string table does not become too
    136 // large, even if many items are inserted.
    137 TEST_F(DatabaseStringTableTest, Prune) {
    138   DatabaseStringTable table("size_test");
    139   table.Initialize(&db_);
    140 
    141   // Wrap the lookups in a transaction to improve performance.
    142   sql::Transaction transaction(&db_);
    143 
    144   transaction.Begin();
    145   for (int i = 0; i < 2000; i++) {
    146     int64 id;
    147     ASSERT_TRUE(table.StringToInt(&db_, base::StringPrintf("value-%d", i),
    148                                   &id));
    149   }
    150   transaction.Commit();
    151 
    152   // The maximum size below should correspond to kMaximumCacheSize in
    153   // database_string_table.cc, with a small amount of additional slop (an entry
    154   // might be inserted after doing the pruning).
    155   ASSERT_LE(table.id_to_value_.size(), 1005U);
    156   ASSERT_LE(table.value_to_id_.size(), 1005U);
    157 }
    158 
    159 }  // namespace extensions
    160