csonar_utils API

csonar_utils provides utilities for writing custom Python warning processors for CodeSonar.

class csonar_utils.WarningProcessor

A utility class for writing Python warning processors.

To use this class, make a subclass that defines any of the optional WarningProcessor command methods:

The WarningProcessor class also provides helper methods for creating custom warning processors. In particular:

WarningProcessor Command Methods

Each WarningProcessor command method corresponds to a warning processor command line argument. For example, if my_processor is run with my_processor begin T123 then on_begin("T123") is called.

Warnings are processed in transactions, as described in How Warning Processors Work. The session_id argument to on_begin(), on_retry(), on_commit(), on_rollback(), and on_abort() allows a warning processor to keep track of different transactions, even if they are happening at the same time (for example, because many different users are sending warnings to your processor at the same time). If your warning processor needs to keep any state during a transaction, it can associate that state with the session_id value.

The sample bugzilla processor provides an example of how the session_id can be used to keep a transaction log.

WarningProcessor.on_install()

Will be called when the processor is invoked with my_processor install.

Returns:

None

Notes:

If the processor has a display script, call render_file() to output it. For example:

def on_install(self):
   self.render_file('path/to/display_script.py')
WarningProcessor.on_begin(session_id)

Will be called when the processor is invoked with my_processor begin session_id.

Parameters:

session_id – An identifier for the warning processor transaction, as described above.

Returns:

0 on success, non-0 on failure

Note:

This method will generally responsible for carrying out (or calling other methods to perform) most of the ‘work’ of the warning processor. In particular, this includes managing the processor’s input and output. A typical structure is the following:

def on_begin(self, session_id):
   self.parse_xml()
   if self.active:
      self.output('</change></changes>')

where self.active is used to track whether any output has been produced by customized handlers for parse_xml(), and output() is invoked to close the output XML tags if necessary.

The return code determines the yes/no vote submitted by the processor session during the “voting phase” of the two-phase commit protocol.

WarningProcessor.on_retry(session_id)

Will be called when the processor is invoked with my_processor retry session_id.

Parameters:

session_id – An identifier for the warning processor transaction, as described above.

Returns:

0 on success, non-0 on failure

Notes:

In most cases, the retry and begin commands will be similar or identical:

def on_retry(self, session_id):
   self.on_begin(session_id)

The return code determines the yes/no vote submitted by the processor session during the “voting phase” of the two-phase commit protocol.

WarningProcessor.on_commit(session_id)

Will be called when the processor is invoked with my_processor commit session_id. Use to perform any necessary bookkeeping tasks (such as removing logs).

Parameters:session_id – An identifier for the warning processor transaction, as described above.
Returns:None
Notes:This method should not write anything to stdout.
WarningProcessor.on_rollback(session_id)

Will be called when the processor is invoked with my_processor rollback session_id. Use to perform any necessary bookkeeping tasks (such as removing logs).

Parameters:session_id – An identifier for the warning processor transaction, as described above.
Returns:None
Notes:This method should not write anything to stdout.
WarningProcessor.on_abort(session_id)

Will be called when the processor is invoked with my_processor abort session_id. Use to perform any necessary bookkeeping tasks (such as removing logs).

Parameters:session_id – An identifier for the warning processor transaction, as described above.
Returns:None
Notes:This method should not write anything to stdout.
WarningProcessor.on_analysis_transition(analysis_id, old_state, new_state)

Will be called when the processor is invoked with my_processor analysis_transition analysis_id old_state new_state. Note that this can only occur with automatic application.

Parameters:
Returns:

None

Note:

Use to perform actions that are not warning-specific, such as sending summary email about all the actions performed by the processor for the warnings in an analysis.

WarningProcessor Input Handling

WarningProcessor provides parse_xml(), which parses the XML input to the warning processor and invokes handlers for certain elements. Writing a warning processor with csonar_utils will generally involve defining one or more of these handlers:

In particular, most custom warning processors will define at least handle_warning(), since the processor behavior will probably depend on the identities and properties of the warnings being processed.

WarningProcessor.parse_xml()

Set up an XML parser and parse input from self._in.

Returns:None
Note:The parser uses five handlers: handle_post_attrs(), handle_user_data(), handle_form_data(), handle_env_data(), handle_warning().
WarningProcessor.handle_post_attrs(attrs)

Used by parse_xml() to handle a <post> element in XML input.

Parameters:attrs – a dictionary that maps <post> attribute names to attribute values.
Returns:None
Notes:<post> is the top-level element of the XML input.
WarningProcessor.handle_user_data(udata)

Used by parse_xml() to handle a <userdata> element in XML input.

Parameters:udata – a dictionary that maps <userdata> sub-element names to their values.
Returns:None
Note:This method will be ignored by automatically-applied warning processors.
WarningProcessor.handle_form_data(fdata)

Used by parse_xml() to handle a <formdata> element in XML input.

Parameters:fdata – a dictionary that maps <formdata> sub-element names to their values.
Returns:None
Note:This method will be ignored by automatically-applied warning processors.
WarningProcessor.handle_env_data(envdata)

Used by parse_xml() to handle an <env> element in XML input.

Parameters:envdata

an object with the following attributes. The values for all attributes are lists of strings.

priorities The set of valid Priority values for the hub.
states The set of valid State values for the hub.
findings The set of valid Finding values for the hub.
users The set of valid Owner values for the hub.
Returns:None
WarningProcessor.handle_warning(warningdata)

Used by parse_xml() to handle a <warning> element in XML input.

Parameters:warningdata

an object of class WarningReport, with attributes as follows. All attributes are string-valued.

is_new True if there are no previous instances of the same warning and False otherwise. This attribute is only present in automatic application.
id The warning’s Warning ID.
listing The warning’s Listing XML.
warning attributes One attribute for each attribute of the <warning> element, with identical names and corresponding values.
project attributes One attribute for each attribute of the <project> sub-element, with names of the form project_attname and corresponding values.
analysis attributes One attribute for each attribute of the <analysis> sub-element, with names of the form analysis_attname and corresponding values.
Returns:None

Other Useful WarningProcessor Methods

WarningProcessor also provides output helpers:

and unusual termination helpers:

WarningProcessor.output(msg, context=None, log=None)

Output msg to self._out. If context is specified and not None, render msg in context first. If log is not None, also write the (rendered) message to log.

Parameters:
  • msg – the message to output
  • context – kwargs for string.Template.safe_substitute()
  • log – a log file, or name of a log file, to write msg to.
Returns:

None

Note:

Use this method to write your warning processor output.

WarningProcessor.write(file, msg)

Write msg to file.

Parameters:
  • file – a file, or name of a file, to write msg to.
  • msg – the message to write
Returns:

None

Note:

Use this method to write to a file without also writing to self._out. To write warning processor output, use output().

WarningProcessor.die(msg=None)

Write msg to stderr and exit.

Parameters:msg – the message to write
Returns:None
WarningProcessor.fatal_error()

Call die(), providing part of the stack trace as the message.

Returns:None