Class: Sprout::FDBTask
- Inherits:
-
ToolTask
- Object
- ToolTask
- Sprout::FDBTask
- Defined in:
- lib/sprout/tasks/fdb_task.rb
Overview
The FDBTask provides a procedural rake front end to the FDB command line tool
Here is a decent tutorial on using FDB with SWF or HTML content: installingcats.wordpress.com/tag/adobe-flex/
You can send the fdb task some debug commands directly or simply execute the rake task and interact with the debugger manually.
The FDBTask requires that you have a debug Flash Player installed on your system as the default execution application for SWF files.
Following is an example of setting up a breakpoint in SomeFile at line 23
fdb :debug do |t|
t.file = 'bin/SomeProject-debug.swf'
t.run
t.break = 'SomeFile:23'
t.continue
end
You can also point the FDBTask at HTML pages. These pages will be launched in your default browser. You will need to manually install a debug Flash Player in that particular browser.
To use a browser instead of the desktop Flash Player, simply point the file argument at an HTML document or remote URL. The SWF file loaded must be compiled using the -debug flag, and executed in a debug Flash Player in order to connect to properly connect to the debugger.
fdb :debug do |t|
t.file = 'bin/SomeProject-debug.html'
t.run
t.continue
end
.h3 Continuous Integration
The FDBTask is also the only effective way to execute SWF content in front of a CI (continuous integration) tool like Cruise Control. The biggest problem facing SWF execution for CI is uncaught runtime exceptions. The debug Flash Player throws uncaught exceptions up to the operating system GUI layer where a user must manually dismiss a dialog. In addition to blocking the CI process indefinitely, these messages are also difficult to capture and log.
Using Sprouts and the FDBTask, we can capture these messages along with additonal information (e.g. local variables and a complete stack trace) about the state of the SWF file, and then cleanly exit the Flash Player and log this information.
The FDBTask has also been configured to work with the ASUnit XMLPrinter so that an XML artifact is created and written to disk that includes the results of running your test suites.
To use FDB with a CI tool do the following:
1) Create a new base runner class (we usually name this XMLRunner.as) and make it look like the following:
package {
import asunit.textui.TestRunner;
import asunit.textui.XMLResultPrinter;
public class XMLRunner extends TestRunner {
public function XMLRunner() {
setPrinter(new XMLResultPrinter());
start(AllTests, null, TestRunner.SHOW_TRACE);
}
}
}
2) Create a new MXMLCTask to compile the newly created runner. NOTE: Be sure you set debug
to true, otherwise the SWF will not connect to the debugger properly.
library :asunit3
desc 'Compile the CI SWF'
mxmlc 'bin/XMLRunner.swf' => :asunit3 do |t|
t.input = 'src/XMLRunner.as'
t.debug = true
t.source_path << 'test'
# Add additional configuration here.
end
3) Create a new FDBTask and set kill_on_fault
to true.
desc 'Execute the test harness for CI'
fdb :cruise do |t|
t.kill_on_fault = true
t.file = 'bin/XMLRunner.swf'
t.run
t.continue
end
4) Configure your CI task to call:
rake cruise
5) That’s it!
Constant Summary collapse
- TEST_RESULT_PRELUDE =
'<XMLResultPrinter>'
- TEST_RESULT_CLOSING =
'</XMLResultPrinter>'
- TEST_RESULT_FILE =
'AsUnitResults.xml'
Instance Attribute Summary collapse
-
#kill_on_fault ⇒ Object
writeonly
Boolean value that tells fdb whether or not it should automatically shut down when an exception is encountered.
- #test_result_closing ⇒ Object
- #test_result_file ⇒ Object
- #test_result_prelude ⇒ Object
Instance Method Summary collapse
-
#break=(point) ⇒ Object
Set breakpoint at specified line or function.
-
#bt ⇒ Object
Print backtrace of all stack frames.
-
#c ⇒ Object
Alias for continue.
-
#cf ⇒ Object
Display the name and number of the current file.
-
#clear=(point) ⇒ Object
Clear breakpoint at specified line or function.
-
#command_queue ⇒ Object
:nodoc:.
-
#commands=(cmd) ⇒ Object
Sets commands to execute when breakpoint hit.
-
#condition=(cond) ⇒ Object
Apply/remove conditional expression to a breakpoint.
-
#continue ⇒ Object
Continue execution after stopping at breakpoint.
-
#define ⇒ Object
:nodoc:.
-
#delete ⇒ Object
Delete breakpoints or auto-display expressions.
-
#directory=(dir) ⇒ Object
Add a directory to the search path for source files.
-
#disable ⇒ Object
Disable breakpoints or auto-display expressions.
-
#disassemble ⇒ Object
Disassemble source lines or functions.
-
#display=(disp) ⇒ Object
Add an auto-display expressions.
-
#e ⇒ Object
Enable breakpoints or auto-display expressions.
-
#enable ⇒ Object
Enable breakpoints or auto-display expressions.
-
#execute(*args) ⇒ Object
:nodoc:.
-
#file=(file) ⇒ Object
Specify application to be debugged.
-
#finish ⇒ Object
Execute until current function returns.
-
#get_executable ⇒ Object
:nodoc:.
-
#handle ⇒ Object
Specify how to handle a fault.
-
#handle_command(buffer, command) ⇒ Object
:nodoc:.
-
#home ⇒ Object
Set listing location to where execution is halted.
-
#info ⇒ Object
Display information about the program being debugged.
-
#info_arguments ⇒ Object
Argument variables of current stack frame.
-
#info_breakpoints ⇒ Object
Status of user-settable breakpoints.
-
#info_display ⇒ Object
Display list of auto-display expressions.
-
#info_files ⇒ Object
Names of targets and files being debugged.
-
#info_functions=(value) ⇒ Object
All function names.
-
#info_handle ⇒ Object
How to handle a fault.
-
#info_locals ⇒ Object
Local variables of current stack frame.
-
#info_scopechain ⇒ Object
Scope chain of current stack frame.
-
#info_sources ⇒ Object
Source files in the program.
-
#info_stack ⇒ Object
Backtrace of the stack.
-
#info_swfs ⇒ Object
List of swfs in this session.
-
#info_targets ⇒ Object
Application being debugged.
-
#info_variables ⇒ Object
All global and static variable names.
-
#initialize_task ⇒ Object
:nodoc:.
-
#input=(file) ⇒ Object
alias for self.file=.
-
#kill ⇒ Object
Kill execution of program being debugged.
- #kill_on_fault? ⇒ Boolean
-
#list ⇒ Object
List specified function or line.
-
#next ⇒ Object
Step program.
-
#print=(msg) ⇒ Object
Print value of variable EXP.
-
#pwd ⇒ Object
Print working directory.
-
#quit ⇒ Object
Exit fdb.
-
#run ⇒ Object
Start debugged program.
-
#set=(value) ⇒ Object
Set the value of a variable.
-
#sleep_until(str) ⇒ Object
Sleep until some ‘str’ String is sent to the output,.
-
#source=(file) ⇒ Object
Read fdb commands from a file.
-
#stdout ⇒ Object
:nodoc:.
-
#stdout=(out) ⇒ Object
:nodoc:.
-
#step ⇒ Object
Step program until it reaches a different source line.
-
#terminate ⇒ Object
Force the Flash Debugger and running SWF to close.
-
#undisplay ⇒ Object
Remove an auto-display expression.
- #validate_swf(swf) ⇒ Object
-
#viewswf ⇒ Object
Set or clear filter for file listing based on swf.
-
#what=(value) ⇒ Object
Displays the context of a variable.
-
#where ⇒ Object
Same as bt.
Instance Attribute Details
#kill_on_fault=(value) ⇒ Object (writeonly)
Boolean value that tells fdb whether or not it should automatically shut down when an exception is encountered. This feature is used to prevent GUI prompts for unhandled exceptions, especially when running a test harness under a continuous integration tool - like cruise control. If an exception is encountered, fdb will automatically print the exception, a full stack trace and all local variables in the function where the failure occured.
142 143 144 |
# File 'lib/sprout/tasks/fdb_task.rb', line 142 def kill_on_fault=(value) @kill_on_fault = value end |
#test_result_closing ⇒ Object
236 237 238 |
# File 'lib/sprout/tasks/fdb_task.rb', line 236 def test_result_closing @test_result_closing ||= TEST_RESULT_CLOSING end |
#test_result_file ⇒ Object
228 229 230 |
# File 'lib/sprout/tasks/fdb_task.rb', line 228 def test_result_file @test_result_file ||= TEST_RESULT_FILE end |
#test_result_prelude ⇒ Object
232 233 234 |
# File 'lib/sprout/tasks/fdb_task.rb', line 232 def test_result_prelude @test_result_prelude ||= TEST_RESULT_PRELUDE end |
Instance Method Details
#break=(point) ⇒ Object
Set breakpoint at specified line or function
246 247 248 |
# File 'lib/sprout/tasks/fdb_task.rb', line 246 def break=(point) @queue << "break #{point}" end |
#bt ⇒ Object
Print backtrace of all stack frames
241 242 243 |
# File 'lib/sprout/tasks/fdb_task.rb', line 241 def bt @queue << "bt" end |
#c ⇒ Object
Alias for continue
271 272 273 |
# File 'lib/sprout/tasks/fdb_task.rb', line 271 def c @queue << "continue" end |
#cf ⇒ Object
Display the name and number of the current file
251 252 253 |
# File 'lib/sprout/tasks/fdb_task.rb', line 251 def cf @queue << "cf" end |
#clear=(point) ⇒ Object
Clear breakpoint at specified line or function
256 257 258 |
# File 'lib/sprout/tasks/fdb_task.rb', line 256 def clear=(point) @queue << "clear #{point}" end |
#command_queue ⇒ Object
:nodoc:
220 221 222 |
# File 'lib/sprout/tasks/fdb_task.rb', line 220 def command_queue # :nodoc: @queue end |
#commands=(cmd) ⇒ Object
Sets commands to execute when breakpoint hit
276 277 278 |
# File 'lib/sprout/tasks/fdb_task.rb', line 276 def commands=(cmd) @queue << "com #{cmd}" end |
#condition=(cond) ⇒ Object
Apply/remove conditional expression to a breakpoint
261 262 263 |
# File 'lib/sprout/tasks/fdb_task.rb', line 261 def condition=(cond) @queue << "condition #{cond}" end |
#continue ⇒ Object
Continue execution after stopping at breakpoint
266 267 268 |
# File 'lib/sprout/tasks/fdb_task.rb', line 266 def continue @queue << "continue" end |
#define ⇒ Object
:nodoc:
152 153 154 155 156 |
# File 'lib/sprout/tasks/fdb_task.rb', line 152 def define # :nodoc: super CLEAN.add(test_result_file) self end |
#delete ⇒ Object
Delete breakpoints or auto-display expressions
281 282 283 |
# File 'lib/sprout/tasks/fdb_task.rb', line 281 def delete @queue << "delete" end |
#directory=(dir) ⇒ Object
Add a directory to the search path for source files
286 287 288 |
# File 'lib/sprout/tasks/fdb_task.rb', line 286 def directory=(dir) @queue << "directory #{dir}" end |
#disable ⇒ Object
Disable breakpoints or auto-display expressions
291 292 293 |
# File 'lib/sprout/tasks/fdb_task.rb', line 291 def disable @queue << "disable" end |
#disassemble ⇒ Object
Disassemble source lines or functions
296 297 298 |
# File 'lib/sprout/tasks/fdb_task.rb', line 296 def disassemble @queue << "dissassemble" end |
#display=(disp) ⇒ Object
Add an auto-display expressions
301 302 303 |
# File 'lib/sprout/tasks/fdb_task.rb', line 301 def display=(disp) @queue << "disp #{disp}" end |
#e ⇒ Object
Enable breakpoints or auto-display expressions
311 312 313 |
# File 'lib/sprout/tasks/fdb_task.rb', line 311 def e @queue << "enable" end |
#enable ⇒ Object
Enable breakpoints or auto-display expressions
306 307 308 |
# File 'lib/sprout/tasks/fdb_task.rb', line 306 def enable @queue << "enable" end |
#execute(*args) ⇒ Object
:nodoc:
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/sprout/tasks/fdb_task.rb', line 174 def execute(*args) # :nodoc: # Ensure that if we load a SWF it's been compiled with debugging turned on! file_name = @file if(file_name.match(/\.swf$/)) validate_swf(file_name) end buffer = FDBBuffer.new(get_executable, stdout) buffer.test_result_file = test_result_file buffer.test_result_prelude = test_result_prelude buffer.test_result_closing = test_result_closing buffer.kill_on_fault = kill_on_fault? buffer.wait_for_prompt @queue.each do |command| handle_command(buffer, command) end buffer.join # wait here until the buffer is closed. if(buffer.runtime_exception_encountered && kill_on_fault?) raise FDBTaskError.new("[ERROR] ActionScript runtime exception encountered") end self end |
#file=(file) ⇒ Object
Specify application to be debugged.
316 317 318 319 320 |
# File 'lib/sprout/tasks/fdb_task.rb', line 316 def file=(file) @prerequisites << file @queue << "file #{file}" @file = file end |
#finish ⇒ Object
Execute until current function returns
328 329 330 |
# File 'lib/sprout/tasks/fdb_task.rb', line 328 def finish @queue << "finish" end |
#get_executable ⇒ Object
:nodoc:
215 216 217 218 |
# File 'lib/sprout/tasks/fdb_task.rb', line 215 def get_executable # :nodoc: exe = Sprout.get_executable(gem_name, gem_path, gem_version) User.clean_path(exe) end |
#handle ⇒ Object
Specify how to handle a fault
333 334 335 |
# File 'lib/sprout/tasks/fdb_task.rb', line 333 def handle @queue << "handle" end |
#handle_command(buffer, command) ⇒ Object
:nodoc:
201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/sprout/tasks/fdb_task.rb', line 201 def handle_command(buffer, command) # :nodoc: parts = command.split(' ') name = parts.shift value = parts.shift case name when "sleep" buffer.sleep_until value when "terminate" buffer.kill else buffer.write command end end |
#home ⇒ Object
Set listing location to where execution is halted
338 339 340 |
# File 'lib/sprout/tasks/fdb_task.rb', line 338 def home @queue << "home" end |
#info ⇒ Object
Display information about the program being debugged
343 344 345 |
# File 'lib/sprout/tasks/fdb_task.rb', line 343 def info @queue << "info" end |
#info_arguments ⇒ Object
Argument variables of current stack frame
348 349 350 |
# File 'lib/sprout/tasks/fdb_task.rb', line 348 def info_arguments @queue << "i a" end |
#info_breakpoints ⇒ Object
Status of user-settable breakpoints
353 354 355 |
# File 'lib/sprout/tasks/fdb_task.rb', line 353 def info_breakpoints @queue << "i b" end |
#info_display ⇒ Object
Display list of auto-display expressions
358 359 360 |
# File 'lib/sprout/tasks/fdb_task.rb', line 358 def info_display @queue << "i d" end |
#info_files ⇒ Object
Names of targets and files being debugged
363 364 365 |
# File 'lib/sprout/tasks/fdb_task.rb', line 363 def info_files @queue << "i f" end |
#info_functions=(value) ⇒ Object
All function names
368 369 370 |
# File 'lib/sprout/tasks/fdb_task.rb', line 368 def info_functions=(value) @queue << "i fu #{value}" end |
#info_handle ⇒ Object
How to handle a fault
373 374 375 |
# File 'lib/sprout/tasks/fdb_task.rb', line 373 def info_handle @queue << "i h" end |
#info_locals ⇒ Object
Local variables of current stack frame
378 379 380 |
# File 'lib/sprout/tasks/fdb_task.rb', line 378 def info_locals @queue << "i l" end |
#info_scopechain ⇒ Object
Scope chain of current stack frame
383 384 385 |
# File 'lib/sprout/tasks/fdb_task.rb', line 383 def info_scopechain @queue << "i sc" end |
#info_sources ⇒ Object
Source files in the program
388 389 390 |
# File 'lib/sprout/tasks/fdb_task.rb', line 388 def info_sources @queue << "i so" end |
#info_stack ⇒ Object
Backtrace of the stack
393 394 395 |
# File 'lib/sprout/tasks/fdb_task.rb', line 393 def info_stack @queue << "i s" end |
#info_swfs ⇒ Object
List of swfs in this session
398 399 400 |
# File 'lib/sprout/tasks/fdb_task.rb', line 398 def info_swfs @queue << "i sw" end |
#info_targets ⇒ Object
Application being debugged
403 404 405 |
# File 'lib/sprout/tasks/fdb_task.rb', line 403 def info_targets @queue << "i t" end |
#info_variables ⇒ Object
All global and static variable names
408 409 410 |
# File 'lib/sprout/tasks/fdb_task.rb', line 408 def info_variables @queue << "i v" end |
#initialize_task ⇒ Object
:nodoc:
144 145 146 147 148 149 150 |
# File 'lib/sprout/tasks/fdb_task.rb', line 144 def initialize_task # :nodoc: Thread.abort_on_exception = true @default_gem_name = 'sprout-flex3sdk-tool' @default_gem_path = 'bin/fdb' @kill_on_fault = false @queue = [] end |
#input=(file) ⇒ Object
alias for self.file=
323 324 325 |
# File 'lib/sprout/tasks/fdb_task.rb', line 323 def input=(file) self.file = file end |
#kill ⇒ Object
Kill execution of program being debugged
413 414 415 |
# File 'lib/sprout/tasks/fdb_task.rb', line 413 def kill @queue << "kill" end |
#kill_on_fault? ⇒ Boolean
224 225 226 |
# File 'lib/sprout/tasks/fdb_task.rb', line 224 def kill_on_fault? @kill_on_fault end |
#list ⇒ Object
List specified function or line
418 419 420 |
# File 'lib/sprout/tasks/fdb_task.rb', line 418 def list @queue << "list" end |
#next ⇒ Object
Step program
423 424 425 |
# File 'lib/sprout/tasks/fdb_task.rb', line 423 def next @queue << "next" end |
#print=(msg) ⇒ Object
Print value of variable EXP
428 429 430 |
# File 'lib/sprout/tasks/fdb_task.rb', line 428 def print=(msg) @queue << "print #{msg}" end |
#pwd ⇒ Object
Print working directory
433 434 435 |
# File 'lib/sprout/tasks/fdb_task.rb', line 433 def pwd @queue << "pwd" end |
#quit ⇒ Object
Exit fdb
438 439 440 441 442 |
# File 'lib/sprout/tasks/fdb_task.rb', line 438 def quit @queue << "quit" @queue << "y" @queue << "terminate" end |
#run ⇒ Object
Start debugged program
445 446 447 |
# File 'lib/sprout/tasks/fdb_task.rb', line 445 def run @queue << "run" end |
#set=(value) ⇒ Object
Set the value of a variable
450 451 452 |
# File 'lib/sprout/tasks/fdb_task.rb', line 450 def set=(value) @queue << "set #{value}" end |
#sleep_until(str) ⇒ Object
Sleep until some ‘str’ String is sent to the output,
455 456 457 |
# File 'lib/sprout/tasks/fdb_task.rb', line 455 def sleep_until(str) @queue << "sleep #{str}" end |
#source=(file) ⇒ Object
Read fdb commands from a file
460 461 462 |
# File 'lib/sprout/tasks/fdb_task.rb', line 460 def source=(file) @queue << "source #{file}" end |
#stdout ⇒ Object
:nodoc:
162 163 164 |
# File 'lib/sprout/tasks/fdb_task.rb', line 162 def stdout # :nodoc: @stdout ||= $stdout end |
#stdout=(out) ⇒ Object
:nodoc:
158 159 160 |
# File 'lib/sprout/tasks/fdb_task.rb', line 158 def stdout=(out) # :nodoc: @stdout = out end |
#step ⇒ Object
Step program until it reaches a different source line
465 466 467 |
# File 'lib/sprout/tasks/fdb_task.rb', line 465 def step @queue << "step" end |
#terminate ⇒ Object
Force the Flash Debugger and running SWF to close
470 471 472 |
# File 'lib/sprout/tasks/fdb_task.rb', line 470 def terminate @queue << "terminate" end |
#undisplay ⇒ Object
Remove an auto-display expression
475 476 477 |
# File 'lib/sprout/tasks/fdb_task.rb', line 475 def undisplay @queue << "undisplay" end |
#validate_swf(swf) ⇒ Object
166 167 168 169 170 171 172 |
# File 'lib/sprout/tasks/fdb_task.rb', line 166 def validate_swf(swf) # TODO: Ensure the SWF has been compiled with debugging # turned on. # I believe this will require actually parsing the SWF file and # scanning for the EnableDebugger2 tag. # http://www.adobe.com/devnet/swf/pdf/swf_file_format_spec_v9.pdf end |
#viewswf ⇒ Object
Set or clear filter for file listing based on swf
480 481 482 |
# File 'lib/sprout/tasks/fdb_task.rb', line 480 def viewswf @queue << "viewswf" end |
#what=(value) ⇒ Object
Displays the context of a variable
485 486 487 |
# File 'lib/sprout/tasks/fdb_task.rb', line 485 def what=(value) @queue << "what #{value}" end |
#where ⇒ Object
Same as bt
490 491 492 |
# File 'lib/sprout/tasks/fdb_task.rb', line 490 def where @queue << "bt" end |