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
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)
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
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)
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
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)
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
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)
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)
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)
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
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)
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)
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
def configs(self): if not self._configs: self._configs = ConfigsFile(self.projfolder) return self._configs
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