/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Author: jmarantz@google.com (Joshua Marantz)

// Unit-test the threadsafe cache.  Creates an LRU-cache first, and then
// wraps a thread-safe cache around that and a mutex

#include "pagespeed/kernel/cache/threadsafe_cache.h"

#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/scoped_ptr.h"
#include "pagespeed/kernel/base/shared_string.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/thread_system.h"
#include "pagespeed/kernel/cache/cache_interface.h"
#include "pagespeed/kernel/cache/cache_spammer.h"
#include "pagespeed/kernel/cache/cache_test_base.h"
#include "pagespeed/kernel/cache/lru_cache.h"
#include "pagespeed/kernel/util/platform.h"

namespace {
const int kMaxSize = 100;
const int kNumThreads = 4;
const int kNumIters = 10000;
const int kNumInserts = 10;
}

namespace net_instaweb {

class ThreadsafeCacheTest : public testing::Test {
 protected:
  ThreadsafeCacheTest()
      : lru_cache_(new LRUCache(kMaxSize)),
        thread_runtime_(Platform::CreateThreadSystem()),
        threadsafe_cache_(lru_cache_.get(), thread_runtime_->NewMutex()) {
  }

  void TestHelper(bool expecting_evictions, bool do_deletes,
                  const char* value_pattern) {
    CacheSpammer::RunTests(kNumThreads, kNumIters, kNumInserts,
                           expecting_evictions, do_deletes, value_pattern,
                           &threadsafe_cache_, thread_runtime_.get());
    lru_cache_->SanityCheck();
  }

  scoped_ptr<LRUCache> lru_cache_;
  scoped_ptr<ThreadSystem> thread_runtime_;
  ThreadsafeCache threadsafe_cache_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ThreadsafeCacheTest);
};

TEST_F(ThreadsafeCacheTest, BasicOperation) {
  SharedString put_buffer("val");
  threadsafe_cache_.Put("key", &put_buffer);
  CacheTestBase::Callback callback;
  threadsafe_cache_.Get("key", &callback);
  EXPECT_TRUE(callback.called());
  EXPECT_EQ(CacheInterface::kAvailable, callback.state());
  EXPECT_EQ(GoogleString("val"), callback.value()->Value());
}

TEST_F(ThreadsafeCacheTest, SpamCacheNoEvictionsOrDeletions) {
  // By writing 10 inserts, with 5 bytes of value "valu%d" plus 5 bytes
  // of key, we should never evict anything.  In this test the
  // threads can each check that all their Gets succeed.
  TestHelper(false, false, "valu");
}

TEST_F(ThreadsafeCacheTest, SpamCacheWithEvictions) {
  // By writing 10 inserts, with 6 bytes of value "value%d" plus 5
  // bytes of key, we may get evictions.  In this test the threads
  // ignores the return value from Get, but we ensure that the
  // eviction logic in the cache is tested in a multi-threaded context.
  TestHelper(true, false, "value");
}

TEST_F(ThreadsafeCacheTest, SpamCacheWithDeletions) {
  // In this testcase, we expect no evictions, but we will be
  // doing some deletions, so we do not require Gets to succeed.
  TestHelper(false, true, "valu");
}

TEST_F(ThreadsafeCacheTest, SpamCacheWithDeletionsAndEvictions) {
  // In this testcase, we expect evictions, and we will also be
  // doing deletions.
  TestHelper(true, true, "value");
}

TEST_F(ThreadsafeCacheTest, Backend) {
  EXPECT_EQ(lru_cache_.get(), threadsafe_cache_.Backend());
}

}  // namespace net_instaweb
