package com.yahoo.dtf.actions.event;
import java.net.URI;
import com.yahoo.dtf.actions.reference.Referencable;
import com.yahoo.dtf.exception.ActionException;
import com.yahoo.dtf.exception.DTFException;
import com.yahoo.dtf.exception.ParseException;
import com.yahoo.dtf.recorder.RecorderBase;
import com.yahoo.dtf.recorder.RecorderFactory;
/**
* @dtf.tag record
*
* @dtf.since 1.0
* @dtf.author Rodney Gomes
*
* @dtf.tag.desc This tag is used to record DTF events thrown within the code
* and also thrown from the test case using the event tag. These
* events can be recorded to the following output formats: XML,
* Text file. Then the query tag can be used to get data back out
* of the recorded medium for later to be used by other test cases
* or the same one.
*
* @dtf.tag.example
* <record uri="storage://OUTPUT/dtf.internals.txt"
* type="txt"
* event="dtf.perf.*">
* <local>
* <testscript uri="storage://INPUT/parallel.xml"/>
* </local>
* </record>
*
* @dtf.tag.example
* <record type="txt" uri="storage://OUTPUT/recorder2.txt">
* <for property="index" range="1,2,3,4,5,6,7,8,9,10">
* <event name="dtf.echo.outter">
* <local>
* <echo>Testing...</echo>
* </local>
* </event>
* </for>
* <record type="txt" uri="storage://OUTPUT/recorder3.txt">
* <for property="index" range="1,2,3,4,5,6,7,8,9,10">
* <event name="dtf.echo.inner">
* <local>
* <echo>Testing...</echo>
* </local>
* </event>
* </for>
* </record>
* </record>
*/
public class Record extends Referencable {
/**
* @dtf.attr uri
* @dtf.attr.desc output URI used by all the record types except the
* console recorder.
*/
private String uri = null;
/**
* @dtf.attr type
* @dtf.attr.desc Identifies the type of recorder to instantiate to record
* events that are thrown child tags of this recorder tag.
*
* <b>Recorder Types</b>
* <table border="1">
* <tr>
* <th>Name</th>
* <th>Description</th>
* </tr>
* <tr>
* <td>txt</td>
* <td>
* Text recorder will record events to a file in a human readable format like so:
* <pre>
* dtf.perf.action.component.start=1166719862514
* dtf.perf.action.component.stop=1166719862690
* </pre>
* </td>
* </tr>
* <tr>
* <td>console</td>
* <td>
* Outputs in the same format as the txt type but
* instead of to a file it will output the
* results to the STDOUT of the process from
* where you execute your test case.
*
* Output on screen would look like this:
* <pre>
* INFO 27/12/2006 00:12:31 Echo - Testing...
* INFO 27/12/2006 00:12:31 ConsoleRecorder - dtf.echo.start=1167208531453
* INFO 27/12/2006 00:12:31 ConsoleRecorder - dtf.echo.stop=1167208531453
* </pre>
* </td>
* </tr>
* <tr>
* <td>object</td>
* <td>
* <b>DEPRECATED: there is no reason to use this
* anymore since all of the events are available as
* a property immediately after their execution.</b>
* <br/>
* <br/>
* Will output the results of an event to an in memory
* property that can be accessed after the event to
* get important information about the event.
* </td>
* </tr>
* <tr>
* <td>stats</td>
* <td>
* This recorder will calculate your statistics as they
* are being thrown within the framework. It will give
* you the same statistics that you'd get using the
* {@dtf.link Stats} tag but they're immediately available after all
* actions within the recorder are done executing. The
* {@dtf.link Stats} are recorded using the event name followed by
* the usual properties for each stat calculated with
* the {@dtf.link Stats} tag (see the {@dtf.link Stats} for more
* information on the available statistics).
* <br/>
* <br/>
* <b>Remember:</b> if you want to be able to record the same
* events to a file just wrap this record tag with
* another and you'll have the recording of events to a
* file along with the immediate calculation of
* statistics.
* </td>
* </tr>
* </table>
*/
private String type = null;
/**
* @dtf.attr event
* @dtf.attr.desc prefix of the events you intend to recorder.
*/
private String event = null;
/**
* @dtf.attr append
* @dtf.attr.desc This value indicates if the events should be appended to
* the existing output file or start the recording from
* scratch eliminating any previous results. Accepted values
* are "true" and "false".
*/
private String append = null;
/**
* @dtf.attr encoding
* @dtf.attr.desc See {@dtf.link Loadproperties} for more information on the
* encoding attribute.
*/
private String encoding = null;
public Record() { }
public void execute() throws DTFException {
/*
* Make the object recorder be debugging logging because this is usually
* used in loops to grab events generated by other tags and can be very
* spamy if we always log as info.
*/
if ( getLogger().isDebugEnabled() ) {
getLogger().debug("Starting recorder: " + this);
}
RecorderBase recorder = RecorderFactory.getRecorder(getType(),
getUri(),
getAppend(),
getEncoding());
pushRecorder(recorder, getEvent());
try {
executeChildren();
} finally {
// If there's an exception we still need to close up the recorder
popRecorder();
}
if ( getLogger().isDebugEnabled() ) {
getLogger().debug("Stopping recorder: " + this);
}
}
public String getEvent() throws ParseException { return replaceProperties(event); }
public void setEvent(String event) { this.event = event; }
public String getType() throws ParseException { return replaceProperties(type); }
public void setType(String type) { this.type = type; }
public URI getUri() throws ActionException, ParseException { return parseURI(uri); }
public void setUri(String uri) { this.uri = uri; }
public boolean getAppend() throws ParseException {
if (append == null)
return true;
return Boolean.valueOf(replaceProperties(append)).booleanValue();
}
public void setAppend(String append) { this.append = append; }
public void setEncoding(String encoding) { this.encoding = encoding; }
public String getEncoding() throws ParseException { return replaceProperties(encoding); }
}