def run_all(args):
    """Runs test scenario in multiple threads."""
    if args.thread_count < 1 or args.thread_count > 256:
        raise Exception('Please use between 1 and 256 threads.')

    test_type = ['content', 'user_state',
                 'user_state_summary'].index(args.test_type)

    start_time = time.time()
    logging.info('Started testing: %s', args.base_url)
    logging.info('Running tests for: %s' % args.test_type)
    logging.info('thread_count: %s', args.thread_count)
    logging.info('iteration_count: %s', args.iteration_count)

    if test_type == XBlockLoadTest.TEST_TYPE_USER_STATE_SUMMARY:
        block_data = XBlockLoadTest(args.base_url).get_block_data()
        logging.info('testing block usage_id: %s' % block_data['usage_id'])
        start_user_state_summary = int(block_data['user_state_summary'])
        logging.info('start user_state_summary value: %s' %
                     start_user_state_summary)

    try:
        for iteration_index in xrange(0, args.iteration_count):
            logging.info('Started iteration: %s', iteration_index)
            tasks = []
            WebSession.PROGRESS_BATCH = args.thread_count
            for index in xrange(0, args.thread_count):
                uid = '%s-%s' % (iteration_index, index)
                test = XBlockLoadTest(args.base_url,
                                      uid=uid,
                                      test_type=test_type,
                                      startup_interval=args.startup_interval)
                task = TaskThread(test.run,
                                  name='PeerReviewLoadTest-%s' % index)
                tasks.append(task)
            try:
                TaskThread.execute_task_list(tasks)
            except Exception as e:
                logging.info('Failed iteration: %s', iteration_index)
                raise e
    finally:
        WebSession.log_progress(force=True)

    if test_type == XBlockLoadTest.TEST_TYPE_USER_STATE_SUMMARY:
        block_data = XBlockLoadTest(args.base_url).get_block_data()
        final_user_state_summary = int(block_data['user_state_summary'])
        logging.info('expected increment count: %s' %
                     (args.iteration_count * args.thread_count))
        logging.info('actual increment count: %s' %
                     (final_user_state_summary - start_user_state_summary))
        logging.info('final user_state_summary value: %s' %
                     final_user_state_summary)

    logging.info('Done! Duration (s): %s', time.time() - start_time)
def run_all(args):
    """Runs test scenario in multiple threads."""
    if args.thread_count < 1 or args.thread_count > 256:
        raise Exception('Please use between 1 and 256 threads.')

    test_type = ['content', 'user_state', 'user_state_summary'].index(args.test_type)

    start_time = time.time()
    logging.info('Started testing: %s', args.base_url)
    logging.info('Running tests for: %s' % args.test_type)
    logging.info('thread_count: %s', args.thread_count)
    logging.info('iteration_count: %s', args.iteration_count)

    if test_type == XBlockLoadTest.TEST_TYPE_USER_STATE_SUMMARY:
        block_data = XBlockLoadTest(args.base_url).get_block_data()
        logging.info('testing block usage_id: %s' % block_data['usage_id'])
        start_user_state_summary = int(block_data['user_state_summary'])
        logging.info('start user_state_summary value: %s' % start_user_state_summary)

    try:
        for iteration_index in xrange(0, args.iteration_count):
            logging.info('Started iteration: %s', iteration_index)
            tasks = []
            WebSession.PROGRESS_BATCH = args.thread_count
            for index in xrange(0, args.thread_count):
                uid = '%s-%s' % (iteration_index, index)
                test = XBlockLoadTest(
                    args.base_url, uid=uid, test_type=test_type,
                    startup_interval=args.startup_interval)
                task = TaskThread(
                    test.run, name='PeerReviewLoadTest-%s' % index)
                tasks.append(task)
            try:
                TaskThread.execute_task_list(tasks)
            except Exception as e:
                logging.info('Failed iteration: %s', iteration_index)
                raise e
    finally:
        WebSession.log_progress(force=True)

    if test_type == XBlockLoadTest.TEST_TYPE_USER_STATE_SUMMARY:
        block_data = XBlockLoadTest(args.base_url).get_block_data()
        final_user_state_summary = int(block_data['user_state_summary'])
        logging.info('expected increment count: %s' % (args.iteration_count * args.thread_count))
        logging.info('actual increment count: %s' % (final_user_state_summary - start_user_state_summary))
        logging.info('final user_state_summary value: %s' % final_user_state_summary)

    logging.info('Done! Duration (s): %s', time.time() - start_time)
    def __init__(self,
                 base_url,
                 uid='',
                 test_type=TEST_TYPE_NONE,
                 startup_interval=0):
        self.uid = uid
        self.base_url = base_url
        self.test_type = test_type
        self.startup_interval = startup_interval

        # this is an impersonation identity for the actor thread
        self.email = '*****@*****.**' % self.uid
        self.name = 'Load Test Bot #%s' % self.uid

        impersonate_header = {
            'email': self.email,
            'user_id': u'impersonation-%s' % self.uid
        }
        self.session = WebSession(
            uid=uid,
            common_headers={'Gcb-Impersonate': json.dumps(impersonate_header)})
        self.html_parser = html5lib.HTMLParser(
            tree=html5lib.treebuilders.getTreeBuilder('etree', cElementTree),
            namespaceHTMLElements=False)
    def __init__(self, base_url, uid='', test_type=TEST_TYPE_NONE, startup_interval=0):
        self.uid = uid
        self.base_url = base_url
        self.test_type = test_type
        self.startup_interval = startup_interval

        # this is an impersonation identity for the actor thread
        self.email = '*****@*****.**' % self.uid
        self.name = 'Load Test Bot #%s' % self.uid

        impersonate_header = {
            'email': self.email, 'user_id': u'impersonation-%s' % self.uid}
        self.session = WebSession(
            uid=uid,
            common_headers={'Gcb-Impersonate': json.dumps(impersonate_header)})
        self.html_parser = html5lib.HTMLParser(
            tree=html5lib.treebuilders.getTreeBuilder('etree', cElementTree),
            namespaceHTMLElements=False)
class XBlockLoadTest(object):
    TEST_TYPE_NONE = -1
    TEST_TYPE_CONTENT = 0
    TEST_TYPE_USER_STATE = 1
    TEST_TYPE_USER_STATE_SUMMARY = 2

    def __init__(self, base_url, uid='', test_type=TEST_TYPE_NONE, startup_interval=0):
        self.uid = uid
        self.base_url = base_url
        self.test_type = test_type
        self.startup_interval = startup_interval

        # this is an impersonation identity for the actor thread
        self.email = '*****@*****.**' % self.uid
        self.name = 'Load Test Bot #%s' % self.uid

        impersonate_header = {
            'email': self.email, 'user_id': u'impersonation-%s' % self.uid}
        self.session = WebSession(
            uid=uid,
            common_headers={'Gcb-Impersonate': json.dumps(impersonate_header)})
        self.html_parser = html5lib.HTMLParser(
            tree=html5lib.treebuilders.getTreeBuilder('etree', cElementTree),
            namespaceHTMLElements=False)

    def run(self):
        time.sleep(self.startup_interval * random.random())
        block_data = self.get_block_data()
        self.usage_id = block_data['usage_id']
        self.xsrf_token = block_data['xsrf_token']

        if self.test_type == self.TEST_TYPE_CONTENT:
            self.read_content_and_settintgs()
        elif self.test_type == self.TEST_TYPE_USER_STATE:
            self.set_and_confirm_user_state()
        elif self.test_type == self.TEST_TYPE_USER_STATE_SUMMARY:
            self.increment_user_state_summary()

    def get_block_data(self):
        """Get the test_xblock in a lesson page and read its displayed data."""

        def extract_field(node, field_class):
            return node.find('.//div[@class="%s"]' % field_class).text

        body = self.session.get('%s/unit' % self.base_url)
        root = self.html_parser.parse(body)
        xblock_root = root.find('.//div[@class="xblock"]')
        block_data = {}
        block_data['xsrf_token'] = xblock_root.attrib['data-xsrf-token']
        for item in (
                'usage_id', 'content', 'settings', 'user_state',
                'user_state_summary'):
            block_data[item] = extract_field(xblock_root, item)
        return block_data

    def post_to_handler(
            self, xsrf_token=None, usage_id=None, handler=None, post_dict=None):
        url = '%s/modules/xblock_module/handler?%s' % (
            self.base_url, urllib.urlencode({
                'handler': handler,
                'usage': usage_id,
                'xsrf_token': xsrf_token}))
        return self.session.post(url, post_dict)

    def set_user_state(self, value):
        response = self.post_to_handler(
            xsrf_token=self.xsrf_token,
            usage_id=self.usage_id,
            handler='set_user_state',
            post_dict={'value': value})
        response_dict = json.loads(response)
        assert response_dict == {"status": 'ok'}

    def confirm_field(self, name, value):
        block_data = self.get_block_data()
        assert block_data[name] == value

    def set_and_confirm_user_state(self):
        value = uuid.uuid4().hex
        self.set_user_state(value)
        self.confirm_field('user_state', value)

    def increment_user_state_summary(self):
        response = self.post_to_handler(
            xsrf_token=self.xsrf_token,
            usage_id=self.usage_id,
            handler='increment_user_state_summary',
            post_dict={})
        response_dict = json.loads(response)
        assert response_dict['status'] == 'ok'

    def read_content_and_settintgs(self):
        block_data = self.get_block_data()
        assert block_data['content'] == 'content_value'
        assert block_data['settings'] == 'settings_value'
class XBlockLoadTest(object):
    TEST_TYPE_NONE = -1
    TEST_TYPE_CONTENT = 0
    TEST_TYPE_USER_STATE = 1
    TEST_TYPE_USER_STATE_SUMMARY = 2

    def __init__(self,
                 base_url,
                 uid='',
                 test_type=TEST_TYPE_NONE,
                 startup_interval=0):
        self.uid = uid
        self.base_url = base_url
        self.test_type = test_type
        self.startup_interval = startup_interval

        # this is an impersonation identity for the actor thread
        self.email = '*****@*****.**' % self.uid
        self.name = 'Load Test Bot #%s' % self.uid

        impersonate_header = {
            'email': self.email,
            'user_id': u'impersonation-%s' % self.uid
        }
        self.session = WebSession(
            uid=uid,
            common_headers={'Gcb-Impersonate': json.dumps(impersonate_header)})
        self.html_parser = html5lib.HTMLParser(
            tree=html5lib.treebuilders.getTreeBuilder('etree', cElementTree),
            namespaceHTMLElements=False)

    def run(self):
        time.sleep(self.startup_interval * random.random())
        block_data = self.get_block_data()
        self.usage_id = block_data['usage_id']
        self.xsrf_token = block_data['xsrf_token']

        if self.test_type == self.TEST_TYPE_CONTENT:
            self.read_content_and_settintgs()
        elif self.test_type == self.TEST_TYPE_USER_STATE:
            self.set_and_confirm_user_state()
        elif self.test_type == self.TEST_TYPE_USER_STATE_SUMMARY:
            self.increment_user_state_summary()

    def get_block_data(self):
        """Get the test_xblock in a lesson page and read its displayed data."""
        def extract_field(node, field_class):
            return node.find('.//div[@class="%s"]' % field_class).text

        body = self.session.get('%s/unit' % self.base_url)
        root = self.html_parser.parse(body)
        xblock_root = root.find('.//div[@class="xblock"]')
        block_data = {}
        block_data['xsrf_token'] = xblock_root.attrib['data-xsrf-token']
        for item in ('usage_id', 'content', 'settings', 'user_state',
                     'user_state_summary'):
            block_data[item] = extract_field(xblock_root, item)
        return block_data

    def post_to_handler(self,
                        xsrf_token=None,
                        usage_id=None,
                        handler=None,
                        post_dict=None):
        url = '%s/modules/xblock_module/handler?%s' % (
            self.base_url,
            urllib.urlencode({
                'handler': handler,
                'usage': usage_id,
                'xsrf_token': xsrf_token
            }))
        return self.session.post(url, post_dict)

    def set_user_state(self, value):
        response = self.post_to_handler(xsrf_token=self.xsrf_token,
                                        usage_id=self.usage_id,
                                        handler='set_user_state',
                                        post_dict={'value': value})
        response_dict = json.loads(response)
        assert response_dict == {"status": 'ok'}

    def confirm_field(self, name, value):
        block_data = self.get_block_data()
        assert block_data[name] == value

    def set_and_confirm_user_state(self):
        value = uuid.uuid4().hex
        self.set_user_state(value)
        self.confirm_field('user_state', value)

    def increment_user_state_summary(self):
        response = self.post_to_handler(xsrf_token=self.xsrf_token,
                                        usage_id=self.usage_id,
                                        handler='increment_user_state_summary',
                                        post_dict={})
        response_dict = json.loads(response)
        assert response_dict['status'] == 'ok'

    def read_content_and_settintgs(self):
        block_data = self.get_block_data()
        assert block_data['content'] == 'content_value'
        assert block_data['settings'] == 'settings_value'