1#!/usr/bin/env python
2# Copyright 2013 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6from cache_chain_object_store import CacheChainObjectStore
7from test_object_store import TestObjectStore
8import unittest
9
10class CacheChainObjectStoreTest(unittest.TestCase):
11  def setUp(self):
12    self._first = TestObjectStore('first', init={
13      'storage.html': 'storage',
14    })
15    self._second = TestObjectStore('second', init={
16      'runtime.html': 'runtime',
17      'storage.html': 'storage',
18    })
19    self._third = TestObjectStore('third', init={
20      'commands.html': 'commands',
21      'runtime.html': 'runtime',
22      'storage.html': 'storage',
23    })
24    self._store = CacheChainObjectStore(
25        (self._first, self._second, self._third))
26
27  def testGetFromFirstLayer(self):
28    self.assertEqual('storage', self._store.Get('storage.html').Get())
29    self.assertTrue(*self._first.CheckAndReset(get_count=1))
30    # Found in first layer, stop.
31    self.assertTrue(*self._second.CheckAndReset())
32    self.assertTrue(*self._third.CheckAndReset())
33    # Cached in memory, won't re-query.
34    self.assertEqual('storage', self._store.Get('storage.html').Get())
35    self.assertTrue(*self._first.CheckAndReset())
36    self.assertTrue(*self._second.CheckAndReset())
37    self.assertTrue(*self._third.CheckAndReset())
38
39  def testGetFromSecondLayer(self):
40    self.assertEqual('runtime', self._store.Get('runtime.html').Get())
41    # Not found in first layer but found in second.
42    self.assertTrue(*self._first.CheckAndReset(get_count=1, set_count=1))
43    self.assertTrue(*self._second.CheckAndReset(get_count=1))
44    self.assertTrue(*self._third.CheckAndReset())
45    # First will now have it cached.
46    self.assertEqual('runtime', self._first.Get('runtime.html').Get())
47    self._first.Reset()
48    # Cached in memory, won't re-query.
49    self.assertEqual('runtime', self._store.Get('runtime.html').Get())
50    self.assertTrue(*self._first.CheckAndReset())
51    self.assertTrue(*self._second.CheckAndReset())
52    self.assertTrue(*self._third.CheckAndReset())
53
54  def testGetFromThirdLayer(self):
55    self.assertEqual('commands', self._store.Get('commands.html').Get())
56    # As above but for third.
57    self.assertTrue(*self._first.CheckAndReset(get_count=1, set_count=1))
58    self.assertTrue(*self._second.CheckAndReset(get_count=1, set_count=1))
59    self.assertTrue(*self._third.CheckAndReset(get_count=1))
60    # First and second will now have it cached.
61    self.assertEqual('commands', self._first.Get('commands.html').Get())
62    self.assertEqual('commands', self._second.Get('commands.html').Get())
63    self._first.Reset()
64    self._second.Reset()
65    # Cached in memory, won't re-query.
66    self.assertEqual('commands', self._store.Get('commands.html').Get())
67    self.assertTrue(*self._first.CheckAndReset())
68    self.assertTrue(*self._second.CheckAndReset())
69    self.assertTrue(*self._third.CheckAndReset())
70
71  def testGetFromAllLayers(self):
72    self.assertEqual({
73      'commands.html': 'commands',
74      'runtime.html': 'runtime',
75      'storage.html': 'storage',
76    }, self._store.GetMulti(('commands.html',
77                             'runtime.html',
78                             'storage.html')).Get())
79    self.assertTrue(*self._first.CheckAndReset(get_count=1, set_count=1))
80    self.assertTrue(*self._second.CheckAndReset(get_count=1, set_count=1))
81    self.assertTrue(*self._third.CheckAndReset(get_count=1))
82    # First and second will have it all cached.
83    self.assertEqual('runtime', self._first.Get('runtime.html').Get())
84    self.assertEqual('commands', self._first.Get('commands.html').Get())
85    self.assertEqual('commands', self._second.Get('commands.html').Get())
86    self._first.Reset()
87    self._second.Reset()
88    # Cached in memory.
89    self.assertEqual({
90      'commands.html': 'commands',
91      'runtime.html': 'runtime',
92      'storage.html': 'storage',
93    }, self._store.GetMulti(('commands.html',
94                             'runtime.html',
95                             'storage.html')).Get())
96    self.assertTrue(*self._first.CheckAndReset())
97    self.assertTrue(*self._second.CheckAndReset())
98    self.assertTrue(*self._third.CheckAndReset())
99
100  def testPartiallyCachedInMemory(self):
101    self.assertEqual({
102      'commands.html': 'commands',
103      'storage.html': 'storage',
104    }, self._store.GetMulti(('commands.html', 'storage.html')).Get())
105    self.assertTrue(*self._first.CheckAndReset(get_count=1, set_count=1))
106    self.assertTrue(*self._second.CheckAndReset(get_count=1, set_count=1))
107    self.assertTrue(*self._third.CheckAndReset(get_count=1))
108    # runtime wasn't cached in memory, so stores should still be queried.
109    self.assertEqual({
110      'commands.html': 'commands',
111      'runtime.html': 'runtime',
112    }, self._store.GetMulti(('commands.html', 'runtime.html')).Get())
113    self.assertTrue(*self._first.CheckAndReset(get_count=1, set_count=1))
114    self.assertTrue(*self._second.CheckAndReset(get_count=1))
115    self.assertTrue(*self._third.CheckAndReset())
116
117  def testNotFound(self):
118    self.assertEqual(None, self._store.Get('notfound.html').Get())
119    self.assertTrue(*self._first.CheckAndReset(get_count=1))
120    self.assertTrue(*self._second.CheckAndReset(get_count=1))
121    self.assertTrue(*self._third.CheckAndReset(get_count=1))
122    # Not-foundedness shouldn't be cached.
123    self.assertEqual(None, self._store.Get('notfound.html').Get())
124    self.assertTrue(*self._first.CheckAndReset(get_count=1))
125    self.assertTrue(*self._second.CheckAndReset(get_count=1))
126    self.assertTrue(*self._third.CheckAndReset(get_count=1))
127    # Test some things not found, some things found.
128    self.assertEqual({
129      'runtime.html': 'runtime',
130    }, self._store.GetMulti(('runtime.html', 'notfound.html')).Get())
131    self.assertTrue(*self._first.CheckAndReset(get_count=1, set_count=1))
132    self.assertTrue(*self._second.CheckAndReset(get_count=1))
133    self.assertTrue(*self._third.CheckAndReset(get_count=1))
134
135  def testSet(self):
136    self._store.Set('hello.html', 'hello')
137    self.assertTrue(*self._first.CheckAndReset(set_count=1))
138    self.assertTrue(*self._second.CheckAndReset(set_count=1))
139    self.assertTrue(*self._third.CheckAndReset(set_count=1))
140    # Should have cached it.
141    self.assertEqual('hello', self._store.Get('hello.html').Get())
142    self.assertTrue(*self._first.CheckAndReset())
143    self.assertTrue(*self._second.CheckAndReset())
144    self.assertTrue(*self._third.CheckAndReset())
145    # Should have the new content.
146    self.assertEqual('hello', self._first.Get('hello.html').Get())
147    self.assertEqual('hello', self._second.Get('hello.html').Get())
148    self.assertEqual('hello', self._third.Get('hello.html').Get())
149
150  def testDel(self):
151    # Cache it.
152    self.assertEqual('storage', self._store.Get('storage.html').Get())
153    self.assertTrue(*self._first.CheckAndReset(get_count=1))
154    # Delete it.
155    self._store.Del('storage.html')
156    self.assertTrue(*self._first.CheckAndReset(del_count=1))
157    self.assertTrue(*self._second.CheckAndReset(del_count=1))
158    self.assertTrue(*self._third.CheckAndReset(del_count=1))
159    # Not cached anymore.
160    self.assertEqual(None, self._store.Get('storage.html').Get())
161    self.assertTrue(*self._first.CheckAndReset(get_count=1))
162    self.assertTrue(*self._second.CheckAndReset(get_count=1))
163    self.assertTrue(*self._third.CheckAndReset(get_count=1))
164
165  def testStartEmpty(self):
166    store = CacheChainObjectStore((self._first, self._second, self._third),
167                                  start_empty=True)
168    # Won't query delegate file systems because it starts empty.
169    self.assertEqual(None, store.Get('storage.html').Get())
170    self.assertTrue(*self._first.CheckAndReset())
171    self.assertTrue(*self._second.CheckAndReset())
172    self.assertTrue(*self._third.CheckAndReset())
173    # Setting values will set on all delegates, though.
174    store.Set('storage.html', 'new content')
175    self.assertEqual('new content', store.Get('storage.html').Get())
176    self.assertTrue(*self._first.CheckAndReset(set_count=1))
177    self.assertTrue(*self._second.CheckAndReset(set_count=1))
178    self.assertTrue(*self._third.CheckAndReset(set_count=1))
179    self.assertEqual('new content', self._first.Get('storage.html').Get())
180    self.assertEqual('new content', self._second.Get('storage.html').Get())
181    self.assertEqual('new content', self._third.Get('storage.html').Get())
182
183if __name__ == '__main__':
184  unittest.main()
185