Forum Discussion

OLEONTYEV's avatar
OLEONTYEV
Occasional Contributor
12 years ago

Recursion is broken for DelphiScript

Hello!

The post is going to be long, so i'll put the essential questions first, and detailed report afterwards.



We have recently upgraded TestComplete/TestExecute licenses from 7.52 to 9.30. Tests are written in DelphiScript.

A large part of the tests depends on parsing XML data, and it's done by recursive algorithms.

Suddently, it happens that all the tests fail, because recursion is broken for DelphiScript in TC9. It seems to work for JScript, but it's not a good idea to translate over 50 kloc to another scripting language.



So, I want to ask the support team:

1) Perhaps, you can suggest some quick hack that can be used to continue testing with TC9.

2) Perhaps, it's a known issue, and it's already in backlog for the nearest releases.

  • karkadil's avatar
    karkadil
    Valued Contributor
    This post looks very funny for me, because 4 Russian-speaking people gathered here to have a conversation in English :D



    (Sorry for spam, I just couldn't resist the temptation to become a part of this chat)
  • OLEONTYEV's avatar
    OLEONTYEV
    Occasional Contributor
    Now, the report of my experience.



    The general code in our tests looks tike that:



    procedure SomeParser(xmlNode : OleVariant);

    var i, node, ...

    begin

      try

        // ... some code

         for i := 0 to xmlNode.childNodes.length - 1 do // <-- here it breaks

        begin

          node := xmlNode.childNodes;

          // ... some code

          SomeParser(node);  // <-- recursion

          // ... some code

        end;

      except

        Log.Error('Exception', ExceptionMessage)

      end;

    end;  



    In TC7, it works fine.

    In TC9, at the second level of recursion, it suddently breaks when we enter the FOR loop. It throws an exception without any additional message.

    The problem was localized this way:



    Let's create a project that contains one small script:



    procedure RecurrentStuff1(depth : integer);

    begin

      try

        Log.Message('Entering level ' + IntToStr(depth));

      if depth > 0 then

      begin

        Log.Message('Calling stuff');

        RecurrentStuff1(depth - 1);

        Log.Message('Call finished at level ' + IntToStr(depth));

      end;

      Log.Message('Leaving level ' + IntToStr(depth));

      except

        Log.Error('Exception', ExceptionMessage)

      end;

    end;



    procedure Main;

    begin

      RecurrentStuff1(3);

    end;



    In the log there are messages:

    (i) Entering level 3

    (i) Calling stuff

    (i) Entering level 2

    (i) Calling stuff

    .....

    (i) Leaving level 2

    (X) DelphiScript runtime error

        Stack is empty



    At least, it goes through some levels. It tells what happened and doesn't break at the 2nd level, unlike in my real projects.

    It can be one of 2 issues:

    1) because of referencing the local variable;

    2) because of the loop itself.

    Let's check it to see what's happening in the real projects.



    procedure RecurrentStuff2(depth : integer);

    var i : integer;

    begin

      try

        Log.Message('Entering level ' + IntToStr(depth));

        i := -1;

        Log.Message('i has been referenced');

        for i := 1 to depth do

        begin

          Log.Message('Iteration #' + IntToStr(i));

          RecurrentStuff2(depth - 1);

          Log.Message('Iteration #' + IntToStr(i) + ' at level ' + IntToStr(depth) + ' completed');

        end;

        Log.Message('Leaving level ' + IntToStr(depth));

      except

        Log.Error('Exception', ExceptionMessage)

      end;

    end;



    Log messages are:



    (i) Entering level 3

    (i) i has been referenced

    (i) Iteration #1

    (i) Entering level 2

    (i) i has been referenced

    (X) Exception

    (i) Iteration #1 at level 3 completed

    .....



    So, it has nothing to do with referencing i variable, but it breaks when entering the FOR loop. And exceptions have no message.

    I tried to find a workaround and used "while true" loop, issuing a break from inside. It really walked through all levels of recursion, but it issued the same runtime error "Stack is empty" in the end.



    A funny thing, that in JScript it all works fine, no fails in TC/TE v.9! But we can't just create one part of the suite in DelphiScript and another in JScript, we need to translate all the suite then.

  • TanyaYatskovska's avatar
    TanyaYatskovska
    SmartBear Alumni (Retired)

    Hi Oleg,


     


    As far as I remember, there were some significant changes in the DelphiScript engine in TestComplete 9. First of all, please check whether the problem is reproduced with the latest product version - v. 9.31. If it persists, please contact the TestComplete Support team as some investigation from the R&D team will be required here.


     

  • OLEONTYEV's avatar
    OLEONTYEV
    Occasional Contributor
    Updated to 9.31.3889.11, and it has the same problem.



    Fixed the problem by implementing a tree-walking algorithm that avoids recursion where possible, and in difficult cases uses ArrayObject to imitate stack.
  • AlexKaras's avatar
    AlexKaras
    Champion Level 3
    Hi Oleg,



    Just wondering if you contacted Support and what was their reply?

    I'm wondering because I like to use DelphiScript and while I haven't met with yours problem  it is good to know if it was registered in SmartBear's database and what is its status.

    Besides that, SmartBear is usually very responsive to the problems like this and if this is really some regression case, I think that the chances are high that it will be either corrected in the next update or even the patch is prepared and send to you.
  • OLEONTYEV's avatar
    OLEONTYEV
    Occasional Contributor
    Alexei, I beleive in the team's responsiveness. But it's difficult for me to ask the SmartBear support, because it requires that I should be an actual customer.

    I'm just an engineer, and software is purchased by our principal, so I have to contact my CEO so he would contact our principal's CEO and the secretary would post a request.

    Not an easy way for technical requests.
  • AlexKaras's avatar
    AlexKaras
    Champion Level 3
    Hi Oleg,



    > [...] because it requires that I should be an actual customer.

    Not exactly. :) SmartBear's Support is equally open to those who already purchased a license and to those who just evaluates their software.

    Navigate to http://support.smartbear.com/message/?prod=TestComplete, select the 'No, I am not a registered customer' option, provide any other information required and submit the request.