def test_update_field_maxretries(self, m_save): """ Test that conflict retries work for updating a single field. """ # Create a doc doc = Document(self.db, 'julia006') doc['name'] = 'julia' doc['age'] = 6 doc.create() self.assertTrue(doc['_rev'].startswith('1-')) self.assertEqual(doc['age'], 6) # Mock conflicts when saving updates m_save.side_effect = requests.HTTPError( response=mock.Mock(status_code=409, reason='conflict')) # Tests that failing on retry eventually throws with self.assertRaises(requests.HTTPError) as cm: doc.update_field(doc.field_set, 'age', 7, max_tries=2) # There is an off-by-one error for "max_tries" # It really means max_retries i.e. 1 attempt # followed by a max of 2 retries self.assertEqual(m_save.call_count, 3) self.assertEqual(cm.exception.response.status_code, 409) self.assertEqual(cm.exception.response.reason, 'conflict') # Fetch again before asserting, otherwise we assert against # the locally updated age field doc.fetch() self.assertFalse(doc['_rev'].startswith('2-')) self.assertNotEqual(doc['age'], 7)
def test_update_field_success_on_retry(self): """ Test that conflict retries work for updating a single field. """ # Create a doc doc = Document(self.db, 'julia006') doc['name'] = 'julia' doc['age'] = 6 doc.create() self.assertTrue(doc['_rev'].startswith('1-')) self.assertEqual(doc['age'], 6) # Mock when saving the document # 1st call throw a 409 # 2nd call delegate to the real doc.save() with mock.patch('cloudant.document.Document.save', side_effect=[ requests.HTTPError(response=mock.Mock( status_code=409, reason='conflict')), doc.save() ]) as m_save: # A list of side effects containing only 1 element doc.update_field(doc.field_set, 'age', 7, max_tries=1) # Two calls to save, one with a 409 and one that succeeds self.assertEqual(m_save.call_count, 2) # Check that the _rev and age field were updated self.assertTrue(doc['_rev'].startswith('2-')) self.assertEqual(doc['age'], 7)
def update_schedule_status(self, doc_id, to_value): database = CloudantDatabase( self.client, self.app.config['CLOUDANT_NOSQL_DB_SCHEDULE_DATABASE_NAME']) remote_doc = Document(database, doc_id) remote_doc.update_field(action=remote_doc.field_set, field='status', value=to_value)
def update_user_info(self, doc_id, update_field, to_value): database = CloudantDatabase( self.client, self.app.config['CLOUDANT_NOSQL_DB_USER_DATABASE_NAME']) remote_doc = Document(database, doc_id) remote_doc.update_field(action=remote_doc.field_set, field=update_field, value=to_value)
def test_document_update_field(self): """ _test_document_update_field_ Tests for the field update functions. """ # Setup a routine for testing conflict handing. errors = {'conflicts': 0} def raise_conflict(conflicts=3): if errors['conflicts'] < conflicts: errors['conflicts'] += 1 err = requests.HTTPError() err.response = mock.Mock() err.response.status_code = 409 raise err # Mock our our doc doc = Document(self.database, "HOWARD") mock_put_resp = mock.Mock() mock_put_resp.side_effect = mock.Mock() mock_put_resp.status_code = 200 mock_put_resp.raise_for_status = raise_conflict mock_put_resp.json.side_effect = lambda: {'id': "ID", "rev": "updated"} self.mock_session.put.return_value = mock_put_resp mock_get_resp = mock.Mock() mock_get_resp.status_code = 200 mock_get_resp.json.side_effect = lambda: {"foo": "baz"} self.mock_session.get.return_value = mock_get_resp # Verify that our mock doc has the old value doc.fetch() self.assertEqual(doc["foo"], "baz") # And that we replace it with an updated value doc.update_field(doc.field_set, "foo", "bar") self.assertEqual(doc["foo"], "bar") # And verify that we called mock_session.put self.assertTrue(self.mock_session.put.called) # Try again, verifing that excessive conflicts get raised errors['conflicts'] = 0 mock_put_resp.raise_for_status = lambda: raise_conflict(conflicts=11) self.assertRaises( requests.HTTPError, doc.update_field, doc.field_set, "foo", "bar" )
def update(self, selector, field, new_value): q_res = self.c_db.get_query_result(selector) for document in q_res: doc_id = document['_id'] doc = Document(self.db, doc_id) doc.update_field(action=doc.field_set, field=field, value=new_value) doc.update_field(action=doc.field_set, field='timestamp', value=_timestamp())
def test_update_field(self): """ Test that we can update a single field remotely using the update_field method. """ doc = Document(self.db, 'julia006') doc['name'] = 'julia' doc['age'] = 6 doc['pets'] = ['cat', 'dog'] doc.create() self.assertTrue(doc['_rev'].startswith('1-')) self.assertEqual(doc['pets'], ['cat', 'dog']) doc.update_field(doc.list_field_append, 'pets', 'fish') self.assertTrue(doc['_rev'].startswith('2-')) self.assertEqual(doc['pets'], ['cat', 'dog', 'fish'])