def test_batch_delete_if_exists_success(self): """ Tests that batch deletes with if_exists work, and throw proper LWTException when they are are not applied @since 3.1 @jira_ticket PYTHON-432 @expected_result Deletes will be preformed if they exist, otherwise throw LWTException @test_category object_mapper """ id = uuid4() m = TestIfExistsModel.create(self.conn, id=id, count=8, text="123456789") with Batch(self.conn) as b_conn: m.if_exists().delete(b_conn) q = TestIfExistsModel.objects(id=id) self.assertEqual(len(q.find_all(self.conn)), 0) with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: m = TestIfExistsModel(id=uuid4(), count=42) # Doesn't exist m.if_exists().delete(b_conn) self.assertEqual(assertion.exception.existing, {"[applied]": False})
def test_batch_insert_if_not_exists(self): """ tests that batch insertion with if_not_exists work as expected """ id = uuid4() with Batch(self.conn) as b_conn: TestIfNotExistsModel.if_not_exists().create( b_conn, id=id, count=8, text='123456789', ) with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: TestIfNotExistsModel.if_not_exists().create( b_conn, id=id, count=9, text='111111111111', ) self.assertEqual(assertion.exception.existing, { 'count': 8, 'id': id, 'text': '123456789', '[applied]': False, }) q = TestIfNotExistsModel.objects(id=id) self.assertEqual(len(q.find_all(self.conn)), 1) tm = q.first(self.conn) self.assertEqual(tm.count, 8) self.assertEqual(tm.text, '123456789')
def test_batch_update_if_exists_success(self): """ Tests that batch update with if_exists work as expected @since 3.1 @jira_ticket PYTHON-432 @expected_result @test_category object_mapper """ id = uuid4() m = TestIfExistsModel.create(self.conn, id=id, count=8, text="123456789") with Batch(self.conn) as b_conn: m.text = "111111111" m.if_exists().update(b_conn) with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: m = TestIfExistsModel(id=uuid4(), count=42) # Doesn't exist m.if_exists().update(b_conn) self.assertEqual(assertion.exception.existing, {"[applied]": False}) q = TestIfExistsModel.objects(id=id) self.assertEqual(len(q.find_all(self.conn)), 1) tm = q.first(self.conn) self.assertEqual(tm.count, 8) self.assertEqual(tm.text, "111111111")
def test_batch_insert_if_not_exists(self): """ tests that batch insertion with if_not_exists work as expected """ id = uuid4() with Batch(self.conn) as b_conn: TestIfNotExistsModel.if_not_exists().create(b_conn, id=id, count=8, text="123456789") with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: TestIfNotExistsModel.if_not_exists().create( b_conn, id=id, count=9, text="111111111111") self.assertEqual( assertion.exception.existing, { "count": 8, "id": id, "text": "123456789", "[applied]": False }, ) q = TestIfNotExistsModel.objects(id=id) self.assertEqual(len(q.find_all(self.conn)), 1) tm = q.first(self.conn) self.assertEqual(tm.count, 8) self.assertEqual(tm.text, "123456789")
def test_insert_success_case(self): b_conn = Batch(self.conn) TestMultiKeyModel.create(b_conn, partition=self.pkey, cluster=2, count=3, text="4") with self.assertRaises(TestMultiKeyModel.DoesNotExist): TestMultiKeyModel.get(self.conn, partition=self.pkey, cluster=2) b_conn.execute_batch() TestMultiKeyModel.get(self.conn, partition=self.pkey, cluster=2)
def test_batch_delete_mixed(self): """ Tests that batch deletes with multiple queries and throw proper LWTException when they are are not all applicable @since 3.1 @jira_ticket PYTHON-432 @expected_result If one delete clause doesn't exist all should fail. @test_category object_mapper """ m = TestIfExistsModel2.create(self.conn, id=3, count=8, text="123456789") with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: m.if_exists().delete(b_conn) # Does exist n = TestIfExistsModel2(id=3, count=42, text="1111111") # Doesn't exist n.if_exists().delete(b_conn) self.assertEqual(assertion.exception.existing.get("[applied]"), False) q = TestIfExistsModel2.objects(id=3, count=8) self.assertEqual(len(q.find_all(self.conn)), 1)
def test_batch_mixed_update_if_exists_success(self): """ Tests that batch update with with one bad query will still fail with LWTException @since 3.1 @jira_ticket PYTHON-432 @expected_result @test_category object_mapper """ m = TestIfExistsModel2.create(self.conn, id=1, count=8, text="123456789") with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: m.text = "111111112" m.if_exists().update(b_conn) # Does exist n = TestIfExistsModel2(id=1, count=10, text="Failure") # Doesn't exist n.if_exists().update(b_conn) self.assertEqual(assertion.exception.existing.get("[applied]"), False)
def test_batch_if_not_exists(self): """ ensure 'IF NOT EXISTS' exists in statement when in batch """ with mock.patch.object(self.conn.session, "execute") as m: with Batch(self.conn) as b_conn: TestIfNotExistsModel.if_not_exists().create(b_conn, count=8) self.assertIn("IF NOT EXISTS", m.call_args[0][0].query_string)
def test_update_success_case(self): inst = TestMultiKeyModel.create( self.conn, partition=self.pkey, cluster=2, count=3, text='4', ) with Batch(self.conn) as b_conn: inst.count = 4 inst.save(b_conn) inst2 = TestMultiKeyModel.get( self.conn, partition=self.pkey, cluster=2, ) self.assertEqual(inst2.count, 3) inst3 = TestMultiKeyModel.get( self.conn, partition=self.pkey, cluster=2, ) self.assertEqual(inst3.count, 4)
def test_batch_consistency(self): with mock.patch.object(self.conn.session, 'execute') as m: with Batch(self.conn, consistency=CL.ALL) as b_conn: TestConsistencyModel.create(b_conn, text="monkey") args = m.call_args self.assertEqual(CL.ALL, args[0][0].consistency_level) with mock.patch.object(self.conn.session, 'execute') as m: with Batch(self.conn) as b_conn: TestConsistencyModel.create(b_conn, text="monkey") args = m.call_args self.assertNotEqual(CL.ALL, args[0][0].consistency_level)
def test_batch_update_conditional(self): t = TestConditionalModel.create(self.conn, text="something", count=5) id = t.id with Batch(self.conn) as b_conn: t.iff(count=5).update(b_conn, text="something else") updated = TestConditionalModel.objects(id=id).first(self.conn) self.assertEqual(updated.text, "something else") with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: updated.iff(count=6).update(b_conn, text="and another thing") self.assertEqual(assertion.exception.existing, {"id": id, "count": 5, "[applied]": False}) updated = TestConditionalModel.objects(id=id).first(self.conn) self.assertEqual(updated.text, "something else")
def test_instance_update_in_batch(self): with mock.patch.object(self.conn.session, "execute") as m: with Batch(self.conn) as b_conn: self.instance.timestamp(timedelta(seconds=30)).update(b_conn, count=2) query = m.call_args[0][0].query_string "USING TIMESTAMP".should.be.within(query)
def test_batch(self): with mock.patch.object(self.conn.session, "execute") as m: with Batch(self.conn) as b_conn: TestTimestampModel.timestamp(timedelta(seconds=10)).create( b_conn, count=1) query = m.call_args[0][0].query_string self.assertIsNot(re.search(r"INSERT.*USING TIMESTAMP", query), None) self.assertIs(re.search(r"TIMESTAMP.*INSERT", query), None)
def test_batch_execute_no_timeout(self): with mock.patch.object(self.conn.session, 'execute') as mock_execute: with Batch(self.conn) as b_conn: BatchLogModel.create(b_conn, k=2, v=2) self.assertEqual( mock_execute.call_args[-1]['timeout'], TIMEOUT_NOT_SET, ) self.assertEqual(mock_execute.call_count, 1)
def test_batch(self): with mock.patch.object(self.conn.session, "execute") as m: with Batch(self.conn) as b_conn: TestTimestampModel.timestamp(timedelta(seconds=10)).create( b_conn, count=1) query = m.call_args[0][0].query_string query.should.match(r"INSERT.*USING TIMESTAMP") query.should_not.match(r"TIMESTAMP.*INSERT")
def test_context_manager(self): with Batch(self.conn) as b_conn: for i in range(5): TestMultiKeyModel.create(b_conn, partition=self.pkey, cluster=i, count=3, text="4") for i in range(5): with self.assertRaises(TestMultiKeyModel.DoesNotExist): TestMultiKeyModel.get(self.conn, partition=self.pkey, cluster=i) for i in range(5): TestMultiKeyModel.get(self.conn, partition=self.pkey, cluster=i)
def test_delete_success_case(self): inst = TestMultiKeyModel.create( self.conn, partition=self.pkey, cluster=2, count=3, text="4" ) with Batch(self.conn) as b_conn: inst.delete(b_conn) TestMultiKeyModel.get(self.conn, partition=self.pkey, cluster=2) with self.assertRaises(TestMultiKeyModel.DoesNotExist): TestMultiKeyModel.get(self.conn, partition=self.pkey, cluster=2)
def test_batch_update_conditional(self): t = TestConditionalModel.create(self.conn, text='something', count=5) id = t.id with Batch(self.conn) as b_conn: t.iff(count=5).update(b_conn, text='something else') updated = TestConditionalModel.objects(id=id).first(self.conn) self.assertEqual(updated.text, 'something else') with self.assertRaises(LWTException) as assertion: with Batch(self.conn) as b_conn: updated.iff(count=6).update( b_conn, text='and another thing', ) self.assertEqual(assertion.exception.existing, { 'id': id, 'count': 5, '[applied]': False, }) updated = TestConditionalModel.objects(id=id).first(self.conn) self.assertEqual(updated.text, 'something else')
def test_callbacks_properly_execute_callables_and_tuples(self): call_history = [] def my_callback(*args, **kwargs): call_history.append(args) # adding on init: batch = Batch(self.conn) batch.add_callback(my_callback) batch.add_callback(my_callback, 'more', 'args') batch.execute_batch() self.assertEqual(len(call_history), 2) self.assertEqual([(), ('more', 'args')], call_history)
def test_bulk_delete_success_case(self): for i in range(1): for j in range(5): TestMultiKeyModel.create( self.conn, partition=i, cluster=j, count=i * j, text="{0}:{1}".format(i, j) ) with Batch(self.conn) as b_conn: TestMultiKeyModel.filter(partition=0).delete(b_conn) self.assertEqual(TestMultiKeyModel.filter(partition=0).count(self.conn), 5) self.assertEqual(TestMultiKeyModel.filter(partition=0).count(self.conn), 0) # cleanup for m in TestMultiKeyModel.objects.iter(self.conn): m.delete(self.conn)
def test_API_managing_callbacks(self): # Callbacks can be added at init and after def my_callback(*args, **kwargs): pass # adding on init: batch = Batch(self.conn) batch.add_callback(my_callback) batch.add_callback(my_callback, 2, named_arg='value') batch.add_callback(my_callback, 1, 3) self.assertEqual(batch._callbacks, [(my_callback, (), {}), (my_callback, (2, ), { 'named_arg': 'value' }), (my_callback, (1, 3), {})])
def test_callbacks_work_multiple_times(self): """ Tests that multiple executions of execute on a batch statement logs a warning, and that we don't encounter an attribute error. @since 3.1 @jira_ticket PYTHON-445 @expected_result warning message is logged @test_category object_mapper """ call_history = [] def my_callback(*args, **kwargs): call_history.append(args) with warnings.catch_warnings(record=True) as w: batch = Batch(self.conn) batch.add_callback(my_callback) batch.execute_batch() batch.execute_batch() self.assertEqual(len(w), 1) self.assertRegexpMatches(str(w[0].message), r"^Batch.*multiple.*")
def test_batch_is_included(self): with mock.patch.object(self.conn.session, "execute") as m: with Batch(self.conn, timestamp=timedelta(seconds=30)) as b_conn: TestTimestampModel.create(b_conn, count=1) "USING TIMESTAMP".should.be.within(m.call_args[0][0].query_string)
def test_batch_execute_timeout(self): with mock.patch.object(self.conn.session, "execute") as mock_execute: with Batch(self.conn, timeout=1) as b_conn: BatchLogModel.create(b_conn, k=2, v=2) self.assertEqual(mock_execute.call_args[-1]["timeout"], 1) self.assertEqual(mock_execute.call_count, 1)
def test_callbacks_tied_to_execute(self): """Batch callbacks should NOT fire if batch is not executed in context manager mode""" call_history = [] def my_callback(*args, **kwargs): call_history.append(args) b_conn = Batch(self.conn) b_conn.add_callback(my_callback) b_conn.execute_batch() self.assertEqual(len(call_history), 1) class SomeError(Exception): pass with self.assertRaises(SomeError): with Batch(self.conn) as b_conn: b_conn.add_callback(my_callback) # this error bubbling up through context manager # should prevent callback runs (along with b.execute()) raise SomeError # still same call history. Nothing added self.assertEqual(len(call_history), 1) # but if execute ran, even with an error bubbling through # the callbacks also would have fired with self.assertRaises(SomeError): with Batch(self.conn, execute_on_exception=True) as b_conn: b_conn.add_callback(my_callback) raise SomeError # updated call history self.assertEqual(len(call_history), 2)
def test_empty_batch(self): b = Batch(self.conn) b.execute_batch()