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

Variable support #45

Closed snorrebrandstadmoen closed 6 years ago

snorrebrandstadmoen commented 9 years ago

Hi mr. Landrø,

I'm using your excellent tool to test drive our BIG-IP development. One question on variable support:

The following (valid BIG-IP) iRule:

rule http_error {

  when HTTP_REQUEST {
    set log_level debug
    # ..
    log local0.$log_level "Request"
  }

  when HTTP_RESPONSE {
    # ..
    log local0.$log_level "Response"
    HTTP::respond 404
  }
}

When testing the event HTTP_RESPONSE, the log_level variable is never set, and thus not available in the HTTP_RESPONSE clause. Is there a way to achieve this?

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

it "should respond with 404" {
  event HTTP_RESPONSE
  endstate HTTP::respond 404
  run irules/http_error_irule.tcl http_error
}

stats
error     Expected end state with return code 3, got 1
error     Error info: can't read "log_level": no such variable
error         while executing
error     "log local0.$log_level "Response""

Is there any way I can use variables, or does the test runner currently not support this?

Regards, Snorre

landro commented 9 years ago

Glad you like TesTcl, @snorrebrandstadmoen. Have you tried defining this as a global variable?

snorrebrandstadmoen commented 9 years ago

@landro - I guess the log_level variable could be global, but this was just an example. Typically I want to log ie. session based information like HTTP:uri or HTTP:host in the HTTP_RESPONSE event, and these are unavailable in the "response context" and must therefore be set as an variable in the incoming HTTP_REQUEST event.

landro commented 9 years ago

F5 has redefined the behavior of the set command - right now TesTcl uses a standard set implementation, where variables go out of scope as you would expect in any programming language. They should have used/defined some kind of exchange/context similar to what you find in SOAP/REST frameworks. Well - whatever - right now you're left with two options:

  1. Use global variables (which could work - you might have to define tests in separate files maybe to avoid collisions)
  2. Make a code contribution. One could use upvar/uplevel, look at the callstack, and redefine set if called inside when command (otherwise, stuff might stop working elsewhere, since set is a standard command).

I noticed by the way #34 is a similar open issue

landro commented 6 years ago

closed in a5c289d30481cb6a17ba9c196aa4b1f34bfe3545

snorrebrandstadmoen commented 6 years ago

Thanks!