### Navigation

- index
- modules |
- JSON Link 0.9.2a documentation »
- Module code »

# Source code for json_link.faults.fault_inject

    """
    Fault Inject
    ~~~~~~~~~~~~

    A module that enables easy injection of faults into a JSON link exchange, useful
    for both our own unittests and when testing other implementations

    Classes:

    * :class:`FaultInjectMixIn`
    * :class:`MasterFaultInject`
    * :class:`SlaveFaultInject`

    Related Functions:

    Notes:

    @author: Bryan Palmintier, NREL 2013
    """
    # __future__ imports must occur at top of file. They enable using features from
    # python 3.0 in older (2.x) versions are are ignored in newer (3.x) versions
    # New print function
    from __future__ import print_function
    # Use Python 3.0 import semantics
    from __future__ import absolute_import

    __author__ = "Bryan Palmintier"
    __copyright__ = "Copyright (c) 2013 Bryan Palmintier"
    __license__ = """
    @copyright: Copyright (c) 2013, Bryan Palmintier
    @license: BSD 3-clause --
    All rights reserved.

    Redistribution and use in source and binary forms, with or without modification,
    are permitted provided that the following conditions are met:
     1) Redistributions of source code must retain the above copyright notice, this
        list of conditions and the following disclaimer.
     2) Redistributions in binary form must reproduce the above copyright notice,
        this list of conditions and the following disclaimer in the documentation
        and/or other materials provided with the distribution.
     3) Neither the name of the National Renewable Energy Lab nor the names of its
        contributors may be used to endorse or promote products derived from this
        software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
    ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
    ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."""

    ## ===== History ====
    #  [Current]             version     date       time     who     Comments
    #                        -------  ----------    ----- ---------- -------------
    __version__, __date__ = "0.1.0a","2013-05-01"  #21:40   BryanP   Initial Version
    # [Older, in reverse order]
    # version      date       time     who     Comments
    # -------   ----------    ----- ---------- ---------------------------------------

    #Standard Library imports
    import sys
    import json

    #local imports
    from .. import json_link

    #===============================================================================
    # Module level constants
    #===============================================================================

    #===============================================================================
    # Error (Exception) Class definitions
    #===============================================================================

    #===============================================================================
    # FaultInjectMixIn (module internal)
    #===============================================================================
    class FaultInjectMixIn(json_link._BaseLink):
        """ Mix in class to enable JSON fault injection by overloading message sending functions"""

        fault = {}
        # Create a dictionary with send counts for each message type initialized to zero
        send_count = dict(zip(json_link.MsgTypeList, [0] * len(json_link.MsgTypeList)))

        def sendMsg(self, action, data, data_name='data'):
            """
            Injects a fault into either the JSON link or raw exchange message
            by using the fault data field instead of the proper message
            """

            # Yes, this nested if could be replaced by assigning inject_fault to a
            # long boolean expression, BUT we keep the if structure for future
            # expansion
            if action in self.fault:

                #Enable shorthand for simple faults
                if type(self.fault[action]) is not dict \
                        or 'data' not in self.fault[action]:
                    self.fault[action]={'data':self.fault[action]}

                #by default, we expect to inject a fault
                inject_fault = True

                #But if the delay parameter is set, we only inject the fault for
                #listed number attempts
                if ('delay' in self.fault[action]) and (
                        self.send_count[action] not in self.fault[action]['delay']):
                    inject_fault = False
            else:
                inject_fault = False

            if inject_fault:
                if 'raw' in self.fault[action] and self.fault[action]['raw']:
                    output = json_link._BaseLink.sendMsg(self, action,
                                                         self.fault[action]['data'],
                                                         data_name, raw_packet=True)
                else:
                    output = json_link._BaseLink.sendMsg(self, action,
                                                         self.fault[action]['data'],
                                                         data_name, raw_json=True)
            else:
                output = json_link._BaseLink.sendMsg(self, action, data, data_name)

            self.send_count[action] += 1

            return output

    #===============================================================================
    # MasterFaultInject
    #===============================================================================
    class MasterFaultInject(json_link.MasterLink, FaultInjectMixIn):
        """ JSON Link Master/client with fault injection"""

        description_dict = {'application':"JSON_Link_Master_with_Fault_Inject",
                            'version':__version__,
                            'modelname':sys.argv[0]
                            }

    #===============================================================================
    # SlaveLink
    #===============================================================================
    class SlaveFaultInject(json_link.SlaveLink, FaultInjectMixIn):
        """ JSON Link Slave/server with fault injection"""

        #Passed via the init link message, must include 'remote'
        description_dict = {'remote':"JSON Link Slave/Server with Fault Inject", 'version':__version__}

### Navigation

- index
- modules |
- JSON Link 0.9.2a documentation »
- Module code »