Beispiel #1
0
def set_chamber_slots(max_chamber_slots=None):
    active_chamber_slots_key, max_chamber_slots_key = get_chamber_slots_keys()
    max_slots = str(DEFAULT_MAX_CHAMBER_SLOTS
                    ) if not max_chamber_slots else max_chamber_slots
    aplib.cache_data(active_chamber_slots_key, [])
    aplib.cache_data(max_chamber_slots_key, max_slots)
    return True
Beispiel #2
0
def reset_globals():
    """ Reset Globals
    Used by Supercontainer in SC-PreSeq
    """
    log.debug("Chamber globals: reset...")
    container = aplib.get_my_container_key()
    S_KEY = '_'.join(container.split('|')[:-1])
    cp_key = 'chamber_profile_' + S_KEY
    cc_key = 'chamber_corners_' + S_KEY
    aplib.cache_data(cp_key, None)
    aplib.cache_data(cc_key, None)
    log.debug("Chamber globals reset done!")
    return
Beispiel #3
0
def prestep__restore_container():
    """Restore running status container
    read local slots status from /tftpboot/slot_status/slot_status, restore start containers
    :return:
    """
    area = 'SYSBI'
    slot_status_file = r'/tftpboot/slot_status/slot_status'
    with open(slot_status_file, 'r') as f:
        slot_status = [cell.strip() for cell in f.readlines() if ':' in cell]

    lib.cache_data('slot_status', slot_status)
    log.info('Local: {}'.format(slot_status))
    log.debug('******************')
    for i in range(1, 9):
        log.info('{}'.format(slot_status[(i - 1) * 12:i * 12]))
    log.debug('******************')

    keep_status = ['ERRO', 'FAIL', 'PASS', 'IDLE', 'NULL']

    for ctr in slot_status:
        station = 'Station'
        cell = 'AUTO:UUT{:02}_{:02}'.format(
            int(ctr.split(':')[1].split('-')[0]),
            int(ctr.split(':')[1].split('-')[1]))
        log.info('Station: {}, Cell: {}'.format(station, cell))
        if any(status in ctr for status in keep_status):
            log.info('Container [{}] Keep {}'.format(cell, ctr))
            continue
        log.info('Container ctr restore to running'.format(ctr))
        while True:
            run_apollo_container(prod_line='UAG_C3K',
                                 area=area,
                                 test_station=station,
                                 container=cell,
                                 mode='PROD')
            if lib.get_container_status(cell) == 'RUNNING':
                time.sleep(60)
                break
            log.info('{} running meet issue, re-start'.format(cell))
            continue

    return lib.PASS
Beispiel #4
0
def prestep__chamber_staging(area):
    """ Chamber Staging
    Run by Supercontainer
    Operator selects which UUT slots to run for the chamber.
    :param (str) area: Test Area
    :return:
    """
    info = aplib.get_pre_sequence_info()
    active_chamber_slots = '0'
    max_chamber_slots = len(info.containers)
    log.debug("MAX Chamber SLots = {0}".format(max_chamber_slots))
    ans_good = False
    while not ans_good:
        ans = aplib.ask_question(
            "Enter sequential UUT slots for chamber testing [Default = 1-{0}]:\n"
            " Ex1. 1-10,12,15\n"
            " Ex2. 2,4,6,8\n"
            " Ex3. 2-11\n".format(max_chamber_slots))
        ans = '1-{0}'.format(max_chamber_slots) if ans == '' else ans
        ans_good = True if re.match("(^[0-9]+[0-9,\-]*$)", ans) else False
        if ans.upper() == 'ABORT':
            raise apexceptions.AbortException(
                "Operator aborted chamber staging of UUT slots.")

        active_chamber_slots = common_utils.expand_comma_dash_num_list(ans)
        if max(active_chamber_slots) > max_chamber_slots:
            log.warning(
                "Chamber UUT slot selection exceeds maximum available; please re-enter."
            )
            ans_good = False

    log.debug(
        "Active Chamber SLots accepted: {0}".format(active_chamber_slots))
    ACTIVECS_KEY, MAXCS_KEY = get_chamber_slots_keys()
    aplib.cache_data(ACTIVECS_KEY, active_chamber_slots)
    aplib.cache_data(MAXCS_KEY, str(max_chamber_slots))

    # Reset globals
    reset_globals()

    return aplib.PASS
Beispiel #5
0
def change_slot_status(slot, status, skip_error=True):
    """Change Slot Status
    Change slot status in local file
    :param slot:
    sample: Station_B_01 = 1-1: first 1 is Rack number , second 1 is Cell number
    :param status:
    sample: status: Pass, Fail1, Fail2, Idel.
    pass: product_name,1-1,Pass
    Fail1: product_name,1-1,Fail1,num-num.   #num-num:re-test cell
    Fail2: product_name,1-1,Fail2
    IDEL:
    :param skip_error:
    :return:
    """
    log.info('{} {} change lock...'.format(slot, status))
    with locking.named_priority_lock(lockname='slot_status_lock',
                                     release_timeout=60,
                                     wait_timeout=30 * 60):
        slot_status = lib.get_cached_data('slot_status')
        log.debug('>>>>> ')
        for i in range(1, 9):
            log.info('{}'.format(slot_status[(i - 1) * 12:i * 12]))
        log.debug('>>>>> '.format(slot_status))
        if 'ERRO' in slot_status[slot_index[slot]] and skip_error:
            log.debug('ERROR cannot change')
        else:
            if "ERRO" in status:
                status = "0ERRO1"
            slot_status[slot_index[slot]] = "{}:{}".format(status, slot)
            lib.cache_data('slot_status', slot_status)
        log.debug('<<<<< ')
        for i in range(1, 9):
            log.info('{}'.format(slot_status[(i - 1) * 12:i * 12]))
        log.debug('<<<<< ')
    cap_slot_status()
    log.info('Change local OK')
    return True
Beispiel #6
0
    def _allocate_card(self,
                       action,
                       priority=100,
                       card_name='card',
                       keep_last=False):
        """ Allocate Card (INTERNAL)

        Activating a linecard or Supervisor = start using it.
        Deactivating a linecard or Supervisor = done using it and no longer need to talk to the card.

        This routine uses an "active card" list maintained in global cache to keep track of all linecards/Supervisors in use.
        Also a 'remove from list' is performed on all non-running containers still in the 'active card list'
        (could happen with abort or exception w/ no cleanup).

        :param (str) action: 'deactivate', 'activate', 'show'
        :param (int) priority: lower number is higher priority
        :param (bool) keep_last: Future feature (NOT USED); use to keep last container when deactivating to stay
                          powered on for something else prior to cleanup.
        :return: True|False
        """
        log.debug("Configuration Data")
        self.ud.derive_device_info()
        card_config = self.ud.uut_config.get(card_name.lower(), None)
        if not card_config:
            log.warning("No configuration data for the UUT card: {0}".format(
                card_name))
            log.warning(
                "Please check the card name and the Apollo x_config.py.")
            return False
        log.debug("Card config = {0}".format(card_config))

        container_key = aplib.get_my_container_key()
        container = container_key.split("|")[-1]
        pl, ar, ts, _ = container_key.split("|", 3)
        active_name = '_'.join([pl, ar, ts, 'ActiveModular'])
        with locking.ContainerPriorityLock('__active_modular__',
                                           priority=priority):
            log.debug("Lock    : {0}".format(active_name))
            log.debug("Priority: {0}".format(priority))

            active_cards = aplib.get_cached_data(active_name)
            if active_cards:
                idx = active_cards.index(
                    container) if container in active_cards else -1
            else:
                active_cards = []

            if action == 'activate':
                log.debug("Active {0}.".format(card_name))
                if not active_cards:
                    log.debug("First {0} container to use: '{1}'".format(
                        card_name.lower(), container))
                    active_cards = [container]
                    aplib.cache_data(active_name, active_cards)
                else:
                    if container not in active_cards:
                        log.debug(
                            "Adding {0} container to the active list: {1}".
                            format(card_name.lower(), container))
                        active_cards.append(container)
                        aplib.cache_data(active_name, active_cards)
                    else:
                        log.debug("{0} container already active: {1}".format(
                            card_name, container))

            elif action == 'deactivate':
                log.debug("Deactive {0}.".format(card_name))
                for c in active_cards:
                    # Check & remove orphaned containers (not running but still in the active list due to no cleanup).
                    status = aplib.get_container_status(c)
                    log.debug("{0:<10} = {1}{2}".format(
                        c, status, '*' if status != 'RUNNING' else ''))
                    if status != 'RUNNING':
                        idx = active_cards.index(c)
                        active_cards.pop(idx)
                if len(active_cards) > 1:
                    if idx >= 0:
                        log.info("Deactivating {0} container: '{1}'...".format(
                            card_name.lower(), container))
                        active_cards.pop(idx)
                        aplib.cache_data(active_name, active_cards)
                        log.info(
                            "{0} container deactivated.".format(card_name))
                    else:
                        log.info("{0} container already deactivated.".format(
                            card_name))
                elif len(active_cards) == 1:
                    if not keep_last:
                        log.info(
                            "Only one {0} container remains active and it will be deactivated."
                            .format(card_name.lower()))
                        aplib.cache_data(active_name, [])
                    else:
                        log.warning(
                            "Only one {0} container remains active; deactivate is bypassed."
                            .format(card_name.lower()))
                        log.warning(
                            "This should only be done when the chassis needs to stay powered on."
                        )
                else:
                    log.info(
                        "No {0} containers were activated; nothing to deactivate."
                        .format(card_name.lower()))

            elif action == 'show':
                log.debug("Show {0}.".format(card_name))

            else:
                log.error("Unknown action for {0} allocation.".format(
                    card_name.lower()))
                return False

            msg = "Active {0}s".format(card_name)
            log.info(msg)
            log.info("-" * len(msg))
            for lc in active_cards:
                log.info("{0} {1}".format(lc, '*' if lc == container else ''))

        return True
Beispiel #7
0
def set_global_corners(forced_corners=None):
    """ Set Global ChamberCorners
    Used by the UUT Container PRE-SEQ.
    This sets the corners to be used by ALL UUTs in the chamber via a global data cache.
    IMPORTANT: Global cache key is the station path (i.e. chamber).
    Differing product families are allowed to run but their corner selections MUST match; if not then it will abort.

    Example set in product_definition:
    'chamber_corners': [('NTNV', False), ('HTLV', True), ('HTHV', True), ('LTLV', True)]

    Example of globally saved after processing:
    OrderedDict([('NTNV', ('AMBIENT', 'NOMINAL', False)),
             ('HTLV', ('HOT', 'LOW', True)),
             ('HTHV', ('HOT', 'HIGH', True)),
             ('LTLV', ('COLD', 'LOW', True))])

    :param (list) forced_corners:
    :return:
    """
    log.debug("Global Corners: set...")
    # Check for a product-specific corner definition.
    _lookup = {
        'HT': HOT,
        'LT': COLD,
        'NT': AMBIENT,
        'HV': 'HIGH',
        'LV': 'LOW',
        'NV': 'NOMINAL'
    }
    container = aplib.get_my_container_key()

    try:
        udd = aplib.apdicts.userdict.get('udd')
        if not udd:
            log.error("The UutDescriptor Dict was not available.")
            log.error(
                "Please confirm proper application of the application software!"
            )
            raise Exception("The UutDescriptor Dict was not available.")

        chamber_corners = udd.get('chamber_corners')

        if forced_corners:
            listed_corners = collections.OrderedDict(forced_corners)
            log.debug("Chamber Corners Source: FORCED.")
        elif chamber_corners:
            listed_corners = collections.OrderedDict(chamber_corners)
            log.debug("Chamber Corners Source: UUT DESCRIPTOR.")
        else:
            log.warning(
                "No UutDescriptor chamber_corners, or forced_corners available."
            )
            log.warning(
                "Check the product definitions and common definition for 'chamber_corners'."
            )
            log.warning(
                "The default '2-Corner' sequence (HTLV, LTHV) will be used.")
            listed_corners = [('LTHV', True), ('HTLV', True)]

        processed_corners = []
        if listed_corners:
            for lc in listed_corners:
                name = lc[0] if isinstance(lc, tuple) else lc
                adt = lc[1] if isinstance(lc, tuple) and len(lc) > 1 else False
                if len(name) == 4:
                    temp = _lookup.get(name[:2], AMBIENT)
                    volt = _lookup.get(name[2:4], 'NOMINAL')
                elif len(name) == 2:
                    temp = _lookup.get(name, AMBIENT)
                    volt = 'NOMINAL'
                else:
                    temp = AMBIENT
                    volt = 'NOMINAL'
                processed_corners.append((name, (temp, volt, adt)))
        corners = collections.OrderedDict(
            processed_corners) if processed_corners else None
    except (KeyError, AttributeError):
        log.warning(
            "Chamber corner data is not available or not in correct form.")
        return False

    log.debug('-' * 20)
    log.debug("{0} : Chamber Corners = {1}".format(container, listed_corners))

    # Now check for proper form of corners dict.
    for corner in corners:
        if not isinstance(corners[corner], tuple):
            log.error("Product specific corners are not in the proper form.")
            raise apexceptions.AbortException

    # Get the current corner definition (possibly set by another container in the same chamber)
    S_KEY = '_'.join(container.split('|')[:-1])
    cc_key = 'chamber_corners_' + S_KEY
    with locking.named_priority_lock('__corners__' + S_KEY):
        try:
            log.debug("Chamber corner cache key (set) = {0}".format(cc_key))
            established_corners = aplib.get_cached_data(cc_key)
        except (KeyError, apexceptions.ApolloException):
            established_corners = None

        if not forced_corners:
            # Save the product-specific corner selections for use by SEQ.
            if not established_corners:
                established_corners = corners
                aplib.cache_data(cc_key, established_corners)
                log.debug(
                    "*** A new chamber corner set has been established. ***")

            # All UUT corner definitions must match.  This allows different PIDs in the same chamber BUT requires them
            # to all have the same corner definition.
            if corners != established_corners:
                log.error("Chamber corners: REJECTED!")
                log.error(
                    "There is a mismatch of chamber_corners in {0}.  This is NOT allowed."
                    .format(container))
                log.error(
                    "Please correct the situation before running the chamber.  Inspect UUT product definitions."
                )
                raise apexceptions.AbortException(
                    "MISMATCH of chamber corners in {0}.".format(container))
            else:
                log.debug("Chamber corners: ACCEPTED.  {0}".format(
                    established_corners))
        else:
            aplib.cache_data(cc_key, corners)
            log.debug("Chamber corners: FORCED.  {0}".format(corners))

    return True
Beispiel #8
0
def set_global_profile(forced_profile=None):
    """ Set Global Chamber Profile
    Used by the UUT Container PRE-SEQ.
    This sets the profile to be used by ALL UUTs in the chamber via a global data cache.
    IMPORTANT: Global cache key is the station path (i.e. chamber).
    Differing product families are allowed to run but their profile selections MUST match; if not then it will abort.
    :param (list) forced_profile:
    :return:
    """

    log.debug("Global Profile: set...")
    container = aplib.get_my_container_key()
    # Source the profile.
    try:
        udd = aplib.apdicts.userdict.get('udd')
        if not udd:
            log.error("The UutDescriptor Dict was not available.")
            log.error(
                "Please confirm proper application of the application software!"
            )
            raise Exception("The UutDescriptor Dict was not available.")

        chamber_profile = udd.get('chamber_profile')

        if forced_profile:
            profile = collections.OrderedDict(forced_profile)
            log.debug("Chamber Profile Source: FORCED.")
        elif chamber_profile:
            profile = collections.OrderedDict(chamber_profile)
            log.debug("Chamber Profile Source: UUT DESCRIPTOR.")
        else:
            log.warning(
                "No UutDescriptor chamber_profile, or forced_profile available."
            )
            log.warning(
                "Check the product definitions and common definition for 'chamber_profile'."
            )
            log.warning("The default commercial profile will be used.")
            profile = collections.OrderedDict(DEFAULT_PROFILES['commercial'])
    except (KeyError, AttributeError):
        log.error(
            "Chamber profile data is not available or not in correct form.")
        return False

    log.debug('-' * 50)
    log.debug("{0} : Chamber Profile = {1}".format(container, profile))

    # Get the current profile definition (possibly set by another container in the same chamber)
    # Global cache key is the station path (i.e. chamber)
    S_KEY = '_'.join(container.split('|')[:-1])
    cp_key = 'chamber_profile_' + S_KEY
    with locking.named_priority_lock('__profile__' + S_KEY):
        try:
            log.debug("Chamber profile cache key (set) = {0}".format(cp_key))
            established_profile = aplib.get_cached_data(cp_key)
        except (KeyError, apexceptions.ApolloException):
            established_profile = None

        if not forced_profile:
            # Save the product-specific profile selections for use by SEQ.
            if not established_profile:
                established_profile = profile
                aplib.cache_data(cp_key, established_profile)
                log.debug(
                    "*** A new chamber profile set has been established. ***")

            # All UUT profile definitions must match.  This allows different PIDs in the same chamber BUT requires
            # them to all have the same profile definition.
            if profile != established_profile:
                log.error("Chamber profile: REJECTED!")
                log.error(
                    "There is a mismatch of chamber_profiles in {0}.  This is NOT allowed."
                    .format(container))
                log.error(
                    "Please correct the situation before running the chamber.  Inspect UUT product definitions."
                )
                raise apexceptions.AbortException(
                    "MISMATCH of chamber profiles in {0}.".format(container))
            else:
                log.debug("Chamber profile: ACCEPTED.  {0}".format(
                    established_profile))
        else:
            aplib.cache_data(cp_key, profile)
            log.debug("Chamber profile: FORCED.  {0}".format(profile))

    return True