riotnode: node abstraction package#10949
Conversation
Either you are sending a wrong command here or I don't really understand what you are doing in the background and why (the command is just |
|
The issue I noted in here for matching |
It was a test to see who will read this, I updated the code :p |
7649520 to
48b5ce8
Compare
|
I added tests for process management and started refactoring commits (so rewrote history) to go in a direction where bug fixes could be merged alone and used in the current As long as a name is chosen for the package, some 'utils' functions could be added and used. |
|
After one night on this, should the wrapper really take care of a It requires adding Which means, when a user uses I would be maybe in favor of documenting correctly to which signals the |
48b5ce8 to
de577c4
Compare
It is a python directory to start developping the package. I include all files around for testing and integrating in RIOT. Test dependencies in tox are already ready for testing with pytest. * sitecustomize.py: allow implementing 'riotnode' in a subdirectory * setup.py implement a releaseable package * requirements.txt: uses 'setup.py' could then be used by our standard way of installing * tox.ini: run the test suite with 'tox' * setup.cfg/.coveragerc: test suites configuration
de577c4 to
9ce1f1b
Compare
The abstraction is a basic class to replicate behavior that was in `testrunner. Implementation was sometime directly taken from `testrunner` without being technically justified to keep backward compatibility. This is described in `TODO.rst` and dedicated implementation. This also adds a test `node` implementation with a Makefile. It is currently an easy to use node as no output is lost and reset correctly resets. TODO maybe put this as a comment in the file!! When pexpect 'close' a 'ptyprocess' it starts by 'SIGHUP'. It is not handled by default to call 'atexit'. To not do a specific handling for 'SIGHUP' just forward all signals to the child. This wrapper should not do any specific things anyway. TODO Split the 'safe_term_close' to utils with a test not using Make term and so directly only wanting 'sigkill' This should allow merging it before and using it in testrunner TODO settle the `env` handling. Get feedback on what to do here. Disable local echo otherwise pexpect matches sent characters. REMOVE ME: Include fix for RIOT-OS#10952
…nd tests TODO ADD TEST THAT WE DO NOT RESET IN START TERM
Use 'riotnode' directly in '__init__.py' not with the 'spawn' wrapper.
Allow handling custom pexpect class.
This allows finer analysis of exception as sometime the calling line is only `expect(variable)` without knowing the value. testrunner needs to find the correct exception context as the class is inherited.
On a non-meta level, |
|
Thanks for adding me as a reviewer. Until I get a chance to review, please take a look at my pytest repo for CoAP. In particular see conftest.py for a pexpect host class. |
|
@kb2ma I somehow try to provide the same, in a riot specific way. So without specifying "make term" as argument because it is "of course" make term. Currently I do not have the "send_recv" as I see it more maybe as an other layer on top. I like your "nanocoap_server", "gcoap_example" fixtures. "Return me a firmware in a ready state to use". A plan I have for further steps, would be to add a class describing this "nanocoap_server" and the operations you could have on it. Not mandatory as you could still use the "node.term" but giving you other methods that could be useful. |
|
However, my idea here, would be to give the nanocoap_server object, but not describe it as a fixture. |
| except pexpect.ExceptionPexpect: | ||
| # Not sure how to cover this in a test | ||
| # 'make term' is not killed by 'term.close()' | ||
| self.logger.critical('Could not close make term') |
There was a problem hiding this comment.
How about
| self.logger.critical('Could not close make term') | |
| self.logger.critical('Could not close make term') | |
| finally: | |
| self.term = None |
? Thes way one can check (e.g. in a subclass) if the terminal is running or not.
There was a problem hiding this comment.
I may even maybe put a started variable. As currently when starting we wait some time. I will see with the multi nodes handling.
Also, the start could just do nothing if it is already started.
However I did not really see a use case for calling start multiple times. In the current tests, the test function receive a started child. So I assumed to somehow have this initialization done before anything else.
|
I will look into the usage of the I also found |
|
I think this is a great contribution that could help improving our test suit. I can see a direct usage in putting in common a lot of the
I like having a "send_recv" function, I've ended up implementing something like that many times.
+1
An iotlab node extension would be great to have. It would help scripting "manually automatic" (#11954) integrations tests for our release specs, and other features.
I think we should work on integrating this, it will definitively help with having common building blocks. |
|
@cladmi was there a reason why you wanted this in RIOT and not as an external pkg, hosted in RIOT-OS for examples. I would like to make this available, although maybe not yet used since Feature freeze is coming soon. |
|
@fjmolinas It would be mapped to exactly the exposed interface of RIOT shell so subject to change at any commit. Keeping them in the same repo allows staying in sync without having to merge the tool PR before the code modification. But it is a long term and ecosystem concern, during dev or release you could store it elsewhere indeed. |
|
@miri64 @aabadie Thoughts on this one? Should we postpone again or target integrating as a tool although not used? It could get the ball rolling, it would basically just mean removing the usage in |
|
I would like to have this in rather sooner than later, even if there are things still to kink out. As you said, this would rather get the ball rolling (also we can go ahead with #11406). |
I would propose going with but without the modifications to |
|
|
||
| def board(self): | ||
| """Return board type.""" | ||
| return self.env['BOARD'] |
There was a problem hiding this comment.
| return self.env['BOARD'] | |
| return self.env.get('BOARD') |
so it doesn't return a key error, or is this on purpose?
|
#13612 was closed because the project moved to https://github.com/riot-os/riotctrl |
Contribution description
This is a start to try providing a common interface that could be used as a test agnostic base that could be used for automating experiments but also, on a shorter term for testing with the current tests, the i2c testing, some framework directions with tests (RobotFramework/pytest), release specs with multiple nodes under test.
Different parallel directions have been taken with different low level wrapper (see refs below). The goal here would be to share a common base where then every usage could benefit of the common developments.
It is currently only a base class without any
shellabstraction but wanted to publish early to get feedback and it could also be used in this state. I focused to put the test ecosystem around to help developing.Usage can be seen in
testrunnerwrapping and intest_running_error_cases(app_pidfile_env)test.Current usage in code is
One important thing I think, is that it implements wrapping for only one node, as it is the only thing we can do in RIOT. Handling two nodes means having two different environments (specific env variables) with two instances of one node.
This pull requests is an aggregate of:
expectspawn object. So somehow whattestrunnerdoes but with a different interface.Upcoming work
After different IRL discussions, I am thinking about providing other abstraction classes for shell commands more as a composition than inherited objects (or more let other provide abstractions, as it is the goal to share this between different developers).
And implemented with independent classes that you use alone instead of an aggregated object with everything in the same object.
This could allow a light usage with a specific object, while still allowing to create an aggregated objects if needed but not enforcing it.
This one could still maybe use a common
RIOTNodeShellWrapperas base class, it is thing that should be discussed depending on the usages.Reviewing procedure
I would advise to review commit by commit as they are focusing on different concepts.
Also see if the abstraction could currently work for you.
I still have
TODOcomments in the code I want to address before merging I would gladly get feedback on them. They are shown when runningtoxtest command.There is also a
TODO.rstfor things that were here before intestrunnerand could be addressed later.I was told that
nodethat I took from my work on IoT-LAB was maybe not a good name for this.I did not choose
boardas it as theBOARDmeaning, you could have two boards being the sameBOARDbut maybe it is just an issue with me.Please show me where this could help you or not and if you already have needs around this.
And also, if you have issues with the current implementation.
Testing procedure
Running the test suite can be run with
tox(pip install --user tox).Note: there should now be TODO` warning as I thought about something I want to address before any merging.
See if it can be used a as base for your cases and if you have feedback on the next steps.
Issues/PRs references
Depend on having a terminal without decoration/additional behavior:
My comment on RobotFramework RFC #10241 (comment)
Some example place where it could be used as a base
serial_aggregatoras a base)shelltestsRIOTDriverinriot_pal.