[ ERROR ] Error in test library 'ttCanLibrary': Creating keyword 'Is Alive' failed: Keyword with same name defined multiple times.

901 views
Skip to first unread message

David Miller Lowe

unread,
Apr 4, 2018, 5:43:18 PM4/4/18
to robotframework-users
Hi Users, 

I see the following error every time we start an otherwise working environment that allows us to uses robot-framework to simulate multiple CAN transceivers.  We produce gauges for ORVs and some on-road vehicles.

$ robot --version
Robot Framework 3.0.2 (Python 3.5.2 on linux)

$ robot -P . --test "*Setup" --test "*Speed" ./c4_slingshot.robot
[ ERROR ] Error in test library 'ttCanLibrary': Creating keyword 'Is Alive' failed: Keyword with same name defined multiple times.





The top of our CAN module is derived from threading.Thread so that I can have the ECU simulation running throughout the test suite.

class ttCanLibrary(threading.Thread):


    ROBOT_LIBRARY_SCOPE
= 'TEST SUITE'


   
def __init__(self):
        threading
.Thread.__init__(self, name="MainSndRecv")
        logging
.basicConfig(level=logging.DEBUG)
       
self.bus=None
       
self.keepGoing = False
       
self.semTx = threading.Semaphore()
       
self.semLst = threading.Semaphore()
       
self.perodicList = []
       
self.protocol = J1939.J1939()
       
self.traplist = {}
       
.....
       
# lots of stuff below..



I start each suite setting up and the can bus ecu simulation..



Library  ttCanLibrary
Library  Dialogs


Suite Setup         j1939 start  ${TESTER_ADDRESS}  64   [65]
Suite Teardown      j1939 stop



The j1939_start actually fires up the main thread 


    def j1939_start(self, ecu_addr=0, key_gen=None, secondary_addrs=None):


        logger
.info('j1939_start: suite start, ecu_addr=%s __name__=%s, secondary=%s' % (ecu_addr, __name__, secondary_addrs))


       
try:
            interfaces
= subprocess.check_output('ifconfig')
            canIF
= re.search('.*(can[0-9]).*', str(interfaces)).group(1)
       
except:
            logging
.exception("j1939_start: Failed to locate CAN interface, is the interface started?")
           
raise


       
if callable(key_gen):
            keyFunction
= key_gen
       
else:
            keyFunction
= None

        logger
.info('j1939_start: discovered can interface %s' % canIF )
       
self.ecu_addr = self._valueParm(ecu_addr)
       
self.bus = j1939.Bus(  channel=canIF,
                               broadcast
=None,
                               name
='j1939StartGeneral',
                               keygen
=keyFunction,
                               ignoreCanSendError
=True)
        addrs
= [ecu_addr]
       
if isinstance(secondary_addrs, list):
            logger
.debug('WWWW: j1939_start: discovered secondary addrs %s' % secondary_addrs )
            addrs
= addrs + secondary_addrs
       
self.node = j1939.Node(self.bus, j1939.NodeName(0), [ecu_addr])
       
self.bus.connect(self.node)
       
self.reader = can.BufferedReader()
       
self.notifier = can.Notifier(self.bus, [self.reader], 0.01)
       
self.dispatch = Dispatcher(self, self.reader);
       
self.dispatch.start()
       
self.keepGoing = True


       
self.start()
        logger
.info('j1939_start: suite start, ecu_addr=%s __name__=%s' % (ecu_addr, __name__))



This error message occurs at the start of all of all of our suites, In my suite setup I create some python threads to time and send periodic CAN messages.  I think the "Is Alive" the framework is griping about is the old is_alive() method in the python threading module.

Should I worry about it?  The tests all seem to operate as expected it's just a bit ugly and our SQA folks don't really like the persistent error..   

Sorry if this is a scattered question but there is a lot of background, I'm trying to extract only the relevent snippets.




Pekka Klärck

unread,
Apr 5, 2018, 4:26:16 AM4/5/18
to mil...@gmail.com, robotframework-users
Hello,

The error you get is due to the framework finding two methods in your
library that would match same keyword name. In your case these methods
apparently are `isAlive` and its newer PEP-8 compatible alias
`is_alive` that both could be used as a keyword `Is Alive` (case and
space insensitively). These methods are implemented in Python's
`threading.Thread` class which your library extends. There are at
least two ways how you can avoid it:

- Change the library architecture. Don't extend `threading.Thread`
directly but instead use it or its subclass in your library. Using
composition instead of inheritance is a recommended practice in
general: https://en.wikipedia.org/wiki/Composition_over_inheritance

- Turn your library into so called "hybrid library" that returns names
of its keyword methods from special a `get_keyword_names` method. This
way Robot will only consider those methods keywords and others are
ignored. For details see the User Guide:
http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#hybrid-library-api

Cheers,
.peke
> --
> You received this message because you are subscribed to the Google Groups
> "robotframework-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to robotframework-u...@googlegroups.com.
> To post to this group, send email to robotframe...@googlegroups.com.
> Visit this group at https://groups.google.com/group/robotframework-users.
> For more options, visit https://groups.google.com/d/optout.



--
Agile Tester/Developer/Consultant :: http://eliga.fi
Lead Developer of Robot Framework :: http://robotframework.org
Reply all
Reply to author
Forward
0 new messages