test-fullautomation / robotframework

Generic automation framework for acceptance testing and RPA
http://robotframework.org
Apache License 2.0
1 stars 0 forks source link

destructor of keyword library not executed #85

Closed HolQue closed 2 months ago

HolQue commented 4 months ago

A Robot Framework keyword library is implemented in Python. At the end of a test suite some things need to be done (close file handles, disconnect from tcp/ip servers). This is placed in the destructor of the keyword library. The problem is: The Robot Framework does not execute the destructor at the end of a test suite.

This has a big negative impact on the test execution.

The tests are executed in a standard Windows console. This console is used to execute several separate test suites in rotation (without being closed in between).

Are there still Robot Framework processes alive as long as the Windows console is open?

Expected. At end of test suite execution the destructors of all keyword libraries are executed.

test-fullautomation commented 3 months ago

Hi @milanac030988 , bits_interface library has high priority. Thank you, Thomas

milanac030988 commented 2 months ago

Hello @test-fullautomation, Hello @HolQue,

I took a look into your implementation in the file bits_platform.py and noticed the following:

  1. Robot Framework's Object Cleanup Mechanism: Robot Framework actually has a pretty robust mechanism for cleaning up objects that were created during the execution of a test suite. When a test suite ends, all the libraries loaded during the suite will have their destructors called.

  2. The Problem with Your Implementation: In your library file, you've launched a thread with the daemon attribute set to False by default. This means that when the test ends, this thread continues to run, leading to a situation where the reference count to the library object remains greater than zero.

    • In Python, an object's destructor (__del__ method) is called only when its reference count reaches zero. However, in this case, because the non-daemon thread is still running and holds a reference to the library object, the reference count never drops to zero. As a result, the destructor is not called, and the object is not garbage collected.
  3. When you call the interface_cleanup function, it triggers the __StopEvent, which causes the running thread to end (the while loop condition while not self.__StopEvent.is_set(): is satisfied). This allows the reference count of the library object to drop to zero, enabling the destructor to be called. That's why the issue is resolved when you call interface_cleanup.

  4. Suggested Solution: To address this problem more robustly, I suggest modifying your library to start the thread with daemon=True. This can be done as follows:

    self.__ListenerThread = threading.Thread(target=self.__tcpip_listener, daemon=True)

    By setting daemon=True, the __tcpip_listener thread will terminate along with the main thread when the test ends. This ensures that the reference to the library object is released, allowing the destructor to be called and the object to be properly cleaned up.

Thank you, Cuong

test-fullautomation commented 2 months ago

Issue is solved. RobotFramework allows to implement _close() method which calls destructor.