'Test to validate callback api
@since 3.9.0
@jira_ticket PYTHON-733
@expected_result callbacks shouldn\'t be called twice per message
and the fetch_size should be handled in a transparent way to the user
@test_category queries'

def test_paging_callbacks(self):

    statements_and_params = zip(cycle(['INSERT    INTO    test3rf.test    (k,    v)    VALUES    (%s,    0)']), [(i,) for i in range(100)])
    execute_concurrent(self.session, list(statements_and_params))
    prepared = self.session.prepare('SELECT    *    FROM    test3rf.test')
    for fetch_size in (2, 3, 7, 10, 99, 100, 101, 10000):
        self.session.default_fetch_size = fetch_size
        future = self.session.execute_async('SELECT    *    FROM    test3rf.test', timeout=20)
        event = Event()
        counter = count()
        number_of_calls = count()
        def handle_page(rows, future, counter, number_of_calls):
            next(number_of_calls)
            for row in rows:
                next(counter)
            if future.has_more_pages:
                future.start_fetching_next_page()
            else:
                event.set()
        def handle_error(err):
            event.set()
            self.fail(err)
        future.add_callbacks(callback=handle_page, callback_args=(future, counter, number_of_calls), errback=handle_error)
        event.wait()
        self.assertEqual(next(number_of_calls), ((100 // fetch_size) + 1))
        self.assertEqual(next(counter), 100)
        future = self.session.execute_async(SimpleStatement('SELECT    *    FROM    test3rf.test'), timeout=20)
        event.clear()
        counter = count()
        number_of_calls = count()
        future.add_callbacks(callback=handle_page, callback_args=(future, counter, number_of_calls), errback=handle_error)
        event.wait()
        self.assertEqual(next(number_of_calls), ((100 // fetch_size) + 1))
        self.assertEqual(next(counter), 100)
        future = self.session.execute_async(prepared, timeout=20)
        event.clear()
        counter = count()
        number_of_calls = count()
        future.add_callbacks(callback=handle_page, callback_args=(future, counter, number_of_calls), errback=handle_error)
        event.wait()
        self.assertEqual(next(number_of_calls), ((100 // fetch_size) + 1))
        self.assertEqual(next(counter), 100)
