def test_new_instance_should_be_added_in_collection(self): self.assertEqual(set(Bike.collection()), set()) bike = Bike() self.assertEqual(set(Bike.collection()), set()) bike1 = Bike(name="trotinette") self.assertEqual(set(Bike.collection()), set([bike1._pk])) bike2 = Bike(name="tommasini") self.assertEqual(set(Bike.collection()), set([bike1._pk, bike2._pk]))
def test_end_update_local_bike(result): """ This function will be used as a post_callback when setting a new name of the local bike object. It tests than, as we updated a lockable field, we only have the local bike in redis as for now, the one in the thread should have waited for the local save to be finished. """ self.assertEqual(len(Bike.collection()), 1) return result
def test_two_updates_of_same_indexable_field_should_be_done_one_after_the_other(self): """ Will test that when a lockable field is updated, an external update on the same field (in this instance or another instance) wait for the first update to be finished. """ class BikeLockThread(LockTest.LockModelThread): methods = ['test_create_new_bike'] def test_create_new_bike(self): """ Create a new instance of the thread's model """ # test that we have a lock self.test_lock('name') # create the instance (does nothing in redis) bike = self.model() def test_before_update(name, *args, **kwargs): """ This function will be used as a pre_callback when setting a new name of the thread's bike object. It will test that we already have a bike in the collection. """ self.test.assertEqual(len(self.model.collection()), 1) return (args, kwargs) # set a name (will wait for lock to be released) bike.name.set('velocipede', _pre_callback=test_before_update) # start a new thread to work on the model Bike thread = BikeLockThread(self, Bike) thread.start() def ping_thread(name, *args, **kwargs): """ This function will be used as a pre_callback when setting a new name of the local bike object. It send a ping telling the thread that it must create a new bike, with a name. As the name of a bike is indexable, a Lock will occurs, so the new bike in the thread should only be created after the name of the local bike is really saved and indexed. """ time.sleep(0.1) # wait for thread to be ready LockTest.ping('test_create_new_bike') time.sleep(0.1) # to be sure the we can test lock in the thread return (args, kwargs) def test_end_update_local_bike(result): """ This function will be used as a post_callback when setting a new name of the local bike object. It tests than, as we updated a lockable field, we only have the local bike in redis as for now, the one in the thread should have waited for the local save to be finished. """ self.assertEqual(len(Bike.collection()), 1) return result # create a new bike (does nothing in redis) bike = Bike() # set a name to the bike and use pre/post callbacks to: # - ping the thread when the lock will be set # - test the thread did nothing just before the release of the lock bike.name.set('rosalie', _pre_callback=ping_thread, _post_callback=test_end_update_local_bike) # wait before thread exit if thread.is_alive(): LockTest.wait_for_ping('thread_end', None) # now we should have the both bikes fully created self.assertEqual(len(Bike.collection()), 2)