def run( self ):
<EOL>params = self.parameters()<EOL>self._metadata = dict()<EOL>self._results = None<EOL>res = None<EOL>doneSetupTime = doneExperimentTime = doneTeardownTime = None<EOL>try:<EOL><INDENT>startTime = datetime.now()<EOL>self.setUp(params)<EOL>doneSetupTime = datetime.now()<EOL>res = self.do(params)<EOL>doneExperimentTime = datetime.now() <EOL>self.tearDown()<EOL>doneTeardownTime = datetime.now() <EOL>self._metadata[self.START_TIME] = startTime<EOL>self._metadata[self.END_TIME] = doneTeardownTime<EOL>self._metadata[self.ELAPSED_TIME] = (doneTeardownTime - startTime).total_seconds()<EOL>self._metadata[self.SETUP_TIME] = (doneSetupTime - startTime).total_seconds()<EOL>self._metadata[self.EXPERIMENT_TIME] = (doneExperimentTime - doneSetupTime).total_seconds()<EOL>self._metadata[self.TEARDOWN_TIME] = (doneTeardownTime - doneExperimentTime).total_seconds()<EOL>self._metadata[self.STATUS] = True<EOL><DEDENT>except Exception as e:<EOL><INDENT>print("<STR_LIT>".format(e = e))<EOL>tb = traceback.format_exc()<EOL>if (doneSetupTime is not None) and (doneExperimentTime is None):<EOL><INDENT>try:<EOL><INDENT>self.tearDown()<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>self._metadata[self.STATUS] = False<EOL>self._metadata[self.EXCEPTION] = e<EOL>self._metadata[self.TRACEBACK] = tb<EOL><DEDENT>self._results = res<EOL>return self.report(params,<EOL>self._metadata,<EOL>res)<EOL>
Run the experiment, using the parameters set using :meth:`set`.
        A "run" consists of calling :meth:`setUp`, :meth:`do`, and :meth:`tearDown`,
        followed by collecting and storing (and returning) the
        experiment's results. If running the experiment raises an
        exception, that will be returned in the metadata along with
        its traceback to help with experiment debugging.

        :returns: a :term:`results dict`