mecate - Interacting with a bosal generated test harness
This manpage describes the mecate package which is a Tcl script extension that simplifies interactions with a bosal generated test harness.
The main command in the package is a TclOO class command to create a rein object. The methods of a rean object provide access to the test harness. In addition, some utility procedures are provided. The package commands form a namespace ensemble command.
The mecate package is organized as a single TclOO class called rein. The rein class command is also exported as an ensemble command from the mecate namespace. The constructor for rein takes a set of option / value pairs. The options are:
The eventTraceFormat converts a raw event trace dictionary into a a human readable string. The output is similar to that produced by formatEventTraces but is intended to format only a single trace.
The instrTraceFormat converts a raw instrumentation trace dictionary into a a human readable string. The output is similar to that produced by formatInstrTraces but is intended to format only a single trace.
The fatalTraceFormat converts a raw fatal error trace dictionary into a a human readable string. The output is similar to that produced by formatFatalTraces but is intended to format only a single trace.
This section lists the methods supported by objects of the rein class.
The destructor for rein objects closes any communications connection made to the harnessed application.
The cget method may be used to obtain the values of the options that were set during construction. Option is one of the options described for the constructor. The method returns the value of the given option.
The configure method may be used to set the values of the configuration options. Option names and values are those described for the constructor. Returns the empty string.
The methods in this section are used to set up and take down a test harness program. It is necessary to start the execution of a test harness before is can be used. Sometimes this is accomplished outside of a test script, for example if the test harness is running under control of a debugger. When a bosal generated test harness starts, it acts as a server, opening a TCP port on the local host and awaiting a connection. To communicate with the test harness program, it is necessary to establish a TCP client connection to the test harness acting as a server. The rein class provides methods to manage these actions directly from a test script.
The start method is used to begin execution of the test harness program. Starting is separated out as a method because certain test situations will have the harness program running under a debugger which will be responsible for starting program execution. The return value is the process ID of the harness program, although such a number is of little use in the Tcl world. When the test harness communications channel is destroyed, the harness program itself exits.
The connect` method forms a communications connection to the test harness. All I/O to and from the test harness happens across this connection. The method returns the empty string and throws an error if the connection cannot be established.
The disconnect method closes the communications connection to the test harness. This causes the test harness process to exit.
The null method performs no action on the test domain, but communicates with it to insure that it is responsive.
The version method returns the version number of bosal used to create the test harness code.
A bosal generated harness has introspection capabilities that can be used to determine the characteristics of the domains in the harness. This information is available using the query method described in this section.
The query method returns the result of querying various entities in a test harness. It is possible to determine the domains in the harness, the classes of each domain and many other characteristics.
The domainop method invokes a domain operation on a domain.
The create method creates an instance of the given class and returns a integer identifier for the instance. The identifying number is unique only within the class.
N.B. that the instance is created in an uninitialized state and it is necessary to follow up with invocation of the update method on the instance to initialize it attributes. Also, creating instances can cause problems with referential integrity which will be detected on the next transaction boundary. Since there is no way to deal with associations from the test harness interface, creating class instances is of limited utility.
The delete method deletes the given instance.
N.B. Deleting an instance often causes a referential integrity problem that my create a fatal error when the next thread of control is finished. In general, it is not safe to delete arbitrary instances and there is no mechanism provide to manipulate relationship instances in the harnessed domains.
The read method reads the values of attributes from classes in a domain.
N.B. Not all attributes of an instance may be read. In particular, instance data used to implement associations and generalizations is not available since these values are memory addresses and not meaningful outside of the domain.
The update method updates the values of attributes of classes in a domain. The attribute names and values are given in pairs as arguments to the method. Note that multiple attributes may be updated in a single invocation of the method.
One of the primary ways to cause a domain to react is to signal events to the class instances. Both immediate and delayed signaling is supported.
The signal method signals an event to a class instance. Signals generated from a test harness are considered to be generated outside of a state machine context and so start a new thread of control
The delaysignal method signals an event to a class instance at some time in the future.
The cancel method requests an delayed signal be canceled.
The remaining method returns the number of milliseconds before the event is to be signaled. A return value of 0, implies that either the event has already been signaled (i.e. its delay time has already expired) or the delayed event did not exist.
The createasync method creates a class instance asynchronously by signaling a creation event.
The test harness generated by bosal makes extensive use of the means provided by the micca run-time code to control the event loop. The micca run-time code allows the dispatch of individual events, an entire thread of control and exiting the event event loop. In addition, the test harness installs its own fatal condition handler to prevent the harness program from exiting if a fatal error condition arises.
With no arguments the eloop method returns the current state of the event loop, either running or halted. An additional argument may be given to control the state of the event loop.
Test harnesses can output traces showing the chronological sequence of event dispatch for the state machines. Mecate has methods to accumulate and synchronize to the event traces. Internally, rein object keep a cache of the state machine traces as well as accumulate them for later storage. The cache is used to search and wait for particular events.
The trace method controls whether state machine dispatch traces are output from the test harness and accumulated by mecate.
The waitForEventTrace method examines the cache of state machine event traces in chronological order searching for a match to the field / pattern pairs given. Any trace that does not match is discarded from the cache. If necessary, execution of the test is suspended until a state machine trace matching the given parameters arrives or a timeout occurs. Matching multiple fields is conjunctive in nature, i.e. if multiple fields are given, then all fields must match to consider the event trace to be a match.
The method returns the matching state machine trace. If a timeout or fatal error occurs, then the method throw an error.
The clearEventTraceCache method deletes any accumulated state machine event traces contained in the event trace cache. All future attempts to match an event trace will operate only against those traces received after this method was invoked.
The formatEventTraces method returns a string containing a human readable print out of the received traces.
The discardEventTraces method deletes the set of accumulated event traces.
The traceNotify method returns and optionally sets the command prefix for a command that is executed whenever a state machine trace arrives from a test harness. The prefix argument is optional. If present, then the argument is interpreted as a command prefix and will be invoked with an additional argument as: prefix trace where trace is a dictionary with the trace information. The keys to the trace dictionary are the same as the field names listed in the waitForEventTrace method. If missing, then no changes are made to the notification command. In both cases, the current value of the notification command prefix is returned. Setting the prefix to the empty string, disables trace notification.
The seqDiag method returns a string consisting of text that can be given to plantuml to create a graphical representation of the state machine traces as a UML sequence diagram.
The seqDiagConfig method sets one or more options used to control the manner in which sequence diagrams are rendered. The return value of the method is the current configuration which is a dictionary of option name keys with corresponding option values.
The seqDiagToChan method writes to a Tcl channel a string consisting of text that can be given to plantuml to create a graphical representation of the state machine traces as a UML sequence diagram.
The seqDiagToFile method writes to a file a string consisting of text that can be given to plantuml to create a graphical representation of the state machine traces as a UML sequence diagram.
In addition to event traces, micca domains produce instrumentation traces. During code generation, micca inserts trace statements into state activities and other functions. The traces statements are actually "C" pre-processor macros which, by default, produce instrumentation output of the function name, the file containing the function, and line number. This gives a record which functions in the the domain are executed. In addition, the MRT_DEBUG macro, which has the same interface as printf(), is available to activities for generating instrumentation output. In a test harness, the instrumentation output is directed to the harness communications port and the methods in this section define the operations that can be applied to instrumentation traces.
The instr method controls whether instrumentation traces are output from the test harness and accumulated.
The waitForInstrTrace method suspends execution until a instrumentation trace matches the given parameters or a timeout occurs.
The clearInstrTraceCache method deletes any accumulated instrumentation traces contained in the instrumentation trace cache. All future attempts to match an instrumentation trace will operate only against those traces received after this method was invoked.
The formatInstrTraces method returns a string containing a human readable print out of the received instrumentation traces.
The discardInstrTraces method deletes the set of accumulated instrumentation traces.
The instrNotify method returns command prefix for a command that is executed whenever an instrumentation trace arrives from a test harness. The prefix argument is optional. If present, then the argument is interpreted as a command prefix and will be invoked with an additional argument as: prefix instr where instr is a dictionary with the instrumentation information. If missing, then no changes are made to the notification command. In both cases, the current value of the notification command prefix is returned. Setting the prefix to the empty string, disables instrumentation notification.
The micca run-time code detects several fatal errors. By default, the micca run-time invokes the `abort` function from the "C" standard library. Most implementations of abort cause the process to terminate and dump core for debugging. When running as a test harness, terminating the process is not desirable. We would like to be able to examine the state of things after the fatal error has happened. So, bosal generates code to install its own fatal error handler and this handler allows the test harness communication socket to remain open. The fatal error handle also emits a fatal error message with the details. Note that the fatal error messages are sent asynchronously to any command / response sequence and cannot be tuned off.
The waitForFatalTrace method suspends execution until a fatal error trace matches the given parameters or a timeout occurs.
The clearFatalTraceCache method deletes any accumulated fatal error traces contained in the fatal error trace cache. All future attempts to match an fatal error trace will operate only against those traces received after this method was invoked.
The formatFatalTraces method returns a string containing a human readable print out of the received traces.
The discardFatalTraces method deletes the set of accumulated fatal error traces.
The fatalNotify method returns command prefix for a command that is executed whenever a fatal error trace arrives from a test harness. The prefix argument is optional. If present, then the argument is interpreted as a command prefix and will be invoked with an additional argument as: prefix fatal where fatal is a dictionary with the fatal error information. If missing, then no changes are made to the notification command. In both cases, the current value of the notification command prefix is returned. Setting the prefix to the empty string, disables fatal error notification.
Traces received by mecate are accumulated and can be saved. The traces can be serialized to the native format of TclRAL or can be written to a SQLite database.
The saveTraces method stores any accumulated event, instrumentation and fatal traces to a file.
bosal, micca