Execute the test batch

def execute(self):
        """Execute the test batch
        """

        try:
            # START SELENIUM GRID
            if BROME_CONFIG['grid_runner']['start_selenium_server']:
                self.start_selenium_server()

            # Get all the browsers id
            self.browsers_id = BROME_CONFIG['runner_args']['remote_runner'].split(',')  # noqa

            # Start all the instances
            instance_threads = []
            for i, browser_id in enumerate(self.browsers_id):
                browser_config = BrowserConfig(
                    runner=self,
                    browser_id=browser_id,
                    browsers_config=BROME_CONFIG['browsers_config']
                )

                self.browser_configs[browser_id] = browser_config

                # EC2
                if browser_config.location == 'ec2':

                    max_number_of_instance = browser_config.get(
                        'max_number_of_instance'
                    )
                    nb_browser_by_instance = browser_config.get(
                        'nb_browser_by_instance'
                    )

                    if len(self.tests) < \
                            max_number_of_instance * \
                            nb_browser_by_instance:

                        nb_instance_to_launch = int(
                            math.ceil(
                                float(len(self.tests))/nb_browser_by_instance
                            )
                        )

                    else:
                        nb_instance_to_launch = max_number_of_instance

                    for j in range(nb_instance_to_launch):
                        _ec2_instance = ec2_instance.EC2Instance(
                            runner=self,
                            browser_config=browser_config,
                            index=j
                        )

                        ec2_instance_thread = InstanceThread(_ec2_instance)
                        ec2_instance_thread.start()

                        instance_threads.append(ec2_instance_thread)

                # VIRTUALBOX
                elif browser_config.location == 'virtualbox':
                    vbox_instance = virtualbox_instance.VirtualboxInstance(
                        runner=self,
                        browser_config=browser_config,
                        index=i,
                    )

                    vbox_instance_thread = InstanceThread(vbox_instance)
                    vbox_instance_thread.start()

                    instance_threads.append(vbox_instance_thread)

                # SAUCELABS
                elif browser_config.location == 'saucelabs':

                    if not self.instances.get(browser_id):
                        self.instances[browser_id] = []

                    self.instances[browser_id].append(
                        saucelabs_instance.SauceLabsInstance()
                    )

                # BROWSERSTACK
                elif browser_config.location == 'browserstack':

                    if not self.instances.get(browser_id):
                        self.instances[browser_id] = []

                    self.instances[browser_id].append(
                        browserstack_instance.BrowserstackInstance()
                    )

                # LOCALHOST
                elif browser_config.location == 'localhost':

                    max_number_of_instance = browser_config.get(
                        'max_number_of_instance', 1
                    )

                    if len(self.tests) < max_number_of_instance:
                        nb_instance_to_launch = len(self.tests)
                    else:
                        nb_instance_to_launch = max_number_of_instance

                    for i in range(0, nb_instance_to_launch):
                        if not self.instances.get(browser_id):
                            self.instances[browser_id] = []

                        self.instances[browser_id].append(
                            localhost_instance.LocalhostInstance(
                                self,
                                browser_config,
                                test_name=i
                            )
                        )

            # MILESTONE
            if len(instance_threads):
                with DbSessionContext(BROME_CONFIG['database']['mongo_database_name']) as session:  # noqa
                    test_batch = session.query(Testbatch)\
                        .filter(Testbatch.mongo_id == self.test_batch_id).one()
                    test_batch.add_milestone(
                        'NbInstanceToSetup',
                        {'nb': len(instance_threads)}
                    )
                    session.save(test_batch, safe=True)

            for t in instance_threads:
                t.join()

            self.info_log("The test batch is now ready!")

            # MILESTONE
            if len(instance_threads):
                with DbSessionContext(BROME_CONFIG['database']['mongo_database_name']) as session:  # noqa
                    test_batch = session.query(Testbatch)\
                        .filter(Testbatch.mongo_id == self.test_batch_id).one()
                    test_batch.add_milestone('InstanceSetupCompleted')
                    session.save(test_batch, safe=True)

            try:
                self.run()
            except:
                tb = traceback.format_exc()
                self.error_log(
                    "Exception in run of the grid runner: %s"
                    % str(tb)
                )
                raise

            finally:
                try:
                    self.tear_down_instances()

                    # MILESTONE
                    with DbSessionContext(BROME_CONFIG['database']['mongo_database_name']) as session:  # noqa
                        test_batch = session.query(Testbatch)\
                            .filter(Testbatch.mongo_id == self.test_batch_id)\
                            .one()
                        test_batch.add_milestone('InstanceTearDownCompleted')
                        session.save(test_batch, safe=True)

                    # Kill selenium server
                    if BROME_CONFIG['grid_runner']['kill_selenium_server']:  # noqa
                        if self.selenium_pid:
                            self.kill_pid(self.selenium_pid)

                            # MILESTONE
                            with DbSessionContext(BROME_CONFIG['database']['mongo_database_name']) as session:  # noqa
                                test_batch = session.query(Testbatch)\
                                    .filter(Testbatch.mongo_id == self.test_batch_id).one()  # noqa
                                test_batch.add_milestone(
                                    'SeleniumServerKilled'
                                )
                                session.save(test_batch, safe=True)

                    # Kill xvfb process
                    for xvfb_pid in self.xvfb_pids:
                        self.kill_pid(xvfb_pid)

                except:
                    tb = traceback.format_exc()
                    self.error_log("Exception in finally block of the grid runner: %s" % str(tb))  # noqa
        except:
            self.set_ending_timestamp()
            tb = traceback.format_exc()
            self.error_log("Exception in finally block of the grid runner: %s" % str(tb))  # noqa
            raise

        self.info_log("The test batch is finished.")