def main(self):
    'Main function. This should not be overridden by the subclass test scripts.'
    parser = optparse.OptionParser(usage='%prog [options]')
    parser.add_option('--nocleanup', dest='nocleanup', default=False, action='store_true', help='Leave t_notesds and test.* datadir on exit or error')
    parser.add_option('--noshutdown', dest='noshutdown', default=False, action='store_true', help="Don't stop t_notesds after the test execution")
    parser.add_option('--srcdir', dest='srcdir', default=os.path.normpath((os.path.dirname(os.path.realpath(__file__)) + '/../../../src')), help='Source directory containing t_notesd/t_notes-cli (default: %default)')
    parser.add_option('--cachedir', dest='cachedir', default=os.path.normpath((os.path.dirname(os.path.realpath(__file__)) + '/../../cache')), help='Directory for caching pregenerated datadirs')
    parser.add_option('--tmpdir', dest='tmpdir', help='Root directory for datadirs')
    parser.add_option('-l', '--loglevel', dest='loglevel', default='INFO', help='log events at this level and higher to the console. Can be set to DEBUG, INFO, WARNING, ERROR or CRITICAL. Passing --loglevel DEBUG will output all logs to console. Note that logs at all levels are always written to the test_framework.log file in the temporary test directory.')
    parser.add_option('--tracerpc', dest='trace_rpc', default=False, action='store_true', help='Print out all RPC calls as they are made')
    parser.add_option('--portseed', dest='port_seed', default=os.getpid(), type='int', help='The seed to use for assigning port numbers (default: current process id)')
    parser.add_option('--coveragedir', dest='coveragedir', help='Write tested RPC commands into this directory')
    parser.add_option('--configfile', dest='configfile', help='Location of the test framework config file')
    parser.add_option('--legacywallet', dest='legacywallet', default=False, action='store_true', help='create pre-HD wallets only')
    parser.add_option('--tiertwo', dest='tiertwo', default=False, action='store_true', help='run tier two tests only')
    parser.add_option('--sapling', dest='sapling', default=False, action='store_true', help='run tier two tests only')
    parser.add_option('--pdbonfailure', dest='pdbonfailure', default=False, action='store_true', help='Attach a python debugger if test fails')
    parser.add_option('--usecli', dest='usecli', default=False, action='store_true', help='use t_notes-cli instead of RPC for all commands')
    self.add_options(parser)
    (self.options, self.args) = parser.parse_args()
    PortSeed.n = self.options.port_seed
    os.environ['PATH'] = ((((self.options.srcdir + ':') + self.options.srcdir) + '/qt:') + os.environ['PATH'])
    check_json_precision()
    self.options.cachedir = os.path.abspath(self.options.cachedir)
    if self.options.tmpdir:
        self.options.tmpdir = os.path.abspath(self.options.tmpdir)
        os.makedirs(self.options.tmpdir, exist_ok=False)
    else:
        self.options.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX)
    self._start_logging()
    success = TestStatus.FAILED
    try:
        if (self.options.usecli and (not self.supports_cli)):
            raise SkipTest('--usecli specified but test does not support using CLI')
        self.setup_chain()
        self.setup_network()
        time.sleep(5)
        self.run_test()
        success = TestStatus.PASSED
    except JSONRPCException as e:
        self.log.exception('JSONRPC error')
    except SkipTest as e:
        self.log.warning(('Test Skipped: %s' % e.message))
        success = TestStatus.SKIPPED
    except AssertionError as e:
        self.log.exception('Assertion failed')
    except KeyError as e:
        self.log.exception('Key error')
    except Exception as e:
        self.log.exception('Unexpected exception caught during testing')
    except KeyboardInterrupt as e:
        self.log.warning('Exiting after keyboard interrupt')
    if ((success == TestStatus.FAILED) and self.options.pdbonfailure):
        print('Testcase failed. Attaching python debugger. Enter ? for help')
        pdb.set_trace()
    if (not self.options.noshutdown):
        self.log.info('Stopping nodes')
        if self.nodes:
            self.stop_nodes()
    else:
        for node in self.nodes:
            node.cleanup_on_exit = False
        self.log.info('Note: t_notesds were not stopped and may still be running')
    if ((not self.options.nocleanup) and (not self.options.noshutdown) and (success != TestStatus.FAILED)):
        self.log.info('Cleaning up')
        shutil.rmtree(self.options.tmpdir)
    else:
        self.log.warning(('Not cleaning up dir %s' % self.options.tmpdir))
    if (success == TestStatus.PASSED):
        self.log.info('Tests successful')
        exit_code = TEST_EXIT_PASSED
    elif (success == TestStatus.SKIPPED):
        self.log.info('Test skipped')
        exit_code = TEST_EXIT_SKIPPED
    else:
        self.log.error('Test failed. Test logging available at %s/test_framework.log', self.options.tmpdir)
        self.log.error("Hint: Call {} '{}' to consolidate all logs".format(os.path.normpath((os.path.dirname(os.path.realpath(__file__)) + '/../combine_logs.py')), self.options.tmpdir))
        exit_code = TEST_EXIT_FAILED
    logging.shutdown()
    sys.exit(exit_code)
Main function. This should not be overridden by the subclass test scripts.
def main(self):
    
    parser = optparse.OptionParser(usage='%prog [options]')
    parser.add_option('--nocleanup', dest='nocleanup', default=False, action='store_true', help='Leave t_notesds and test.* datadir on exit or error')
    parser.add_option('--noshutdown', dest='noshutdown', default=False, action='store_true', help="Don't stop t_notesds after the test execution")
    parser.add_option('--srcdir', dest='srcdir', default=os.path.normpath((os.path.dirname(os.path.realpath(__file__)) + '/../../../src')), help='Source directory containing t_notesd/t_notes-cli (default: %default)')
    parser.add_option('--cachedir', dest='cachedir', default=os.path.normpath((os.path.dirname(os.path.realpath(__file__)) + '/../../cache')), help='Directory for caching pregenerated datadirs')
    parser.add_option('--tmpdir', dest='tmpdir', help='Root directory for datadirs')
    parser.add_option('-l', '--loglevel', dest='loglevel', default='INFO', help='log events at this level and higher to the console. Can be set to DEBUG, INFO, WARNING, ERROR or CRITICAL. Passing --loglevel DEBUG will output all logs to console. Note that logs at all levels are always written to the test_framework.log file in the temporary test directory.')
    parser.add_option('--tracerpc', dest='trace_rpc', default=False, action='store_true', help='Print out all RPC calls as they are made')
    parser.add_option('--portseed', dest='port_seed', default=os.getpid(), type='int', help='The seed to use for assigning port numbers (default: current process id)')
    parser.add_option('--coveragedir', dest='coveragedir', help='Write tested RPC commands into this directory')
    parser.add_option('--configfile', dest='configfile', help='Location of the test framework config file')
    parser.add_option('--legacywallet', dest='legacywallet', default=False, action='store_true', help='create pre-HD wallets only')
    parser.add_option('--tiertwo', dest='tiertwo', default=False, action='store_true', help='run tier two tests only')
    parser.add_option('--sapling', dest='sapling', default=False, action='store_true', help='run tier two tests only')
    parser.add_option('--pdbonfailure', dest='pdbonfailure', default=False, action='store_true', help='Attach a python debugger if test fails')
    parser.add_option('--usecli', dest='usecli', default=False, action='store_true', help='use t_notes-cli instead of RPC for all commands')
    self.add_options(parser)
    (self.options, self.args) = parser.parse_args()
    PortSeed.n = self.options.port_seed
    os.environ['PATH'] = ((((self.options.srcdir + ':') + self.options.srcdir) + '/qt:') + os.environ['PATH'])
    check_json_precision()
    self.options.cachedir = os.path.abspath(self.options.cachedir)
    if self.options.tmpdir:
        self.options.tmpdir = os.path.abspath(self.options.tmpdir)
        os.makedirs(self.options.tmpdir, exist_ok=False)
    else:
        self.options.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX)
    self._start_logging()
    success = TestStatus.FAILED
    try:
        if (self.options.usecli and (not self.supports_cli)):
            raise SkipTest('--usecli specified but test does not support using CLI')
        self.setup_chain()
        self.setup_network()
        time.sleep(5)
        self.run_test()
        success = TestStatus.PASSED
    except JSONRPCException as e:
        self.log.exception('JSONRPC error')
    except SkipTest as e:
        self.log.warning(('Test Skipped: %s' % e.message))
        success = TestStatus.SKIPPED
    except AssertionError as e:
        self.log.exception('Assertion failed')
    except KeyError as e:
        self.log.exception('Key error')
    except Exception as e:
        self.log.exception('Unexpected exception caught during testing')
    except KeyboardInterrupt as e:
        self.log.warning('Exiting after keyboard interrupt')
    if ((success == TestStatus.FAILED) and self.options.pdbonfailure):
        print('Testcase failed. Attaching python debugger. Enter ? for help')
        pdb.set_trace()
    if (not self.options.noshutdown):
        self.log.info('Stopping nodes')
        if self.nodes:
            self.stop_nodes()
    else:
        for node in self.nodes:
            node.cleanup_on_exit = False
        self.log.info('Note: t_notesds were not stopped and may still be running')
    if ((not self.options.nocleanup) and (not self.options.noshutdown) and (success != TestStatus.FAILED)):
        self.log.info('Cleaning up')
        shutil.rmtree(self.options.tmpdir)
    else:
        self.log.warning(('Not cleaning up dir %s' % self.options.tmpdir))
    if (success == TestStatus.PASSED):
        self.log.info('Tests successful')
        exit_code = TEST_EXIT_PASSED
    elif (success == TestStatus.SKIPPED):
        self.log.info('Test skipped')
        exit_code = TEST_EXIT_SKIPPED
    else:
        self.log.error('Test failed. Test logging available at %s/test_framework.log', self.options.tmpdir)
        self.log.error("Hint: Call {} '{}' to consolidate all logs".format(os.path.normpath((os.path.dirname(os.path.realpath(__file__)) + '/../combine_logs.py')), self.options.tmpdir))
        exit_code = TEST_EXIT_FAILED
    logging.shutdown()
    sys.exit(exit_code)