Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Robot 6.1rc1: Listener errors? #4786

Closed
pianofab opened this issue Jun 7, 2023 · 5 comments
Closed

Robot 6.1rc1: Listener errors? #4786

pianofab opened this issue Jun 7, 2023 · 5 comments

Comments

@pianofab
Copy link
Contributor

pianofab commented Jun 7, 2023

We have an internal application that uses Robot Framework 6.0.2 and I was trying to test it with 6.1rc1 to ensure that everything still works. It looked OK but then I realized that the live feedback was missing, and then I went to the log and found this:

Test Execution Errors

20230607 10:36:36.972 ERROR Calling method 'start_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.  
20230607 10:36:36.974 ERROR Calling method 'start_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.  
20230607 10:36:36.976 ERROR Calling method 'start_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.  
20230607 10:36:36.987 ERROR Calling method 'start_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.  
20230607 10:36:36.988 ERROR Calling method 'start_test' of listener 'RobotListener' failed: AttributeError: Protocol message TestResultsObject has no "_setter__body" field.  
20230607 10:36:36.990 ERROR Calling method 'end_test' of listener 'RobotListener' failed: AttributeError: Protocol message TestResultsObject has no "_setter__body" field.  
20230607 10:36:36.991 ERROR Calling method 'start_test' of listener 'RobotListener' failed: AttributeError: Protocol message TestResultsObject has no "_setter__body" field.  
20230607 10:36:36.996 ERROR Calling method 'end_test' of listener 'RobotListener' failed: AttributeError: Protocol message TestResultsObject has no "_setter__body" field.  
20230607 10:36:36.998 ERROR Calling method 'end_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.  
20230607 10:36:36.999 ERROR Calling method 'end_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.  
20230607 10:36:37.000 ERROR Calling method 'end_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.  
20230607 10:36:37.001 ERROR Calling method 'end_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.

Now, I noticed that in my listener I have used type hints to clarify what is going on:

class RobotListener():
    """Standard Robot Listener to intercept Robot events live.
https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#listener-interface
https://github.com/robotframework/robotframework/blob/master/doc/userguide/src/ExtendingRobotFramework/ListenerInterface.rst

    Raises:
        KeyboardInterrupt: awkward attempt at stopping Robot run.
    """
    ROBOT_LISTENER_API_VERSION = 3

    def __init__(self,
                 robot_queue: RobotMsgQueue,
                 stop_event: MP_Event,
                 maxmsglen: int):
# etc

    def start_suite(self,
                    suite: _running.model.TestSuite,
                    result: _result.model.TestSuite):
        """Robot hook

        Args:
            suite (_running.model.TestSuite): input suite
            result (_result.model.TestSuite): input result
        """

Could that be the issue?

@pianofab
Copy link
Contributor Author

pianofab commented Jun 7, 2023

I removed all the type hints so that there would be no question about it, and the issue still reproduces. There was no stack trace, and I remembered that there was a way to get more info, and sure enough: ROBOT_SYSLOG_FILE=robot_syslog.txt gave the stack trace.

20230607 20:43:02.644 | ERROR | Calling method 'start_suite' of listener 'RobotListener' failed: AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.
20230607 20:43:02.644 | INFO | Details:
Traceback (most recent call last):
File "/kcos-system-tests/kcos_msd/server/msdserv.py", line 263, in start_suite
self.copy_suite(grpc_msg.robot_event.start_suite, suite, result, True)
File "/kcos-system-tests/kcos_msd/server/msdserv.py", line 198, in copy_suite
setattr(grpc_msg.suite_result, varname,
AttributeError: Protocol message SuiteResultsObject has no "_setter__suites" field.

My code is marshaling the Robot results to my own grpc message object.

    @staticmethod
    def copy_suite(grpc_msg,
                   suite,
                   result,
                   starting: bool) -> None:
        """Marshals the suite from Robot to grpc message

        Args:
            grpc_msg (_type_): output grpc message
            suite (_running.model.TestSuite): input suite
            result (_result.model.TestSuite): input result
            starting (bool): is this a start command?
        """
        grpc_msg.suite.name = suite.name
        grpc_msg.suite.doc = suite.doc
        # endtime is missing so we get an ERROR if we attempt...
        _theslots = result.__slots__.copy()
        if starting:
            _theslots.remove('endtime')
        for varname in _theslots:
            setattr(grpc_msg.suite_result, varname,  # line that causes the error
                    getattr(result, varname))

I am calling getattr() on the result object from within the listener.

@pekkaklarck
Copy link
Member

First is all, thanks for testing the rc!

If I got it right, the error comes from setattr() that is setting an attribute to SuiteResultsObject. Is there any chance that this object would have been changed? For example, if it had got __slots__ there would be an AttributeError like this.

@pekkaklarck
Copy link
Member

Copying whatever is in result.__slots__ feels somewhat risky in general. It would be safer to explicitly list attributes you want to copy.

@pianofab
Copy link
Contributor Author

pianofab commented Jun 9, 2023

Copying whatever is in result.__slots__ feels somewhat risky in general. It would be safer to explicitly list attributes you want to copy.

Yes, but I do not mind because my objects are closely mirroring yours, and if you add new useful items to your Robot object, I would like to know about it so that I can add support for the new feature (or not). I should probably skip anything that starts with an underscore though... like these new items which are clearly internal use only.
Thanks for your quick feedback. I am going to close since I do not consider this a problem.

@pianofab
Copy link
Contributor Author

pianofab commented Jun 9, 2023

To clarify: adding the following code (which skips the new item) makes the issue go away:

_theslots.remove('_setter__suites')

@pianofab pianofab closed this as not planned Won't fix, can't repro, duplicate, stale Jun 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants