Exemple #1
0
    def __init__(self,
                 row_key_field_name='Description',
                 init_fields_dict=dict(),
                 obj_name='tally_sheet'):

        r"""
        Create a tally sheet object.

        Description of arguments:
        row_key_field_name          The name of the row key field (e.g.
                                    boot_type, team_name, etc.)
        init_fields_dict            A dictionary which contains field
                                    names/initial values.
        obj_name                    The name of the tally sheet.
        """

        self.__obj_name = obj_name
        # The row key field uniquely identifies the row.
        self.__row_key_field_name = row_key_field_name
        # Create a "table" which is an ordered dictionary.
        # If we're running python 2.7 or later, collections has an
        # OrderedDict we can use.  Otherwise, we'll try to use the DotDict (a
        # robot library).  If neither of those are available, we fail.
        try:
            self.__table = collections.OrderedDict()
        except AttributeError:
            self.__table = DotDict()
        # Save the initial fields dictionary.
        self.__init_fields_dict = init_fields_dict
        self.__totals_line = init_fields_dict
        self.__sum_fields = []
        self.__calc_fields = []
 def __call__(self, **updates) -> Tuple[str, Iterable[Iterable]]:
     output_ref = CacheLines().upload(self._output)
     for i in range(0, len(self._data)):
         _template = DotDict(self._data[i]._asdict())
         _template.update({'OUTPUT_REF': output_ref})
         self._data[i] = self.table.template(*list(_template.values()))
     return super().__call__(**updates)
 def test_equality(self):
     assert_true(self.dd == self.dd)
     assert_false(self.dd != self.dd)
     assert_true(self.dd == DotDict(self.dd))
     assert_false(self.dd != DotDict(self.dd))
     assert_false(self.dd == DotDict())
     assert_true(self.dd != DotDict())
def wait_for_comm_cycle(start_boot_seconds, quiet=None):
    r"""
    Wait for communications to the BMC to stop working and then resume working.
    This function is useful when you have initiated some kind of reboot.

    Description of arguments:
    start_boot_seconds  The time that the boot test started.  The format is the
                        epoch time in seconds, i.e. the number of seconds since
                        1970-01-01 00:00:00 UTC.  This value should be obtained
                        from the BMC so that it is not dependent on any kind of
                        synchronization between this machine and the target BMC
                        This will allow this program to work correctly even in
                        a simulated environment.  This value should be obtained
                        by the caller prior to initiating a reboot.  It can be
                        obtained as follows:
                        state = st.get_state(req_states=['epoch_seconds'])
    """

    quiet = int(gp.get_var_value(quiet, 0))

    # Validate parms.
    error_message = gv.svalid_integer(start_boot_seconds,
                                      var_name="start_boot_seconds")
    if error_message != "":
        BuiltIn().fail(gp.sprint_error(error_message))

    match_state = anchor_state(DotDict([('packet_loss', '100')]))
    # Wait for 100% packet loss trying to ping machine.
    wait_state(match_state, wait_time="8 mins", interval="0 seconds")

    match_state['packet_loss'] = '^0$'
    # Wait for 0% packet loss trying to ping machine.
    wait_state(match_state, wait_time="8 mins", interval="0 seconds")

    # Get the uptime and epoch seconds for comparisons.  We want to be sure
    # that the uptime is less than the elapsed boot time.  Further proof that
    # a reboot has indeed occurred (vs random network instability giving a
    # false positive.
    state = get_state(req_states=['uptime', 'epoch_seconds'], quiet=quiet)

    elapsed_boot_time = int(state['epoch_seconds']) - start_boot_seconds
    gp.qprint_var(elapsed_boot_time)
    if int(float(state['uptime'])) < elapsed_boot_time:
        uptime = state['uptime']
        gp.qprint_var(uptime)
        gp.qprint_timen("The uptime is less than the elapsed boot time," +
                        " as expected.")
    else:
        error_message = "The uptime is greater than the elapsed boot time," +\
                        " which is unexpected:\n" +\
                        gp.sprint_var(start_boot_seconds) +\
                        gp.sprint_var(state)
        BuiltIn().fail(gp.sprint_error(error_message))

    gp.qprint_timen("Verifying that REST API interface is working.")
    match_state = DotDict([('rest', '^1$')])
    state = wait_state(match_state, wait_time="5 mins", interval="2 seconds")
Exemple #5
0
 def test_init(self):
     assert_true(DotDict() == DotDict({}) == DotDict([]))
     assert_true(DotDict(a=1) == DotDict({'a': 1}) == DotDict([('a', 1)]))
     assert_true(DotDict({'a': 1}, b=2) ==
                 DotDict({'a': 1, 'b': 2}) ==
                 DotDict([('a', 1), ('b', 2)]))
     assert_raises(TypeError, DotDict, None)
 def replace(self, positional, named, variables=None):
     # `variables` is None in dry-run mode and when using Libdoc
     if variables:
         positional = variables.replace_list(positional,
                                             self._resolve_until)
         named = DotDict(
             self._replace_named(named, variables.replace_scalar))
     else:
         positional = list(positional)
         named = DotDict(item for item in named if isinstance(item, tuple))
     return positional, named
Exemple #7
0
 def test_order_does_not_affect_equality(self):
     d = dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7)
     od1 = OrderedDict(sorted(d.items()))
     od2 = OrderedDict(reversed(list(od1.items())))
     dd1 = DotDict(sorted(d.items()))
     dd2 = DotDict(reversed(list(dd1.items())))
     for d1, d2 in [(dd1, dd2), (dd1, d), (dd2, d), (dd1, od1), (dd2, od2)]:
         assert_equal(d1, d2)
         assert_equal(d2, d1)
     if not IRONPYTHON:
         # https://github.com/IronLanguages/main/issues/1168
         for d1, d2 in [(dd1, od2), (dd2, od1)]:
             assert_equal(d1, d2)
             assert_equal(d2, d1)
     assert_not_equal(od1, od2)
 def test_order_does_not_affect_equality(self):
     d = dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7)
     od1 = OrderedDict(sorted(d.items()))
     od2 = OrderedDict(reversed(list(od1.items())))
     dd1 = DotDict(sorted(d.items()))
     dd2 = DotDict(reversed(list(dd1.items())))
     for d1, d2 in [(dd1, dd2), (dd1, d), (dd2, d), (dd1, od1), (dd2, od2)]:
         assert_equal(d1, d2)
         assert_equal(d2, d1)
     if not IRONPYTHON:
         # https://github.com/IronLanguages/main/issues/1168
         for d1, d2 in [(dd1, od2), (dd2, od1)]:
             assert_equal(d1, d2)
             assert_equal(d2, d1)
     assert_not_equal(od1, od2)
    def download(self, url: str) -> DownloadedFile:
        """Download given url content.

        Keyword returns dictionary which contains downloaded file path
        and suggested filename as keys (saveAs and suggestedFilename).
        If the file URL cannot be found (the download is triggered by event handlers)
        use `Wait For Download`keyword.

        To enable downloads context's ``acceptDownloads`` needs to be true.

        To configure download directory use New Browser's ``downloadsPath`` settings

        With default filepath downloaded files are deleted when Context the download happened in is closed.

        This keyword requires that there is currently an open page. The keyword uses
        the current pages local state (cookies, sessionstorage, localstorage) for the
        download to avoid authentication problems.

        Example:
        | ${file_object}=    `Download`    ${url}
        | ${actual_size}=    Get File Size    ${file_object.saveAs}

        Example 2:
        | ${elem}=          Get Element   text="Download File"
        | ${href}=          Get Property  ${elem}  href
        | ${file_object}=   Download  ${href}
        | ${file_path}=     Set Variable  ${file_object.saveAs}
        """
        with self.playwright.grpc_channel() as stub:
            response = stub.Download(Request().Url(url=url))
        logger.info(response.log)
        dot_dict = DotDict()
        for key, value in json.loads(response.json).items():
            dot_dict[key] = value
        return dot_dict
Exemple #10
0
 def _set_built_in_variables(self, settings):
     for name, value in [('${TEMPDIR}', abspath(tempfile.gettempdir())),
                         ('${EXECDIR}', abspath('.')),
                         ('${OPTIONS}', DotDict({
                             'include': Tags(settings.include),
                             'exclude': Tags(settings.exclude),
                             'skip': Tags(settings.skip),
                             'skip_on_failure': Tags(settings.skip_on_failure)
                         })),
                         ('${/}', os.sep),
                         ('${:}', os.pathsep),
                         ('${\\n}', os.linesep),
                         ('${SPACE}', ' '),
                         ('${True}', True),
                         ('${False}', False),
                         ('${None}', None),
                         ('${null}', None),
                         ('${OUTPUT_DIR}', settings.output_directory),
                         ('${OUTPUT_FILE}', settings.output or 'NONE'),
                         ('${REPORT_FILE}', settings.report or 'NONE'),
                         ('${LOG_FILE}', settings.log or 'NONE'),
                         ('${DEBUG_FILE}', settings.debug_file or 'NONE'),
                         ('${LOG_LEVEL}', settings.log_level),
                         ('${PREV_TEST_NAME}', ''),
                         ('${PREV_TEST_STATUS}', ''),
                         ('${PREV_TEST_MESSAGE}', '')]:
         self[name] = GlobalVariableValue(value)
    def __init__(self,
                 row_key_field_name='Description',
                 init_fields_dict=dict(),
                 obj_name='tally_sheet'):
        r"""
        Create a tally sheet object.

        Description of arguments:
        row_key_field_name          The name of the row key field (e.g.
                                    boot_type, team_name, etc.)
        init_fields_dict            A dictionary which contains field
                                    names/initial values.
        obj_name                    The name of the tally sheet.
        """

        self.__obj_name = obj_name
        # The row key field uniquely identifies the row.
        self.__row_key_field_name = row_key_field_name
        # Create a "table" which is an ordered dictionary.
        # If we're running python 2.7 or later, collections has an
        # OrderedDict we can use.  Otherwise, we'll try to use the DotDict (a
        # robot library).  If neither of those are available, we fail.
        try:
            self.__table = collections.OrderedDict()
        except AttributeError:
            self.__table = DotDict()
        # Save the initial fields dictionary.
        self.__init_fields_dict = init_fields_dict
        self.__totals_line = init_fields_dict
        self.__sum_fields = []
        self.__calc_fields = []
    def add_row(self, row_key, init_fields_dict=None):
        r"""
        Add a row to the tally sheet.

        Description of arguments:
        row_key                     A unique key value.
        init_fields_dict            A dictionary of field names/initial
                                    values.  The number of fields in this
                                    dictionary must be the same as what was
                                    specified when the tally sheet was
                                    created.  If no value is passed, the value
                                    used to create the tally sheet will be
                                    used.
        """

        if row_key in self.__table:
            # If we allow this, the row values get re-initialized.
            message = "An entry for \"" + row_key + "\" already exists in"
            message += " tally sheet."
            raise ValueError(message)
        if init_fields_dict is None:
            init_fields_dict = self.__init_fields_dict
        try:
            self.__table[row_key] = collections.OrderedDict(init_fields_dict)
        except AttributeError:
            self.__table[row_key] = DotDict(init_fields_dict)
Exemple #13
0
    def get_cookies(self, as_dict=False):
        """Returns all cookies of the current page.

        If ``as_dict`` argument evaluates as false, see `Boolean arguments`
        for more details, then cookie information is returned as
        a single string in format ``name1=value1; name2=value2; name3=value3``.
        When ``as_dict`` argument evaluates as true, cookie information
        is returned as Robot Framework dictionary format. The string format
        can be used, for example, for logging purposes or in headers when
        sending HTTP requests. The dictionary format is helpful when
        the result can be passed to requests library's Create Session
        keyword's optional cookies parameter.

        The `` as_dict`` argument is new in SeleniumLibrary 3.3
        """
        if is_falsy(as_dict):
            pairs = []
            for cookie in self.driver.get_cookies():
                pairs.append(f"{cookie['name']}={cookie['value']}")
            return "; ".join(pairs)
        else:
            pairs = DotDict()
            for cookie in self.driver.get_cookies():
                pairs[cookie["name"]] = cookie["value"]
            return pairs
Exemple #14
0
    def result(self) -> Result:
        if self._process is None:
            raise RuntimeError("Process not started")

        if self._result is None:
            raise RuntimeError("No result set, call poll() or wait() first")

        self._is_pending = False

        if "error" in self._result:
            raise RuntimeError(self._result["error"])

        result = DotDict()

        fields = self._result["value"]
        for element in self._elements:
            if is_input(element):
                key = element["name"]
                assert key in fields, f"Missing input value for '{key}'"
                result[key] = self._post_process_value(fields[key], element=element)
            elif is_submit(element):
                result["submit"] = fields["submit"]

        assert "submit" in result, "Missing submit value"
        return result
Exemple #15
0
 def __init__(self):
     self.name = 'testmock'
     self.doc = 'cod'
     self.tags = ['foo', 'bar']
     self.message = 'Expected failure'
     self.status = 'FAIL'
     self.data = DotDict({'name':self.name})
 def test_other_list_like_items_are_not_touched(self):
     value = ({'key': 'value'}, [{}])
     d = DotDict(key=value)
     assert_equal(d.key[0]['key'], 'value')
     assert_false(hasattr(d.key[0], 'key'))
     assert_true(isinstance(d.key[0], dict))
     assert_true(isinstance(d.key[1][0], dict))
def create_boot_table(file_path=None, os_host=""):
    r"""
    Read the boot table JSON file, convert it to an object and return it.

    Note that if the user is running without a global OS_HOST robot variable specified, this function will
    remove all of the "os_" start and end state requirements from the JSON data.

    Description of argument(s):
    file_path                       The path to the boot_table file.  If this value is not specified, it will
                                    be obtained from the "BOOT_TABLE_PATH" environment variable, if set.
                                    Otherwise, it will default to "data/boot_table.json".  If this value is a
                                    relative path, this function will use the code_base_dir_path as the base
                                    directory (see definition above).
    os_host                         The host name or IP address of the host associated with the machine being
                                    tested.  If the user is running without an OS_HOST (i.e. if this argument
                                    is blank), we remove os starting and ending state requirements from the
                                    boot entries.
    """
    if file_path is None:
        if redfish_support_trans_state:
            file_path = os.environ.get('BOOT_TABLE_PATH',
                                       'data/boot_table_redfish.json')
        elif platform_arch_type == "x86":
            file_path = os.environ.get('BOOT_TABLE_PATH',
                                       'data/boot_table_x86.json')
        else:
            file_path = os.environ.get('BOOT_TABLE_PATH',
                                       'data/boot_table.json')

    if not file_path.startswith("/"):
        file_path = code_base_dir_path + file_path

    # Pre-process the file by removing blank lines and comment lines.
    temp = tempfile.NamedTemporaryFile()
    temp_file_path = temp.name

    cmd_buf = "egrep -v '^[ ]*$|^[ ]*#' " + file_path + " > " + temp_file_path
    gc.cmd_fnc_u(cmd_buf, quiet=1)

    boot_file = open(temp_file_path)
    boot_table = json.load(boot_file, object_hook=DotDict)

    # If the user is running without an OS_HOST, we remove os starting and ending state requirements from
    # the boot entries.
    if os_host == "":
        for boot in boot_table:
            state_keys = ['start', 'end']
            for state_key in state_keys:
                for sub_state in list(boot_table[boot][state_key]):
                    if sub_state.startswith("os_"):
                        boot_table[boot][state_key].pop(sub_state, None)

    # For every boot_type we should have a corresponding mfg mode boot type.
    enhanced_boot_table = DotDict()
    for key, value in boot_table.items():
        enhanced_boot_table[key] = value
        enhanced_boot_table[key + " (mfg)"] = value

    return enhanced_boot_table
 def _cookie_as_dot_dict(self, cookie):
     dot_dict = DotDict()
     for key in cookie:
         if key == "expires":
             dot_dict[key] = datetime.fromtimestamp(cookie[key])
         else:
             dot_dict[key] = cookie[key]
     return dot_dict
 def test_items_inserted_outside_init_are_not_converted(self):
     d = DotDict()
     d['dict'] = {'key': 'value'}
     d['list'] = [{}]
     assert_equal(d.dict['key'], 'value')
     assert_false(hasattr(d.dict, 'key'))
     assert_true(isinstance(d.dict, dict))
     assert_true(isinstance(d.list[0], dict))
 def test_dicts_inside_lists_are_converted(self):
     leaf = {'key': 'value'}
     d = DotDict(list=[leaf, leaf, [leaf]], deeper=[leaf, {'deeper': leaf}])
     assert_equal(d.list[0].key, 'value')
     assert_equal(d.list[1].key, 'value')
     assert_equal(d.list[2][0].key, 'value')
     assert_equal(d.deeper[0].key, 'value')
     assert_equal(d.deeper[1].deeper.key, 'value')
Exemple #21
0
 def _convert(self, value):
     if isinstance(value, xmlrpclib.Binary):
         return bytes(value.data)
     if is_dict_like(value):
         return DotDict((k, self._convert(v)) for k, v in value.items())
     if is_list_like(value):
         return [self._convert(v) for v in value]
     return value
Exemple #22
0
 def _set_variables(self, positional, kwargs, variables):
     before_varargs, varargs = self._split_args_and_varargs(positional)
     for name, value in zip(self.arguments.positional, before_varargs):
         variables['${%s}' % name] = value
     if self.arguments.varargs:
         variables['@{%s}' % self.arguments.varargs] = varargs
     if self.arguments.kwargs:
         variables['&{%s}' % self.arguments.kwargs] = DotDict(kwargs)
 def _handle_binary(self, value):
     if isinstance(value, xmlrpclib.Binary):
         return str(value)
     if is_dict_like(value):
         return DotDict(
             (k, self._handle_binary(v)) for k, v in value.items())
     if is_list_like(value):
         return [self._handle_binary(v) for v in value]
     return value
Exemple #24
0
 def __init__(self, argspec, variables):
     defaults = argspec.defaults
     if variables:
         defaults = variables.replace_list(defaults)
     self._positional = argspec.positional
     self._supports_kwargs = bool(argspec.kwargs)
     self._supports_named = argspec.supports_named
     self.args = [None] * argspec.minargs + [Default(d) for d in defaults]
     self.kwargs = DotDict()
 def test_nested_dicts_inside_list_likes(self):
     leaf = {'key': 'value'}
     d = DotDict(list=[leaf, leaf, [leaf]], tuple=(leaf, {'deeper': leaf}))
     assert_equal(d.list[0].key, 'value')
     assert_equal(d.list[1].key, 'value')
     assert_equal(d.list[2][0].key, 'value')
     assert_equal(d.tuple[0].key, 'value')
     assert_equal(d.tuple[1].deeper.key, 'value')
     assert_true(isinstance(d.tuple, list))
Exemple #26
0
 def _set_variables(self, positional, kwargs, variables):
     before_varargs, varargs = self._split_args_and_varargs(positional)
     for name, value in zip(self.arguments.positional, before_varargs):
         if isinstance(value, DefaultValue):
             value = value.resolve(variables)
         variables['${%s}' % name] = value
     if self.arguments.varargs:
         variables['@{%s}' % self.arguments.varargs] = varargs
     if self.arguments.kwargs:
         variables['&{%s}' % self.arguments.kwargs] = DotDict(kwargs)
def parse_file_path(file_path):

    r"""
    Parse a file path created by create_file_path and return the result as a
    dictionary.

    This function is the complement to create_file_path.

    Description of argument(s):
    file_path                       The file_path.

    Example use:
    gp.pvar(boot_results_file_path)
    file_path_data = parse_file_path(boot_results_file_path)
    gp.pvar(file_path_data)

    Program output.

    boot_results_file_path:
    /tmp/pgm_name.obmc_boot_test:openbmc_nickname.beye6:master_pid.2039:boot_re
    sults
    file_path_data:
      file_path_data[dir_path]:                       /tmp/
      file_path_data[pgm_name]:                       obmc_boot_test
      file_path_data[openbmc_nickname]:               beye6
      file_path_data[master_pid]:                     2039
      file_path_data[boot_results]:
    """

    try:
        result_dict = collections.OrderedDict()
    except AttributeError:
        result_dict = DotDict()

    dir_path = os.path.dirname(file_path) + os.sep
    file_path = os.path.basename(file_path)

    result_dict['dir_path'] = dir_path

    result_dict.update(split_to_dict(file_path))

    return result_dict
def wait_for_comm_cycle(start_boot_seconds, quiet=None):
    r"""
    Wait for the BMC uptime to be less than elapsed_boot_time.

    This function will tolerate an expected loss of communication to the BMC.
    This function is useful when some kind of reboot has been initiated by the
    caller.

    Description of argument(s):
    start_boot_seconds  The time that the boot test started.  The format is the
                        epoch time in seconds, i.e. the number of seconds since
                        1970-01-01 00:00:00 UTC.  This value should be obtained
                        from the BMC so that it is not dependent on any kind of
                        synchronization between this machine and the target BMC
                        This will allow this program to work correctly even in
                        a simulated environment.  This value should be obtained
                        by the caller prior to initiating a reboot.  It can be
                        obtained as follows:
                        state = st.get_state(req_states=['epoch_seconds'])
    """

    quiet = int(gp.get_var_value(quiet, 0))

    # Validate parms.
    error_message = gv.valid_integer(start_boot_seconds)
    if error_message:
        BuiltIn().fail(gp.sprint_error(error_message))

    # Wait for uptime to be less than elapsed_boot_time.
    set_start_boot_seconds(start_boot_seconds)
    expr = 'int(float(state[\'uptime\'])) < int(state[\'elapsed_boot_time\'])'
    match_state = DotDict([('uptime', '^[0-9\\.]+$'),
                           ('elapsed_boot_time', '^[0-9]+$'),
                           (expressions_key(), [expr])])
    wait_state(match_state, wait_time="12 mins", interval="5 seconds")

    gp.qprint_timen("Verifying that REST/Redfish API interface is working.")
    if not redfish_support_trans_state:
        match_state = DotDict([('rest', '^1$')])
    else:
        match_state = DotDict([('redfish', '^1$')])
    state = wait_state(match_state, wait_time="5 mins", interval="2 seconds")
Exemple #29
0
 def _undecorate(self, name, value):
     validate_var(name)
     if name[0] == '@':
         if not is_list_like(value):
             self._raise_cannot_set_type(name, value, 'list')
         value = list(value)
     if name[0] == '&':
         if not is_dict_like(value):
             self._raise_cannot_set_type(name, value, 'dictionary')
         value = DotDict(value)
     return name[2:-1], value
def parse_file_path(file_path):
    r"""
    Parse a file path created by create_file_path and return the result as a
    dictionary.

    This function is the complement to create_file_path.

    Description of argument(s):
    file_path                       The file_path.

    Example use:
    gp.pvar(boot_results_file_path)
    file_path_data = parse_file_path(boot_results_file_path)
    gp.pvar(file_path_data)

    Program output.

    boot_results_file_path:
    /tmp/pgm_name.obmc_boot_test:openbmc_nickname.beye6:master_pid.2039:boot_re
    sults
    file_path_data:
      file_path_data[dir_path]:                       /tmp/
      file_path_data[pgm_name]:                       obmc_boot_test
      file_path_data[openbmc_nickname]:               beye6
      file_path_data[master_pid]:                     2039
      file_path_data[boot_results]:
    """

    try:
        result_dict = collections.OrderedDict()
    except AttributeError:
        result_dict = DotDict()

    dir_path = os.path.dirname(file_path) + os.sep
    file_path = os.path.basename(file_path)

    result_dict['dir_path'] = dir_path

    result_dict.update(split_to_dict(file_path))

    return result_dict
 def replace(self, positional, named, variables=None):
     # `variables` is None in dry-run mode and when using Libdoc.
     if variables:
         positional = variables.replace_list(positional,
                                             self._resolve_until)
         named = list(self._replace_named(named, variables.replace_scalar))
     else:
         positional = list(positional)
         named = [item for item in named if isinstance(item, tuple)]
     # FIXME: DotDict is somewhat slow and not generally needed.
     # Either use normal dict by default or return list of tuples.
     return positional, DotDict(named)
 def _set_variables(self, positional, kwargs, variables):
     spec = self.arguments
     args, varargs = self._split_args_and_varargs(positional)
     kwonly, kwargs = self._split_kwonly_and_kwargs(kwargs)
     for name, value in chain(zip(spec.positional, args), kwonly):
         if isinstance(value, DefaultValue):
             value = value.resolve(variables)
         variables['${%s}' % name] = value
     if spec.varargs:
         variables['@{%s}' % spec.varargs] = varargs
     if spec.kwargs:
         variables['&{%s}' % spec.kwargs] = DotDict(kwargs)
Exemple #33
0
 def _validate_value(self, value, identifier, name):
     if identifier == '@':
         if not is_list_like(value):
             raise VariableError("Value of variable '%s' is not list or "
                                 "list-like." % name)
         return list(value)
     if identifier == '&':
         if not is_dict_like(value):
             raise VariableError("Value of variable '%s' is not dictionary "
                                 "or dictionary-like." % name)
         return DotDict(value)
     return value
 def _dot_dict(self, value):
     if is_dict_like(value):
         value = DotDict((n, self._dot_dict(v)) for n, v in value.items())
     return value
 def setUp(self):
     self.dd = DotDict([('z', 1), (2, 'y'), ('x', 3)])
class tally_sheet:

    r"""
    This class is the implementation of a tally sheet.  The sheet can be
    viewed as rows and columns.  Each row has a unique key field.

    This class provides methods to tally the results (totals, etc.).

    Example code:

    # Create an ordered dict to represent your field names/initial values.
    try:
        boot_results_fields = collections.OrderedDict([('total', 0), ('pass',
        0), ('fail', 0)])
    except AttributeError:
        boot_results_fields = DotDict([('total', 0), ('pass', 0), ('fail', 0)])
    # Create the tally sheet.
    boot_test_results = tally_sheet('boot type', boot_results_fields,
    'boot_test_results')
    # Set your sum fields (fields which are to be totalled).
    boot_test_results.set_sum_fields(['total', 'pass', 'fail'])
    # Set calc fields (within a row, a certain field can be derived from
    # other fields in the row.
    boot_test_results.set_calc_fields(['total=pass+fail'])

    # Create some records.
    boot_test_results.add_row('BMC Power On')
    boot_test_results.add_row('BMC Power Off')

    # Increment field values.
    boot_test_results.inc_row_field('BMC Power On', 'pass')
    boot_test_results.inc_row_field('BMC Power Off', 'pass')
    boot_test_results.inc_row_field('BMC Power On', 'fail')
    # Have the results tallied...
    boot_test_results.calc()
    # And printed...
    boot_test_results.print_report()

    Example result:

    Boot Type                           Total Pass Fail
    ----------------------------------- ----- ---- ----
    BMC Power On                            2    1    1
    BMC Power Off                           1    1    0
    ===================================================
    Totals                                  3    2    1

    """

    def __init__(self,
                 row_key_field_name='Description',
                 init_fields_dict=dict(),
                 obj_name='tally_sheet'):
        r"""
        Create a tally sheet object.

        Description of arguments:
        row_key_field_name          The name of the row key field (e.g.
                                    boot_type, team_name, etc.)
        init_fields_dict            A dictionary which contains field
                                    names/initial values.
        obj_name                    The name of the tally sheet.
        """

        self.__obj_name = obj_name
        # The row key field uniquely identifies the row.
        self.__row_key_field_name = row_key_field_name
        # Create a "table" which is an ordered dictionary.
        # If we're running python 2.7 or later, collections has an
        # OrderedDict we can use.  Otherwise, we'll try to use the DotDict (a
        # robot library).  If neither of those are available, we fail.
        try:
            self.__table = collections.OrderedDict()
        except AttributeError:
            self.__table = DotDict()
        # Save the initial fields dictionary.
        self.__init_fields_dict = init_fields_dict
        self.__totals_line = init_fields_dict
        self.__sum_fields = []
        self.__calc_fields = []

    def init(self,
             row_key_field_name,
             init_fields_dict,
             obj_name='tally_sheet'):
        self.__init__(row_key_field_name,
                      init_fields_dict,
                      obj_name='tally_sheet')

    def set_sum_fields(self, sum_fields):
        r"""
        Set the sum fields, i.e. create a list of field names which are to be
        summed and included on the totals line of reports.

        Description of arguments:
        sum_fields                  A list of field names.
        """

        self.__sum_fields = sum_fields

    def set_calc_fields(self, calc_fields):
        r"""
        Set the calc fields, i.e. create a list of field names within a given
        row which are to be calculated for the user.

        Description of arguments:
        calc_fields                 A string expression such as
                                    'total=pass+fail' which shows which field
                                    on a given row is derived from other
                                    fields in the same row.
        """

        self.__calc_fields = calc_fields

    def add_row(self, row_key, init_fields_dict=None):
        r"""
        Add a row to the tally sheet.

        Description of arguments:
        row_key                     A unique key value.
        init_fields_dict            A dictionary of field names/initial
                                    values.  The number of fields in this
                                    dictionary must be the same as what was
                                    specified when the tally sheet was
                                    created.  If no value is passed, the value
                                    used to create the tally sheet will be
                                    used.
        """

        if init_fields_dict is None:
            init_fields_dict = self.__init_fields_dict
        try:
            self.__table[row_key] = collections.OrderedDict(init_fields_dict)
        except AttributeError:
            self.__table[row_key] = DotDict(init_fields_dict)

    def update_row_field(self, row_key, field_key, value):
        r"""
        Update a field in a row with the specified value.

        Description of arguments:
        row_key                     A unique key value that identifies the row
                                    to be updated.
        field_key                   The key that identifies which field in the
                                    row that is to be updated.
        value                       The value to set into the specified
                                    row/field.
        """

        self.__table[row_key][field_key] = value

    def inc_row_field(self, row_key, field_key):
        r"""
        Increment the value of the specified field in the specified row.  The
        value of the field must be numeric.

        Description of arguments:
        row_key                     A unique key value that identifies the row
                                    to be updated.
        field_key                   The key that identifies which field in the
                                    row that is to be updated.
        """

        self.__table[row_key][field_key] += 1

    def dec_row_field(self, row_key, field_key):
        r"""
        Decrement the value of the specified field in the specified row.  The
        value of the field must be numeric.

        Description of arguments:
        row_key                     A unique key value that identifies the row
                                    to be updated.
        field_key                   The key that identifies which field in the
                                    row that is to be updated.
        """

        self.__table[row_key][field_key] -= 1

    def calc(self):
        r"""
        Calculate totals and row calc fields.  Also, return totals_line
        dictionary.
        """

        self.__totals_line = copy.deepcopy(self.__init_fields_dict)
        # Walk through the rows of the table.
        for row_key, value in self.__table.items():
            # Walk through the calc fields and process them.
            for calc_field in self.__calc_fields:
                tokens = [i for i in re.split(r'(\d+|\W+)', calc_field) if i]
                cmd_buf = ""
                for token in tokens:
                    if token in ("=", "+", "-", "*", "/"):
                        cmd_buf += token + " "
                    else:
                        # Note: Using "mangled" name for the sake of the exec
                        # statement (below).
                        cmd_buf += "self._" + self.__class__.__name__ +\
                                   "__table['" + row_key + "']['" +\
                                   token + "'] "
                exec(cmd_buf)

            for field_key, sub_value in value.items():
                if field_key in self.__sum_fields:
                    self.__totals_line[field_key] += sub_value

        return self.__totals_line

    def sprint_obj(self):
        r"""
        sprint the fields of this object.  This would normally be for debug
        purposes.
        """

        buffer = ""

        buffer += "class name: " + self.__class__.__name__ + "\n"
        buffer += gp.sprint_var(self.__obj_name)
        buffer += gp.sprint_var(self.__row_key_field_name)
        buffer += gp.sprint_var(self.__table)
        buffer += gp.sprint_var(self.__init_fields_dict)
        buffer += gp.sprint_var(self.__sum_fields)
        buffer += gp.sprint_var(self.__totals_line)
        buffer += gp.sprint_var(self.__calc_fields)
        buffer += gp.sprint_var(self.__table)

        return buffer

    def print_obj(self):
        r"""
        print the fields of this object to stdout.  This would normally be for
        debug purposes.
        """

        sys.stdout.write(self.sprint_obj())

    def sprint_report(self):
        r"""
        sprint the tally sheet in a formatted way.
        """

        buffer = ""
        # Build format strings.
        col_names = [self.__row_key_field_name.title()]
        report_width = 40
        key_width = 40
        format_string = '{0:<' + str(key_width) + '}'
        dash_format_string = '{0:-<' + str(key_width) + '}'
        field_num = 0

        first_rec = next(iter(self.__table.items()))
        for row_key, value in first_rec[1].items():
            field_num += 1
            if isinstance(value, int):
                align = ':>'
            else:
                align = ':<'
            format_string += ' {' + str(field_num) + align +\
                             str(len(row_key)) + '}'
            dash_format_string += ' {' + str(field_num) + ':->' +\
                                  str(len(row_key)) + '}'
            report_width += 1 + len(row_key)
            col_names.append(row_key.title())
        num_fields = field_num + 1
        totals_line_fmt = '{0:=<' + str(report_width) + '}'

        buffer += format_string.format(*col_names) + "\n"
        buffer += dash_format_string.format(*([''] * num_fields)) + "\n"
        for row_key, value in self.__table.items():
            buffer += format_string.format(row_key, *value.values()) + "\n"

        buffer += totals_line_fmt.format('') + "\n"
        buffer += format_string.format('Totals',
                                       *self.__totals_line.values()) + "\n"

        return buffer

    def print_report(self):
        r"""
        print the tally sheet in a formatted way.
        """

        sys.stdout.write(self.sprint_report())
class TestDotDict(unittest.TestCase):

    def setUp(self):
        self.dd = DotDict([('z', 1), (2, 'y'), ('x', 3)])

    def test_init(self):
        assert_true(DotDict() == DotDict({}) == DotDict([]))
        assert_true(DotDict(a=1) == DotDict({'a': 1}) == DotDict([('a', 1)]))
        assert_true(DotDict({'a': 1}, b=2) ==
                    DotDict({'a': 1, 'b': 2}) ==
                    DotDict([('a', 1), ('b', 2)]))
        assert_raises(TypeError, DotDict, None)

    def test_get(self):
        assert_equal(self.dd[2], 'y')
        assert_equal(self.dd.x, 3)
        assert_raises(KeyError, self.dd.__getitem__, 'nonex')
        assert_raises(AttributeError, self.dd.__getattr__, 'nonex')

    def test_equality(self):
        assert_true(self.dd == self.dd)
        assert_false(self.dd != self.dd)
        assert_true(self.dd == DotDict(self.dd))
        assert_false(self.dd != DotDict(self.dd))
        assert_false(self.dd == DotDict())
        assert_true(self.dd != DotDict())

    def test_equality_with_normal_dict(self):
        assert_equal(self.dd, {'z': 1, 2: 'y', 'x': 3})

    def test_hash(self):
        assert_raises(TypeError, hash, self.dd)

    def test_set(self):
        self.dd.x = 42
        self.dd.new = 43
        self.dd[2] = 44
        self.dd['n2'] = 45
        assert_equal(self.dd, {'z': 1, 2: 44, 'x': 42, 'new': 43, 'n2': 45})

    def test_del(self):
        del self.dd.x
        del self.dd[2]
        self.dd.pop('z')
        assert_equal(self.dd, {})
        assert_raises(KeyError, self.dd.__delitem__, 'nonex')
        assert_raises(AttributeError, self.dd.__delattr__, 'nonex')

    def test_same_str_and_repr_format_as_with_normal_dict(self):
        D = {'foo': 'bar', '"\'': '"\'', '\n': '\r', 1: 2, (): {}, True: False}
        for d in {}, {'a': 1}, D:
            for formatter in str, repr:
                result = formatter(DotDict(d))
                assert_equal(eval(result, {}), d)

    def test_is_ordered(self):
        assert_equal(list(self.dd), ['z', 2, 'x'])
        self.dd.z = 'new value'
        self.dd.a_new_item = 'last'
        self.dd.pop('x')
        assert_equal(list(self.dd.items()),
                     [('z', 'new value'), (2, 'y'), ('a_new_item', 'last')])
        self.dd.x = 'last'
        assert_equal(list(self.dd.items()),
                     [('z', 'new value'), (2, 'y'), ('a_new_item', 'last'), ('x', 'last')])

    def test_order_does_not_affect_equality(self):
        d = dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7)
        od1 = OrderedDict(sorted(d.items()))
        od2 = OrderedDict(reversed(list(od1.items())))
        dd1 = DotDict(sorted(d.items()))
        dd2 = DotDict(reversed(list(dd1.items())))
        for d1, d2 in [(dd1, dd2), (dd1, d), (dd2, d), (dd1, od1), (dd2, od2)]:
            assert_equal(d1, d2)
            assert_equal(d2, d1)
        if not IRONPYTHON:
            # https://github.com/IronLanguages/main/issues/1168
            for d1, d2 in [(dd1, od2), (dd2, od1)]:
                assert_equal(d1, d2)
                assert_equal(d2, d1)
        assert_not_equal(od1, od2)
# Here are comments describing the lines in the body of the created function.
# Put a reference to the "s" version of this function in s_func.
# Call the "s" version of this function passing it all of our arguments.  Log
# the result to the console.

robot_prefix = "r"
robot_func_names =\
    [
        'print_error_report', 'print_pgm_header',
        'print_issuing_keyword', 'print_vars', 'print_auto_vars'
    ]
func_names = gp.func_names + robot_func_names

explicit_definitions = ['print', 'printn']

func_names = list(my_ord_dict.fromkeys(func_names))

if gen_robot_print_debug:
    rprintn()
    BuiltIn().log_to_console(gp.sprint_var(func_names), no_newline=True)
    rprintn()

for func_name in func_names:

    if func_name not in explicit_definitions:
        # The print_var function's job is to figure out the name of arg 1 and
        # then call print_varx.  This is not currently supported for robot
        # programs.  Though it IS supported for python modules.
        if func_name == "print_error" or func_name == "print_error_report":
            output_stream = "STDERR"
        else: