예제 #1
0
 def find_unmatched(self, test):
     """Does this manager's filters match the given test properties?
     Returns '' if it does, the filter that failed if not.
     """
     fe = self.filterenv(test)
     fe['SELF'] = test
     for f in self.filters:
         #print 'SAD DEBUG Filter is %s.'% repr(f)
         #print fe.copy()
         #print 'SAD END'
         try:
             if eval(f, {}, fe.copy()):
                 #print 'SAD DEBUG Filter %s DID pass.'% repr(f)
                 pass
             else:
                 #print 'SAD DEBUG Filter %s did not pass.'% repr(f)
                 if debug():
                     log('Filter %s did not pass.' % repr(f))
                 return f
         except KeyboardInterrupt:
             raise
         except Exception as e:
             if debug():
                 log('In filter %s:' % repr(f), e)
             return f
     return ''
예제 #2
0
    def logStart(self, test, result):
        "Make appropriate log entries about the test that was started"
        if result:
            m1 = "Start"
        elif configuration.options.skip:
            m1 = "SKIP "
        else:
            m1 = ""
            if self.verbose or debug():
                m1 = "Failed attempting to start"
        n = len(test.group)
        my_nn = 0
        my_nt = 0
        my_ngpu = 0
        msgHosts = ""
        if hasattr(test, 'rs_nodesToUse'):
            if len(test.rs_nodesToUse) > 0:
                msgHosts = "Hosts = [ "
                for host in test.rs_nodesToUse:
                    msgHosts += str(host) + " "
                msgHosts += "]"
        if hasattr(test, 'num_nodes'):
            my_nn = test.num_nodes
        if hasattr(test, 'nt'):
            my_nt = test.nt
        if hasattr(test, 'ngpu'):
            my_ngpu = test.ngpu

        if n == 1:
            if (test.srunRelativeNode >= 0):
                msg = '%s #%4d r=%d, N=%d-%d, np=%s, %s, %s' % \
                  (m1, test.serialNumber, test.srunRelativeNode, test.numberOfNodesNeeded, test.numNodesToUse, test.np, time.asctime(), test.name)
            else:
                msg = '%s #%4d %s, %s nn=%i, np=%i, nt=%i, ngpu=%i %s' % \
                  (m1, test.serialNumber, test.name, msgHosts, my_nn, test.np, my_nt, my_ngpu, time.asctime())
        else:
            if (test.srunRelativeNode >= 0):
                msg = '%s #%4d r=%d, N=%d-%d, np=%s, %s, (Group %d #%d) %s' % \
                  (m1, test.serialNumber, test.srunRelativeNode, test.numberOfNodesNeeded, test.numNodesToUse, test.np, test.groupNumber, time.asctime(), test.groupSerialNumber, test.name)
            else:
                msg = '%s #%4d (Group %d #%d) %s, %s nn=%i, np=%i, nt=%i, ngpu=%i %s' % \
                  (m1, test.serialNumber, test.groupNumber, test.groupSerialNumber, test.name, msgHosts, my_nn, test.np, my_nt, my_ngpu, time.asctime())

        if configuration.options.showGroupStartOnly:
            echo = (not result) or self.verbose or (test.groupSerialNumber
                                                    == 1) or test.options.get(
                                                        'record', False)
        else:
            echo = (result) or self.verbose or test.options.get(
                'record', False)
        log(msg, echo=echo)
        self.schedule(msg)
        if self.verbose or debug():
            log.indent()
            log("Executing", test.commandLine)
            log("in directory", test.directory)
            #log("with timelimit", test.timelimit)
            log.dedent()
예제 #3
0
    def step(self):
        """Do one step of the loop, checking for tests that have finished and
           starting new ones. Return True until all tests done.
        """
        machine.checkRunning()
        if machine.remainingCapacity() == 0:
            return True

        # It is possible that a job can be started. Try to do so.
        # Note that this is not certain; for example, all waiting jobs have np = 2 but only one
        # processor available, so nothing is eligible.
        nextTest = self.findNextTest()
        while nextTest is not None:
            if debug():
                self.schedule("Chose #%d to start." % nextTest.serialNumber)
            self.addBlock(nextTest)
            result = machine.startRun(nextTest)
            self.logStart(nextTest, result)
            if not result:
                self.removeBlock(nextTest)
                break  # failure to launch, let it come back if tests left.
            nextTest = self.findNextTest()

        # find out if we need to be called again, as cheaply as possible.
        if machine.numberTestsRunning > 0:
            return True
        for t in chain(*self.groups):
            if t.status is CREATED:
                return True
        else:
            return False
예제 #4
0
    def firstBanner(self):
        "Write the opening banner."
        log.echo = True
        log('ATS START', atsStartTimeLong)
        log('ATS VERSION', version.version)
        log('ATS HOST NAME:', socket.gethostname())
        log('ATS LOG DIRECTORY:', log.directory)
        log('SYS_TYPE:', configuration.SYS_TYPE)
        log('MACHINE_TYPE', configuration.MACHINE_TYPE)
        log('BATCH_TYPE', configuration.BATCH_TYPE)
        log("Machine description: ", self.machine.label(), echo=True)

        if self.batchmachine:
            log("Batch facility name:", self.batchmachine.label(), echo=True)
        else:
            log("No batch facility found.", echo=True)

        if not configuration.options.logUsage:
            log('NOT logging usage.')

        if configuration.options.info or debug():
            configuration.documentConfiguration()

        log.echo = self.verbose
        if configuration.options.oneFailure:
            log('Will stop after first failure.')

        if configuration.options.allInteractive:
            log('Will run all tests (including any batch tests) as interactive.'
                )

        log('Default time limit for each test=',
            Duration(configuration.timelimit))
예제 #5
0
    def init(self, clas='', adder=None, examiner=None):
        """This initialization is separate so that unit tests can be done on this module.
            For this reason we delay any logging until main is called.
            adder and examiner are called in configuration if given to allow user
            a chance to add options and see results of option parsing.
        """
        tempfile.tempdir = os.getcwd()
        configuration.init(clas, adder, examiner)
        self.options = configuration.options
        self.inputFiles = configuration.inputFiles
        self.machine = configuration.machine
        self.batchmachine = configuration.batchmachine

        if configuration.options.nobatch:
            self.batchmachine = None
        self.verbose = configuration.options.verbose or debug()
        log.echo = self.verbose
        self.started = datestamp(long_format=True)
        self.continuationFileName = ''
        self.atsRunPath = os.getcwd()
        for a in configuration.options.filter:
            self.filter(a)
        pat1 = re.compile(r'^([^\'].*)\'$')
        pat2 = re.compile(r'^([^\"].*)\"$')
        for a in configuration.options.glue:
            if pat1.search(a) or pat2.search(a):
                a1 = a
            else:
                a1 = a.strip('"').strip("'")
            exec('AtsTest.glue(%s)' % a1)
        if configuration.options.level:
            self.filter("level<= %s" % configuration.options.level)
예제 #6
0
def filterdefs(text=None):
    """Add the given text into the environment
       used for filtering.
       With no arguments, clear defined list.
    """
    global _filterwith
    if text is None:
        log('filterdefs: erasing definitions')
        _filterwith = []
    else:
        try:
            d = {}
            for f in _filterwith:
                exec(f, d)
            exec(text, d)
        except SyntaxError as e:
            raise AtsError(e)
        except KeyboardInterrupt:
            raise
        except Exception as e:
            pass
        if debug():
            log('filterdefs:')
            log.indent()
            log(text)
            log.dedent()
        _filterwith.append(text)
예제 #7
0
    def report(self):
        "Log a report, showing each test."
        doAll = debug() or \
               configuration.options.skip or \
               configuration.options.verbose

        outputCaptured = False
        for test in self.testlist:
            if test.output:
                outputCaptured = True

        if outputCaptured and not configuration.options.hideOutput:
            log("NOTICE:",
                "Captured output, see log.",
                echo=True,
                logging=False)

        for test in self.testlist:
            if doAll or test.notes or test.groupSerialNumber ==1 or \
                test.group.echoStatus() or test.options.get('record', False):
                echo = True
            else:
                echo = False

            log("#%d %s %s %s (Group %d #%d)" % \
                   (test.serialNumber, test.status, test.name, test.message,
                    test.group.number, test.groupSerialNumber),
                    echo=echo)

            for line in test.notes:
                log("NOTE:", line, echo=echo)

            log.indent()
            if debug() or configuration.options.skip:
                log([t.serialNumber for t in test.waitUntil], echo=False)
            log.dedent()
예제 #8
0
    def source(self, *paths, **vocabulary):
        """Input one or more source files, with optional additional vocabulary.
         If introspection=f given in the vocabulary, or using define,
         it should be a function taking one argument and returning any
         introspective portion of it.
        """
        if debug():
            log("source:", ' '.join(paths), echo=True)

        introspector = vocabulary.get(
            'introspection',
            testEnvironment.get('introspection', standardIntrospection))

        for path in paths:
            self._source(path, introspector, vocabulary)
예제 #9
0
    def prioritize(self, interactiveTests):
        """Give each test a final totalPriority.  onCollected routines may change."""
        # have to delay looking at the machine / configuration to avoid import race
        global machine, configuration
        from ats import configuration
        machine = configuration.machine
        self.verbose = configuration.options.verbose or debug() or \
                       configuration.options.skip
        self.schedule = AtsLog(directory=log.directory,
                               name='atss.log',
                               logging=configuration.options.logUsage,
                               echo=False)

        for t in interactiveTests:
            waitOnMe = [x for x in interactiveTests if t in x.waitUntil]
            t.totalPriority += sum([w.priority for w in waitOnMe])
예제 #10
0
 def reportObstacles(self, echo=False):
     "Report on status of tests that can't run now."
     s = self.schedule
     if machine.remainingCapacity() == 0:
         return
     if (not machine.numberTestsRunning) or debug():
         tc = [t for t in chain(*self.groups) if t.status is CREATED and \
              ((not machine.canRunNow(t)) or self.isBlocked(t) or self.isWaiting(t))]
         if not tc:
             return
         s("------------------------------------------------", echo=echo)
         s("Jobs ready to run but not able to due to wait, block, or cpu",
           echo=echo)
         s("Serial",
           "tPriority",
           "Priority",
           "Group",
           "W",
           "B",
           "C",
           "Name",
           echo=echo)
         for t in tc:
             s("%6d %9d %8d %5d %1d %1d %1d %s" % \
                (t.serialNumber, t.totalPriority, t.priority, t.groupNumber,
                 self.isWaiting(t),
                 self.isBlocked(t), not machine.canRunNow(t), t.name), echo=echo)
         s(" ", echo=echo)
     elif self.verbose:
         tc = [t for t in chain(*self.groups) if t.status is CREATED and \
              self.isBlocked(t) and (not self.isWaiting(t))]
         if not tc:
             return
         s("------------------------------------------------", echo=echo)
         s("Jobs ready to run but not able due to block or cpu", echo=echo)
         s("Serial",
           "tPriority",
           "Priority",
           "Group",
           "B",
           "C",
           "Name",
           echo=echo)
         for t in tc:
             s("%6d %9d %8d %5d %1d %1d %s" % \
                (t.serialNumber, t.totalPriority, t.priority, t.groupNumber,
                self.isBlocked(t), not machine.canRunNow(t), t.name), echo=echo)
예제 #11
0
 def addBlock(self, test):
     "Block directories, if any, needed for test and its group."
     g = test.group
     if g.isBlocking:
         return
     for t in g:
         if t.independent:
             continue
         d = t.block
         if d:
             # If any test in the group blocks, add the block (directory)
             # to the blocking list and mark this group as blocking.
             g.isBlocking = True
             self.blocks[d] = g.number
     if g.isBlocking:
         if debug():
             self.schedule("Add blocks", g.number)
예제 #12
0
파일: tests.py 프로젝트: LLNL/ATS
    def __init__(self, *fixedargs, **options):
        "Must not throw an exception -- object must always get created."
        super(AtsTest, self).__init__()
        AtsTest.serialNumber += 1
        AtsTest.waitUntilAccumulator.append(self)
        # populate attributes
        self.serialNumber = AtsTest.serialNumber
        if AtsTest.group is None:
            AtsTest.groupCounter += 1
            self.group = AtsTestGroup(AtsTest.groupCounter)
        else:
            self.group = AtsTest.group
        self.group.append(self)
        self.groupNumber = self.group.number
        self.groupSerialNumber = len(self.group)
        self.waitUntil = AtsTest.waitUntil  #never modify this, it may be shared.
        self.runOrder = 0  # to aid in diagnosis of wait, priority
        self.depends_on = None
        self.dependents = []
        self.expectedResult = PASSED
        self.setName("uninitialized")
        self.set(INVALID, "New test, unitialized")
        self.srunRelativeNode = -1
        self.numNodesToUse = -1
        self.priority = -1
        self.totalPriority = -1
        self.startDateTime = curDateTime()
        self.endDateTime = curDateTime()
        self.output = []  #magic output, newlines and magic removed.
        self.notes = []  #note from the run
        self.block = ''
        # these will all get changed below but want them set to something for getResults
        self.level = 0
        self.independent = False
        self.np = 1
        self.priority = 1
        self.totalPriority = 1
        self.directory = ''
        self.batch = False
        self.clas = ''

        self.combineOutput = False
        self.outname = ''
        self.shortoutname = ''
        self.errname = ''
        self.outhandle = None
        self.errhandle = None

        self.commandList = ['not run']
        # this is just used for documentation
        self.commandLine = 'not run'

        rootdict = dict(ATSROOT=configuration.ATSROOT)

        # Combine the options: first the defaults, then the glued, then the tacked,
        # then the stuck, then the test options.
        self.options = AttributeDict(
            script='',
            clas=[],
            executable='',
            directory='',
        )
        try:
            self.options.update(configuration.options.testDefaults)
            self.options.update(AtsTest.glued)
            self.options.update(AtsTest.tacked)
            self.options.update(AtsTest.stuck)
            self.options.update(AtsTest.grouped)
            self.options.update(options)
        except Exception as e:
            self.set(INVALID, 'Bad options: ' + e)
            return

        self.level = self.options['level']
        self.np = self.options['np']
        self.priority = self.options.get('priority', max(1, self.np))
        self.totalPriority = self.priority

        self.testStdout = self.options['testStdout']
        outOpts = ['file', 'terminal', 'both']
        if not self.testStdout in outOpts:
            msg = 'Invalid setting for option testStdout: ' + self.testStdout
            raise AtsError(msg)

        if configuration.options.allInteractive:
            self.batch = False
        else:
            self.batch = self.options['batch']

        if configuration.options.combineOutErr:
            self.combineOutput = True
        else:
            self.combineOutput = False

        # process the arguments
        # Note: old interface was script, clas='', **options
        # Now allow for possibility of no script, or clas as unnamed second
        # positional
        lc = len(fixedargs)
        if lc > 2:
            self.set(INVALID, 'Too many positional arguments to test command.')
            return
        elif lc == 2:
            self.options['script'] = fixedargs[0]
            self.options['clas'] = fixedargs[1]
        elif lc == 1:
            self.options['script'] = fixedargs[0]
        script = self.options['script']
        clas = self.options['clas']
        if isinstance(clas, str):
            clas = configuration.machine.split(clas)
        self.clas = [c % self.options for c in clas]
        executable = str(self.options.get('executable'))
        self.directory = self.options['directory']

        if executable == '1':
            if not script:
                self.set(INVALID, "executable = 1 requires a first argument.")
                return

            script = script.replace('$ATSROOT', configuration.ATSROOT)
            if len(configuration.ATSROOT) == 0:
                script = script[1:]  # remove leading "/" or "\"
            script = script % rootdict
            self.executable = Executable(script)
            if self.directory == '':
                self.directory = os.getcwd()
            path = self.executable.path
            junk, filename = os.path.split(path)
        else:
            if executable:
                executable = executable.replace('$ATSROOT',
                                                configuration.ATSROOT)
                self.executable = Executable(executable % rootdict)
            else:
                self.executable = configuration.defaultExecutable

            if script:
                script = abspath(script) % self.options
                self.clas.insert(0, script)
                if self.directory == '':
                    self.directory, filename = os.path.split(script)
            else:
                if self.directory == '':
                    self.directory = os.getcwd()
                junk, filename = os.path.split(self.executable.path)

        name, junk = os.path.splitext(filename)
        self.setName(self.options.get('name', name))
        label = self.options.get('label', '')
        if label:
            label = str(label).strip()
            self.setName(self.name + '(' + label + ')')

        if debug():
            log("Results of parsing test arguments", echo=False)
            log.indent()
            log("Name:", self.name, echo=False)
            log("Options:", echo=False)
            log.indent()
            for k in self.options:
                log(k, ": ", self.options[k], echo=False)
            log.dedent()
            log("Executable path:", self.executable.path, echo=False)
            log("Directory:", self.directory, echo=False)
            log.dedent()

        self.independent = self.options.get('independent', False)
        if not self.independent:
            # the lower() is due to peculiarities on at least the Mac
            # where os.chdir() seems to change case partially.
            self.block = self.directory.lower()

        if not self.executable.is_valid():
            self.set(INVALID, 'Executable "%s" not valid.' % self.executable)
            return

        if not os.path.isdir(self.directory):
            self.set(INVALID, 'Directory not valid: %s' % self.directory)

        if script and not is_valid_file(script):
            self.set(INVALID, "Script %s does not exist." % script)
            return

        self.fileOutNamesSet()

        #set the timelimit
        try:
            tl = options.get('timelimit', None)
            if tl is None:
                self.timelimit = configuration.timelimit
            else:
                self.timelimit = Duration(tl)
        except AtsError as msg:
            self.set(INVALID, msg)
            return

        if self.priority <= 0:
            self.set(SKIPPED, 'Test has priority <= zero.')
            return

        # if the test ends up BATCHED, such jobs are legal.

        if self.batch and configuration.options.nobatch:
            self.set(SKIPPED, "Batch not available")

        elif self.batch:
            problem = configuration.batchmachine.canRun(self)
            if not problem:
                if configuration.options.skip:
                    self.set(SKIPPED, "BACH skipped due to skip flag")
                else:
                    self.set(BATCHED, "Ready to run in batch.")
            else:
                self.set(SKIPPED, problem)

        else:
            problem = configuration.machine.canRun(self)
            if not problem:
                self.set(CREATED, "Ready to run interactively.")
            elif configuration.options.allInteractive or \
               configuration.options.nobatch or \
               self.groupNumber:
                self.set(SKIPPED, problem)
            else:
                self.set(BATCHED, problem)
                self.notes.append(\
                    "Changed to batch since unable to run interactively on this machine.")
예제 #13
0
def init(clas = '', adder = None, examiner=None):
    """Called by manager.init(class, adder, examiner)
       Initialize configuration and process command-line options; create log,
       options, inputFiles, timelimit, machine, and batchmatchine.
       Call backs to machine and to adder/examiner for options.
    """
    global log, options, inputFiles, timelimit, machine, batchmachine,\
           defaultExecutable, ATSROOT, cuttime

    init_debugClass = False

    if init_debugClass:
        print("DEBUG init entered clas=%s " % (clas))

    # get the machine and possible batch facility
    machineDirs = MACHINE_DIR

    # delete, not needed, handled above
    #if MACHINE_OVERRIDE_DIR:
    #    machineDirs.append(MACHINE_OVERRIDE_DIR)

    machineList = []
    for machineDir in machineDirs:
       log('machineDir', machineDir)
       machineList.extend([os.path.join(machineDir,x) for x in os.listdir(machineDir) if x.endswith('.py') and not x.endswith('__init__.py')])
       sys.path.insert(0, machineDir)

    #machineList = []
    #for machineDir in machineDirs:
    #    print("DEBUG machineDir=%s " % (machineDir))
    #    machineList.extend(
    #        [os.path.join(machineDir,x) for x in os.listdir(machineDir)
    #         if x.endswith('.py') and not x.endswith('__init__.py')])

    machine = None
    batchmachine = None
    specFoundIn = ''
    bspecFoundIn = ''

    if init_debugClass:
        print("DEBUG init 100")
        print(machineDirs)
        print(machineList)
        print(MACHINE_TYPE)
        print("DEBUG init 200")

    for full_path in machineList:
        moduleName = ''
        fname = os.path.basename(full_path)
        # print "DEBUG 000 fname = %s" % fname
        f = open(full_path, 'r')
        for line in f:
            if line.startswith('#ATS:') and not machine:
                items = line[5:-1].split()
                machineName, moduleName, machineClass, npMaxH = items
                if init_debugClass:
                    print("DEBUG init machineName=%s moduleName=%s machineClass=%s npMaxH=%s" %
                          (machineName, moduleName, machineClass, npMaxH))

                # print "DEBUG init MACHINE_TYPE=%s machineName=%s moduleName=%s machineClass=%s npMaxH=%s" % (MACHINE_TYPE, machineName, moduleName, machineClass, npMaxH)

                if machineName == MACHINE_TYPE:
                    if moduleName == "SELF":
                        moduleName, junk = os.path.splitext(fname)
                    specFoundIn = full_path
                    print(f"from ats.atsMachines.{moduleName} "
                          f"import {machineClass} as Machine")
                    try:
                        machine_factory = get_machine_factory(moduleName,
                                                              machineClass)
                    except ModuleNotFoundError:
                        machine_factory = get_machine_factory(moduleName,
                                                              machineClass,
                                                              machine_package='atsMachines')
                    machine = machine_factory(machineName, int(npMaxH))

            elif line.startswith('#BATS:') and not batchmachine:
                items = line[6:-1].split()
                machineName, moduleName, machineClass, npMaxH = items

                if machineName == BATCH_TYPE:
                    if moduleName == "SELF":
                        moduleName, junk = os.path.splitext(fname)
                    bspecFoundIn = full_path
                    try:
                        machine_factory = get_machine_factory(moduleName,
                                                              machineClass)
                    except ModuleNotFoundError:
                        machine_factory = get_machine_factory(moduleName,
                                                              machineClass,
                                                              machine_package='atsMachines')
                    batchmachine = machine_factory(moduleName, int(npMaxH))
        f.close()

        if machine and batchmachine:
            break

    if machine is None:
        terminal("No machine specifications for", SYS_TYPE, "found, using generic.")
        machine = machines.Machine('generic', -1)

# create the option set
    usage = "usage: %prog [options] [input files]"
    parser = OptionParser(usage=usage, version="%prog " + version.version)
    addOptions(parser)
    machine.addOptions(parser)
# add the --nobatch option but force it true if no batch facility here.
    parser.add_option('--nobatch', action='store_true', dest='nobatch', default=(batchmachine is None),
        help = 'Do not run batch jobs.')
    if batchmachine:
        batchmachine.addOptions(parser)
# user callback?
    if adder is not None:
        adder(parser)
# parse the command line
    if clas:
        import shlex
        argv = shlex.split(clas)
    else:
        argv = sys.argv[1:]
    (toptions, inputFiles) = parser.parse_args(argv)

# immediately make the options a real dictionary -- the way optparse leaves it
# is misleading.
    options = AttributeDict()
    for k in vars(toptions).keys():
        options[k] = getattr(toptions, k)

# set up the test default options so the machine(s) can add to it
    options['testDefaults'] = AttributeDict(np=1,
        batch=0,
        level=1,
        keep = options.keep,
        hideOutput = options.hideOutput,
        verbose = options.verbose,
        testStdout = options.testStdout,
        globalPrerunScript = options.globalPrerunScript,
        globalPostrunScript = options.globalPostrunScript,
        sequential = options.sequential,
        nosrun = options.nosrun,
        salloc = options.salloc
        )

# let the machine(s) modify the results or act upon them in other ways.
    machine.examineOptions(options)
    if batchmachine:
        batchmachine.examineOptions(options)
# unpack basic options
    debug(options.debug)
    if options.logdir:
        log.set(directory = options.logdir)
    else:
        dirname = SYS_TYPE + "." + atsStartTime + ".logs"
        log.set(directory = dirname)
    log.mode="w"
    log.logging = 1
# user callback?
    if examiner is not None:
        examiner(options)

    if specFoundIn:
        log("Found specification for", MACHINE_TYPE, "in", specFoundIn)
    else:
        log("No specification found for", MACHINE_TYPE, ', using generic')
    if bspecFoundIn:
        log("Batch specification for ", BATCH_TYPE, "in", bspecFoundIn)

# unpack other options
    cuttime = options.cuttime
    if cuttime is not None:
        cuttime = Duration(cuttime)
    timelimit = Duration(options.timelimit)
    defaultExecutable = executables.Executable(abspath(options.executable))
    # ATSROOT is used in tests.py to allow paths pointed at the executable's directory
    if 'ATSROOT' in os.environ:
        ATSROOT = os.environ['ATSROOT']
    else:
        ATSROOT = os.path.dirname(defaultExecutable.path)
예제 #14
0
    def collectTests(self):
        """Process the input and collect the tests to be executed.
We immediately make sure each input file exists and is readable.
(If we don't we might not find out until many tests have run.)
"""
        # It is worth settling this now.
        if debug():
            log("Checking that input files exist.")
        files = []
        for input_file in self.inputFiles:
            t = abspath(input_file)
            dir, filename = os.path.split(t)
            name, e = os.path.splitext(filename)
            if e:
                namelist = [t]
            else:
                namelist = [t, t + '.ats', t + '.py']
            for t1 in namelist:
                try:
                    f = open(t1, 'r')
                    break
                except IOError:
                    pass
            else:
                log.fatal_error('Cannot open %s.' % t)
            f.close()
            files.append(t1)

        log("Input ok. Now collect the tests.")

        # Now collect the tests.
        for t in files:
            self.source(t)

# Stop the execution of ats when the first INVALID test is found unless option --okInvalid.
        log.indent()
        found = False
        for item in self.badlist:
            found = True
            log('Bad file:', item, echo=True)
        for test in self.testlist:
            if test.status is INVALID:
                found = True
                log(test.status,
                    "#%d" % test.serialNumber,
                    test.name,
                    echo=True)
        log.dedent()

        if found:
            log('************************************************', echo=True)
            log('NOTE: Invalid tests or files', echo=True)
            if not configuration.options.okInvalid:
                log.fatal_error("Fix invalid tests or rerun with --okInvalid.")

# Make sure that every test has distinct name
        testnames = [t.name.lower() for t in self.testlist]
        for i in range(len(testnames)):
            name = testnames[i]
            while testnames.count(name) > 1:
                count = 1
                for j in range(i + 1, len(testnames)):
                    if testnames[j] == name:
                        count += 1
                        t = self.testlist[j]
                        t.name += ("#%d" % count)
                        testnames[j] = t.name.lower()

# Add parents to each test's waitlist.
        for t in self.testlist:
            if t.status is CREATED:
                for d in t.dependents:
                    if t not in d.waitUntil:
                        d.waitUntil = d.waitUntil + [t]

        log.leading = ''
        log("------------------ Input complete --------", echo=True)
        echo =  configuration.options.verbose or \
                debug() or \
                configuration.options.skip
        for t in self.testlist:
            log(repr(t), echo=echo)
예제 #15
0
    def _source(self, path, introspector, vocabulary):
        "Process source file. Returns true if successful"
        here = os.getcwd()
        t = abspath(path)
        directory, filename = os.path.split(t)
        name, e = os.path.splitext(filename)
        if e:
            namelist = [t]
        else:
            namelist = [t, t + '.ats', t + '.py']
        for t1 in namelist:
            if t1 in AtsManager.alreadysourced:
                log("Already sourced:", t1)
                return
            try:
                f = open(t1)
                break
            except IOError as e:
                pass
        else:
            log("Error opening input file:", t1, echo=True)
            self.badlist.append(t1)
            raise AtsError("Could not open input file %s" % path)
        t = abspath(t1)
        directory, filename = os.path.split(t1)
        name, e = os.path.splitext(filename)
        AtsManager.alreadysourced.append(t1)
        # save to restore after this file is read
        savestuck = dict(AtsTest.stuck)
        savetacked = dict(AtsTest.tacked)
        unstick()  #clear sticky list at the start of a file.
        AtsTest.waitNewSource()

        testenv = dict(testEnvironment)
        testenv.update(vocabulary)
        testenv['SELF'] = t1
        atstext = []
        for line1 in f:
            if not line1: continue
            if line1.startswith('#!'):
                continue
            magic = introspector(line1[:-1])
            if magic is not None:
                atstext.append(magic)
        f.close()
        if atstext:
            log('-> Executing statements in', t1, echo=False)
            log.indent()
            code = '\n'.join(atstext)
            if debug():
                for line in atstext:
                    log(line, echo=False)
            os.chdir(directory)
            try:
                exec(code, testenv)
                if debug():
                    log('Finished ', t1, datestamp())
            except KeyboardInterrupt:
                raise
            except Exception as details:
                self.badlist.append(t1)
                log('Error while processing statements in', t1, ':', echo=True)
                log(details, echo=True)
            log.dedent()
        else:
            log('-> Sourcing', t1, echo=False)
            log.indent()
            os.chdir(directory)
            try:
                exec(compile(open(t1, "rb").read(), t1, 'exec'), testenv)
                if debug(): log('Finished ', t1, datestamp())
                result = 1
            except KeyboardInterrupt:
                raise
            except Exception as details:
                self.badlist.append(t1)
                log('Error in input file', t1, ':', echo=True)
                log(details, echo=True)
                log('------------------------------------------', echo=True)
            log.dedent()
        AtsTest.endGroup()
        unstick()
        stick(**savestuck)
        untack()
        tack(**savetacked)
        AtsTest.waitEndSource()
        os.chdir(here)