2167
2167
c1 = self.stack
2168
2168
c2 = self.get_stack(self)
2170
# We spawn a thread that will pause *during* the write
2170
# We spawn a thread that will pause *during* the config saving.
2171
2171
before_writing = threading.Event()
2172
2172
after_writing = threading.Event()
2173
2173
writing_done = threading.Event()
2199
2199
c2.set('one', 'c2')
2200
2200
self.assertEquals('c2', c2.get('one'))
2202
# FIXME: We should adapt the tests in TestLockableConfig about concurrent
2203
# writes. Since this requires a clearer rewrite, I'll just rely on using
2204
# the same code in LockableIniFileStore (copied from LockableConfig, but
2205
# trivial enough, the main difference is that we add @needs_write_lock on
2206
# save() instead of set_user_option() and remove_user_option()). The intent
2207
# is to ensure that we always get a valid content for the store even when
2208
# concurrent accesses occur, read/write, write/write. It may be worth
2209
# looking into removing the lock dir when it's not needed anymore and look
2210
# at possible fallouts for concurrent lockers -- vila 20110-04-06
2202
def test_read_while_writing(self):
2204
# We spawn a thread that will pause *during* the write
2205
ready_to_write = threading.Event()
2206
do_writing = threading.Event()
2207
writing_done = threading.Event()
2208
# We override the _save implementation so we know the store is locked
2209
c1_orig = c1.store._save
2211
ready_to_write.set()
2212
# The lock is held. We wait for the main thread to decide when to
2217
c1.store._save = c1_save
2220
t1 = threading.Thread(target=c1_set)
2221
# Collect the thread after the test
2222
self.addCleanup(t1.join)
2223
# Be ready to unblock the thread if the test goes wrong
2224
self.addCleanup(do_writing.set)
2226
# Ensure the thread is ready to write
2227
ready_to_write.wait()
2228
self.assertTrue(c1.store._lock.is_held)
2229
self.assertEquals('c1', c1.get('one'))
2230
# If we read during the write, we get the old value
2231
c2 = self.get_stack(self)
2232
self.assertEquals('1', c2.get('one'))
2233
# Let the writing occur and ensure it occurred
2236
# Now we get the updated value
2237
c3 = self.get_stack(self)
2238
self.assertEquals('c1', c3.get('one'))
2240
# FIXME: It may be worth looking into removing the lock dir when it's not
2241
# needed anymore and look at possible fallouts for concurrent lockers. This
2242
# will matter if/when we use config files outside of bazaar directories
2243
# (.bazaar or .bzr) -- vila 20110-04-11
2213
2246
class TestSectionMatcher(TestStore):