def main(argv): try: if '-h' in argv or '--help' in argv: return run_nose(argv) sb = Sandbox(SBROOT) #Add different options for using an appliance to run a test #more info about this can be found at #https:// ... /working-with-code/concepts/existing-appliances/run-tests-using-an-appliance # TODO refer to correct doc site #TODO move all the info below into the above website. # #This can # speed things up when creating test # Allows one to debug a test with a full appliance # can be used to run tests with an appliance setup from a variety of repos # #This does not # Replace the current system of running tests off of a sandbox as an appliance # Does not leave behind it's files in a way that is easy to inspect # Is not as reproducable of an environment # #The different options available are # --setup sets up appliances to run tests off of, as well as some # other setup options related to tests # --sb-setup same as --setup, but is specific to the current sandbox # --ip ipaddress --ea applianceName --user username --passwd password # accomplishes the same thing as --setup, but without going through the interactive prompts # --no-adding-args using --setup sb test can be set up to automatically add # arguments when you run sb test, this prevents that from happening # --app someApplianceName the setup file created with --setup or --sb-setup # maps a user defined name with the appliance credentials. You can specify the name # of one of those appliances to run test off of, or you can use a new name and # a brand new appliance will be created and used. You can then reuse that appliance as many times as desired # --recreate-psa this can only be used with an appliance that was previously created # with the above command. This restores the VM to a snapshot before any PSA RPMs were # copied over and installed, the VM then refetches all of the necessary RPMs and # installs them # --branding someBranding --release release_branch these can be used to specify the branding and release # branch when creating a PSA # --repo this can be used instead of the above command to specify a different repo to install off of # this command overrides any branding or release branches that were specified with the above command if '--setup' in argv: argv.remove('--setup') isetup.defaultSetup() print '\n' sys.exit('setup is complete') if '--sb-setup' in argv: argv.remove('--sb-setup') isetup.sbSetup() print '\n' sys.exit('setup is complete') global addingArgs if '--no-adding-args' in argv: addingArgs = False argv.remove('--no-adding-args') if addingArgs: argsToAdd = getAdditionalArgs() if argsToAdd: added = '' for arg in argsToAdd.split(): if arg not in argv: added += ' ' + arg argv.append(arg) if added: print 'added', added global_vars.ea = None ip = None user = None passwd = None def retreiveAndDelArg(arg): for i, tryArg in enumerate(argv): if tryArg == arg: ret = argv[i + 1] del argv[i] del argv[i] return ret branding = None release = None repo = None for i, arg in enumerate(argv): if arg == '--ea' or arg == '--psa': global_vars.ea = argv[i + 1] del argv[i] del argv[i] for i, arg in enumerate(argv): if arg == '--ip' or arg == '--host': ip = argv[i + 1] del argv[i] del argv[i] for i, arg in enumerate(argv): if arg == '--user': user = argv[i + 1] del argv[i] del argv[i] for i, arg in enumerate(argv): if arg == '--passwd' or arg == '--password': passwd = argv[i + 1] del argv[i] del argv[i] for i, arg in enumerate(argv): if arg == '--release': release = argv[i + 1] del argv[i] del argv[i] for i, arg in enumerate(argv): if arg == '--branding': branding = argv[i + 1] del argv[i] del argv[i] for i, arg in enumerate(argv): if arg == '--repo': repo = argv[i + 1] del argv[i] del argv[i] if global_vars.ea and ip and user and passwd: setup.setSetupFile() setup.configAppliance(global_vars.ea, ip, user, passwd) #make sure we're creating a new PSA if an appliance sandbox type is being used if 'appliance' in sb.get_sandboxtype().get_variant(): global_vars.ea = 'sb-test-appliance' if '--recreate-psa' not in argv and global_vars.ea in isetup.getAppliances(): argv.append('--recreate-psa') isetup.setSetupFile() #create the appliance if the appliance doesn't exist in the setup file if global_vars.ea and global_vars.ea not in isetup.getAppliances(): ansi.printc('Appliance %s does not exist, will attempt to create it in 5 seconds, push ctrl+c to cancel' % global_vars.ea, colors.WARNING_COLOR) time.sleep(5) ip = controlVM.createPSA(global_vars.ea, branding, release, repo) isetup.setAppliance(global_vars.ea, ip, 'root', 'psa') if '--recreate-psa' in argv: assert global_vars.ea, 'A VM must be specified with the --ea option to use the --recreate-psa option' controlVM.createPSA(global_vars.ea, branding, release, repo) argv.remove('--recreate-psa') # Support "modes" of tests. This allows us to run a set of tests in # more than one way -- for example, with valgrind enabled or disabled, # or with SearchServer using hs5 versus hs3. mode_path = os.path.join(sb.get_root(), _MODE_FILE) argv, modes = get_modes(argv) if os.path.isfile(mode_path): os.remove(mode_path) if modes: if modes[0].lower() != 'none': with open(mode_path, 'w') as f: f.write(','.join(modes)) attr_arg = find_attr_arg_index(argv) if len(modes) == 0 and attr_arg is None: modeattrs = sb.get_sandboxtype().get_test_mode_attrs_combo() result = 0 runcompiled = True runcodescan = True for modeattr in modeattrs.split(';'): runnable_assembly._modes = None if modeattr.find(':') == -1: if len(modeattr) > 3: print('Skipping mode+attr combo "%s" because no separator ":" was found' % modeattr) continue print('Running mode+attr combo: %s' % modeattr) mode, attrs = modeattr.split(':') argnew = argv[:]#copy argv into argnew so we can append things for this round of tests argnew.insert(1, '-A') argnew.insert(2, attrs.strip()) argnew.insert(3, '--mode') argnew.insert(4, mode.strip()) if not runcompiled: argnew.append('--skip-compiled') if not runcodescan: argnew.append('--skip-codescan') result = result + main(argnew); runcompiled = False runcodescan = False print("") if result == 0: print("All test combos passed.") else: print("%s test combos failed!" % result) return result elif attr_arg is None: argv.insert(1, '-A') attrs = sb.get_sandboxtype().get_test_attrs() argv.insert(2, attrs) print('Running tests that are: %s.' % attrs) else: # If we're running interactive tests, make sure we're also # running with the -s switch. print('Running tests that are: %s.' % argv[attr_arg + 1]) x = argv[attr_arg + 1].replace('not ', '!') if 'interactive' in x and '!interactive' not in x: if '-s' not in argv: argv.insert(1, '-s') if len(modes) > 0: if modes[0].lower() == 'none': modes = [] print('Running modes: %s' % ','.join(modes)) # Make sure any path args in the arg list are fully normalized so they # are not sensitive to working directory changes. normalize_path_args(argv) # If we're collecting tests, it's virtually guaranteed that we want to # display the list... if '--collect-only' in argv: if '-v' not in argv and '--verbose' not in argv: verbosity_found = False for a in argv: if a.startswith('--verbosity'): verbosity_found = True break if not verbosity_found: argv.append('--verbose') # The "full" flag tells us to test all components in the sandbox, # instead of just the ones that are present in code form. If our scope # is full, no special effort is required. However, if our scope is # normal (quick), we have to tell nose which subdirs to use during # discovery. if not SPECIFIC_TESTS_SELECTED: global quick if '--full' in argv: argv.remove('--full') quick = False if '--quick' in argv: quick = True argv.remove('--quick') if quick: subset = [] cr = sb.get_code_root() tr = sb.get_test_root() deps = [l.name for l in sb.get_cached_components()] for c in deps: if component.CODE_ASPECT_NAME in sb.get_component_aspects(c) or c == sb.get_top_component(): component_test_root = sb.get_component_path(c, component.TEST_ASPECT_NAME) if os.path.isdir(component_test_root): if could_have_tests(component_test_root): # Nose treats the first --where arg as a specifier # of the working directory, and subsequent --where # args as folders to use for discovery. So if we're # going to add --where, we have to guarantee working # dir is the first --where. if not subset: argv.append('--where') argv.append(sb.get_root()) argv.append('--where') argv.append(component_test_root) subset.append(c) if subset: print('Targeting: ' + ', '.join(subset) + ' (--full to override).') # The default behavior of the "sb test" command is supposed to be that # all tests get run, no matter what part of the sandbox you're in when # you invoke the command. This is consistent with "sb build", "sb publish", # and other sandbox-level commands. By default, nose will discover tests # beginning in the current working directory. We could override nose's # behavior by adding an extra arg that specifies that the scope for # discovery is the test root, but this would interfere with other logic # that we have, that disables the running of compiled tests when any # sort of constraining file/directory scope is given. So the simplest # way to achieve our goal is to temporarily set the current working dir # to the test root whenever no explicit scope is provided. try: restore_dir = os.getcwd() os.chdir(sb.get_test_root()) # always run tests with the current directory being the test root if '--with-id' not in argv: argv.insert(1, '--with-id') if '--auto' in argv: argv.remove('--auto') auto_test(sb, argv) else: if '--build-first' in argv: sb.set_auto_build(True) argv.remove('--build-first') err = build.main([]) if err: return err elif '--no-build-first' in argv: sb.set_auto_build(False) argv.remove('--no-build-first') # Before running tests, automatically build sandbox if it's out of date. # This allows testers to get a built sandbox and immediately run tests. It # also allows developers to repeatedly code and test without explicitly # rebuilding in between. elif sb.needs_build() and sb.get_auto_build(): print(''' Built artifacts are out of date and will be refreshed before running tests. To run tests without automatic build as needed, use "--no-build-first". ''') err = build.main([]) if err: return err return 0 if run_all(sb, argv) else 1 finally: os.chdir(restore_dir) except: print(traceback.print_exc()) return 1 # make sure bad things show up as an error