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