Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Passing a duration time from 1 subroutine to another

by gasjunkie_jabz (Novice)
on Aug 20, 2015 at 22:44 UTC ( [id://1139355]=perlquestion: print w/replies, xml ) Need Help??

gasjunkie_jabz has asked for the wisdom of the Perl Monks concerning the following question:

hello, I am trying to pass a duration time for running a series of tests to a cleanup subroutine. I am running a loop of different tests (sub run_test)and documenting the duration for each test ran within sub run_tests. I am getting the correct time for each. My problem is trying to pass the same duration time to a cleanup subroutine (sub cleanup_test), which happens after all the tests are completed. below are the 2 subroutines:

sub run_test{ my ($self, @tests) = @_; # Setup test system. $self->_setup_test_system(); # Run each test. TEST: for my $test_name (@tests) { # Setup everything necessary for current test. $self->setup_test_system($test_name); # Run each testcase for current test. TESTCASE: while ($self->__fetch_next()){ my $start = gettimeofday(); my $is_pass = $self->_run_testcase(); my $end = gettimeofday(); my $duration = $end - $start; if (!$is_pass && $self->{_abort_on_failure}) { print "\nFailure occurred,for $test_name.\n"; last TESTCASE; # Exit loop } }

I would like to pass my $duration to this cleanup subroutine:

sub cleanup_test{ my ($self, $result) = @_; # Update statistics $self->{_test_statistics}{num_tests}++; if ($result == 0) { $self->{_test_statistics}{num_tests_failed}++; } # Log testcase result and return log_testcase($self->{_test_name}, $self->{_testcase_name}, $self->{_ +test_statistics}{num_tests_failed}, $duration, $self->{_log_file});

I can't get the duration time from (sub run_test) to (sub cleanup_test). What am I missing? Thanks for reading

Replies are listed 'Best First'.
Re: Passing a duration time from 1 subroutine to another
by 1nickt (Canon) on Aug 20, 2015 at 23:02 UTC

    Maybe you can do something like this

    sub run_test { # stuff for my $test_name (@tests) { # stuff my $duration = $end - $start; $self->{'duration'}->{ $test_name } = $duration; # more stuff } }
    Then you'll have the durations available in the cleanup sub.

    Note: It's impossible to really know because:

    • The code you posted doesn't compile (it's missing a two closing brackets).
    • The code you posted is incomplete: we don't know what's in $self or how cleanup_sub() gets called.
    • You mention run_test() and run_tests() is that a typo?
    • Does $self really provide __fetch_next()? Or is it _fetch_next()?

    Please read How do I post a question effectively?. In particular, copy and paste working sample code; don't type it in on these pages.

    I strongly suggest spending some time learning good Perl style (you could start by reading perlstyle), since the reason you missed the curly brackets in your sample code is probably the lack of proper indentation.

    sub run_test { my ($self, @tests) = @_; # Setup test system. $self->_setup_test_system(); # Run each test. TEST: for my $test_name (@tests) { # Setup everything necessary for current test. $self->setup_test_system($test_name); # Run each testcase for current test. TESTCASE: while ($self->__fetch_next()){ my $start = gettimeofday(); my $is_pass = $self->_run_testcase(); my $end = gettimeofday(); my $duration = $end - $start; if (!$is_pass && $self->{_abort_on_failure}) { + print "\nFailure occurred,for $test_name.\n"; last TESTCASE; # Exit loop } } # Hm, I guess there are two missing ...

    Update: show re-indented code

    The way forward always starts with a minimal test.

      Thank you for the clarification, run_test() NOT run_tests(). This code is very long, so I purposely cut it short for the reader's sake. here's a better code description:

      sub new { my ($class) = @_; # Initialize attributes my $self = { _test_name => undef, # Name of the current test _testcase_name => undef, # Name of the current testcase _test_statistics => {}, # Statistics for the current + test }; bless $self, $class; # Two-argument version used to support inhe +ritance return $self; }

      here is where the run_test() is called and how cleanup_test() is used

      sub run_test{ my ($self, @tests) = @_; # Setup test system. $self->_setup_test_system(); # Run each test. TEST: for my $test_name (@tests) { # Setup everything necessary for current test. $self->setup_test_system($test_name); # Run each testcase for current test. TESTCASE: while ($self->__fetch_next()){ my $start = gettimeofday(); my $is_pass = $self->_run_testcase(); my $end = gettimeofday(); my $duration = $end - $start; if (!$is_pass && $self->{_abort_on_failure}) { print "\nFailure occurred,for $test_name.\n"; last TESTCASE; # Exit loop } } # Cleanup at end of test. $self->cleanup_test(); # Clean up test system. $self->_cleanup_test_system(); return $self->{_test_system_stats}{num_tests_failed}; } }

        Cool, thanks for replying. The best thing is always if you can reduce the problem to its simplest example; this may mean writing a new, small script to show your issue. People want to be able to copy your sample code right into a file on their computer, run it as is, see the error, make some changes and implement a fix, and post that back here. It's more difficult to help when you can only think about the problem in abstract terms.

        For example, now that you've posted your object constructor, I wonder whether you need to construct an object at all. You mention inheritance in a comment, but your code looks like a standalone program. Is there a reason why your code doesn't simply call subroutines as it moves through its flow? Why do you think you need to make this code OO?

        As an aside, the constructor for an object usually looks more like this:

        sub new { my $class = shift; my %args = @_; my $self = {}; # validate the args # do stuff to populate $self bless $self, $class; return $self; }
        Hope this helps!

        The way forward always starts with a minimal test.
Re: Passing a duration time from 1 subroutine to another
by stevieb (Canon) on Aug 20, 2015 at 23:22 UTC

    I don't know if I understand you correctly, but I'll take a crack.

    Are you trying to get cumulative?:

    in your test loop (untested)...

    $self->{start} = $self->{start} || gettimeofday(): ... # at end of test my $end = gettimeofday(); $self->{duration} += ($end - $self->{start});

    Then in your cleanup sub, get the data simply by using $self->{duration}.

    If you need a count for each test, keep the existing code, but add at the end:

    $self->{tests}{test_name} = $duration;

    Then in cleanup, loop over $self->{tests} and extract the duration for each test.

    You'll need to fill us in on exactly what you want for us to give a full response.

    -stevieb

      Thanks Stevie!, I initialized a new attribute called (_duration_time)in my constructor and passed the duration time from the loop into this constructor variable. I am now able to access the duration times in my cleanup sub. Thanks! My new issue now is, I cant get the very first testcase time when I run the testsuite. It gives me a "HASH(0x6c64344)" for the time. All other times are fine. This sounds like there is no time for the first test YET, so it logs the memory data. Is there a way around this?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1139355]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-24 19:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found