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

Use Config.invocation_params for consistent worker initialization #448

Merged
merged 1 commit into from Jul 11, 2019

Conversation

nicoddemus
Copy link
Member

@nicoddemus nicoddemus commented Jul 2, 2019

EDIT

Decided to keep the old way still working for now.

Fix #6
Fix #445


ORIGINAL POST

While investigating a recent node id bug (#445) I decided to play
with config initialization, around the idea of initializing the config
on the remote exactly how we initialize the config object on pytest.main()

One thing that immediately broke all tests was inprocess pytester runs,
but other than that just a few tests failed which I find encouraging.

While this patch is in no way even remotely ready, I would like to get
opinions if the overall idea of initializing the config object
like this is sound.

@RonnyPfannschmidt
Copy link
Member

initializing the config the same way everywhere is structurally a good idea

i believe however that the main config initialization process needs some solid and api breaking work to support that sanely

@nicoddemus
Copy link
Member Author

nicoddemus commented Jul 3, 2019

i believe however that the main config initialization process needs some solid and api breaking work to support that sanely

You mean _prepareconfig is not suitable for this (other than not being public API of course)?

If we can get this working with _prepareconfig, I think it is still worth releasing this as this will fix quite a number of long standing issues. We can think of a good API for config initialization later down the road so other plugins can use the new API, but given that xdist is maintained by the core team, I don't see any harm on using the internal API as an intermediate step.

@RonnyPfannschmidt
Copy link
Member

im totally fine with having sometihng that works a little bit better, but we will have to break api from he pytestside a few times to get things work nice

@nicoddemus
Copy link
Member Author

nicoddemus commented Jul 3, 2019

Cool, sounds like a plan then.

but we will have to break api from he pytestside a few times to get things work nice

We don't really have an API to properly initialize the config objects from the command line arguments today, do we?

I'm thinking, for starters, an API to create the config object from argsand plugins, exactly as given to pytest.main. Something like:

config = Config.from_args_and_plugins(args, plugins)

But we should brainstorm how to initialize both config and session objects so one can selectively run certain stages (say only collection) using public APIs and without having to manually call hooks. I believe some niche use cases would greatly benefit from it, for example IDE launchers.

@nicoddemus
Copy link
Member Author

Great news!

With pytest-dev/pytest#5564, all tests in pytest-xdist and pytest (with xdist of course) pass. 🎉

This leads me to believe this is indeed the way to go. We can try to nail this down after pytest 5.1 gets released.

Decided to keep the old way still working for now.

Fix pytest-dev#6
Fix pytest-dev#445
@nicoddemus nicoddemus changed the title WIP play around with config initialization Use Config.invocation_params for consistent worker initialization Jul 10, 2019
@nicoddemus
Copy link
Member Author

@RonnyPfannschmidt I think this is now ready for review. 👍

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt left a comment

Choose a reason for hiding this comment

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

lovely, great job 👍

@nicoddemus nicoddemus merged commit 4642f16 into pytest-dev:master Jul 11, 2019
@nicoddemus nicoddemus deleted the config-init-test branch August 3, 2019 11:58
@@ -236,10 +238,14 @@ def shutting_down(self):
def setup(self):
self.log("setting up worker session")
spec = self.gateway.spec
args = self.config.args
if hasattr(self.config, "invocation_params"):
args = [str(x) for x in self.config.invocation_params.args or ()]
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't this give unwanted arguments to the worker?

I'm investigating why pytest-cov's test suite is broken on 0.30 and invocation_params.args has lots of stuff while config.args is just the test file.

Copy link
Contributor

Choose a reason for hiding this comment

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

@nicoddemus
Can you comment, please?
(I'm currently looking into getting pytest-cov's CI to pass again so this would help there)

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry @ionelmc and @blueyed, I must have missed this.

Why do you say it would give unwanted arguments to the worker? Using invocation_params it will initialize exactly like the master process (well almost), which solved a problem with initialization of the config file.

Copy link
Member

Choose a reason for hiding this comment

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

@nicoddemus I guess I'm just confused about what's wrong with the latest pytest/xdist/cov combination (it's broken in some situations). Any explanation about how the all works would help me debug it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure myself, but the latest implementation just forwards all the parameters given in the command line to the workers, making them initialize the same way as the master node.

Copy link
Member

Choose a reason for hiding this comment

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

@nicoddemus the way I understand this the problem is that option_dict is empty in the new "invocation_params mode", thus plugins like pytest-cov don't have the necessary options to initialize. Am I missing something?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thus plugins like pytest-cov don't have the necessary options to initialize.

Unless pytest-cov is trying to get the options from pytest-xdist structures instead of config.getoption, it should just work. The workers should now be initializing the same way as the master node/without xdist, so all the options should be there.

Copy link
Member

Choose a reason for hiding this comment

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

@nicoddemus the problem is that none of the plugin options are there when stuff like --dist=load --tx=popen//chdir=1 is used. When using -n 1 everything is fine.

@@ -236,10 +238,14 @@ def shutting_down(self):
def setup(self):
self.log("setting up worker session")
spec = self.gateway.spec
args = self.config.args
if hasattr(self.config, "invocation_params"):
args = [str(x) for x in self.config.invocation_params.args or ()]
Copy link
Member

Choose a reason for hiding this comment

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

@nicoddemus the problem is that none of the plugin options are there when stuff like --dist=load --tx=popen//chdir=1 is used. When using -n 1 everything is fine.

option_dict = {}
else:
args = self.config.args
option_dict = vars(self.config.option)
if not spec.popen or spec.chdir:
args = make_reltoroot(self.nodemanager.roots, args)
Copy link
Member

Choose a reason for hiding this comment

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

@nicoddemus I think now I correctly identified the cause of the problem. In the new code the args stripping matters cause the old option_dict is no more, while previously this stripping had no effect.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, what "stripping" you mean? Can you please clarify?

Copy link
Member

Choose a reason for hiding this comment

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

@nicoddemus see #491 - make_reltoroot removes anything that ain't a valid path (like the arguments I need).

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

Successfully merging this pull request may close these issues.

pytest-xdist is not reporting the same nodeid as pytest does Poor interaction between -n# and -c X.cfg
4 participants