landro / TesTcl

when you don't have the balls to test your F5 BIG-IP iRules directly in production
https://testcl.com
BSD 3-Clause "New" or "Revised" License
98 stars 30 forks source link

testing elseif/else conditions failure #64

Closed mayupumi closed 4 years ago

mayupumi commented 4 years ago

Hi. Thanks for developing the great tool. I faced weird error but I'm not sure it's right behavior or not.

Here is a simple iRule else.tcl that I want to apply test:

rule else_test {
    when CLIENT_ACCEPTED {
        if { [IP::client_addr] equals "192.168.0.1"} {
            pool hoge
        }
        elseif { [IP::client_addr] equals "192.168.100.1"} {
            pool fuga
        }
    }
}

I want to test both condition (if and elseif) with one testcl file, so I wrote _testelse.tcl like

package require -exact testcl 1.0.14
namespace import ::testcl::*

it "should handle request using pool hoge" {
    event CLIENT_ACCEPTED
    on IP::client_addr return "192.168.0.1"
    endstate pool hoge
    run else.tcl else_test
}

it "should handle request using pool fuga" {
    event CLIENT_ACCEPTED
    on IP::client_addr return "192.168.100.1"
    endstate pool fuga
    run else.tcl else_test
}

However, it will produce an error on the second test.

jtcl .\test_else.tcl

**************************************************************************
* it should handle request using pool hoge
**************************************************************************
-> Test ok

**************************************************************************
* it should handle request using pool fuga
**************************************************************************

Unexpected unknown command invocation 'elseif { [IP::client_addr] equals "192.168.100.1"} {
            pool fuga
        }'

Maybe you should add an "on" statement similar to the one below to your "it" block?

    it "your description" {
      ...
      on elseif { [IP::client_addr] equals "192.168.100.1"} {
            pool fuga
        } return "your return value"
      ...
    }

error     Expected end state with return code 3, got 1
error     Error info: Unexpected unknown command invocation 'elseif { 
[IP::client_addr] equals "192.168.100.1"} {
error                 pool fuga
error             }'
error         while executing
error     "error $errorMessage"
error         ("if" then script line 11)
error         invoked from within
error     "if {$rc == 1500} {
error         #expectation and end state not found
error         set errorMessage "Unexpected unknown command invocation 
'$args'"
error         puts "\n$errorMes..."
error         (procedure "::unknown" line 9)
error         invoked from within
error     "elseif { [IP::client_addr] equals "192.168.100.1"} {       
error                 pool fuga
error             }"
error     ++++++++++++++++++++++++++++++++++++++++++
error     Expected return code 200 from calling when, got 1
error     Error info: Expected end state with return code 3, got 1
error         while executing
error     "error "Expected end state with return code 3, got $rc""
error         ("if" then script line 5)
error         invoked from within
error     "if {$rc != 1000} {
error           log::log error "Expected end state with return code 3, got $rc"
error           log::log error "Error info: $::errorInfo"
error           log::lo..."
error         ("if" then script line 16)
error         invoked from within
error     "if {[info exists expectedEvent] && $event eq $expectedEvent} {
error         log::log debug "when invoked with expected event '$event'"
error         set rc [catch $body ..."
error         (procedure "when" line 20)
error         invoked from within
error     "when CLIENT_ACCEPTED {
error             if { [IP::client_addr] equals "192.168.0.1"} {
error                 pool hoge
error             }
error             elseif { [IP::client_addr] equal..."
error     ++++++++++++++++++++++++++++++++++++++++++
error     Running irule else.tcl failed: Expected return code 2000 from calling when, got 1
error     Error info: Expected return code 2000 from calling when, got 1
error         while executing
error     "error "Expected return code 2000 from calling when, got $rc""
error         ("if" then script line 5)
error         invoked from within
error     "if {$rc != 2000} {
error         log::log error "Expected return code 200 from calling when, got $rc"
error         log::log error "Error info: $::errorInfo"
error         log::log..."
error         (procedure "rule" line 6)
error         invoked from within
error     "rule else_test {
error         when CLIENT_ACCEPTED {
error             if { [IP::client_addr] equals "192.168.0.1"} {
error                 pool hoge
error             }
error             elseif { [I..."
error         (file "else.tcl" line 1)
error         invoked from within
error     "source $irule"
error     ++++++++++++++++++++++++++++++++++++++++++
-> Test failure!!
-> -> Running irule else.tcl failed: Expected return code 2000 from calling when, got 1
error     Running irule else.tcl failed: Expected return code 2000 from calling when, got 1

Same error occur when I use else instead of elseif to test the second condition. I found out that it will be done successfully if I use if for each condition like:

rule else_test {
    when CLIENT_ACCEPTED {
        if { [IP::client_addr] equals "192.168.0.1"} {
            pool hoge
        }
        if { [IP::client_addr] equals "192.168.100.1"} {
            pool fuga
        }
    }
}
jtcl .\test_else.tcl

**************************************************************************
* it should handle request using pool hoge
**************************************************************************
-> Test ok

**************************************************************************
* it should handle request using pool fuga
**************************************************************************
-> Test ok

but it's not the code I want to test. Do I have some mistake or it's right behavior?

landro commented 4 years ago

Sorry for the late response. Your Tcl syntax is not correct. elseif should not be on a new line (its not a keyword, it's a parameter to the if command.


if {boolean_expression 1} {
   # Executes when the boolean expression 1 is true
} elseif {boolean_expression 2} {
   # Executes when the boolean expression 2 is true 
} elseif {boolean_expression 3} {
   # Executes when the boolean expression 3 is true 
} else {
   # executes when the none of the above condition is true 
}