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

[take over] riotnode: node abstraction package #13612

Conversation

leandrolanzieri
Copy link
Contributor

@leandrolanzieri leandrolanzieri commented Mar 11, 2020

Contribution description

As discussed offline with @fjmolinas, this PR is taking over @cladmi's work in #10949. I added some missing tests that he proposed as TODOs, and cleaned up a bit git history.

There seems to be an agreement on #10949 on merging the package with the current features (and without the changes to 'testrunner'), and improve it in follow-up PRs. It would be nice to have this soonish, in order to start working on release tests before the freezes.

Testing procedure

Running the test suite can be done with tox (pip install --user tox).

Issues/PRs references

For a full description see #10949

It is a python directory to start developing 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 releasable 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
The abstraction is a basic class to replicate behavior that was in
`testrunner.

Implementation was sometimes 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.
This allows finer analysis of exception as sometimes the calling line
is only `expect(variable)` without knowing the value.
This allows having a nicely printed output on `pytest`.
This could be moved outside of here too.
Add functions that handle killing all child processes using psutil.

This allows killing child processes that may not have been correctly
terminated by its parent.

It should not be necessary in an ideal world, but it would allow
detecting errors in the tests.
This shows the current handling that could correctly terminate a
subprocess that is not always killed.

It is here as a regression test when removing the process group sigkill.
In case all children are not correctly cleaned by '_safe_term_close',
sigkill them anyway.

This prepares for replacing the global kill with SIGKILL with a less
violent method.

Also, adds a test where the terminal program tries to do a cleanup.

It is important that a terminal can clean itself correctly to close
files, or remove created interfaces.
The process should be closed alone with 'self.term.close'.
Closing child processes must be done by the `make term` program.
Remove now unused _kill_term.
@leandrolanzieri leandrolanzieri added Area: tests Area: tests and testing framework Type: new feature The issue requests / The PR implemements a new feature for RIOT Area: tools Area: Supplementary tools labels Mar 11, 2020
@leandrolanzieri leandrolanzieri added this to the Release 2020.04 milestone Mar 11, 2020
@fjmolinas fjmolinas added this to Backlog / Proposals in RIOT Sprint Day via automation Mar 17, 2020
@fjmolinas fjmolinas moved this from Backlog / Proposals to Ready for Review in RIOT Sprint Day Mar 17, 2020
@aabadie aabadie self-assigned this Mar 19, 2020
@aabadie aabadie moved this from Ready for Review to Under Review in RIOT Sprint Day Mar 19, 2020
@aabadie
Copy link
Contributor

aabadie commented Mar 24, 2020

I started to have a look at this PR and have several general comments/questions:

  • In the current state, this PR doesn't make use of riotnode for the existing tests. So it is a PR with > 1k unused lines of codes.
  • In the documentation or inline comments, there are a lot of sentences written using the first person (e.g. I do this, I do that), this is not right IMHO. The sentences should be re-written in a something more impersonal.
  • Is riotnode a good name for this feature ? I think something like riottest or riotrunner would be better.
  • What is the need for putting the whole riotnode implementation as a complete Python package (with versions, setup.py, etc) inside the RIOT codebase ? Wouldn't it make more sense to provide this package in an external public repository (if it meant to be used from another project, like riot-release-specs) ? This package could then be installed using regular Python packaging tools (pip) from any project that needs it (and not only RIOT or RIOT-release-specs). It would be great to have some discussion on this particular point.

@miri64
Copy link
Member

miri64 commented Mar 24, 2020

* What is the need for putting the whole riotnode implementation as a complete Python package (with versions, setup.py, etc) inside the RIOT codebase ? Wouldn't it make more sense to provide this package in an external public repository (if it meant to be used from another project, like riot-release-specs) ? This package could then be installed using regular Python packaging tools (pip) from any project that needs it (and not only RIOT or RIOT-release-specs). It would be great to have some discussion on this particular point.

👍

@leandrolanzieri
Copy link
Contributor Author

  • In the current state, this PR doesn't make use of riotnode for the existing tests. So it is a PR with > 1k unused lines of codes.

True, this is following the proposal in the original PR, introducing the package as is with no changes on testrunner, and integrate it later.

  • In the documentation or inline comments, there are a lot of sentences written using the first person (e.g. I do this, I do that), this is not right IMHO. The sentences should be re-written in a something more impersonal.

Sure, I will address this!

  • Is riotnode a good name for this feature ? I think something like riottest or riotrunner would be better.

Discussion about naming is seems to be ongoing since the original PR. IMHO as the package provides an abstraction on the node (or whatever we would like to call it) which runs a certain firmware, the current name reflects more what the package is, as opposed to riottest or riotrunner which talk about one use case of it.

That being said, I'm not 100% convinced by riotnode and I would like to continue this discussion. Proposals which came up in the original PR are:

  • riotdevice
  • riotthing
  • riotagent
  • riotauthority
  • What is the need for putting the whole riotnode implementation as a complete Python package (with versions, setup.py, etc) inside the RIOT codebase ? Wouldn't it make more sense to provide this package in an external public repository (if it meant to be used from another project, like riot-release-specs) ? This package could then be installed using regular Python packaging tools (pip) from any project that needs it (and not only RIOT or RIOT-release-specs). It would be great to have some discussion on this particular point.

Regarding this the main concern seemed to be keeping the package in sync with RIOT's shell interfaces. What I see is that a big part of this package (and code) will be in the mixins we write to interact with commands (and those are the ones which need to be kept in sync with RIOT's shell, mostly). Would we have some on RIOT and some on Release-Specs? Will it come the time when we need to group them to reduce duplication?

I can see how keeping the package out of the codebase could be a good thing. Let's discuss further how this would look like.

@miri64
Copy link
Member

miri64 commented Mar 25, 2020

Regarding this the main concern seemed to be keeping the package in sync with RIOT's shell interfaces. What I see is that a big part of this package (and code) will be in the mixins we write to interact with commands (and those are the ones which need to be kept in sync with RIOT's shell, mostly). Would we have some on RIOT and some on Release-Specs? Will it come the time when we need to group them to reduce duplication?

The framework could go into its own repository, while the mixins for the shell commands could remain in RIOT-OS/RIOT. Regarding the ReleaseSpecs: we need the RIOT repo for testing those anyways (its what we are testing after all), so we would then also pull in the latest version of the mixins ;-).

@fjmolinas fjmolinas moved this from Under Review to In progress in RIOT Sprint Day Apr 14, 2020
@fjmolinas fjmolinas removed this from In progress in RIOT Sprint Day Apr 14, 2020
@leandrolanzieri
Copy link
Contributor Author

I'm fine with having the package on a separate repo if the mixins can be kept in RIOT-OS/RIOT and stay in sync with shell commands. @aabadie how should we proceed in this direction?

@fjmolinas
Copy link
Contributor

The framework could go into its own repository, while the mixins for the shell commands could remain in RIOT-OS/RIOT. Regarding the ReleaseSpecs: we need the RIOT repo for testing those anyways (its what we are testing after all), so we would then also pull in the latest version of the mixins ;-).

+1 for this

@aabadie
Copy link
Contributor

aabadie commented Apr 16, 2020

I'm not in favor of using the mixins but rather follow @cladmi's suggestion in #10949 and in #11406 (comment).

Otherwise I'm also OK for moving riotnode (or whatever better name it takes) to a separate repo.

@miri64
Copy link
Member

miri64 commented Apr 16, 2020

Regardless if we do it as mixins or associations, this is something we can decide once this framework is in place. I want this (and the shell command wrappers, however they look like) in for 2020.07, so we should do the first step ASAP :-).

@cladmi
Copy link
Contributor

cladmi commented Apr 17, 2020

Without re-reading my comments, what I was "against" was to have the implementation in the mixins.
If it is a separate class, you can use it with composition, or inheritance if you really want, and wrap it after as mixin.

Defining mixins allows simple instantiation for the price of an enforced usage convention.
Restricting tools at that level is for me a bad idea, so preferred having both. The low level powerful layer where you must be explicit, and on top the easy to instantiate but constrained mixins.

I had in mind (and played with) a layer on top with mixins that would create a composed class:

class MyNodeUnderTest(IfconfigWrapperMixin, RouteWrapperMixin): with the hierarchy node.shell.ifconfig.list_interfaces() or something.

And even the next abstraction being class MyNodeUnderTest(RiotNodeShellMixinsFromModulesList): with an horrible metaclass.

@cladmi
Copy link
Contributor

cladmi commented Apr 17, 2020

The term target should be replaced by cleanterm.

For a first version, you can remove the exception handling from there I think. The shorter exception is a nice thing but may better be done after using it and seeing what is wanted.

The "ensuring all process stopped" is an horrible thing that should be removed
I did it to match the replace the SIGKILL, yes kill dash nine!, the whole group in testrunner as I was planning to be a drop-in replacement. If the terminal process does not stop on sigterm/sigint, the terminal process must be fixed, not the caller there that must do horrible ps listing, as dev will also want to do ctrl+c to stop it.

Only go for the first two commits. It was developed with separate steps to demo what could be done at what price, not take everything as is.

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

That being said, I'm not 100% convinced by riotnode and I would like to continue this discussion. Proposals which came up in the original PR are:

* `riotdevice`

* `riotthing`

* `riotagent`

* `riotauthority`

riottest? IMHO as this is primarily a test framework it should be immediately, that should be immediately obvious from the name.

@fjmolinas
Copy link
Contributor

riottest

+1

@fjmolinas
Copy link
Contributor

As I see this is missing:

  • replace term by cleanterm
  • squash into 2 commits
  • remove _ensure_process_stopped
  • rename to riottest

With that we can move it to the organization.

Copy link
Contributor

@fjmolinas fjmolinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nitpick

command = ['make']
command.extend(self.MAKE_ARGS)
if self._application_directory != '.':
dir_cmd = '--no-print-directory', '-C', self.application_directory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dir_cmd = '--no-print-directory', '-C', self.application_directory
dir_cmd = '--no-print-directory', '-C', self._application_directory

self.logger = logging.getLogger(__name__)

@property
def application_directory(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a setter function for this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussing it offline with @cladmi, it makes sense to not be able to set it since some application have different requirements for the terminal baudrate use of ethos, etc.. so it makes sense to not be able to change the application directory.

@fjmolinas fjmolinas self-assigned this Jun 9, 2020
@fjmolinas
Copy link
Contributor

riottest? IMHO as this is primarily a test framework it should be immediately, that should be immediately obvious from the name.

Are we ok with node in riottest? dist/pythonlibs/riotnode/riotnode/node.py?

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

riottest? IMHO as this is primarily a test framework it should be immediately, that should be immediately obvious from the name.

Are we ok with node in riottest? dist/pythonlibs/riotnode/riotnode/node.py?

If the node module controls a node under test, yes.

@aabadie
Copy link
Contributor

aabadie commented Jun 9, 2020

If the node module controls a node under test, yes.

What is a node ? If we talk about networking, it's a node in a mesh network. But otherwise ? I think there's an abuse of the term here.

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

Then maybe (though maybe confusing with the device terminus within RIOT) device.py?

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

Or dut.py for Device Under Test.

@aabadie
Copy link
Contributor

aabadie commented Jun 9, 2020

If we look back at @leandrolanzieri proposals it could also be agent.py. I also like runner.py :)

@fjmolinas
Copy link
Contributor

So options would be:

  1. pkgName: riotrunner

    • moduleName; runner.py
  2. pkgName: riotagent

    • moduleName; agent.py

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

No, as far as I understood the conversation, the package's name stays riottest either way. The question was about the name of the node sub-module

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

Remember, that it is also important what the URL will look like / the name on the RIOT-OS org landing page:

https://github.com/RIOT-OS/riottest makes it pretty obvious that this is about testing.

https://github.com/RIOT-OS/riotrunner sounds like something mandatory to get RIOT to run, https://github.com/RIOT-OS/riotagent "is this something like SSH agent for RIOT?". If we want to keep the names of riotnode and node.py together, maybe a more non-functional name is better?

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

riotctrl for RIOT control? In the sense that it is for controlling if RIOT is working?

@kaspar030
Copy link
Contributor

https://github.com/RIOT-OS/riottest makes it pretty obvious that this is about testing.

but riotnode would only be a small wheel in the whole RIOT testing infrastructure?

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

https://github.com/RIOT-OS/riottest makes it pretty obvious that this is about testing.

but riotnode would only be a small wheel in the whole RIOT testing infrastructure?

True, but riottest does not claim to be RIOT's whole testing infrastructure IMHO.

@aabadie
Copy link
Contributor

aabadie commented Jun 9, 2020

Now I think that riottest is too specific and the actual project can be used in other contexts. The actual README says that already: https://github.com/RIOT-OS/RIOT/pull/13612/files#diff-1134727da204f7baca0c000c630766daR4-R9

@leandrolanzieri
Copy link
Contributor Author

As I mentioned here testing is one of the possible use cases for this package. Some people commented that riotnode may imply networking connectivity and that will not be always true.

Any strong opinions against riotdevice?

@miri64
Copy link
Member

miri64 commented Jun 9, 2020

As I mentioned here testing is one of the possible use cases for this package. Some people commented that riotnode may imply networking connectivity and that will not be always true.

Any strong opinions against riotdevice?

That has the same problem IMHO. As a new contributor I would ask myself: Do I need this to run my device with RIOT?

@leandrolanzieri
Copy link
Contributor Author

This is being moved to its own repo now.

@leandrolanzieri leandrolanzieri deleted the pr/riotnode_cleanup_squashed branch June 23, 2020 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: tests Area: tests and testing framework Area: tools Area: Supplementary tools Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants