Exemple #1
0
    def run(self, timeout):
        def target():
            logger.debug(pb('Thread started'))
            self.process = subprocess.Popen(self.cmd,
                                            stdout=subprocess.PIPE,
                                            stderr=subprocess.PIPE)
            out, err = self.process.communicate()
            # keep the stdout and stderr
            self.out = out
            self.err = err
            logger.debug(pb('Thread finished'))

        thread = threading.Thread(target=target)
        thread.start()

        thread.join(timeout)
        if thread.is_alive():
            self.timeout = True
            print pr('Terminating process, timed out %i s' % timeout)
            self.process.terminate()
            thread.join()
        self.retcode = self.process.returncode
        # NOTE: a negative returncode -N indicates that the child
        #   was terminated by signal N (Unix only)
        if self.retcode:
            logger.warn(pr('Process return code: %i' % self.retcode))
        else:
            logger.info(pb('Process return code: %i' % self.retcode))
Exemple #2
0
    def run(self, timeout):
        def target():
            logger.debug( pb('Thread started') )
            self.process = subprocess.Popen(self.cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            out, err = self.process.communicate()
            # keep the stdout and stderr
            self.out = out
            self.err = err
            logger.debug( pb('Thread finished') )

        thread = threading.Thread(target=target)
        thread.start()

        thread.join(timeout)
        if thread.is_alive():
            self.timeout = True
            print pr('Terminating process, timed out %i s' %timeout)
            self.process.terminate()
            thread.join()
        self.retcode =  self.process.returncode
        # NOTE: a negative returncode -N indicates that the child
        #   was terminated by signal N (Unix only)
        if self.retcode:
            logger.warn( pr('Process return code: %i' %self.retcode) )
        else:
            logger.info( pb('Process return code: %i' %self.retcode) )
Exemple #3
0
def add_test_project(sch):
    '''
    Add a schematic file as a test on the testsuite.

    - create directory (start with simulation types, ex. DC_TR_myCircuit_prj)
    - search and copy related subcircuits
    - TODO search and copy included SPICE files
    - initialize reference netlis
    - initialize reference data file
    - TODO initialize SPICE, run qucsconv

    :param sch: path to a schematic file (.sch)
    :return: destination directory
    '''

    print pb('Adding new project to test-suite.')
    print 'Adding schematic: %s' % (sch)

    # get schematic basename
    sch_name = os.path.splitext(os.path.basename(sch))[0]

    # scan schematic for types of simulation [.DC, .AC, .TR, .SP, .SW]
    # create dir, concatenate simulation type(s), schematic name, append '_prj'
    # ex. TR_myCircuit_prj, DC_AC_TR_complexCircuit_prj
    sim_used = get_sch_simulations(sch)
    sim_found = ''
    for sim in sim_used:
        #skip dot, prepend simulation types
        sim_found += sim[1:] + '_'
    if not sim_found:
        sys.exit(
            pr('This schematic performs no simulation, is it a subcircuit?'))
    dest = sim_found + sch_name + '_prj'

    # scan for subcircuits, to be copied over to destination
    sub_files = get_sch_subcircuits(sch)

    dest_dir = os.path.join(os.getcwd(), 'testsuite', dest)
    if not os.path.exists(dest_dir):
        print 'Creating directory:', dest_dir
        os.makedirs(dest_dir)
    else:
        print 'Use existing directory:', dest_dir

    # copy schematic
    shutil.copy2(sch, dest_dir)

    # copy listed subcircuit (recursive)
    for sub in sub_files:
        print 'Copying sub-circuit', sub
        src = os.path.join(os.path.dirname(sch), sub)
        if os.path.isfile(src):
            shutil.copy2(src, dest_dir)
        else:
            sys.exit(pr('Oops, subcircuit not found: ', src))

    return dest_dir
Exemple #4
0
def add_test_project(sch):
    '''
    Add a schematic file as a test on the testsuite.

    - create directory (start with simulation types, ex. DC_TR_myCircuit_prj)
    - search and copy related subcircuits
    - TODO search and copy included SPICE files
    - initialize reference netlis
    - initialize reference data file
    - TODO initialize SPICE, run qucsconv

    :param sch: path to a schematic file (.sch)
    :return: destination directory
    '''

    print pb('Adding new project to test-suite.')
    print 'Adding schematic: %s' %(sch)

    # get schematic basename
    sch_name = os.path.splitext(os.path.basename(sch))[0]

    # scan schematic for types of simulation [.DC, .AC, .TR, .SP, .SW]
    # create dir, concatenate simulation type(s), schematic name, append '_prj'
    # ex. TR_myCircuit_prj, DC_AC_TR_complexCircuit_prj
    sim_used = get_sch_simulations(sch)
    sim_found = ''
    for sim in sim_used:
        #skip dot, prepend simulation types
        sim_found+=sim[1:]+'_'
    if not sim_found:
        sys.exit( pr('This schematic performs no simulation, is it a subcircuit?'))
    dest = sim_found + sch_name + '_prj'

    # scan for subcircuits, to be copied over to destination
    sub_files = get_sch_subcircuits(sch)

    dest_dir = os.path.join(os.getcwd(),'testsuite', dest)
    if not os.path.exists(dest_dir):
        print 'Creating directory:', dest_dir
        os.makedirs(dest_dir)
    else:
        print 'Use existing directory:', dest_dir

    # copy schematic
    shutil.copy2(sch, dest_dir)

    # copy listed subcircuit (recursive)
    for sub in sub_files:
        print 'Copying sub-circuit', sub
        src = os.path.join(os.path.dirname(sch),sub)
        if os.path.isfile(src):
            shutil.copy2(src, dest_dir)
        else:
            sys.exit(pr('Oops, subcircuit not found: ', src))

    return dest_dir
Exemple #5
0
def compare_datasets(ref_dataset, test_dataset, rtol, atol):
    '''
    Compare two datasets for numerical differences.

    :param ref_dataset : reference dataset
    :param test_dataset: test dataset
    :param rtol: relative tolerance
    :param atol: absolute tolerance
    :return failed: list of traces that failed numerical check
    '''

    from qucstest.colors import pb, pr, pg

    if not os.path.isfile(ref_dataset):
        sys.exit('No reference dataset: %s' % ref_dataset)
    if not os.path.isfile(test_dataset):
        sys.exit('No test dataset: %s' % test_dataset)

    # TODO failed also catches if the solver didn't run, output_dataset will be empty,
    # it will fail the comparison

    # let's compare results

    # list of failed variable comparisons
    failed = []

    logger.info(pb('load data %s' % (ref_dataset)))
    ref = QucsData(ref_dataset)

    logger.info(pb('load data %s' % (test_dataset)))
    test = QucsData(test_dataset)

    logger.info(
        pb('Comparing dependent variables [rtol=%s, atol=%s]' % (rtol, atol)))

    for name in ref.dependent.keys():
        ref_trace = ref.data[name]
        test_trace = test.data[name]

        # check: abs(test - ref) <= (atol + rtol * abs(ref) )
        if not np.allclose(test_trace, ref_trace, rtol=rtol, atol=atol):
            logger.warning(pr('  Failed %s' % (name)))
            failed.append(name)
        else:
            logger.info(pg('  Passed %s' % (name)))

    return failed
Exemple #6
0
def compare_datasets(ref_dataset, test_dataset, rtol=1e-5, atol=1e-8):
    '''
    Compare two datasets for numerical differences.

    :param ref_dataset : reference dataset
    :param test_dataset: test dataset
    :param rtol: relative tolerance
    :param atol: absolute tolerance
    :return failed: list of traces that failed numerical check
    '''

    from qucstest.colors import pb, pr, pg

    if not os.path.isfile(ref_dataset):
        sys.exit('No reference dataset: %s' %ref_dataset)
    if not os.path.isfile(test_dataset):
        sys.exit('No test dataset: %s' %rest_dataset)

    # TODO failed also catches if the solver didn't run, output_dataset will be empty,
    # it will fail the comparison

    # let's compare results

    # list of failed variable comparisons
    failed=[]

    logger.info( pb('load data %s' %(ref_dataset)) )
    ref = QucsData(ref_dataset)

    logger.info( pb('load data %s' %(test_dataset)) )
    test = QucsData(test_dataset)

    logger.info( pb('Comparing dependent variables [rtol=%s, atol=%s]' %(rtol,atol)) )

    for name in ref.dependent.keys():
        ref_trace  = ref.data[name]
        test_trace = test.data[name]

        # check: abs(test - ref) <= (atol + rtol * ref)
        if not np.allclose(test_trace, ref_trace, rtol=rtol, atol=atol):
            logger.warning( pr('  Failed %s' %(name)) )
            failed.append(name)
        else:
            logger.info(pg('  Passed %s' %(name)) )

    return failed
Exemple #7
0
def run_simulation(test, qucspath, plot_interactive=False):
    '''
    Run simulation from reference netlist and compare outputs (dat, log)

    :param test: test object containing the test info
    :param qucspath: path containing qucsator
    :param plot_interactive: plot graphs as data is compared
    '''

    name = test.getSchematic()


    test_dir = os.getcwd()

    proj_dir = os.path.join(test_dir, 'testsuite', test.name)
    test.path = proj_dir
    print '\nProject : ', proj_dir


    input_net = os.path.join(proj_dir, "netlist.txt")
    if not os.path.isfile(input_net):
        sys.exit('Input netlist not found')

    # fetch types of simulation an types of components
    comps = get_net_components(input_net)
    sim = get_net_simulations(input_net)

    test.comp_types = comps
    test.sim_types = sim

    # get the Qucs Schematic version from the schematic
    schematic = os.path.join(proj_dir, test.schematic)

    test.version = get_sch_version(schematic)
    test.dataset =  get_sch_dataset(schematic)

    output_dataset = os.path.join(proj_dir, "test_"+test.dataset)

    ext = '' if os.name != 'nt' else '.exe'
    cmd = [os.path.join(qucspath, "qucsator"+ext), "-i", input_net, "-o", output_dataset]
    print 'Running : ', ' '.join(cmd)

    # TODO run a few times, record average/best of 3
    # call the solver in a subprocess, set the timeout
    tic = time.time()
    command = Command(cmd)
    command.run(timeout=maxTime)
    toc = time.time()
    runtime = toc - tic

    # If return code, ignore time
    if command.retcode:
        test.status = 'FAIL'
        test.message = 'FAIL CODE %i' %command.retcode
    elif command.timeout:
        test.status = 'TIME_FAIL'
        test.message = 'TIMEOUT'
    else:
        test.status = 'PASS'
        test.runtime = '%f' %runtime

    logger.info( pb('Runtime: %f' %runtime) )

    if (command.timeout):

        errout =  os.path.join(proj_dir, 'error_timeout.txt')
        print pr('Failed with timeout, saving: \n   %s' % errout)
        with open(errout, 'w') as myFile:
            myFile.write(command.err)

    if (command.retcode):
        errout = os.path.join(proj_dir, 'error_code.txt')
        print pr('Failed with error code, saving: \n   %s' % errout)
        with open(errout, 'w') as myFile:
            myFile.write(command.err)

    # perform result comparison
    if (not command.timeout) and (command.retcode==0):
        ref_dataset = os.path.join(proj_dir, get_sch_dataset(schematic))

        numerical_diff = compare_datasets(ref_dataset, output_dataset, rtol, atol)
        if numerical_diff:
            test.failed_traces = numerical_diff
            test.status = 'NUM_FAIL'

        # show all traces
        if plot_interactive:
            plot_error(ref_dataset, output_dataset, QucsData(ref_dataset).dependent.keys(), show=plot_interactive)

        # quiet save of fail numerical check
        if numerical_diff:
            plot_error(ref_dataset, output_dataset, test.failed_traces)

    return test
Exemple #8
0
    # TODO improve the discovery of qucs, qucator
    if args.prefix:
        #prefix = os.path.join(args.prefix, 'bin', os.sep)
        prefix = [args.prefix]
    else:
        # TODO add default paths, build location, system locations
        prefix = os.path.join('/usr/local/bin/')


    if (args.qucs or args.p):
        ext = '' if os.name != 'nt' else '.exe'
        if os.path.isfile(os.path.join(prefix[0], 'qucs'+ext)):
            print pb('Found Qucs in: %s' %(prefix))
        else:
            sys.exit(pr('Oh dear, Qucs not found in: %s' %(prefix)))

    if (args.qucsator or args.reset):
        ext = '' if os.name != 'nt' else '.exe'
        if os.path.isfile(os.path.join(prefix[0], 'qucsator'+ext)):
            print pb('Found Qucsator in: %s' %(prefix))
        else:
            sys.exit(pr('Oh dear, Qucsator not found in: %s' %(prefix)))


    if args.compare_qucsator:

        prefix = args.compare_qucsator

        logger.info( pb('Comparing the following qucsators:') )
Exemple #9
0
def run_simulation(test, qucspath, plot_interactive=False):
    '''
    Run simulation from reference netlist and compare outputs (dat, log)

    :param test: test object containing the test info
    :param qucspath: path containing qucsator
    :param plot_interactive: plot graphs as data is compared
    '''

    name = test.getSchematic()

    test_dir = os.getcwd()

    proj_dir = os.path.join(test_dir, 'testsuite', test.name)
    test.path = proj_dir
    print '\nProject : ', proj_dir

    input_net = os.path.join(proj_dir, "netlist.txt")
    if not os.path.isfile(input_net):
        sys.exit('Input netlist not found')

    # fetch types of simulation an types of components
    comps = get_net_components(input_net)
    sim = get_net_simulations(input_net)

    test.comp_types = comps
    test.sim_types = sim

    # get the Qucs Schematic version from the schematic
    schematic = os.path.join(proj_dir, test.schematic)

    test.version = get_sch_version(schematic)
    test.dataset = get_sch_dataset(schematic)

    output_dataset = os.path.join(proj_dir, "test_" + test.dataset)

    ext = '' if os.name != 'nt' else '.exe'
    cmd = [
        os.path.join(qucspath, "qucsator" + ext), "-i", input_net, "-o",
        output_dataset
    ]
    print 'Running : ', ' '.join(cmd)

    # TODO run a few times, record average/best of 3
    # call the solver in a subprocess, set the timeout
    tic = time.time()
    command = Command(cmd)
    command.run(timeout=maxTime)
    toc = time.time()
    runtime = toc - tic

    # If return code, ignore time
    if command.retcode:
        test.status = 'FAIL'
        test.message = 'FAIL CODE %i' % command.retcode
    elif command.timeout:
        test.status = 'TIME_FAIL'
        test.message = 'TIMEOUT'
    else:
        test.status = 'PASS'
        test.runtime = '%f' % runtime

    logger.info(pb('Runtime: %f' % runtime))

    if (command.timeout):

        errout = os.path.join(proj_dir, 'error_timeout.txt')
        print pr('Failed with timeout, saving: \n   %s' % errout)
        with open(errout, 'w') as myFile:
            myFile.write(command.err)

    if (command.retcode):
        errout = os.path.join(proj_dir, 'error_code.txt')
        print pr('Failed with error code, saving: \n   %s' % errout)
        with open(errout, 'w') as myFile:
            myFile.write(command.err)

    # perform result comparison
    if (not command.timeout) and (command.retcode == 0):
        ref_dataset = os.path.join(proj_dir, get_sch_dataset(schematic))

        numerical_diff = compare_datasets(ref_dataset,
                                          output_dataset,
                                          rtol=test.rtol,
                                          atol=test.atol)
        if numerical_diff:
            test.failed_traces = numerical_diff
            test.status = 'NUM_FAIL'

        # show all traces
        if plot_interactive:
            plot_error(ref_dataset,
                       output_dataset,
                       QucsData(ref_dataset).dependent.keys(),
                       show=plot_interactive)

        # quiet save of fail numerical check
        if numerical_diff:
            plot_error(ref_dataset, output_dataset, test.failed_traces)

    return test
Exemple #10
0
        prefix = args.prefix
        prefix_given = True
    else:
        # use default paths, build location, system locations
        prefix = os.path.join('')

    if args.compare:
        prefixes = args.compare
        if (args.qucsator):
            logger.info(pb('Comparing the following qucsators:'))
            for qp in prefixes:
                ext = '' if os.name != 'nt' else '.exe'
                if os.path.isfile(os.path.join(qp, 'qucsator' + ext)):
                    print pb('%s' % (qp))
                else:
                    sys.exit(pr("No qucsator binary found in: %s" % (qp)))
        else:
            for qp in prefixes:
                ext = '' if os.name != 'nt' else '.exe'
                if os.path.isfile(os.path.join(qp, 'qucs' + ext)):
                    print pb('%s' % (qp))
                else:
                    sys.exit(pr("No qucs binary found in: %s" % (qp)))
    elif not prefix_given:
        pass
    else:
        prefixes = [prefix]

        if (args.qucs or args.qprint):
            ext = '' if os.name != 'nt' else '.exe'
            if os.path.isfile(os.path.join(prefix, 'qucs' + ext)):