Beispiel #1
0
def get_electronics_test_suites(serialno, devicetype, projectfolder, offline=False):
    try:
        gcf = ConfigsFile(projectfolder)
        logger.info("Using gEDA configs file from : " + projects.cards[devicetype])
    except NoGedaProjectError:
        raise AttributeError("gEDA project for " + devicetype + " not found.")
    cnf_suites = gcf.tests()
    for cnf_suite in cnf_suites:
        suite = get_suiteobj_from_cnf_suite(cnf_suite, gcf, devicetype, offline=offline)
        for lsuite in suite:
            lsuite.serialno = serialno
            logger.info("Constructed Suite : " + repr(lsuite))
            yield lsuite
Beispiel #2
0
def get_sno_from_mac(mac=None, mactype=None, devicetype=None, session=None):

    if mactype is None:
        try:
            projectfolder = projects.cards[devicetype]
        except KeyError:
            raise AttributeError("Project for " + devicetype + " not found.")

        try:
            gcf = ConfigsFile(projectfolder)
            logger.debug("Using gEDA configs file from : " +
                         projects.cards[devicetype])
        except NoGedaProjectError:
            raise AttributeError(
                "gEDA project for " + devicetype + " not found."
            )

        modname = gcf.mactype
    else:
        modname = mactype
    funcname = 'get_sno_from_mac'

    mod = import_(os.path.join(macs_folder, modname))
    func = getattr(mod, funcname)
    return func(mac=mac, session=session)
Beispiel #3
0
def import_pcb(cardfolder):
    """Import PCB and return a populated EntityBom

    Accept cardfolder as an argument and return a populated EntityBOM.
    The cardfolder should be the path to a PCB folder, containing the
    file structure described in ``somewhere``.

    .. seealso::
        - ``gedaif.projfile.GedaProjectFile``
        - ``gEDA Project Folder Structure``

    :param cardfolder: PCB folder (containing schematic, pcb, gerber)
    :type cardfolder: str
    :return: Populated EntityBom
    :rtype: EntityBom

    :Example:

    >>> import tendril.boms.electronics
    >>> bom = tendril.boms.electronics.import_pcb('path/to/cardfolder')

    """
    cardfolder = os.path.abspath(cardfolder)
    pcbbom = None
    configfile = ConfigsFile(cardfolder)
    if configfile.rawconfig is not None:
        pcbbom = EntityElnBom(configfile)
    return pcbbom
Beispiel #4
0
def render_test_report_standalone(serialno,
                                  devicetype,
                                  suites,
                                  outfolder=None):

    if serialno is None:
        raise TypeError("serialno cannot be None")

    if devicetype is None:
        raise TypeError("devicetype cannot be None")

    if suites is None:
        raise TypeError("suites cannot be None")

    if outfolder is None:
        outfolder = os.path.join(INSTANCE_ROOT, 'scratch', 'testing')

    template = os.path.join('testing', 'test_report_template.tex')
    outpath = os.path.join(outfolder, 'TEST-REPORT-' + serialno + '.pdf')

    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    graphs = []
    instruments = {}
    for suite in suites:
        for test in suite._tests:
            graphs.extend(test.graphs)
            graphs.extend(test.histograms)
            if test._inststr is not None and \
                    test._inststr not in instruments.keys():
                instruments[test._inststr] = len(instruments.keys()) + 1

    stage = {
        'suites': [x.render_dox() for x in suites],
        'sno': serialno,
        'testdate': max([x.ts for x in suites]).format(),
        'devicetype': devicetype,
        'desc': gcf.description(devicetype),
        'svnrevision': vcs.get_path_revision(projectfolder),
        'svnrepo': vcs.get_path_repository(projectfolder),
        'graphs': graphs,
        'instruments': instruments
    }

    return render_pdf(stage, template, outpath)
Beispiel #5
0
def get_electronics_test_suites(serialno, devicetype, projectfolder,
                                offline=False, dummy=False):
    try:
        gcf = ConfigsFile(projectfolder)
        logger.info("Using gEDA configs file from : " +
                    projects.cards[devicetype])
    except NoGedaProjectError:
        raise AttributeError("gEDA project for " + devicetype + " not found.")
    cnf_suites = gcf.tests()
    for cnf_suite in cnf_suites:
        suite = get_suiteobj_from_cnf_suite(cnf_suite, gcf, devicetype,
                                            offline=offline)
        for lsuite in suite:
            lsuite.dummy = dummy
            lsuite.serialno = serialno
            logger.info("Constructed Suite : " + repr(lsuite))
            yield lsuite
Beispiel #6
0
def render_test_report_standalone(serialno, devicetype, suites, outfolder=None):

    if serialno is None:
        raise TypeError("serialno cannot be None")

    if devicetype is None:
        raise TypeError("devicetype cannot be None")

    if suites is None:
        raise TypeError("suites cannot be None")

    if outfolder is None:
        outfolder = os.path.join(INSTANCE_ROOT, 'scratch', 'testing')

    template = os.path.join('testing', 'test_report_template.tex')
    outpath = os.path.join(outfolder,
                           'TEST-REPORT-' + serialno + '.pdf')

    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    graphs = []
    instruments = {}
    for suite in suites:
        for test in suite._tests:
            graphs.extend(test.graphs)
            graphs.extend(test.histograms)
            if test._inststr is not None and \
                    test._inststr not in instruments.keys():
                instruments[test._inststr] = len(instruments.keys()) + 1

    stage = {'suites': [x.render_dox() for x in suites],
             'sno': serialno,
             'testdate': max([x.ts for x in suites]).format(),
             'devicetype': devicetype,
             'desc': gcf.description(devicetype),
             'svnrevision': vcs.get_path_revision(projectfolder),
             'svnrepo': vcs.get_path_repository(projectfolder),
             'graphs': graphs,
             'instruments': instruments
             }

    return render_pdf(stage, template, outpath)
Beispiel #7
0
def get_production_strategy(cardname):
    # Alternate is ready.
    try:
        cardfolder = projects.cards[cardname]
    except KeyError:
        logger.error("Could not find Card in entityhub.cards")
        raise KeyError
    cardconf = ConfigsFile(cardfolder)

    prodst = None
    lblst = None
    testst = None
    genmanifest = False

    if cardconf.configdata['documentation']['am'] is True:
        # Assembly manifest should be used
        prodst = "@AM"
        genmanifest = True
    elif cardconf.configdata['documentation']['am'] is False:
        # No Assembly manifest needed
        prodst = "@THIS"
    if cardconf.configdata['productionstrategy']['testing'] == 'normal':
        # Normal test procedure, Test when made
        testst = "@NOW"
    if cardconf.configdata['productionstrategy']['testing'] == 'lazy':
        # Lazy test procedure, Test when used
        testst = "@USE"
    if cardconf.configdata['productionstrategy']['labelling'] == 'normal':
        # Normal test procedure, Label when made
        lblst = "@NOW"
    if cardconf.configdata['productionstrategy']['testing'] == 'lazy':
        # Lazy test procedure, Label when used
        lblst = "@USE"
    series = cardconf.configdata['snoseries']
    genlabel = False
    labels = []
    if isinstance(cardconf.configdata['documentation']['label'], dict):
        for k in sorted(cardconf.configdata['documentation']['label'].keys()):
            labels.append({
                'code':
                k,
                'ident':
                cardname + '.' + cardconf.configdata['label'][k]
            })
        genlabel = True
    elif isinstance(cardconf.configdata['documentation']['label'], str):
        labels.append({
            'code': cardconf.configdata['documentation']['label'],
            'ident': cardname
        })
        genlabel = True

    return prodst, lblst, testst, genmanifest, genlabel, series, labels
Beispiel #8
0
def get_mac_from_sno(serialno=None, session=None):
    devicetype = serialnos.get_serialno_efield(sno=serialno)

    try:
        projectfolder = projects.cards[devicetype]
    except KeyError:
        raise AttributeError("Project for " + devicetype + " not found.")

    try:
        gcf = ConfigsFile(projectfolder)
        logger.debug("Using gEDA configs file from : " +
                     projects.cards[devicetype])
    except NoGedaProjectError:
        raise AttributeError("gEDA project for " + devicetype + " not found.")

    modname = gcf.mactype
    funcname = 'get_mac_from_sno'

    mod = import_(os.path.join(macs_folder, modname))
    func = getattr(mod, funcname)
    return func(serialno=serialno, session=session)
Beispiel #9
0
def render_test_report(serialno=None, outfolder=None, session=None):
    """
    Renders the latest test results marked against the specified ``serialno``.

    Since this function is defined against the database, all arguments should
    be keyword arguments.

    :param serialno: The serial number of the device.
    :type serialno: :class:`str` or :class:`tendril.entityhub.db.SerialNumber`
    :param outfolder: The folder in which the output file should be created.
    :type outfolder: str
    :param session: The database session. If None, the function will make
                    it's own.
    :return: The output file path.

    .. rubric:: Template Used

    ``tendril/dox/templates/testing/test_report_template.tex``
    (:download:`Included version
    <../../tendril/dox/templates/testing/test_report_template.tex>`)

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``sno``
          - Serial number of the device.
        * - ``testdate``
          - The timestamp of the latest test suite.
        * - ``devicetype``
          - The device type.
        * - ``desc``
          - The device description.
        * - ``svnrevision``
          - The VCS revision of the project config file.
        * - ``svnrepo``
          - The VCS repository containing the project
        * - ``graphs``
          - A list of graphs, each graph being a list of tuples of
            (graphpath, graphtitle)
        * - ``instruments``
          - A list of instrument ident strings, one for each unique
            instrument used in the suites.
        * - ``suites``
          - A list of instances of
            :class:`tendril.testing.testbase.TestSuiteBase` or its subclasses.

    Note that the ``suites`` provided to the template are typically
    expected to be offline test suites which are reconstructed from the
    database.

    .. seealso:: :func:`tendril.testing.analysis.get_test_suite_objects`

    """
    if serialno is None:
        raise ValueError("serialno cannot be None")
    if not isinstance(serialno, SerialNumber):
        serialno = sno_controller.get_serialno_object(sno=serialno,
                                                      session=session)
    if outfolder is None:
        outfolder = os.path.join(INSTANCE_ROOT, 'scratch', 'testing')

    template = os.path.join('testing', 'test_report_template.tex')
    outpath = os.path.join(outfolder,
                           'TEST-REPORT-' + serialno.sno + '.pdf')

    devicetype = serialnos.get_serialno_efield(sno=serialno.sno,
                                               session=session)
    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    suites = analysis.get_test_suite_objects(serialno=serialno.sno,
                                             session=session)
    graphs = []
    instruments = {}
    for suite in suites:
        for test in suite._tests:
            graphs.extend(test.graphs)
            graphs.extend(test.histograms)
            if test._inststr is not None and \
                    test._inststr not in instruments.keys():
                instruments[test._inststr] = len(instruments.keys()) + 1

    stage = {'suites': [x.render_dox() for x in suites],
             'sno': serialno.sno,
             'testdate': max([x.ts for x in suites]).format(),
             'devicetype': devicetype,
             'desc': gcf.description(devicetype),
             'svnrevision': vcs.get_path_revision(projectfolder),
             'svnrepo': vcs.get_path_repository(projectfolder),
             'graphs': graphs,
             'instruments': instruments
             }

    return render_pdf(stage, template, outpath)
Beispiel #10
0
def render_device_summary(devicetype, include_failed=False, outfolder=None):
    """
    Renders a summary of all of the latest test results marked against the
    serial numbers of the specified ``devicetype``.

    :param devicetype: The type of device for which a summary is desired.
    :type devicetype: str
    :param outfolder: The folder in which the output file should be created.
    :type outfolder: str
    :param include_failed: Whether failed test results should be included in
                      the graphs and the statistical analysis. Default False.
    :type include_failed: bool
    :return: The output file path.

    .. rubric:: Template Used

    ``tendril/dox/templates/testing/test_device_summary_template.tex``
    (:download:`Included version
    <../../tendril/dox/templates/testing/test_device_summary_template.tex>`)

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``devicetype``
          - The device type.
        * - ``desc``
          - The device description.
        * - ``svnrevision``
          - The VCS revision of the project config file.
        * - ``svnrepo``
          - The VCS repository containing the project
        * - ``graphs``
          - A list of graphs, each graph being a list of tuples of
            (graphpath, graphtitle)
        * - ``collector``
          - An instance of :class:`tendril.testing.analysis.ResultCollector`,
            containing the collated test results.

    .. seealso:: :func:`tendril.testing.analysis.get_device_test_summary`

    """
    if outfolder is None:
        outfolder = os.path.join(INSTANCE_ROOT, 'scratch', 'testing')
    template = os.path.join('testing', 'test_device_summary_template.tex')
    outpath = os.path.join(outfolder,
                           'TEST-DEVICE-SUMMARY-' + devicetype + '.pdf')

    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    summary = analysis.get_device_test_summary(devicetype=devicetype,
                                               include_failed=include_failed)
    graphs = summary.graphs

    stage = {'devicetype': devicetype,
             'desc': gcf.description(devicetype),
             'svnrevision': vcs.get_path_revision(projectfolder),
             'svnrepo': vcs.get_path_repository(projectfolder),
             'graphs': graphs,
             'collector': summary
             }

    return render_pdf(stage, template, outpath)
Beispiel #11
0
def gen_production_order(outfolder,
                         prod_sno,
                         sourcedata,
                         snos,
                         sourcing_orders=None,
                         root_orders=None,
                         verbose=True):
    """
    Generates a Production Order for a production order defined in a
    ``.yaml`` file.

    .. note::
        This function does not register the document in the
        :mod:`tendril.dox.docstore`. You should use the output file path
        (returned by this function) to register the document when desired.

    .. todo:: Update this function to also handle registering once the main
              scripts are better integrated into the core.

    .. todo:: Document the format of the .yaml file.

    :param outfolder: The folder within which the output file
                      should be created.
    :type outfolder: str
    :param prod_sno: The serial number of the Production Order to generate.
    :type prod_sno: str
    :param sourcedata: The source data loaded from a ``.yaml`` file.
    :type sourcedata: dict
    :param snos: A list of serial numbers to produce, along with whatever
                 other information should be included in the order. See
                 the template for details.
    :type snos: :class:`list` of :class:`dict`
    :param sourcing_orders: A list of sourcing orders which were made to
                            obtain raw materials for this production order.
    :type sourcing_orders: :class:`list` of :class:`str`
    :param root_orders: A list of root orders which is production order is
                        intended to fulfill.
    :type root_orders: :class:`list` of :class:`str`
    :return: The path to the output PDF file.

    .. rubric:: Template Used

    ``tendril\dox\\templates\production\production-order-template.tex``
    (:download:`Included version
    <../../tendril/dox/templates/production/production-order-template.tex>`)

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``sno``
          - The serial number of the production order.
        * - ``title``
          - The title of the production order.
        * - ``cards``
          - A list of different card types to be produced,
            and quantities of each.
        * - ``snos``
          - A list of cards to produce, with serial numbers and other included
            information.
        * - ``sourcing_orders``
          - A list of sourcing orders which were made to obtain raw materials
            for this production order.
        * - ``root_orders``
          - A list of root orders which is production order is
            intended to fulfill.

    """

    cards = []
    if 'cards' in sourcedata.keys():
        cards = [{
            'qty': sourcedata['cards'][k],
            'desc': ConfigsFile(projects.cards[k]).description(k),
            'ident': k
        } for k in sorted(sourcedata['cards'].keys())]

    deltas = {}
    if 'deltas' in sourcedata.keys():
        for delta in sourcedata['deltas']:
            desc = delta['orig-cardname'] + ' -> ' + delta['target-cardname']
            if desc in deltas.keys():
                deltas[desc] += 1
            else:
                deltas[desc] = 1

    lroot_orders = []
    for root_order in root_orders:
        if root_order is not None:
            try:
                root_order_desc = serialnos.get_serialno_efield(root_order)
            except AttributeError:
                root_order_desc = None
        else:
            root_order_desc = None
        lroot_orders.append({'no': root_order, 'desc': root_order_desc})

    stage = {
        'title': sourcedata['title'],
        'cards': cards,
        'deltas': deltas,
        'sourcing_orders': sourcing_orders,
        'sno': prod_sno,
        'snos': snos,
        'root_orders': lroot_orders,
    }

    outpath = os.path.join(outfolder, str(prod_sno) + '.pdf')
    template = 'production/production-order-template.tex'
    render.render_pdf(stage, template, outpath, verbose=verbose)
    return outpath
Beispiel #12
0
def render_test_report(serialno=None, outfolder=None, session=None):
    """
    Renders the latest test results marked against the specified ``serialno``.

    Since this function is defined against the database, all arguments should
    be keyword arguments.

    :param serialno: The serial number of the device.
    :type serialno: :class:`str` or :class:`tendril.entityhub.db.SerialNumber`
    :param outfolder: The folder in which the output file should be created.
    :type outfolder: str
    :param session: The database session. If None, the function will make
                    it's own.
    :return: The output file path.

    .. rubric:: Template Used

    ``tendril/dox/templates/testing/test_report_template.tex``
    (:download:`Included version
    <../../tendril/dox/templates/testing/test_report_template.tex>`)

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``sno``
          - Serial number of the device.
        * - ``testdate``
          - The timestamp of the latest test suite.
        * - ``devicetype``
          - The device type.
        * - ``desc``
          - The device description.
        * - ``svnrevision``
          - The VCS revision of the project config file.
        * - ``svnrepo``
          - The VCS repository containing the project
        * - ``graphs``
          - A list of graphs, each graph being a list of tuples of
            (graphpath, graphtitle)
        * - ``instruments``
          - A list of instrument ident strings, one for each unique
            instrument used in the suites.
        * - ``suites``
          - A list of instances of
            :class:`tendril.testing.testbase.TestSuiteBase` or its subclasses.

    Note that the ``suites`` provided to the template are typically
    expected to be offline test suites which are reconstructed from the
    database.

    .. seealso:: :func:`tendril.testing.analysis.get_test_suite_objects`

    """
    if serialno is None:
        raise ValueError("serialno cannot be None")
    if not isinstance(serialno, SerialNumber):
        serialno = sno_controller.get_serialno_object(sno=serialno,
                                                      session=session)
    if outfolder is None:
        outfolder = os.path.join(INSTANCE_ROOT, 'scratch', 'testing')

    template = os.path.join('testing', 'test_report_template.tex')
    outpath = os.path.join(outfolder, 'TEST-REPORT-' + serialno.sno + '.pdf')

    devicetype = serialnos.get_serialno_efield(sno=serialno.sno,
                                               session=session)
    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    suites = analysis.get_test_suite_objects(serialno=serialno.sno,
                                             session=session)
    graphs = []
    instruments = {}
    for suite in suites:
        for test in suite._tests:
            graphs.extend(test.graphs)
            graphs.extend(test.histograms)
            if test._inststr is not None and \
                    test._inststr not in instruments.keys():
                instruments[test._inststr] = len(instruments.keys()) + 1

    stage = {
        'suites': [x.render_dox() for x in suites],
        'sno': serialno.sno,
        'testdate': max([x.ts for x in suites]).format(),
        'devicetype': devicetype,
        'desc': gcf.description(devicetype),
        'svnrevision': vcs.get_path_revision(projectfolder),
        'svnrepo': vcs.get_path_repository(projectfolder),
        'graphs': graphs,
        'instruments': instruments
    }

    return render_pdf(stage, template, outpath)
Beispiel #13
0
def render_device_summary(devicetype, include_failed=False, outfolder=None):
    """
    Renders a summary of all of the latest test results marked against the
    serial numbers of the specified ``devicetype``.

    :param devicetype: The type of device for which a summary is desired.
    :type devicetype: str
    :param outfolder: The folder in which the output file should be created.
    :type outfolder: str
    :param include_failed: Whether failed test results should be included in
                      the graphs and the statistical analysis. Default False.
    :type include_failed: bool
    :return: The output file path.

    .. rubric:: Template Used

    ``tendril/dox/templates/testing/test_device_summary_template.tex``
    (:download:`Included version
    <../../tendril/dox/templates/testing/test_device_summary_template.tex>`)

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``devicetype``
          - The device type.
        * - ``desc``
          - The device description.
        * - ``svnrevision``
          - The VCS revision of the project config file.
        * - ``svnrepo``
          - The VCS repository containing the project
        * - ``graphs``
          - A list of graphs, each graph being a list of tuples of
            (graphpath, graphtitle)
        * - ``collector``
          - An instance of :class:`tendril.testing.analysis.ResultCollector`,
            containing the collated test results.

    .. seealso:: :func:`tendril.testing.analysis.get_device_test_summary`

    """
    if outfolder is None:
        outfolder = os.path.join(INSTANCE_ROOT, 'scratch', 'testing')
    template = os.path.join('testing', 'test_device_summary_template.tex')
    outpath = os.path.join(outfolder,
                           'TEST-DEVICE-SUMMARY-' + devicetype + '.pdf')

    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    summary = analysis.get_device_test_summary(devicetype=devicetype,
                                               include_failed=include_failed)
    graphs = summary.graphs

    stage = {
        'devicetype': devicetype,
        'desc': gcf.description(devicetype),
        'svnrevision': vcs.get_path_revision(projectfolder),
        'svnrepo': vcs.get_path_repository(projectfolder),
        'graphs': graphs,
        'collector': summary
    }

    return render_pdf(stage, template, outpath)
Beispiel #14
0
def get_test_report(serialno=None, session=None):
    """
    Constructs and returns the stage components for the latest test results
    marked against the specified ``serialno``.

    Since this function is defined against the database, all arguments should
    be keyword arguments.

    :param serialno: The serial number of the device.
    :type serialno: :class:`str` or :class:`tendril.entityhub.db.SerialNumber`
    :param session: The database session. If None, the function will make
                    it's own.
    :return: The output file path.

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``sno``
          - Serial number of the device.
        * - ``testdate``
          - The timestamp of the latest test suite.
        * - ``devicetype``
          - The device type.
        * - ``desc``
          - The device description.
        * - ``svnrevision``
          - The VCS revision of the project config file.
        * - ``svnrepo``
          - The VCS repository containing the project
        * - ``graphs``
          - A list of graphs, each graph being the htmlcontent generated
            by python-nvd3.
        * - ``instruments``
          - A list of instrument ident strings, one for each unique
            instrument used in the suites.
        * - ``suites``
          - A list of instances of
            :class:`tendril.testing.testbase.TestSuiteBase` or its subclasses.

    Note that the ``suites`` provided to the template are typically
    expected to be offline test suites which are reconstructed from the
    database.

    .. seealso:: :func:`tendril.testing.analysis.get_test_suite_objects`

    .. todo:: Move this function into :mod:`tendril.testing.analysis` and
              have :func:`tendril.dox.testing.render_test_report` use the
              same infrastructure.

    """
    if serialno is None:
        raise ValueError("serialno cannot be None")
    if not isinstance(serialno, SerialNumber):
        serialno = sno_controller.get_serialno_object(sno=serialno,
                                                      session=session)

    devicetype = serialnos.get_serialno_efield(sno=serialno.sno,
                                               session=session)
    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    suites = analysis.get_test_suite_objects(serialno=serialno.sno,
                                             session=session)
    instruments = {}
    for suite in suites:
        for test in suite._tests:
            if test._inststr is not None and \
                    test._inststr not in instruments.keys():
                instruments[test._inststr] = len(instruments.keys()) + 1

    stage = {
        'suites': [x.render_dox() for x in suites],
        'sno': serialno.sno,
        'testdate': max([x.ts for x in suites]).format(),
        'devicetype': devicetype,
        'desc': gcf.description(devicetype),
        'svnrevision': vcs.get_path_revision(projectfolder),
        'svnrepo': vcs.get_path_repository(projectfolder),
        'instruments': instruments
    }

    return stage
Beispiel #15
0
 def configs(self):
     if not self._configs:
         self._configs = ConfigsFile(self.projfolder)
     return self._configs
Beispiel #16
0
def get_test_report(serialno=None, session=None):
    """
    Constructs and returns the stage components for the latest test results
    marked against the specified ``serialno``.

    Since this function is defined against the database, all arguments should
    be keyword arguments.

    :param serialno: The serial number of the device.
    :type serialno: :class:`str` or :class:`tendril.entityhub.db.SerialNumber`
    :param session: The database session. If None, the function will make
                    it's own.
    :return: The output file path.

    .. rubric:: Stage Keys Provided
    .. list-table::

        * - ``sno``
          - Serial number of the device.
        * - ``testdate``
          - The timestamp of the latest test suite.
        * - ``devicetype``
          - The device type.
        * - ``desc``
          - The device description.
        * - ``svnrevision``
          - The VCS revision of the project config file.
        * - ``svnrepo``
          - The VCS repository containing the project
        * - ``graphs``
          - A list of graphs, each graph being the htmlcontent generated
            by python-nvd3.
        * - ``instruments``
          - A list of instrument ident strings, one for each unique
            instrument used in the suites.
        * - ``suites``
          - A list of instances of
            :class:`tendril.testing.testbase.TestSuiteBase` or its subclasses.

    Note that the ``suites`` provided to the template are typically
    expected to be offline test suites which are reconstructed from the
    database.

    .. seealso:: :func:`tendril.testing.analysis.get_test_suite_objects`

    .. todo:: Move this function into :mod:`tendril.testing.analysis` and
              have :func:`tendril.dox.testing.render_test_report` use the
              same infrastructure.

    """
    if serialno is None:
        raise ValueError("serialno cannot be None")
    if not isinstance(serialno, SerialNumber):
        serialno = sno_controller.get_serialno_object(sno=serialno,
                                                      session=session)

    devicetype = serialnos.get_serialno_efield(sno=serialno.sno,
                                               session=session)
    projectfolder = projects.cards[devicetype]
    gcf = ConfigsFile(projectfolder)

    suites = analysis.get_test_suite_objects(serialno=serialno.sno,
                                             session=session)
    instruments = {}
    for suite in suites:
        for test in suite._tests:
            if test._inststr is not None and \
                    test._inststr not in instruments.keys():
                instruments[test._inststr] = len(instruments.keys()) + 1

    stage = {'suites': [x.render_dox() for x in suites],
             'sno': serialno.sno,
             'testdate': max([x.ts for x in suites]).format(),
             'devicetype': devicetype,
             'desc': gcf.description(devicetype),
             'svnrevision': vcs.get_path_revision(projectfolder),
             'svnrepo': vcs.get_path_repository(projectfolder),
             'instruments': instruments
             }

    return stage