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

Combine in finish (extension of #142) #143

Closed
wants to merge 12 commits into from
Closed

Conversation

ionelmc
Copy link
Member

@ionelmc ionelmc commented Jan 3, 2017

Closes #142. Maybe.

@ryanhiebert
Copy link
Contributor

Man, this seems super hacky. What if we made another instance during start, and then just used it for combine at the end, rather than making a new instance at the end? I'll give that a try.

@ionelmc
Copy link
Member Author

ionelmc commented Jan 3, 2017

How would that simplify things? Those paths being made absolute is not that bad, in fact there are many places already doing absolutization in pytest-cov ...

@ryanhiebert
Copy link
Contributor

Is that just internally, or is that for reporting? My concern is that codecov won't understand it, and also that test runs on different machines will be needlessly different because of the path.I haven't tried it, so it's possible I just don't understand what's be absolutized.

@ryanhiebert
Copy link
Contributor

I did try, before, commit 1b12416, and it gave me this error, which is likely because I'm using tox.ini instead of .coveragerc for my config file:

  File "/Users/ryanhiebert/Code/python/coveragepy/coverage/config.py", line 425, in read_coverage_config
    raise CoverageException("Couldn't read '%s' as a config file" % fname)
coverage.misc.CoverageException: Couldn't read '/Users/ryanhiebert/Code/lektor-git/.coveragerc' as a config file

@ionelmc
Copy link
Member Author

ionelmc commented Jan 4, 2017

Interesting, can you paste full traceback?

@ryanhiebert
Copy link
Contributor

Traceback (most recent call last):
  File "/Users/ryanhiebert/Envs/lektor-git/bin/pytest", line 11, in <module>
    sys.exit(main())
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/config.py", line 47, in main
    config = _prepareconfig(args, plugins)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/config.py", line 156, in _prepareconfig
    pluginmanager=pluginmanager, args=args)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 745, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 339, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 334, in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 613, in execute
    return _wrapped_call(hook_impl.function(*args), self.execute)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 250, in _wrapped_call
    wrap_controller.send(call_outcome)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/helpconfig.py", line 32, in pytest_cmdline_parse
    config = outcome.get_result()
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 280, in get_result
    _reraise(*ex)  # noqa
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 265, in __init__
    self.result = func()
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 614, in execute
    res = hook_impl.function(*args)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/config.py", line 910, in pytest_cmdline_parse
    self.parse(args)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/config.py", line 1067, in parse
    self._preparse(args, addopts=addopts)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/config.py", line 1038, in _preparse
    args=args, parser=self._parser)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 745, in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 339, in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 334, in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 613, in execute
    return _wrapped_call(hook_impl.function(*args), self.execute)
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 254, in _wrapped_call
    return call_outcome.get_result()
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 280, in get_result
    _reraise(*ex)  # noqa
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 265, in __init__
    self.result = func()
  File "/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/_pytest/vendored_packages/pluggy.py", line 614, in execute
    res = hook_impl.function(*args)
  File "/Users/ryanhiebert/Code/python/pytest-cov/src/pytest_cov/plugin.py", line 96, in pytest_load_initial_conftests
    plugin = CovPlugin(ns, early_config.pluginmanager)
  File "/Users/ryanhiebert/Code/python/pytest-cov/src/pytest_cov/plugin.py", line 151, in __init__
    self.start(engine.Central)
  File "/Users/ryanhiebert/Code/python/pytest-cov/src/pytest_cov/plugin.py", line 172, in start
    self.cov_controller.start()
  File "/Users/ryanhiebert/Code/python/pytest-cov/src/pytest_cov/engine.py", line 136, in start
    config_file=self.cov_config)
  File "/Users/ryanhiebert/Code/python/coveragepy/coverage/control.py", line 140, in __init__
    concurrency=concurrency,
  File "/Users/ryanhiebert/Code/python/coveragepy/coverage/config.py", line 425, in read_coverage_config
    raise CoverageException("Couldn't read '%s' as a config file" % fname)
coverage.misc.CoverageException: Couldn't read '/Users/ryanhiebert/Code/lektor-git/.coveragerc' as a config file

@ionelmc
Copy link
Member Author

ionelmc commented Jan 4, 2017

Ah, a slight bug. Fixed now.

@@ -18,7 +18,7 @@ def __init__(self, cov_source, cov_report, cov_config, cov_append, config=None,
"""Get some common config used by multiple derived classes."""
self.cov_source = cov_source
self.cov_report = cov_report
self.cov_config = os.path.abspath(cov_config)
self.cov_config = os.path.abspath(cov_config) if os.path.exists(cov_config) else cov_config
Copy link
Contributor

Choose a reason for hiding this comment

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

But now don't we still have that change in working directory bug if you're not setting the config file manually, and it's not the default .coveragerc (which is used to also mean autodetect)?

Copy link
Member Author

Choose a reason for hiding this comment

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

If you're not specifying --cov-config then cov_config will be None (and coverage will try to find it itself).

If you do specify it and it doesn't exist then coverage should complain, I suspect it doesn't and we should do our own check.

You're quite correct here, if coverage is using a autofound config file with a different name this will make the coverage reinit malfunction (since config won't exist in cwd).

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually .... hmmm ... aren't you using --cov-config=tox.ini? That would make the path absolute at the right time ...

Copy link
Contributor

Choose a reason for hiding this comment

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

No, I'm relying on the autodiscover. I know that pytest-cov is using .coveragerc as the default value from argparse, so this won't ever be None, AFAIK, but it will be .coveragerc, which coverage.py interprets the sameway for backward compatibility.

Copy link
Contributor

Choose a reason for hiding this comment

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

Creating the combiner instance early along with the other one would also make this issue go away. It does make me wonder if this just really isn't a use-case that combine was intended for.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, I'm sure it was intended for this, at least in part. I just wonder if this is more of a design bug in coverage. It's also something we want to address here, as usage in tox is very common. Still, it does seem cumbersome.

@ionelmc
Copy link
Member Author

ionelmc commented Jan 4, 2017

Well if this doesn't work I give up. Today at least.

@ryanhiebert
Copy link
Contributor

Nope, not quite. Now it's giving duplicate results, and it's leaving the parallel file, but not leaving the .coverage file:

---------- coverage: platform darwin, python 2.7.12-final-0 ----------
Name                                                                           Stmts   Miss Branch BrPart  Cover
----------------------------------------------------------------------------------------------------------------
src/lektor_git.py                                                                 21      0      6      0   100%
/Users/ryanhiebert/Envs/lektor-git/lib/python2.7/site-packages/lektor_git.py      21      0      6      0   100%
----------------------------------------------------------------------------------------------------------------
TOTAL                                                                             42      0     12      0   100%

self.cov.combine()
self.cov.save()

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the issue that's causing the duplicates is that you're not setting self.cov = self.combining_cov before doing the load().

@@ -221,6 +227,9 @@ def finish(self):

# Combine all the suffix files into the data file.
self.cov.stop()
self.cov.save()
self.cov = self.combining_cov
self.cov.load()
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this is needed in a distributed mode, unless you're having each worker report itself (which I think is a feature you have). It probably would cause problems in the normal case, though, since I think the parallel version of the coverage file gets deleted normally when it's being combined.

@@ -289,3 +298,12 @@ def summary(self, stream):
"""Only the master reports so do nothing."""

pass


def laxabspath(path_or_something, *replacemet):
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it supposed to be *replacement?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants