Esempio n. 1
0
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