Esempio n. 1
0
	def __init__(self, command, arguments, environs, workingDir, state, timeout, stdout=None, stderr=None, displayName=None, **kwargs):
		"""Create an instance of the process wrapper.
		
		@param command:  The full path to the command to execute
		@param arguments:  A list of arguments to the command
		@param environs:  A dictionary of environment variables (key, value) for the process context execution
		@param workingDir:  The working directory for the process
		@param state:  The state of the process (L{pysys.constants.FOREGROUND} or L{pysys.constants.BACKGROUND}
		@param timeout:  The timeout in seconds to be applied to the process
		@param stdout:  The full path to the filename to write the stdout of the process
		@param stderr:  The full path to the filename to write the sdterr of the process
		@param displayName: Display name for this process

		"""
		CommonProcessWrapper.__init__(self, command, arguments, environs, workingDir, 
			state, timeout, stdout, stderr, displayName, **kwargs)

		# private instance variables
		self.__hProcess = None
		self.__hThread = None
		self.__tid = None
		
		self.__lock = threading.Lock() # to protect access to the fields that get updated
		
		# set the stdout|err file handles
		self.fStdout = 'nul'
		self.fStderr = 'nul'
		try:
			if stdout is not None: self.fStdout = _stringToUnicode(stdout)
		except Exception:
			log.info("Unable to create file to capture stdout - using the null device")
		try:
			if stderr is not None: self.fStderr = _stringToUnicode(stderr)
		except Exception:
			log.info("Unable to create file to capture stdout - using the null device")
Esempio n. 2
0
	def wait(self, interval):
		"""Wait for a specified period of time.
		
		@param interval: The time interval in seconds to wait
		
		"""
		log.info('Waiting for %0.1f seconds'%interval)
		time.sleep(interval)
Esempio n. 3
0
def getDriver(database):
    """Downloads database drivers to the staging area, and return the full path to the driver."""
    download_dir = os.path.join(REMOTE_STAGING, 'drivers')
    target = os.path.join(download_dir, database.driver)

    if not os.path.exists(download_dir): os.makedirs(download_dir)

    if not os.path.exists(target):
        log.info('Downloading driver %s' % database.driver)
        database.copyDriver(download_dir)
    return target
Esempio n. 4
0
    def __init__(self, requests_queue, results_queue, poll_timeout=5, **kwds):
        """Class constructor.
		
		@param requests_queue: Reference to the threadpool's request queue
		@param results_queue: Reference to the threadpool's results queue
		@param poll_timeout: The timeout when trying to obtain a request from the request queue
		@param kwds: Variable arguments to be passed to the threading.Thread constructor
		
		"""
        threading.Thread.__init__(self, **kwds)
        log.info("[%s] Creating thread for test execution" % self.getName())
        self.setDaemon(1)
        self._requests_queue = requests_queue
        self._results_queue = results_queue
        self._poll_timeout = poll_timeout
        self._dismissed = threading.Event()
        self.start()
Esempio n. 5
0
    def clean(self):
        descriptors = createDescriptors(self.arguments, None, [], [], None,
                                        self.workingDir)
        for descriptor in descriptors:
            if self.all:
                if sys.version_info >= (3, ):
                    cache = os.path.join(os.path.dirname(descriptor.module),
                                         "__pycache__")
                    if os.path.exists(cache):
                        log.info("Deleting pycache: " + cache)
                        self.purgeDirectory(cache, True)
                else:
                    path = descriptor.module + ".pyc"
                    try:
                        mode = os.stat(path)[stat.ST_MODE]
                        if stat.S_ISLNK(mode):
                            os.unlink(path)
                        if stat.S_ISREG(mode):
                            os.remove(path)
                        log.info("Deleting compiled module: " + path)
                    except Exception:
                        log.debug("Error deleting compiled module: " + path)

            pathToDelete = os.path.join(descriptor.output, self.outsubdir)
            if os.path.exists(pathToDelete):
                log.info("Deleting output directory: " + pathToDelete)
                self.purgeDirectory(pathToDelete, True)
            else:
                log.debug("Output directory does not exist: " + pathToDelete)
Esempio n. 6
0
    def change_stream_listen(self, log, args):
        connStr = args[0]
        log.info("Listen and log")
        # Connect to mongo
        client = MongoClient(host=connStr)
        db = client.get_default_database()
        coll = db.get_collection('test_coll')

        total = 0.0
        count = 0

        # Connect to elastic
        # elastic_conn_str = [self.project.ELASTIC_URL]
        # es = Elasticsearch(elastic_conn_str)

        # index_name = 'mongosearch'
        # doc_type = 'test'
        # es.indices.delete(index=index_name, ignore=[400, 404])

        self.thread_started = True
        try:
            for changed_doc in coll.watch([{
                    '$match': {
                        'operationType': 'insert'
                    }
            }]):

                # doc = changed_doc['fullDocument']
                # doc.pop('_id')
                # res = es.index(index=index_name, doc_type=doc_type, id=count, body=doc)
                # count += 1
                # log.info(res['result'])

                self.records_to_receive -= 1
                log.info(self.records_to_receive)

        except PyMongoError as ex:
            # The ChangeStream encountered an unrecoverable error or the
            # resume attempt failed to recreate the cursor.
            print(ex)
Esempio n. 7
0
    def clean(self):
        Project.findAndLoadProject(outdir=self.outsubdir)

        descriptors = createDescriptors(self.arguments,
                                        None, [], [],
                                        None,
                                        self.workingDir,
                                        expandmodes=False)
        supportMultipleModesPerRun = Project.getInstance().getProperty(
            'supportMultipleModesPerRun', True)

        for descriptor in descriptors:
            if self.all:
                modulepath = os.path.join(descriptor.testDir,
                                          descriptor.module)
                cache = os.path.join(os.path.dirname(modulepath),
                                     "__pycache__")
                if os.path.isdir(cache):
                    log.info("Deleting pycache: " + cache)
                    deletedir(cache)
                else:
                    log.debug('__pycache__ does not exist: %s', cache)
                path = modulepath + ".pyc"
                if os.path.exists(path):
                    log.info("Deleting compiled Python module: " + path)
                    os.remove(path)
                else:
                    log.debug('.pyc does not exist: %s', path)

            for mode in (descriptor.modes or [None]):
                pathToDelete = os.path.join(descriptor.testDir,
                                            descriptor.output, self.outsubdir)

                if os.path.isabs(self.outsubdir
                                 ):  # must delete only the selected testcase
                    pathToDelete += "/" + descriptor.id

                if supportMultipleModesPerRun and mode:
                    pathToDelete += '~' + mode

                if os.path.exists(pathToDelete):
                    log.info("Deleting output directory: " + pathToDelete)
                    deletedir(pathToDelete)
                else:
                    log.debug("Output directory does not exist: " +
                              pathToDelete)
Esempio n. 8
0
    def makeTest(self,
                 input=None,
                 output=None,
                 reference=None,
                 descriptor=None,
                 testclass=None,
                 module=None,
                 group="",
                 constantsImport=None,
                 basetestImport=None,
                 basetest=None,
                 teststring=None):
        if input == None: input = DEFAULT_INPUT
        if output == None: output = DEFAULT_OUTPUT
        if reference == None: reference = DEFAULT_REFERENCE
        if descriptor == None: descriptor = DEFAULT_DESCRIPTOR[0]
        if testclass == None: testclass = DEFAULT_TESTCLASS
        if module == None: module = DEFAULT_MODULE
        if constantsImport == None:
            constantsImport = "from pysys.constants import *"
        if basetestImport == None:
            basetestImport = "from pysys.basetest import BaseTest"
        if basetest == None: basetest = "BaseTest"

        log.info("Creating testcase %s ..." % self.testId)
        try:
            os.makedirs(os.path.join(self.testdir, self.testId))
            log.info("Created directory %s" %
                     os.path.join(self.testdir, self.testId))
        except OSError:
            log.info("Error creating testcase " +
                     os.path.join(self.testdir, self.testId) +
                     " - directory already exists")
            return
        else:
            os.makedirs(os.path.join(self.testdir, self.testId, input))
            log.info("Created directory %s " %
                     os.path.join(self.testdir, self.testId, input))
            os.makedirs(os.path.join(self.testdir, self.testId, output))
            log.info("Created directory %s " %
                     os.path.join(self.testdir, self.testId, output))
            os.makedirs(os.path.join(self.testdir, self.testId, reference))
            log.info("Created directory %s " %
                     os.path.join(self.testdir, self.testId, reference))
            descriptor_fp = open(
                os.path.join(self.testdir, self.testId, descriptor), "w")
            descriptor_fp.write(DESCRIPTOR_TEMPLATE %
                                (self.type, group, testclass, module))
            descriptor_fp.close()
            log.info("Created descriptor %s " %
                     os.path.join(self.testdir, self.testId, descriptor))
            testclass_fp = open(
                os.path.join(self.testdir, self.testId, "%s.py" % module), "w")
            if teststring == None:
                testclass_fp.write(
                    TEST_TEMPLATE %
                    (constantsImport, basetestImport, testclass, basetest))
            else:
                testclass_fp.write(teststring)
            testclass_fp.close()
            log.info("Created test class module %s " %
                     os.path.join(self.testdir, self.testId, "%s.py" % module))
Esempio n. 9
0
    def parseArgs(self, args, printXOptions=None):
        # add any default args first; shlex.split does a great job of providing consistent parsing from str->list,
        # but need to avoid mangling \'s on windows; since this env var will be different for each OS no need for consistent win+unix behaviour
        if os.getenv('PYSYS_DEFAULT_ARGS', ''):
            log.info('Using PYSYS_DEFAULT_ARGS = %s' %
                     os.environ['PYSYS_DEFAULT_ARGS'])
            args = shlex.split(os.environ['PYSYS_DEFAULT_ARGS'].replace(
                os.sep, os.sep * 2 if os.sep == '\\' else os.sep)) + args

        printLogsDefault = PrintLogs.ALL
        if '--ci' in args:
            # to ensure identical behaviour, set these as if on the command line
            # (printLogs we don't set here since we use the printLogsDefault mechanism to allow it to be overridden
            # by CI writers and/or the command line; note that setting --mode=ALL would be incorrect if
            # supportMultipleModesPerRun=false but that's a legacy options so we raise an exception later if this happened)
            args = [
                '--purge', '--record', '-j0', '--type=auto', '--mode=ALL',
                '-XcodeCoverage'
            ] + args
            printLogsDefault = PrintLogs.FAILURES

        try:
            optlist, self.arguments = getopt.gnu_getopt(
                args, self.optionString, self.optionList)
        except Exception:
            log.warn("Error parsing command line arguments: %s" %
                     (sys.exc_info()[1]))
            sys.exit(1)

        log.debug('PySys arguments: tests=%s options=%s', self.arguments,
                  optlist)

        EXPR1 = re.compile("^[\w\.]*=.*$")
        EXPR2 = re.compile("^[\w\.]*$")

        printLogs = None
        ci = False
        defaultAbortOnError = None

        logging.getLogger('pysys').setLevel(logging.INFO)

        # as a special case, set a non-DEBUG log level for the implementation of assertions
        # so that it doesn't get enabled with -vDEBUG only -vassertions=DEBUG
        # as it is incredibly verbose and slow and not often useful
        logging.getLogger('pysys.assertions').setLevel(logging.INFO)

        for option, value in optlist:
            if option in ("-h", "--help"):
                self.printUsage(printXOptions)

            elif option in ['--ci']:
                continue  # handled above

            elif option in ("-r", "--record"):
                self.record = True

            elif option in ("-p", "--purge"):
                self.purge = True

            elif option in ("-v", "--verbosity"):
                verbosity = value
                if '=' in verbosity:
                    loggername, verbosity = value.split('=')
                    assert not loggername.startswith(
                        'pysys.'
                    ), 'The "pysys." prefix is assumed and should not be explicitly specified'
                    if loggername.startswith('python:'):
                        loggername = loggername[len('python:'):]
                        assert not loggername.startswith(
                            'pysys'
                        ), 'Cannot use python: with pysys.*'  # would produce a duplicate log handler
                        # in the interests of performance and simplicity we normally only add the pysys.* category
                        logging.getLogger(loggername).addHandler(
                            pysys.internal.initlogging.pysysLogHandler)
                    else:
                        loggername = 'pysys.' + loggername
                else:
                    loggername = None

                if verbosity.upper() == "DEBUG":
                    verbosity = logging.DEBUG
                elif verbosity.upper() == "INFO":
                    verbosity = logging.INFO
                elif verbosity.upper() == "WARN":
                    verbosity = logging.WARN
                elif verbosity.upper() == "CRIT":
                    verbosity = logging.CRITICAL
                else:
                    log.warn('Invalid log level "%s"' % verbosity)
                    sys.exit(1)

                if loggername is None:
                    # when setting global log level to a higher level like WARN etc we want to affect stdout but
                    # not necessarily downgrade the root level (would make run.log less useful and break
                    # some PrintLogs behaviour)
                    stdoutHandler.setLevel(verbosity)
                    if verbosity == logging.DEBUG:
                        logging.getLogger('pysys').setLevel(logging.DEBUG)
                else:
                    # for specific level setting we need the opposite - only change stdoutHandler if we're
                    # turning up the logging (since otherwise it wouldn't be seen) but also change the specified level
                    logging.getLogger(loggername).setLevel(verbosity)

            elif option in ("-a", "--type"):
                self.type = value
                if self.type not in ["auto", "manual"]:
                    log.warn(
                        "Unsupported test type - valid types are auto and manual"
                    )
                    sys.exit(1)

            elif option in ("-t", "--trace"):
                self.trace = value

            elif option in ("-i", "--include"):
                self.includes.append(value)

            elif option in ("-e", "--exclude"):
                self.excludes.append(value)

            elif option in ("-c", "--cycle"):
                try:
                    self.cycle = int(value)
                except Exception:
                    print(
                        "Error parsing command line arguments: A valid integer for the number of cycles must be supplied"
                    )
                    sys.exit(1)

            elif option in ("-o", "--outdir"):
                value = os.path.normpath(value)
                if os.path.isabs(value) and not value.startswith('\\\\?\\'):
                    value = fromLongPathSafe(toLongPathSafe(value))
                self.outsubdir = value

            elif option in ("-m", "--mode", "--modeinclude"):
                self.modeinclude = self.modeinclude + [
                    x.strip() for x in value.split(',')
                ]

            elif option in ["--modeexclude"]:
                self.modeexclude = self.modeexclude + [
                    x.strip() for x in value.split(',')
                ]

            elif option in ["-n", "-j", "--threads"]:
                N_CPUS = multiprocessing.cpu_count()
                if value.lower() == 'auto': value = '0'
                if value.lower().startswith('x'):
                    self.threads = max(1, int(float(value[1:]) * N_CPUS))
                else:
                    self.threads = int(value)
                    if self.threads <= 0:
                        self.threads = int(
                            os.getenv('PYSYS_DEFAULT_THREADS', N_CPUS))

            elif option in ("-b", "--abort"):
                defaultAbortOnError = str(value.lower() == 'true')

            elif option in ["-g", "--progress"]:
                self.progress = True

            elif option in ["--printLogs"]:
                printLogs = getattr(PrintLogs, value.upper(), None)
                if printLogs is None:
                    print(
                        "Error parsing command line arguments: Unsupported --printLogs value '%s'"
                        % value)
                    sys.exit(1)

            elif option in ["-X"]:
                if '=' in value:
                    key, value = value.split('=', 1)
                else:
                    key, value = value, 'true'

                # best not to risk unintended consequences with matching of other types, but for boolean
                # it's worth it to resolve the inconsistent behaviour of -Xkey=true and -Xkey that existed until 1.6.0,
                # and because getting a bool where you expected a string is a bit more likely to give an exception
                # and be noticed that getting a string where you expected a boolean (e.g. the danger of if "false":)
                if value.lower() == 'true':
                    value = True
                elif value.lower() == 'false':
                    value = False

                self.userOptions[key] = value

            elif option in ("-y", "--validateOnly"):
                self.userOptions['validateOnly'] = True

            elif option in ("-G", "--grep"):
                self.grep = value

            else:
                print("Unknown option: %s" % option)
                sys.exit(1)

        # log this once we've got the log levels setup
        log.debug('PySys is installed at: %s; python from %s',
                  os.path.dirname(pysys.__file__), sys.executable)

        # retained for compatibility, but PYSYS_DEFAULT_ARGS is a better way to achieve the same thing
        if os.getenv('PYSYS_PROGRESS', '').lower() == 'true':
            self.progress = True

        # special hidden dict of extra values to pass to the runner, since we can't change
        # the public API now
        self.userOptions['__extraRunnerOptions'] = {
            'progressWritersEnabled': self.progress,
            'printLogs': printLogs,
            'printLogsDefault':
            printLogsDefault,  # to use if not provided by a CI writer or cmdline
        }

        # load project AFTER we've parsed the arguments, which opens the possibility of using cmd line config in
        # project properties if needed
        Project.findAndLoadProject(outdir=self.outsubdir)

        if defaultAbortOnError is not None:
            setattr(Project.getInstance(), 'defaultAbortOnError',
                    defaultAbortOnError)
        if '--ci' in args and not Project.getInstance().getProperty(
                'supportMultipleModesPerRun', True):
            raise UserError(
                'Cannot use --ci option with a legacy supportMultipleModesPerRun=false project'
            )

        descriptors = createDescriptors(self.arguments,
                                        self.type,
                                        self.includes,
                                        self.excludes,
                                        self.trace,
                                        self.workingDir,
                                        modeincludes=self.modeinclude,
                                        modeexcludes=self.modeexclude,
                                        expandmodes=True)
        descriptors.sort(
            key=lambda d: [d.executionOrderHint, d._defaultSortKey])

        # No exception handler above, as any createDescriptors failure is really a fatal problem that should cause us to
        # terminate with a non-zero exit code; we don't want to run no tests without realizing it and return success

        if self.grep:
            regex = re.compile(self.grep, flags=re.IGNORECASE)
            descriptors = [
                d for d in descriptors
                if (regex.search(d.id) or regex.search(d.title))
            ]

        runnermode = self.modeinclude[0] if len(
            self.modeinclude
        ) == 1 else None  # used when supportMultipleModesPerRun=False
        return self.record, self.purge, self.cycle, runnermode, self.threads, self.outsubdir, descriptors, self.userOptions