docs: def discover(names=None, pattern=['*.py'], skip='efp', dry_run=False, blacklist=None, name_greps=None,
               manual_reset=False, delete_history=False, max_devices=0,
               continue_from=None, result_file='./result.json', auto_reboot=False, keep_explorer=False,
               add_all_devices=False):
      """Discover all test cases and skip those passed
  
      Args:
          pattern (str): Pattern to match case modules, refer python's unittest
                         documentation for more details
          skip (str): types cases to skip
      """
      if not os.path.exists(settings.OUTPUT_PATH):
          os.mkdir(settings.OUTPUT_PATH)
  
      if delete_history:
          os.system('del history.json')
  
      if blacklist:
          try:
              excludes = [line.strip('\n') for line in open(blacklist, 'r').readlines()
                          if not line.startswith('#')]
          except:
              logger.exception('Failed to open test case black list file')
              raise
      else:
          excludes = []
  
      log = None
      if os.path.isfile(result_file):
          try:
              log = json.load(open(result_file, 'r'))
          except:
              logger.exception('Failed to open result file')
  
      if not log:
          log = {}
          json.dump(log, open(result_file, 'w'), indent=2)
  
      suite = unittest.TestSuite()
      discovered = unittest.defaultTestLoader.discover('cases', pattern)
  
      if names and continue_from:
          names = names[names.index(continue_from):]
  
      for s1 in discovered:
          for s2 in s1:
              for case in s2:
                  if case.__class__ is HarnessCase:
                      continue
                  case_name = unicode(case.__class__.__name__)
  
                  # grep name
                  if name_greps and not any(fnmatch.fnmatch(case_name, name_grep) for name_grep in name_greps):
                      logger.info('case[%s] skipped by name greps', case_name)
                      continue
  
                  # whitelist
                  if len(names) and case_name not in names:
                      logger.info('case[%s] skipped', case_name)
                      continue
  
                  # skip cases
                  if case_name in log.keys():
                      if (log[case_name]['passed'] and ('p' in skip)) \
                          or (log[case_name]['passed'] is False and ('f' in skip)) \
                          or (log[case_name]['passed'] is None and ('e' in skip)):
                          logger.warning('case[%s] skipped for its status[%s]', case_name, log[case_name]['passed'])
                          continue
  
                  # continue from
                  if continue_from:
                      if continue_from != case_name:
                          logger.warning('case[%s] skipped for continue from[%s]', case_name, continue_from)
                          continue
                      else:
                          continue_from = None
  
                  # black list
                  if case_name in excludes:
                      logger.warning('case[%s] skipped for blacklist', case_name)
                      continue
  
                  # max devices
                  if max_devices and case.golden_devices_required > max_devices:
                      logger.warning('case[%s] skipped for exceeding max golden devices allowed[%d]', case_name, max_devices)
                      continue
  
                  suite.addTest(case)
                  logger.info('case[%s] added', case_name)
  
      if auto_reboot:
          argv = []
          argv.append('"%s"' % os.sep.join([os.getcwd(), 'start.bat']))
          argv.extend(['-p', pattern])
          argv.extend(['-k', skip])
          argv.extend(['-o', result_file])
          argv.append('-a')
  
          if manual_reset:
              argv.append('-m')
  
          if delete_history:
              argv.append('-d')
  
          auto_reboot_args = argv + names
      else:
          auto_reboot_args = None
          os.system('del "%s"' % RESUME_SCRIPT_PATH)
  
      # manual reset
      if manual_reset:
          settings.PDU_CONTROLLER_TYPE = 'MANUAL_PDU_CONTROLLER'
          settings.PDU_CONTROLLER_OPEN_PARAMS = {}
          settings.PDU_CONTROLLER_REBOOT_PARAMS = {}
  
      result = SimpleTestResult(result_file, auto_reboot_args, keep_explorer, add_all_devices)
      for case in suite:
          logger.info(case.__class__.__name__)
  
      if dry_run:
          return
  
      suite.run(result)
      return result