Skip to content

PythonPackage: add import module smoke tests#20023

Merged
tldahlgren merged 10 commits intospack:developfrom
adamjstewart:tests/python
Dec 16, 2020
Merged

PythonPackage: add import module smoke tests#20023
tldahlgren merged 10 commits intospack:developfrom
adamjstewart:tests/python

Conversation

@adamjstewart
Copy link
Copy Markdown
Member

@adamjstewart adamjstewart commented Nov 20, 2020

This PR adds smoke tests for the 1,255 Python packages in Spack. It has been tested on the 180+ Python packages I have installed on my system.

Specifically, this PR makes the following changes:

  • Automatically detect import_modules
  • Run import module tests as smoke tests and install tests
  • Update existing packages that no longer need to set import_modules
  • Remove build_test and install_test phases
  • Update existing packages that use build_test and install_test
  • Remove no longer needed test deps
  • Update PythonPackage build system docs

Reboot of #15370
Closes #20079
Closes #20090

@adamjstewart adamjstewart added python documentation Improvements or additions to documentation build-systems stand-alone-tests Stand-alone (or smoke) tests for installed packages labels Nov 20, 2020
@adamjstewart

This comment has been minimized.

Comment on lines -362 to -370
def build_test(self):
"""Run unit tests after in-place build.

These tests are only run if the package actually has a 'test' command.
"""
if self._setup_command_available('test'):
args = self.test_args(self.spec, self.prefix)

self.setup_py('test', *args)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Running python setup.py test is deprecated, as most packages tell you to use something like tox instead. Also, the vast majority of packages do not upload any test files to PyPI, making these tests a no-op. Even if they do, I rarely manage to get the tests to pass, and many tests introduce circular dependencies. I've been meaning to do this for a long time now, but I'm removing these tests for the aforementioned reasons.

version('17.1', sha256='f019b770dd64e585a99714f1fd5e01c7a8f11b45635aa953fd41c689a657375b')
version('16.8', sha256='5d50835fdf0a7edf0b55e311b7c887786504efea1177abd7e69329a8e5ea619e')

depends_on('py-setuptools', type='build')
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I noticed a bug where spack install py-packaging would install a .egg-info file but no actual packaging.py file. This was causing other packages to fail. Adding a setuptools dependency fixes this bug.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great find.

@adamjstewart adamjstewart marked this pull request as ready for review November 21, 2020 21:50
@adamjstewart
Copy link
Copy Markdown
Member Author

@skosukhin may be interested in reviewing this.

@vvolkl
Copy link
Copy Markdown
Contributor

vvolkl commented Nov 25, 2020

Refers #20079

@adamjstewart
Copy link
Copy Markdown
Member Author

Ping @becker33 @tldahlgren

@tldahlgren
Copy link
Copy Markdown
Contributor

tldahlgren commented Dec 5, 2020

This PR affects a lot of files. Are you sure you haven't missed any? ;)

I haven't checked each package, but a basic ls py-*lists 1281 (1314 in develop) built-in packages in my clone. Grep'ing for built-in packages that inherit from PythonPackage lists 1228 packages, 22 of which do not start with py-.

FWIW. I plan to install a bunch of packages and run the tests.

@tldahlgren
Copy link
Copy Markdown
Contributor

How did you decide on which (python) test dependencies to remove? I see a number of packages that still list test dependencies on packages such as py-mock (i.e., ambari, awscli), py-nose (e.g., awscli, nest, py-numpy, vigra), googletest (e.g., flann, msgpack-c, snappy, sumo) and others.

@adamjstewart
Copy link
Copy Markdown
Member Author

I removed test dependencies from packages that no longer have unit tests.

elif context == 'test':
import spack.user_environment as uenv # avoid circular import
env.extend(uenv.environment_modifications_for_spec(pkg.spec))
env.extend(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmm. This fix was integrated in #20298 . Unfortunately, it isn't quite enough in some cases (#20326 ).

@tldahlgren
Copy link
Copy Markdown
Contributor

tldahlgren commented Dec 12, 2020

Closed by mistake.

@tldahlgren tldahlgren closed this Dec 12, 2020
@tldahlgren
Copy link
Copy Markdown
Contributor

Reopening since accidentally closed.

@tldahlgren tldahlgren reopened this Dec 12, 2020
Copy link
Copy Markdown
Contributor

@tldahlgren tldahlgren left a comment

Choose a reason for hiding this comment

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

The tests appeared to pass for all of the packages I installed.

I would prefer to see output generated to the test logs along the lines produced by the run_test test method.

@adamjstewart

This comment has been minimized.

@adamjstewart
Copy link
Copy Markdown
Member Author

@tldahlgren the latest commit makes use of run_test. I tested it for py-nose at both install time and as a post-installation test. As far as I'm concerned this should be good to go now.

Copy link
Copy Markdown
Contributor

@tldahlgren tldahlgren left a comment

Choose a reason for hiding this comment

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

LGTM. I prefer explicit purpose descriptions for test but the test log output was sufficient.

I had a failure for one of the packages but that may be because I was having concretization issues with my last round of installs.

Update: FWIW. After re-running spack install on all the packages I was testing, all of the tests now work.

@adamjstewart
Copy link
Copy Markdown
Member Author

What would be a good purpose description? Would you include the module name in the purpose?

@tldahlgren
Copy link
Copy Markdown
Contributor

What would be a good purpose description? Would you include the module name in the purpose?

I do in general. The reason is it can be useful to grep for test: when you're debugging to see which tests at least started. It can be more relevant when there are a variety of tests being executed.

My inclination would be something along the lines
test: <package name-version>: checking import of <python module>.
But I do appreciate that being explicit can appear redundant when you're reviewing the test log.

@adamjstewart
Copy link
Copy Markdown
Member Author

Done. I didn't add test: <package name-version>: because that seems like it should be added globally if that's something we want.

@tldahlgren
Copy link
Copy Markdown
Contributor

tldahlgren commented Dec 14, 2020

Done. I didn't add test: <package name-version>: because that seems like it should be added globally if that's something we want.

I agree. What do you think @becker33 ?

BTW. Without test: my aforementioned greps won't pick up these test starts.

Copy link
Copy Markdown
Contributor

@cosmicexplorer cosmicexplorer left a comment

Choose a reason for hiding this comment

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

One possibly-surprising pylab insertion, and one nonblocking question about checking for modules named test.

When you run ``spack install --test=root py-pyqt5``, Spack will attempt
to import the ``PyQt5`` module after installation.
These tests often catch missing dependencies and non-RPATHed
libraries. Make sure not to add modules/packages containing the word
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great clarification!

Nonblocking: Would it be useful if I created a separate issue discussing checking for test in the added modules/packages? Does that occur in import_modules()? Or is that intrinsic somehow?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

As of now, import_modules doesn't ignore test* modules. When I originally wrote this in #15370, I was using setuptools.find_packages, which has a tool for this. It would probably be good to add something similar to the default import_modules implementation. Do you want that to happen in this PR or would a follow-up PR be fine?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

FWIW. I think a follow-up PR is fine (or preferred).

'matplotlib.sphinxext', 'matplotlib.cbook', 'matplotlib.backends',
'matplotlib.backends.qt_editor', 'matplotlib.style',
'matplotlib.projections', 'matplotlib.testing',
'matplotlib.testing.jpl_units', 'pylab'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'pylab' appears to be new here. Where does that arise from?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In Python lingo, there are "modules" and "packages". "modules" are things like six, where the only thing that gets installed is a single six.py file in site-packages. "packages" are things like numpy, where there is no numpy.py, but instead there is a numpy/__init__.py with sub-directories containing code.

Previously, I was using setuptools.find_packages to get a list of import modules. find_packages only returns "packages", not "modules". matplotlib is one of those rare packages that mixes "modules" and "packages". The installation prefix has both matplotlib/__init__.py, mpl_toolkits/__init__.py, and pylab.py. My new code checks for both, which is why pylab was added.

version('17.1', sha256='f019b770dd64e585a99714f1fd5e01c7a8f11b45635aa953fd41c689a657375b')
version('16.8', sha256='5d50835fdf0a7edf0b55e311b7c887786504efea1177abd7e69329a8e5ea619e')

depends_on('py-setuptools', type='build')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great find.

python_paths.append(root)

pythonpath = ':'.join(python_paths)
env.prepend_path('PYTHONPATH', pythonpath)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Much easier to follow, thank you.

@tldahlgren tldahlgren merged commit 826cd07 into spack:develop Dec 16, 2020
@adamjstewart adamjstewart deleted the tests/python branch December 16, 2020 23:16
bollig pushed a commit to bollig/spack that referenced this pull request Jan 12, 2021
loulawrence pushed a commit to loulawrence/spack that referenced this pull request Jan 19, 2021
matz-e added a commit to BlueBrain/spack that referenced this pull request Feb 4, 2021
Should allow us to automatically check more modules and alleviate the
need to create some private checks in different Jenkins CIs.

Original commit message:

PythonPackage: add import module smoke tests (spack#20023)
matz-e added a commit to BlueBrain/spack that referenced this pull request Feb 16, 2021
Should allow us to automatically check more modules and alleviate the
need to create some private checks in different Jenkins CIs.

Original commit message:

PythonPackage: add import module smoke tests (spack#20023)
matz-e added a commit to BlueBrain/spack that referenced this pull request Feb 16, 2021
Should allow us to automatically check more modules and alleviate the
need to create some private checks in different Jenkins CIs.

Original commit message:

PythonPackage: add import module smoke tests (spack#20023)
matz-e added a commit to BlueBrain/spack that referenced this pull request Mar 10, 2021
Should allow us to automatically check more modules and alleviate the
need to create some private checks in different Jenkins CIs.

Original commit message:

PythonPackage: add import module smoke tests (spack#20023)
matz-e added a commit to BlueBrain/spack that referenced this pull request Mar 15, 2021
Should allow us to automatically check more modules and alleviate the
need to create some private checks in different Jenkins CIs.

Original commit message:

PythonPackage: add import module smoke tests (spack#20023)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build-systems documentation Improvements or additions to documentation python stand-alone-tests Stand-alone (or smoke) tests for installed packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mesa with test dependencies fail to concretize

4 participants