Changeset 2019 for trunk


Ignore:
Timestamp:
Dec 24, 2010, 9:15:21 AM (14 years ago)
Author:
braffert
Message:

Regression tester: adding Test class to keep testing logic isolated from GUI

Location:
trunk/tester
Files:
1 added
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/tester/example/tests/test7.xml

    r2017 r2019  
    22<run>
    33    <test>
    4         <label>multiple|levels|spaces are allowed|</label>
     4        <label>multiple|levels|spaces are allowed...</label>
    55    </test>
    66    <tool>
  • trunk/tester/tclIndex

    r2012 r2019  
    77# a script that loads the command.
    88
    9 set auto_index(::Rappture::Tester::runAll) [list source [file join $dir tester.tcl]]
    10 set auto_index(::Rappture::Tester::runSelected) [list source [file join $dir tester.tcl]]
    11 set auto_index(::Rappture::Tester::runTest) [list source [file join $dir tester.tcl]]
    129set auto_index(::Rappture::Tester::selectionHandler) [list source [file join $dir tester.tcl]]
     10set auto_index(::Rappture::Tester::regoldenize) [list source [file join $dir tester.tcl]]
    1311set auto_index(::Rappture::Tester::TestView) [list source [file join $dir testview.tcl]]
    1412set auto_index(::Rappture::Tester::TestView::constructor) [list source [file join $dir testview.tcl]]
    15 set auto_index(::Rappture::Tester::TestView::clear) [list source [file join $dir testview.tcl]]
     13set auto_index(::Rappture::Tester::TestView::toolxml) [list source [file join $dir testview.tcl]]
     14set auto_index(::Rappture::Tester::TestView::test) [list source [file join $dir testview.tcl]]
     15set auto_index(::Rappture::Tester::TestView::reset) [list source [file join $dir testview.tcl]]
     16set auto_index(::Rappture::Tester::TestView::showDescription) [list source [file join $dir testview.tcl]]
     17set auto_index(::Rappture::Tester::TestView::showStatus) [list source [file join $dir testview.tcl]]
    1618set auto_index(::Rappture::Tester::TestView::updateAnalyzer) [list source [file join $dir testview.tcl]]
    1719set auto_index(::Rappture::Tester::TestView::updateResult) [list source [file join $dir testview.tcl]]
    18 set auto_index(::Rappture::Tester::TestView::showStatus) [list source [file join $dir testview.tcl]]
    19 set auto_index(::Rappture::Tester::TestView::showDescription) [list source [file join $dir testview.tcl]]
    20 set auto_index(::Rappture::Tester::TestView::update) [list source [file join $dir testview.tcl]]
    21 set auto_index(::Rappture::Tester::compare_elements) [list source [file join $dir compare.tcl]]
    22 set auto_index(::Rappture::Tester::compare) [list source [file join $dir compare.tcl]]
    23 set auto_index(::Rappture::Tester::makeDriver) [list source [file join $dir compare.tcl]]
    24 set auto_index(::Rappture::Tester::merge) [list source [file join $dir compare.tcl]]
     20set auto_index(::Rappture::Tester::Test) [list source [file join $dir test.tcl]]
     21set auto_index(::Rappture::Tester::Test::constructor) [list source [file join $dir test.tcl]]
     22set auto_index(::Rappture::Tester::Test::getAdded) [list source [file join $dir test.tcl]]
     23set auto_index(::Rappture::Tester::Test::getDiffs) [list source [file join $dir test.tcl]]
     24set auto_index(::Rappture::Tester::Test::getMissing) [list source [file join $dir test.tcl]]
     25set auto_index(::Rappture::Tester::Test::getResult) [list source [file join $dir test.tcl]]
     26set auto_index(::Rappture::Tester::Test::getRunfile) [list source [file join $dir test.tcl]]
     27set auto_index(::Rappture::Tester::Test::getTestxml) [list source [file join $dir test.tcl]]
     28set auto_index(::Rappture::Tester::Test::hasRan) [list source [file join $dir test.tcl]]
     29set auto_index(::Rappture::Tester::Test::run) [list source [file join $dir test.tcl]]
     30set auto_index(::Rappture::Tester::Test::added) [list source [file join $dir test.tcl]]
     31set auto_index(::Rappture::Tester::Test::compareElements) [list source [file join $dir test.tcl]]
     32set auto_index(::Rappture::Tester::Test::diffs) [list source [file join $dir test.tcl]]
     33set auto_index(::Rappture::Tester::Test::makeDriver) [list source [file join $dir test.tcl]]
     34set auto_index(::Rappture::Tester::Test::merge) [list source [file join $dir test.tcl]]
     35set auto_index(::Rappture::Tester::Test::missing) [list source [file join $dir test.tcl]]
    2536set auto_index(::Rappture::Tester::TestAnalyzer) [list source [file join $dir testanalyzer.tcl]]
    2637set auto_index(::Rappture::Tester::TestAnalyzer::constructor) [list source [file join $dir testanalyzer.tcl]]
     
    2940set auto_index(::Rappture::Tester::TestTree::constructor) [list source [file join $dir testtree.tcl]]
    3041set auto_index(::Rappture::Tester::TestTree::testdir) [list source [file join $dir testtree.tcl]]
     42set auto_index(::Rappture::Tester::TestTree::toolxml) [list source [file join $dir testtree.tcl]]
    3143set auto_index(::Rappture::Tester::TestTree::selectcommand) [list source [file join $dir testtree.tcl]]
     44set auto_index(::Rappture::Tester::TestTree::getTest) [list source [file join $dir testtree.tcl]]
     45set auto_index(::Rappture::Tester::TestTree::getData) [list source [file join $dir testtree.tcl]]
     46set auto_index(::Rappture::Tester::TestTree::getLeaves) [list source [file join $dir testtree.tcl]]
     47set auto_index(::Rappture::Tester::TestTree::getSelected) [list source [file join $dir testtree.tcl]]
    3248set auto_index(::Rappture::Tester::TestTree::populate) [list source [file join $dir testtree.tcl]]
    33 set auto_index(::Rappture::Tester::TestTree::getTests) [list source [file join $dir testtree.tcl]]
    34 set auto_index(::Rappture::Tester::TestTree::getSelected) [list source [file join $dir testtree.tcl]]
    35 set auto_index(::Rappture::Tester::TestTree::getData) [list source [file join $dir testtree.tcl]]
     49set auto_index(::Rappture::Tester::TestTree::runSelected) [list source [file join $dir testtree.tcl]]
     50set auto_index(::Rappture::Tester::TestTree::runTest) [list source [file join $dir testtree.tcl]]
    3651set auto_index(::Rappture::Tester::TestTree::setData) [list source [file join $dir testtree.tcl]]
    3752set auto_index(::Rappture::Tester::TestTree::updateLabel) [list source [file join $dir testtree.tcl]]
  • trunk/tester/tester.tcl

    r2017 r2019  
    11#! /bin/sh
    22# ----------------------------------------------------------------------
    3 # RAPPTURE REGRESSION TESTER
     3#  RAPPTURE REGRESSION TESTER
    44#
    5 # This program will read a set of test xml files typically located in
    6 # a tool's "tests" subdirectory, and provide an interactive test suite.
    7 # The test xml files should contain a complete set of inputs and outputs
    8 # for one run of an application.  In each test xml, a label must be
    9 # located at the path test.label.  Test labels may be organized
    10 # hierarchically by using dots to separate components of the test label
    11 # (example: roomtemp.1eV).  A description may optionally be located at
    12 # the path test.description.  Input arguments are the path to the
    13 # tool.xml of the version being tested, and the path the the directory
    14 # containing a set of test xml files.  If the arguments are missing,
    15 # the program will attempt to locate them automatically.
     5#  This program will read a set of test xml files typically located in
     6#  a tool's "tests" subdirectory, and provide an interactive test suite.
     7#  The test xml files should contain a complete set of inputs and
     8#  outputs for one run of an application.  In each test xml, a label
     9#  must be located at the path test.label.  Test labels may be organized
     10#  hierarchically by using dots to separate components of the test label
     11#  (example: roomtemp.1eV).  A description may optionally be located at
     12#  the path test.description.  Input arguments are the path to the
     13#  tool.xml of the version being tested, and the path the the directory
     14#  containing a set of test xml files.  If the arguments are missing,
     15#  the program will attempt to locate them automatically.
    1616#
    17 # USAGE: tester.tcl ?-tool tool.xml? ?-testdir tests?
     17#  USAGE: tester.tcl ?-tool tool.xml? ?-testdir tests?
    1818# ======================================================================
    1919#  AUTHOR:  Ben Rafferty, Purdue University
     
    6969.pw add [Rappture::Tester::TestTree .tree \
    7070    -testdir $params(-testdir) \
    71     -command Rappture::Tester::runSelected \
     71    -toolxml $params(-tool) \
    7272    -selectcommand Rappture::Tester::selectionHandler]
    7373.pw add [frame .right]
    74 Rappture::Tester::TestView .right.view $params(-tool)
     74Rappture::Tester::TestView .right.view -toolxml $params(-tool)
    7575button .right.regoldenize -text "Regoldenize" -state disabled \
    7676    -command Rappture::Tester::regoldenize
     
    7878pack .right.view -side bottom -expand yes -fill both
    7979pack .pw -expand yes -fill both
    80 set curselection ""
    8180
    8281# TODO: Handle resizing better
     
    8584
    8685# ----------------------------------------------------------------------
    87 # USAGE: runSelected
    88 #
    89 # When this method is invoked, all tests that are currently selected
    90 # will be ran.  If a branch node (folder) is selected, all of its
    91 # descendant tests will be ran as well.
    92 # TODO: Parallel exection
    93 # ----------------------------------------------------------------------
    94 proc Rappture::Tester::runSelected {} {
    95     foreach id [.tree getSelected] {
    96         runTest $id
    97     }
    98     selectionHandler -forcerefresh
    99 }
    100 
    101 # ----------------------------------------------------------------------
    102 # USAGE: runTest <id>
    103 #
    104 # Called by runAll and runSelected to run a single test at the tree node
    105 # specified by the given id.  In most cases, this method should not be
    106 # called directly.  A driver object appropriate for running the test is
    107 # generated by the makeDriver procedure, and the results given by the
    108 # new version are compared to the golden result by the compare
    109 # procedure.
    110 # ----------------------------------------------------------------------
    111 proc Rappture::Tester::runTest {id} {
    112     array set darray [.tree getData $id]
    113     global params
    114     set darray(result) "Running"
    115     .tree setData $id [array get darray]
    116 
    117     set driver [Rappture::Tester::makeDriver $params(-tool) $darray(testxml)]
    118     set tool [Rappture::Tool ::#auto $driver [file dirname $params(-tool)]]
    119     foreach {status result} [eval $tool run] break
    120     set darray(ran) yes
    121     if {$status == 0 && [Rappture::library isvalid $result]} {
    122         set golden [Rappture::library $darray(testxml)]
    123         set diffs [Rappture::Tester::compare $golden $result]
    124         set missing [Rappture::Tester::missing $golden $result]
    125         set added [Rappture::Tester::added $golden $result]
    126         if {$diffs == "" && $missing == "" && $added == ""} {
    127             set darray(result) Pass
    128         } else {
    129             set darray(result) Fail
    130         }
    131         set darray(diffs) $diffs
    132         set darray(missing) $missing
    133         set darray(added) $added
    134         set darray(runfile) [$tool getRunFile]
    135     } else {
    136         set darray(result) Error
    137         set darray(runfile) ""
    138     }
    139     .tree setData $id [array get darray]
    140 }
    141 
    142 # ----------------------------------------------------------------------
    143 # USAGE: selectionHandler ?-forcerefresh?
     86# USAGE: selectionHandler
    14487#
    14588# Used internally to communicate between the test tree and the right
     
    14891# ----------------------------------------------------------------------
    14992proc Rappture::Tester::selectionHandler {args} {
    150     if {[llength $args] > 1} {
    151         error "wrong # args: should be \"selectionHandler ?-forcerefresh?\""
     93    set test [.tree getTest]
     94    .right.view configure -test $test
     95    if {$test != "" && [$test hasRan] && [$test getResult] != "Error"} {
     96        .right.regoldenize configure -state normal
     97    } else {
     98        .right.regoldenize configure -state disabled
    15299    }
    153     global curselection
    154     set sel [.tree getFocus]
    155     if {$sel != $curselection || [lindex $args 0] == "-forcerefresh"} {
    156         set data [.tree getData focus]
    157         .right.view configure -data $data
    158         array set darray $data
    159         if {[array names darray] != "" && $darray(ran)} {
    160             .right.regoldenize configure -state normal
    161         } else {
    162             .right.regoldenize configure -state disabled
    163         }
    164         set curselection $sel
    165     }
    166 }
    167 
    168 # ----------------------------------------------------------------------
    169 # USAGE: makeDriver <tool.xml> <test.xml>
    170 #
    171 # Builds and returns a driver library object to be used for running the
    172 # test specified by testxml.  Copy current values from test xml into the
    173 # newly created driver.  If any inputs are present in the new tool.xml
    174 # which do not exist in the test xml, use the default value.
    175 # ----------------------------------------------------------------------
    176 proc Rappture::Tester::makeDriver {toolxml testxml} {
    177     # TODO: Test with various cases, especially with missing input elements
    178     # TODO: Any way to copy an object rather than creating a duplicate?
    179     # TODO: Sensible way of combining this proc with "merge" below?
    180     set toolobj [Rappture::library $toolxml]
    181     set golden [Rappture::library $testxml]
    182     set driver [Rappture::library $toolxml]
    183     return [Rappture::Tester::merge $toolobj $golden $driver]
    184 }
    185 
    186 # ----------------------------------------------------------------------
    187 # USAGE: merge <toolobj> <golden> <driver> ?path?
    188 #
    189 # Used to recursively build up a driver library object for running a
    190 # test.  Should not be called directly - see makeDriver.
    191 # ----------------------------------------------------------------------
    192 proc Rappture::Tester::merge {toolobj golden driver {path input}} {
    193     foreach child [$toolobj children $path] {
    194         set val [$golden get $path.$child.current]
    195         if {$val != ""} {
    196             $driver put $path.$child.current $val
    197         } else {
    198             set def [$toolobj get $path.$child.default]
    199             if {$def != ""} {
    200                 $driver put $path.$child.current $def
    201             }
    202         }
    203         Rappture::Tester::merge $toolobj $golden $driver $path.$child
    204     }
    205     return $driver
    206100}
    207101
     
    215109# ----------------------------------------------------------------------
    216110proc Rappture::Tester::regoldenize {} {
    217     set data [.tree getData focus]
    218     array set darray $data
    219     if {[tk_messageBox -type yesno -icon warning -message "Are you sure you want to regoldenize?\n$darray(testxml) will be overwritten."]} {
    220         # Copy test info from existing test xml
    221         set newlib [Rappture::library $darray(runfile)]
    222         set oldlib [Rappture::library $darray(testxml)]
    223         $newlib put test.label [$oldlib get test.label]
    224         $newlib put test.description [$oldlib get test.description]
    225         # Overwrite test xml
    226         set fid [open $darray(testxml) w]
    227         puts $fid "<?xml version=\"1.0\"?>"
    228         puts $fid [$newlib xml]
    229         close $fid
    230         # Update tree data accordingly
    231         set darray(result) "Pass"
    232         .tree setData focus [array get darray]
    233         # Refresh right hand side view
    234         selectionHandler -forcerefresh
     111    set test [.tree getTest]
     112    set testxml [$test getTestxml]
     113    if {[tk_messageBox -type yesno -icon warning -message "Are you sure you want to regoldenize?\n$testxml will be overwritten."]} {
     114        $test regoldenize
     115        .tree refresh
     116        selectionHandler
    235117    }
    236118}
  • trunk/tester/testtree.tcl

    r2017 r2019  
    33#
    44#  Used to display a collapsible view of all tests found in the test
    5 #  directory.  The -command configuration option will be called when
    6 #  the run button is clicked. Provides methods to get all tests or all
    7 #  currently selected tests. Also helps handle data stored in treeview
    8 #  columns.  In each test xml, a label must be located at the path
     5#  directory.  In each test xml, a label must be located at the path
    96#  test.label.  Test labels may be organized hierarchically by using
    10 #  dots to separate components of the test label.
     7#  dots to separate components of the test label.  The directory
     8#  containing a set of test xml files, as well as the location of the
     9#  new tool.xml must be given as configuration options.
    1110# ======================================================================
    1211#  AUTHOR:  Ben Rafferty, Purdue University
     
    3433    inherit itk::Widget
    3534
    36     public variable command
    37     public variable selectcommand
    38     public variable testdir
    39 
    40     constructor {testdir args} { #defined later }
    41     public method getTests {{id 0}}
    42     public method getSelected {}
    43     public method getFocus {}
    44     public method getData {id}
    45     public method setData {id data}
    46 
     35    public variable selectcommand ""
     36    public variable testdir ""
     37    public variable toolxml ""
     38
     39    constructor {args} { #defined later }
     40
     41    public method getTest {args}
     42    public method refresh {args}
     43
     44    protected method getData {id}
     45    protected method getLeaves {{id 0}}
     46    protected method getSelected {}
     47    protected method populate {}
     48    protected method runSelected {}
     49    protected method runTest {id}
     50    protected method setData {id data}
    4751    protected method updateLabel {}
    48     protected method populate {}
    4952
    5053}
     
    6972    }
    7073    $itk_component(treeview) column insert 0 result -width 75
    71     $itk_component(treeview) column insert end testxml ran diffs missing \
    72         added runfile
    73     $itk_component(treeview) column configure testxml ran diffs missing \
    74         added runfile -hide yes
     74    $itk_component(treeview) column insert end test -hide yes
    7575    $itk_component(scrollbars) contents $itk_component(treeview)
    7676
     
    9393
    9494    itk_component add bRun {
    95         button $itk_component(bottomBar).bRun -text "Run" -state disabled
    96     } {
    97         keep -command
    98     }
     95        button $itk_component(bottomBar).bRun -text "Run" -state disabled \
     96            -command [itcl::code $this runSelected]
     97    }
    9998    pack $itk_component(bRun) -side right
    10099
     
    109108
    110109    eval itk_initialize $args
    111 }
    112 
    113 # Repopulate tree if test directory changed
     110
     111    if {$testdir == ""} {
     112        error "no -testdir configuration option given."
     113    }
     114    if {$toolxml == ""} {
     115        error "no -toolxml configuration option given."
     116    }
     117}
     118
     119# ----------------------------------------------------------------------
     120# Repopulate tree if test directory or toolxml have been changed.
     121# ----------------------------------------------------------------------
    114122itcl::configbody Rappture::Tester::TestTree::testdir {
    115123    populate
    116124}
    117125
    118 # Forward the TestTree's selectcommand to the treeview, and update the label
    119 # as well.
     126itcl::configbody Rappture::Tester::TestTree::toolxml {
     127    populate
     128}
     129
     130# ----------------------------------------------------------------------
     131# Forward the TestTree's selectcommand to the treeview, but tack on the
     132# updateLabel method to keep the label refreshed when selection is
     133# changed
     134# ----------------------------------------------------------------------
    120135itcl::configbody Rappture::Tester::TestTree::selectcommand {
    121136    $itk_component(treeview) configure -selectcommand \
    122137        "[itcl::code $itk_interior updateLabel]; $selectcommand"
     138}
     139
     140# ----------------------------------------------------------------------
     141# USAGE getTest ?id?
     142#
     143# Returns the test object associated with a given treeview node id.  If
     144# no id is given, return the test associated with the currently focused
     145# node.  Returns empty string if the given id / focused node is a
     146# branch node.
     147# ----------------------------------------------------------------------
     148itcl::body Rappture::Tester::TestTree::getTest {args} {
     149    if {[llength $args] == 0} {
     150         set id [$itk_component(treeview) index focus]
     151    } elseif {[llength $args] == 1} {
     152        set id [lindex $args 0]
     153    } else {
     154        error "wrong # args: should be getTest ?id?"
     155    }
     156    array set darray [getData $id]
     157    if {[lsearch -exact [getLeaves] $id] == -1} {
     158        # Return empty string if branch node selected
     159        return ""
     160    }
     161    return $darray(test)
     162}
     163
     164# ----------------------------------------------------------------------
     165# USAGE: refresh ?id?
     166#
     167# Refreshes the result column and any other information which may be
     168# added later for the given tree node id.  Mainly needed to update the
     169# result from Fail to Pass after regoldenizing a test.  If no id is
     170# given, return the test associated with the currently focused node.
     171# Returns empty string if the given id / focused node is a branch node.
     172# ----------------------------------------------------------------------
     173itcl::body Rappture::Tester::TestTree::refresh {args} {
     174    if {[llength $args] == 0} {
     175         set id [$itk_component(treeview) index focus]
     176    } elseif {[llength $args] == 1} {
     177        set id [lindex $args 0]
     178    } else {
     179        error "wrong # args: should be refresh ?id?"
     180    }
     181    if {[lsearch -exact [getLeaves] $id] == -1} {
     182         error "given id $id is not a leaf node."
     183    }
     184    set test [getTest $id]
     185    setData $id [list result [$test getResult] test $test]
     186}
     187
     188# ----------------------------------------------------------------------
     189# USAGE: getData <id>
     190#
     191# Returns a list of key-value pairs representing the column data stored
     192# at the tree node with the given id.
     193# ----------------------------------------------------------------------
     194itcl::body Rappture::Tester::TestTree::getData {id} {
     195    return [$itk_component(treeview) entry cget $id -data]
     196}
     197
     198# ----------------------------------------------------------------------
     199# USAGE: getLeaves ?id?
     200#
     201# Returns a list of ids for all tests contained in the tree.  If an
     202# optional id is given as an input parameter, then the returned list
     203# will contain the ids of all tests that are descendants of the given
     204# id.  Tests can only be leaf nodes.
     205# ----------------------------------------------------------------------
     206itcl::body Rappture::Tester::TestTree::getLeaves {{id 0}} {
     207    set clist [$itk_component(treeview) entry children $id]
     208    if {$clist == "" && $id == 0} {
     209        # Return nothing if tree is empty
     210        return ""
     211    }
     212    if {$clist == ""} {
     213        return $id
     214    }
     215    set tests [list]
     216    foreach child $clist {
     217        set tests [concat $tests [getLeaves $child]]
     218    }
     219    return $tests
     220}
     221
     222# ----------------------------------------------------------------------
     223# USAGE: getSelected
     224#
     225# Returns a list ids for all currently selected tests (leaf nodes) and
     226# the child tests of any currently selected branch nodes.  Tests can
     227# only be leaf nodes in the tree (the ids in the returned list will
     228# correspond to leaf nodes only).
     229# ----------------------------------------------------------------------
     230itcl::body Rappture::Tester::TestTree::getSelected {} {
     231    set selection [$itk_component(treeview) curselection]
     232    set selectedTests [list]
     233    foreach id $selection {
     234        foreach node [getLeaves $id] {
     235            if {[lsearch -exact $selectedTests $node] == -1} {
     236                lappend selectedTests $node
     237            }
     238        }
     239    }
     240    return $selectedTests
    123241}
    124242
     
    130248# information at path test.label.  Relies on the autocreate treeview
    131249# option so that branch nodes need not be explicitly created.  Deletes
    132 # any nodes previously contained by the treeview.
     250# any existing contents.
    133251# ----------------------------------------------------------------------
    134252itcl::body Rappture::Tester::TestTree::populate {} {
     
    141259        set testpath [$lib get test.label]
    142260        if {$testpath != ""} {
     261            set test [Rappture::Tester::Test ::#auto $toolxml $testxml]
    143262            $itk_component(treeview) insert end $testpath -data \
    144                  [list testxml $testxml ran no result "" diffs ""] \
    145                  -icons "$icon $icon" -activeicons "$icon $icon"
     263                 [list test $test] -icons "$icon $icon" \
     264                 -activeicons "$icon $icon"
    146265        }
    147266    }
     
    151270
    152271# ----------------------------------------------------------------------
    153 # USAGE: getTests ?id?
    154 #
    155 # Returns a list of ids for all tests contained in the tree.  If an
    156 # optional id is given as an input parameter, then the returned list
    157 # will contain the ids of all tests that are descendants of the given
    158 # id.  Tests can only be leaf nodes in the tree (the ids in the returned
    159 # list will correspond to leaf nodes only).
    160 # ----------------------------------------------------------------------
    161 itcl::body Rappture::Tester::TestTree::getTests {{id 0}} {
    162     set clist [$itk_component(treeview) entry children $id]
    163     if {$clist == "" && $id == 0} {
    164         # Return nothing if tree is empty
    165         return ""
    166     }
    167     if {$clist == ""} {
    168         return $id
    169     }
    170     set tests [list]
    171     foreach child $clist {
    172         set tests [concat $tests [getTests $child]]
    173     }
    174     return $tests
    175 }
    176 
    177 # ----------------------------------------------------------------------
    178 # USAGE: getSelected
    179 #
    180 # Returns a list ids for all currently selected tests (leaf nodes) and
    181 # the child tests of any currently selected branch nodes.  Tests can
    182 # only be leaf nodes in the tree (the ids in the returned list will
    183 # correspond to leaf nodes only).
    184 # ----------------------------------------------------------------------
    185 itcl::body Rappture::Tester::TestTree::getSelected {} {
    186     set selection [$itk_component(treeview) curselection]
    187     set selectedTests [list]
    188     foreach id $selection {
    189         foreach node [getTests $id] {
    190             if {[lsearch -exact $selectedTests $node] == -1} {
    191                 lappend selectedTests $node
    192             }
    193         }
    194     }
    195     return $selectedTests
    196 }
    197 
    198 # ----------------------------------------------------------------------
    199 # USAGE: getFocus
    200 #
    201 # Returns index of the focused node in the treeview.
    202 # ----------------------------------------------------------------------
    203 itcl::body Rappture::Tester::TestTree::getFocus {} {
    204     return [$itk_component(treeview) index focus]
    205 }
    206 
    207 # ----------------------------------------------------------------------
    208 # USAGE: getData <id>
    209 #
    210 # Returns a list of key-value pairs representing the column data stored
    211 # at the tree node with the given id.
    212 # ----------------------------------------------------------------------
    213 itcl::body Rappture::Tester::TestTree::getData {id} {
    214     return [$itk_component(treeview) entry cget $id -data]
     272# USAGE: runSelected
     273#
     274# Invoked by the run button to run all currently selected tests.
     275# After completion, call selectcommand to re-select the newly completed
     276# focused node.
     277# ----------------------------------------------------------------------
     278itcl::body Rappture::Tester::TestTree::runSelected {} {
     279    foreach id [$this getSelected] {
     280        runTest $id
     281    }
     282    eval $selectcommand
     283}
     284
     285# ----------------------------------------------------------------------
     286# USAGE: runTest id
     287#
     288# Runs the test located at the tree node with the given id.  The id
     289# must be a leaf node, because tests may not be located at branch nodes.
     290# ----------------------------------------------------------------------
     291itcl::body Rappture::Tester::TestTree::runTest {id} {
     292    if {[lsearch -exact [getLeaves] $id] == -1} {
     293        error "given id $id is not a leaf node"
     294    }
     295    set test [getTest $id]
     296    setData $id [list result Running test $test]
     297    $test run
     298    setData $id [list result [$test getResult] test $test]
    215299}
    216300
  • trunk/tester/testview.tcl

    r2017 r2019  
    11# ----------------------------------------------------------------------
    2 # COMPONENT: testview - display the results of a test
    3 #
    4 # Entire right hand side of the regression tester.  Contains a small
    5 # text widget, plus two TestAnalyzer widgets.  The analyzers are used to
    6 # show the golden set of results, and the new results if the test has
    7 # been ran.  Constructor requires a tool.xml for the tool being tested.
     2#  COMPONENT: testview - display the results of a test
     3#
     4#  Entire right hand side of the regression tester.  Contains a text
     5#  widget for the test description, plus two TestAnalyzer widgets.  The
     6#  analyzers are used to show the golden results, and to compare them to
     7#  the new results if the test has been ran.  The new version's tool.xml
     8#  must be provided through the -toolxml configuration option, and the
     9#  -test configuration option is used to provide a Test object to
     10#  display.
    811# ======================================================================
    912#  AUTHOR:  Ben Rafferty, Purdue University
     
    3033    inherit itk::Widget
    3134
     35    public variable test
     36    public variable toolxml
     37    protected variable _tool
     38
     39    constructor {toolxml args} { #defined later }
     40
     41    protected method reset
     42    protected method showDescription {text}
     43    protected method showStatus {text}
    3244    protected method updateAnalyzer {args}
    3345    protected method updateResult {runfile}
    34     protected method showStatus {text}
    35     protected method showDescription {text}
    36     public method update {datapairs}
    37     public method reset
    38 
    39     public variable data
    40     protected variable _toolobj
    41 
    42     constructor {toolxml args} { #defined later }
     46
    4347}
    4448
     
    4650# CONSTRUCTOR
    4751# ----------------------------------------------------------------------
    48 itcl::body Rappture::Tester::TestView::constructor {toolxml args} {
    49    
    50     set _toolobj [Rappture::Tool ::#auto [Rappture::library $toolxml] \
    51          [file dirname $toolxml]]
    52  
     52itcl::body Rappture::Tester::TestView::constructor {args} {
     53
    5354    itk_component add status {
    5455        label $itk_interior.status
     
    7576    }
    7677    $itk_component(tabs) insert end "Analyzer" -ipady 25 -fill both
    77     $itk_component(tabs) insert end "Result" -ipady 25 -fill both \
     78    $itk_component(tabs) insert end "Info" -ipady 25 -fill both \
    7879        -state disabled
    7980
    80     itk_component add analyzer {
    81         Rappture::Tester::TestAnalyzer $itk_component(tabs).analyzer $_toolobj
    82     }
    83     $itk_component(tabs) tab configure "Analyzer" \
    84         -window $itk_component(tabs).analyzer
    85 
    86     itk_component add result {
    87         text $itk_component(tabs).result
    88     }
    89     $itk_component(tabs) tab configure "Result" -window $itk_component(result)
     81    #itk_component add analyzer {
     82    #    Rappture::Tester::TestAnalyzer $itk_component(tabs).analyzer $_tool
     83    #}
     84    #$itk_component(tabs) tab configure "Analyzer" \
     85    #    -window $itk_component(tabs).analyzer
     86
     87    itk_component add info {
     88        text $itk_component(tabs).info
     89    }
     90    $itk_component(tabs) tab configure "Info" -window $itk_component(info)
    9091    pack $itk_component(tabs) -expand yes -fill both -side top
    9192
    9293    eval itk_initialize $args
    93 }
    94 
    95 # ----------------------------------------------------------------------
    96 # When the -data configuration option is modified, update the display
    97 # accordingly.  The data passed in should be a list of key value pairs
    98 # from the TestTree widget.
    99 # ----------------------------------------------------------------------
    100 itcl::configbody Rappture::Tester::TestView::data {
    101     array set darray $data
     94
     95    if {$toolxml == "" } {
     96        error "no -toolxml configuration option given."
     97    }
     98}
     99
     100# --------------------------------------------------------------------
     101# Create a new Tool object if -toolxml option is changed.  Also
     102# refresh the display by calling the configbody for the -test option.
     103# ----------------------------------------------------------------------
     104itcl::configbody Rappture::Tester::TestView::toolxml {
     105    set _tool [Rappture::Tool ::#auto [Rappture::library $toolxml] \
     106         [file dirname $toolxml]]
     107    $this configure -test [$this cget -test]
     108}
     109
     110# ----------------------------------------------------------------------
     111# When the -test configuration option is modified, update the display
     112# accordingly.  The data passed in should be a Test object, or the
     113# empty string to clear the display.
     114# ----------------------------------------------------------------------
     115itcl::configbody Rappture::Tester::TestView::test {
    102116    # Data array is empty for branch nodes.
    103     if {[array names darray] != ""} {
    104         if {$darray(ran)} {
    105             switch $darray(result) {
     117    if {$test != ""} {
     118        if {![$test isa Test]} {
     119            error "-test option must be a Test object.  $test was given."
     120        }
     121        if {[$test hasRan]} {
     122            switch [$test getResult] {
    106123                Pass {showStatus "Test passed."}
    107124                Fail {showStatus "Test failed."}
    108125                Error {showStatus "Error while running test."}
    109126            }
    110             if {$darray(runfile) != ""} {
     127            if {[$test getRunfile] != ""} {
    111128                # HACK: Add a new input to differentiate between golden and
    112129                # test result.  Otherwise, the slider at the bottom won't
    113130                # be enabled.
    114                 set golden [Rappture::library $darray(testxml)]
     131                set golden [Rappture::library [$test getTestxml]]
    115132                $golden put input.run.current "Golden"
    116                 set result [Rappture::library $darray(runfile)]
    117                 $result put input.run.current "Test"
    118                 updateAnalyzer $golden $result
    119                 updateResult $data
     133                set runfile [Rappture::library [$test getRunfile]]
     134                $runfile put input.run.current "Test result"
     135                updateAnalyzer $golden $runfile
     136                updateResult $test
    120137            } else {
    121138                updateResult
     
    124141            showStatus "Test has not yet ran."
    125142            updateResult
    126             if {$darray(testxml) != ""} {
    127                 updateAnalyzer [Rappture::library $darray(testxml)]
     143            if {[$test getTestxml] != ""} {
     144                updateAnalyzer [Rappture::library [$test getTestxml]]
    128145            }
    129146        }
    130         set descr [[Rappture::library $darray(testxml)] get test.description]
     147        set descr [[Rappture::library [$test getTestxml]] get test.description]
    131148        if {$descr == ""} {
    132149            set descr "No description."
     
    153170    showStatus ""
    154171    showDescription ""
    155 }
    156 
    157 # ----------------------------------------------------------------------
    158 # USAGE: updateAnalyzer ?<lib> <lib>...?
    159 #
    160 # Clears the analyzer and loads the given library objects.  Used to load
    161 # both the golden result as well as the test result.  Clears the
    162 # analyzer space if no arguments are given.
    163 # HACK: Destroys the existing analyzer widget and creates a new one. 
    164 # Eventually this should be able to keep the same widget and swap in
    165 # and out different result sets.
    166 # ----------------------------------------------------------------------
    167 itcl::body Rappture::Tester::TestView::updateAnalyzer {args} {
    168     catch {
    169         $itk_component(analyzer) clear
    170         destroy $itk_component(analyzer)
    171     }
    172     itk_component add analyzer {
    173         Rappture::Tester::TestAnalyzer $itk_component(tabs).analyzer $_toolobj
    174     }
    175     $itk_component(tabs) tab configure "Analyzer" \
    176         -window $itk_component(analyzer)
    177     foreach lib $args {
    178         $itk_component(analyzer) display $lib
    179     }
    180    
    181 }
    182 
    183 # ----------------------------------------------------------------------
    184 # USAGE: updateResult ?data?
    185 #
    186 # Given a set of key value pairs from the test tree, update the result
    187 # page of the testview widget.  If no arguments are given, disable the
    188 # result page.
    189 # ----------------------------------------------------------------------
    190 itcl::body Rappture::Tester::TestView::updateResult {args} {
    191     if {[llength $args] == 0} {
    192         $itk_component(result) delete 0.0 end
    193         # TODO: Switch back to analyzer tab.  Why doesn't this work?
    194         $itk_component(tabs) invoke \
    195             [$itk_component(tabs) index -name "Analyzer"]
    196         $itk_component(tabs) tab configure "Result" -state disabled
    197         return
    198     } elseif {[llength $args] == 1} {
    199         array set darray [lindex $args 0]
    200         $itk_component(tabs) tab configure "Result" -state normal
    201         $itk_component(result) delete 0.0 end
    202         $itk_component(result) insert end "Test xml: $darray(testxml)\n"
    203         $itk_component(result) insert end "Runfile: $darray(runfile)\n"
    204         if {$darray(result) == "Fail"} {
    205             $itk_component(result) insert end "Diffs: $darray(diffs)\n"
    206             $itk_component(result) insert end "Missing: $darray(missing)\n"
    207             $itk_component(result) insert end "Added: $darray(added)\n"
    208         }
    209     } else {
    210         error "wrong # args: should be \"updateResult ?data?\""
    211     }
    212 }
    213 
    214 # ----------------------------------------------------------------------
    215 # USAGE: showStatus <text>
    216 #
    217 # Displays a string in the status info space at the top of the widget.
    218 # ----------------------------------------------------------------------
    219 itcl::body Rappture::Tester::TestView::showStatus {text} {
    220     $itk_component(status) configure -text "$text"
    221172}
    222173
     
    240191}
    241192
     193# ----------------------------------------------------------------------
     194# USAGE: showStatus <text>
     195#
     196# Displays a string in the status info space at the top of the widget.
     197# ----------------------------------------------------------------------
     198itcl::body Rappture::Tester::TestView::showStatus {text} {
     199    $itk_component(status) configure -text "$text"
     200}
     201
     202# ----------------------------------------------------------------------
     203# USAGE: updateAnalyzer ?<lib> <lib>...?
     204#
     205# Clears the analyzer and loads the given library objects.  Used to load
     206# both the golden result as well as the test result.  Clears the
     207# analyzer space if no arguments are given.
     208# HACK: Destroys the existing analyzer widget and creates a new one. 
     209# Eventually this should be able to keep the same widget and swap in
     210# and out different result sets.
     211# ----------------------------------------------------------------------
     212itcl::body Rappture::Tester::TestView::updateAnalyzer {args} {
     213    catch {
     214        $itk_component(analyzer) clear
     215        destroy $itk_component(analyzer)
     216    }
     217    itk_component add analyzer {
     218        Rappture::Tester::TestAnalyzer $itk_component(tabs).analyzer $_tool
     219    }
     220    $itk_component(tabs) tab configure "Analyzer" \
     221        -window $itk_component(analyzer)
     222    foreach lib $args {
     223        $itk_component(analyzer) display $lib
     224    }
     225   
     226}
     227
     228# ----------------------------------------------------------------------
     229# USAGE: updateResult ?test?
     230#
     231# Given a set of key value pairs from the test tree, update the info
     232# page of the testview widget.  If no arguments are given, disable the
     233# info page.
     234# ----------------------------------------------------------------------
     235itcl::body Rappture::Tester::TestView::updateResult {args} {
     236    if {[llength $args] == 0} {
     237        $itk_component(info) delete 0.0 end
     238        # TODO: Switch back to analyzer tab.  Why doesn't this work?
     239        $itk_component(tabs) invoke \
     240            [$itk_component(tabs) index -name "Analyzer"]
     241        $itk_component(tabs) tab configure "Info" -state disabled
     242        return
     243    } elseif {[llength $args] == 1} {
     244        set testxml [$test getTestxml]
     245        set runfile [$test getRunfile]
     246        $itk_component(tabs) tab configure "Info" -state normal
     247        $itk_component(info) delete 0.0 end
     248        $itk_component(info) insert end "Test xml: $testxml\n"
     249        $itk_component(info) insert end "Runfile: $runfile\n"
     250        if {[$test getResult] == "Fail"} {
     251            set diffs [$test getDiffs]
     252            set missing [$test getMissing]
     253            set added [$test getAdded]
     254            $itk_component(info) insert end "Diffs: $diffs\n"
     255            $itk_component(info) insert end "Missing: $missing\n"
     256            $itk_component(info) insert end "Added: $added\n"
     257        }
     258    } else {
     259        error "wrong # args: should be \"updateResult ?data?\""
     260    }
     261}
     262
Note: See TracChangeset for help on using the changeset viewer.