rtcheck.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- Python -*-
00003 # -*- coding: utf-8 -*-
00004 
00005 '''rtshell
00006 
00007 Copyright (C) 2009-2014
00008     Geoffrey Biggs
00009     RT-Synthesis Research Group
00010     Intelligent Systems Research Institute,
00011     National Institute of Advanced Industrial Science and Technology (AIST),
00012     Japan
00013     All rights reserved.
00014 Licensed under the Eclipse Public License -v 1.0 (EPL)
00015 http://www.opensource.org/licenses/eclipse-1.0.txt
00016 
00017 rtcheck library.
00018 
00019 '''
00020 
00021 
00022 import optparse
00023 import os
00024 import rtctree.path
00025 import rtctree.tree
00026 import rtsprofile.rts_profile
00027 import sys
00028 import traceback
00029 
00030 import actions
00031 import option_store
00032 import rts_exceptions
00033 import rtshell
00034 
00035 
00036 class SystemNotOKCB(rtshell.actions.BaseCallback):
00037     '''Callback for a required action.
00038 
00039     Checks the action result and raises @ref RequiredActionFailedError if the
00040     action failed.
00041 
00042     '''
00043     def __init__(self, *args, **kwargs):
00044         super(SystemNotOKCB, self).__init__(*args, **kwargs)
00045         self._failed = False
00046 
00047     def __call__(self, result, err_msg):
00048         if err_msg:
00049             print >>sys.stderr, err_msg
00050         if not result:
00051             self._failed = True
00052 
00053     def __str__(self):
00054         return 'Required'
00055 
00056     @property
00057     def failed(self):
00058         '''Did any calls to this callback indicate failure?'''
00059         return self._failed
00060 
00061 
00062 def get_data_conn_props(conn):
00063     return {'dataport.dataflow_type': str(conn.data_flow_type),
00064             'dataport.interface_type': str(conn.interface_type),
00065             'dataport.subscription_type': str(conn.subscription_type),
00066             'dataport.data_type': str(conn.data_type)}
00067 
00068 
00069 def check_comps(rtsprofile, req_cb):
00070     checks = []
00071     for comp in [c for c in rtsprofile.components if c.is_required]:
00072         checks.append(rtshell.actions.CheckForRequiredCompAct('/' +
00073             comp.path_uri, comp.id, comp.instance_name, callbacks=[req_cb]))
00074     for comp in [c for c in rtsprofile.components if not c.is_required]:
00075         checks.append(rtshell.actions.CheckForRequiredCompAct('/' +
00076             comp.path_uri, comp.id, comp.instance_name))
00077     return checks
00078 
00079 
00080 def check_connection(c, rtsprofile, props, cbs):
00081     s_comp = rtsprofile.find_comp_by_target(c.source_data_port)
00082     s_path = '/' + s_comp.path_uri
00083     s_port = c.source_data_port.port_name
00084     prefix = s_comp.instance_name + '.'
00085     if s_port.startswith(prefix):
00086         s_port = s_port[len(prefix):]
00087     d_comp = rtsprofile.find_comp_by_target(c.target_data_port)
00088     d_path = '/' + d_comp.path_uri
00089     d_port = c.target_data_port.port_name
00090     prefix = d_comp.instance_name + '.'
00091     if d_port.startswith(prefix):
00092         d_port = d_port[len(prefix):]
00093     return rtshell.actions.CheckForConnAct((s_path, s_port), (d_path, d_port),
00094             str(c.connector_id), props, callbacks=cbs)
00095 
00096 
00097 def check_connections(rtsprofile, req_cb):
00098     checks = []
00099     for c in rtsprofile.required_data_connections():
00100         props = get_data_conn_props(c)
00101         checks.append(check_connection(c, rtsprofile, props, [req_cb]))
00102 
00103     for c in rtsprofile.optional_data_connections():
00104         props = get_data_conn_props(c)
00105         checks.append(check_connection(c, rtsprofile, props, []))
00106 
00107     for c in rtsprofile.required_service_connections():
00108         checks.append(check_connection(c, rtsprofile, {} [req_cb]))
00109 
00110     for c in rtsprofile.optional_service_connections():
00111         checks.append(check_connection(c, rtsprofile, {}, []))
00112 
00113     return checks
00114 
00115 
00116 def check_configs(rtsprofile, req_cb):
00117     checks = []
00118     # Check the correct set is active
00119     for c in rtsprofile.components:
00120         if c.active_configuration_set:
00121             checks.append(rtshell.actions.CheckActiveConfigSetAct('/' +
00122                 c.path_uri, c.active_configuration_set, callbacks=[req_cb]))
00123         for cs in c.configuration_sets:
00124             for p in cs.configuration_data:
00125                 checks.append(rtshell.actions.CheckConfigParamAct('/' +
00126                     c.path_uri, cs.id, p.name, p.data, callbacks=[req_cb]))
00127     return checks
00128 
00129 
00130 def check_states(rtsprofile, expected, req_cb):
00131     checks = []
00132     for comp in [c for c in rtsprofile.components if c.is_required]:
00133         for ec in comp.execution_contexts:
00134             checks.append(rtshell.actions.CheckCompStateAct('/' +
00135                 comp.path_uri, comp.id, comp.instance_name, ec.id, expected,
00136                 callbacks=[req_cb]))
00137     for comp in [c for c in rtsprofile.components if not c.is_required]:
00138         for ec in comp.execution_contexts:
00139             checks.append(rtshell.actions.CheckCompStateAct('/' +
00140                 comp.path_uri, comp.id, comp.instance_name, ec.id, expected))
00141     return checks
00142 
00143 
00144 def check(profile=None, xml=True, state='Active', dry_run=False, tree=None):
00145     # Load the profile
00146     if profile:
00147         # Read from a file
00148         with open(profile) as f:
00149             if xml:
00150                 rtsp = rtsprofile.rts_profile.RtsProfile(xml_spec=f)
00151             else:
00152                 rtsp = rtsprofile.rts_profile.RtsProfile(yaml_spec=f)
00153     else:
00154         # Read from standard input
00155         lines = sys.stdin.read()
00156         if xml:
00157             rtsp = rtsprofile.rts_profile.RtsProfile(xml_spec=lines)
00158         else:
00159             rtsp = rtsprofile.rts_profile.RtsProfile(yaml_spec=lines)
00160 
00161     # Build a list of actions to perform that will check the system
00162     cb = SystemNotOKCB()
00163     actions = (check_comps(rtsp, cb) + check_connections(rtsp, cb) +
00164             check_configs(rtsp, cb) + check_states(rtsp, state, cb))
00165     if dry_run:
00166         for a in actions:
00167             print a
00168     else:
00169         if not tree:
00170             # Load the RTC Tree, using the paths from the profile
00171             tree = rtctree.tree.RTCTree(paths=[rtctree.path.parse_path(
00172                 '/' + c.path_uri)[0] for c in rtsp.components])
00173         for a in actions:
00174             a(tree)
00175     if cb.failed:
00176         return False
00177     return True
00178 
00179 
00180 def main(argv=None, tree=None):
00181     usage = '''Usage: %prog [options] <RTSProfile specification file>
00182 Check that the running RT System conforms to an RTSProfile.'''
00183     parser = optparse.OptionParser(usage=usage, version=rtshell.RTSH_VERSION)
00184     parser.add_option('--dry-run', dest='dry_run', action='store_true',
00185             default=False, help="Print what will be done but don't actually '\
00186             'do anything. [Default: %default]")
00187     parser.add_option('-s', '--state', dest='state', action='store',
00188             type='string', default='Active',
00189             help='The expected state of the RT Components in the system. ' \
00190             '[Default: %default]')
00191     parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
00192             default=False,
00193             help='Output verbose information. [Default: %default]')
00194     parser.add_option('-x', '--xml', dest='xml', action='store_true',
00195             default=True, help='Use XML input format. [Default: True]')
00196     parser.add_option('-y', '--yaml', dest='xml', action='store_false',
00197             help='Use YAML input format. [Default: False]')
00198 
00199     if argv:
00200         sys.argv = [sys.argv[0]] + argv
00201     try:
00202         options, args = parser.parse_args()
00203     except optparse.OptionError, e:
00204         print >>sys.stderr, 'OptionError: ', e
00205         return 1
00206     rtshell.option_store.OptionStore().verbose = options.verbose
00207 
00208     if not args:
00209         profile = None
00210     elif len(args) == 1:
00211         profile = args[0]
00212     else:
00213         print >>sys.stderr, usage
00214         return 1
00215 
00216     try:
00217         if not check(profile=profile, xml=options.xml, state=options.state,
00218                 dry_run=options.dry_run, tree=tree):
00219             return 1
00220     except Exception, e:
00221         if options.verbose:
00222             traceback.print_exc()
00223         print >>sys.stderr, '{0}: {1}'.format(sys.argv[0], e)
00224         return 1
00225     return 0
00226 
00227 
00228 # vim: tw=79
00229 


rtshell
Author(s): Geoffrey Biggs
autogenerated on Fri Aug 28 2015 12:55:12