Codebase list mozc / debian/1.6.1187.102-1_exp3 sync / learning_preference_adapter_test.cc
debian/1.6.1187.102-1_exp3

Tree @debian/1.6.1187.102-1_exp3 (Download .tar.gz)

learning_preference_adapter_test.cc @debian/1.6.1187.102-1_exp3raw · history · blame

// Copyright 2010-2012, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "sync/learning_preference_adapter.h"

#include <cmath>
#include <map>
#include <string>

#include "base/base.h"
#include "base/file_stream.h"
#include "base/logging.h"
#include "base/util.h"
#include "storage/lru_storage.h"
#include "sync/inprocess_service.h"
#include "sync/learning_preference_sync_util.h"
#include "sync/sync.pb.h"
#include "sync/sync_util.h"
#include "sync/syncer.h"
#include "testing/base/public/gunit.h"

DECLARE_string(test_tmpdir);

// TODO(peria): Fix tests with DISABLED_ prefix after refactorization
//     of rewriter finishes.

namespace mozc {
namespace sync {

using mozc::storage::LRUStorage;

class LearningPreferenceAdapterTest : public testing::Test {
 public:
  virtual void SetUp() {
    Util::SetUserProfileDirectory(FLAGS_test_tmpdir);
  }

  LRUStorage *CreateStorage(const string &filename) {
    LRUStorage *storage = new LRUStorage;
    EXPECT_TRUE(storage->OpenOrCreate(
        Util::JoinPath(FLAGS_test_tmpdir, filename).c_str(),
        4, 1000, 0xffff));
    return storage;
  }

  virtual void TearDown() {}

  LearningPreferenceAdapter *GetAdapter() {
    return &adapter_;
  }

 private:
  LearningPreferenceAdapter adapter_;
};

TEST_F(LearningPreferenceAdapterTest, BucketSize) {
  LearningPreferenceAdapter *adapter = GetAdapter();
  EXPECT_EQ(512, adapter->bucket_size());
}

TEST_F(LearningPreferenceAdapterTest, BucketId) {
  LearningPreferenceAdapter *adapter = GetAdapter();
  for (int i = 0; i < 1000; ++i) {
    const uint32 id = adapter->GetNextBucketId();
    EXPECT_GT(adapter->bucket_size(), id);
    EXPECT_LE(0, id);
  }
}

TEST_F(LearningPreferenceAdapterTest, DISABLED_Storage) {
  LearningPreferenceAdapter *adapter = GetAdapter();
  const LRUStorage storage1, storage2;

  // The adapter should has two default storages at first, for
  // USER_SEGMENT_HISTORY and USER_BOUNDARY_HISTORY.
  EXPECT_EQ(2, adapter->GetStorageSize());

  adapter->ClearStorage();
  adapter->AddStorage(
      LearningPreference::Entry::USER_SEGMENT_HISTORY,
      &storage1);

  adapter->AddStorage(
      LearningPreference::Entry::USER_BOUNDARY_HISTORY,
      &storage2);

  EXPECT_EQ(2, adapter->GetStorageSize());
  EXPECT_EQ(LearningPreference::Entry::USER_SEGMENT_HISTORY,
            adapter->GetStorage(0).type);
  EXPECT_EQ(LearningPreference::Entry::USER_BOUNDARY_HISTORY,
            adapter->GetStorage(1).type);
  EXPECT_EQ(&storage1,
            adapter->GetStorage(0).lru_storage);
  EXPECT_EQ(&storage2,
            adapter->GetStorage(1).lru_storage);

  adapter->ClearStorage();
  EXPECT_EQ(0, adapter->GetStorageSize());
}

TEST_F(LearningPreferenceAdapterTest, GetItemsToUpload) {
  LearningPreferenceAdapter *adapter = GetAdapter();

  scoped_ptr<LRUStorage> storage1(CreateStorage("file1"));
  scoped_ptr<LRUStorage> storage2(CreateStorage("file2"));

  storage1->Write(0, 0, "tst0", 0);
  storage1->Write(1, 1, "tst1", 10);
  storage1->Write(2, 2, "tst2", 20);
  storage1->Write(3, 3, "tst3", 30);

  storage2->Write(0, 4, "tst4", 5);
  storage2->Write(1, 5, "tst5", 15);
  storage2->Write(2, 6, "tst6", 25);
  storage2->Write(3, 7, "tst7", 35);

  adapter->ClearStorage();
  adapter->AddStorage(LearningPreference::Entry::USER_SEGMENT_HISTORY,
                     storage1.get());
  adapter->AddStorage(LearningPreference::Entry::USER_BOUNDARY_HISTORY,
                     storage2.get());

  {
    adapter->SetLastDownloadTimestamp(10);
    adapter->Start();
    const LearningPreference &update = adapter->local_update();
    LearningPreference update_expected;
    update_expected.CopyFrom(update);
    EXPECT_EQ(5, update.entries_size());
    ime_sync::SyncItems items;
    adapter->GetItemsToUpload(&items);
    EXPECT_EQ(1, items.size());
    const ime_sync::SyncItem &item = items.Get(0);
    const sync::LearningPreferenceValue &value =
        item.value().GetExtension(sync::LearningPreferenceValue::ext);
    EXPECT_TRUE(value.has_learning_preference());
    EXPECT_EQ(value.learning_preference().DebugString(),
              update_expected.DebugString());
  }

  {
    adapter->SetLastDownloadTimestamp(100);
    adapter->Start();
    const LearningPreference &update = adapter->local_update();
    EXPECT_EQ(0, update.entries_size());
  }

  {
    adapter->SetLastDownloadTimestamp(0);
    adapter->Start();
    const LearningPreference &update = adapter->local_update();
    LearningPreference update_expected;
    update_expected.CopyFrom(update);
    EXPECT_EQ(7, update.entries_size());
    ime_sync::SyncItems items;
    adapter->GetItemsToUpload(&items);
    EXPECT_EQ(1, items.size());
    const ime_sync::SyncItem &item = items.Get(0);
    const sync::LearningPreferenceValue &value =
        item.value().GetExtension(sync::LearningPreferenceValue::ext);
    EXPECT_TRUE(value.has_learning_preference());
    EXPECT_EQ(value.learning_preference().DebugString(),
              update_expected.DebugString());
  }
}

TEST_F(LearningPreferenceAdapterTest, SetDownloadedItems) {
  LearningPreferenceAdapter *adapter = GetAdapter();

  LearningPreference *update = adapter->mutable_local_update();
  update->Clear();
  for (int i = 0; i < 1000; ++i) {
    LearningPreference::Entry *entry = update->add_entries();
    entry->set_key(i);
    entry->set_value("test");
    entry->set_last_access_time(i + 1);
    entry->set_type(LearningPreference::Entry::USER_SEGMENT_HISTORY);
  }

  LearningPreference update_expected;
  update_expected.CopyFrom(*update);

  ime_sync::SyncItems items;
  adapter->GetItemsToUpload(&items);

  LearningPreference update_actual;

  for (size_t i = 0; i < items.size(); ++i) {
    const ime_sync::SyncItem &item = items.Get(i);
    EXPECT_EQ(item.component(), adapter->component_id());
    EXPECT_TRUE(item.key().HasExtension(sync::LearningPreferenceKey::ext));
    EXPECT_TRUE(item.value().HasExtension(sync::LearningPreferenceValue::ext));
    const sync::LearningPreferenceValue &value =
        item.value().GetExtension(sync::LearningPreferenceValue::ext);
    EXPECT_TRUE(value.has_learning_preference());
    update_actual.MergeFrom(value.learning_preference());
  }

  EXPECT_EQ(update_expected.DebugString(),
            update_actual.DebugString());

  scoped_ptr<LRUStorage> storage_reference(CreateStorage("file1"));
  adapter->ClearStorage();
  adapter->AddStorage(LearningPreference::Entry::USER_SEGMENT_HISTORY,
                     storage_reference.get());

  adapter->SetDownloadedItems(items);

  LRUStorage storage;
  EXPECT_TRUE(storage.Open((
      storage_reference->filename() + ".merge_pending").c_str()));
  EXPECT_EQ(1000, storage.size());

  update_actual.Clear();
  LearningPreferenceSyncUtil::CreateUpdate(
      storage,
      LearningPreference::Entry::USER_SEGMENT_HISTORY,
      0,
      &update_actual);

  EXPECT_EQ(update_expected.DebugString(),
            update_actual.DebugString());

  Util::Unlink(storage.filename());
  Util::Unlink(storage.filename() + ".merge_pending");
}

TEST_F(LearningPreferenceAdapterTest, LastDownloadTimestamp) {
  LearningPreferenceAdapter *adapter = GetAdapter();
  EXPECT_TRUE(adapter->SetLastDownloadTimestamp(1234));
  EXPECT_EQ(1234, adapter->GetLastDownloadTimestamp());

  for (int i = 0; i < 1000; ++i) {
    EXPECT_TRUE(adapter->SetLastDownloadTimestamp(i));
    EXPECT_EQ(i, adapter->GetLastDownloadTimestamp());
  }
}

TEST_F(LearningPreferenceAdapterTest, MarkUploaded) {
  LearningPreferenceAdapter *adapter = GetAdapter();

  ime_sync::SyncItem item;
  item.set_component(adapter->component_id());
  sync::LearningPreferenceKey *key =
      item.mutable_key()->MutableExtension(
          sync::LearningPreferenceKey::ext);
  sync::LearningPreferenceValue *value =
      item.mutable_value()->MutableExtension(
          sync::LearningPreferenceValue::ext);
  CHECK(key);
  CHECK(value);
  key->set_bucket_id(0);

  const uint64 synced_time = Util::GetTime();
  adapter->Start();

  // last_access_time is not updated.
  adapter->SetLastDownloadTimestamp(1234);
  adapter->MarkUploaded(item, false);
  EXPECT_EQ(1234, adapter->GetLastDownloadTimestamp());

  // last_access_time is updated.
  adapter->MarkUploaded(item, true);
  const int diff = abs(static_cast<int>(synced_time -
                                        adapter->GetLastDownloadTimestamp()));
  EXPECT_LE(diff, 2);
}
}  // sync
}  // mozc