1 /*
2  * Copyright (c) 2014, lamerman
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice, this
9  *   list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  *   this list of conditions and the following disclaimer in the documentation
13  *   and/or other materials provided with the distribution.
14  *
15  * * Neither the name of lamerman nor the names of its
16  *   contributors may be used to endorse or promote products derived from
17  *   this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  */
31 
32 #include "lrucache.h"
33 #include "concurrent_cache.h"
34 #include "gtest/gtest.h"
35 
36 const int NUM_OF_TEST1_RECORDS = 100;
37 const int NUM_OF_TEST2_RECORDS = 100;
38 const int TEST2_CACHE_CAPACITY = 50;
39 
TEST(CacheTest,SimplePut)40 TEST(CacheTest, SimplePut) {
41     zim::lru_cache<int, int> cache_lru(1);
42     cache_lru.put(7, 777);
43     EXPECT_TRUE(cache_lru.exists(7));
44     EXPECT_EQ(777, cache_lru.get(7));
45     EXPECT_EQ(1, cache_lru.size());
46 }
47 
TEST(CacheTest,OverwritingPut)48 TEST(CacheTest, OverwritingPut) {
49     zim::lru_cache<int, int> cache_lru(1);
50     cache_lru.put(7, 777);
51     cache_lru.put(7, 222);
52     EXPECT_TRUE(cache_lru.exists(7));
53     EXPECT_EQ(222, cache_lru.get(7));
54     EXPECT_EQ(1, cache_lru.size());
55 }
56 
TEST(CacheTest,MissingValue)57 TEST(CacheTest, MissingValue) {
58     zim::lru_cache<int, int> cache_lru(1);
59     EXPECT_TRUE(cache_lru.get(7).miss());
60     EXPECT_FALSE(cache_lru.get(7).hit());
61     EXPECT_THROW(cache_lru.get(7).value(), std::range_error);
62 }
63 
TEST(CacheTest,DropValue)64 TEST(CacheTest, DropValue) {
65     zim::lru_cache<int, int> cache_lru(3);
66     cache_lru.put(7, 777);
67     cache_lru.put(8, 888);
68     cache_lru.put(9, 999);
69     EXPECT_EQ(3, cache_lru.size());
70     EXPECT_TRUE(cache_lru.exists(7));
71     EXPECT_EQ(777, cache_lru.get(7));
72 
73     EXPECT_TRUE(cache_lru.drop(7));
74 
75     EXPECT_EQ(2, cache_lru.size());
76     EXPECT_FALSE(cache_lru.exists(7));
77     EXPECT_THROW(cache_lru.get(7).value(), std::range_error);
78 
79     EXPECT_FALSE(cache_lru.drop(7));
80 }
81 
TEST(CacheTest1,KeepsAllValuesWithinCapacity)82 TEST(CacheTest1, KeepsAllValuesWithinCapacity) {
83     zim::lru_cache<int, int> cache_lru(TEST2_CACHE_CAPACITY);
84 
85     for (int i = 0; i < NUM_OF_TEST2_RECORDS; ++i) {
86         cache_lru.put(i, i);
87     }
88 
89     for (int i = 0; i < NUM_OF_TEST2_RECORDS - TEST2_CACHE_CAPACITY; ++i) {
90         EXPECT_FALSE(cache_lru.exists(i));
91     }
92 
93     for (int i = NUM_OF_TEST2_RECORDS - TEST2_CACHE_CAPACITY; i < NUM_OF_TEST2_RECORDS; ++i) {
94         EXPECT_TRUE(cache_lru.exists(i));
95         EXPECT_EQ(i, cache_lru.get(i));
96     }
97 
98     size_t size = cache_lru.size();
99     EXPECT_EQ(TEST2_CACHE_CAPACITY, size);
100 }
101 
TEST(ConcurrentCacheTest,handleException)102 TEST(ConcurrentCacheTest, handleException) {
103     zim::ConcurrentCache<int, int> cache(1);
104     auto val = cache.getOrPut(7, []() { return 777; });
105     EXPECT_EQ(val, 777);
106     EXPECT_THROW(cache.getOrPut(8, []() { throw std::runtime_error("oups"); return 0; }), std::runtime_error);
107     val = cache.getOrPut(8, []() { return 888; });
108     EXPECT_EQ(val, 888);
109 }
110