Add remaining bugfixes and consistency changes from #18210 (#18334)

This commit is contained in:
Tamara Dahlgren
2020-08-27 16:21:59 -07:00
committed by Tamara Dahlgren
parent 86eececc5c
commit 61abc75bc6
8 changed files with 97 additions and 101 deletions

View File

@@ -5,25 +5,50 @@
import base64 import base64
import hashlib import hashlib
import os import os
import re
import shutil import shutil
import sys import sys
import llnl.util.filesystem as fs import llnl.util.filesystem as fs
from spack.spec import Spec
import spack.error import spack.error
import spack.util.prefix import spack.util.prefix
import spack.util.spack_json as sjson import spack.util.spack_json as sjson
def get_expected_output(filename):
"""Retrieve the expected output from the file
Args:
filename (str): path to the file
Returns:
(list of str): escaped text lines read from the file
"""
with open(filename, 'r') as f:
# Ensure special characters are escaped as needed
expected = f.read()
# Split the lines to make it easier to debug failures when there is
# a lot of output
return [re.escape(ln) for ln in expected.split('\n')]
def get_test_stage_dir(): def get_test_stage_dir():
return spack.util.path.canonicalize_path( return spack.util.path.canonicalize_path(
spack.config.get('config:test_stage', '~/.spack/test')) spack.config.get('config:test_stage', '~/.spack/test'))
def get_test_stage(name): def get_test_stage(name):
return spack.util.prefix.Prefix(os.path.join(get_test_stage_dir(), name)) return spack.util.prefix.Prefix(os.path.join(get_test_stage_dir(), name))
def get_results_file(name): def get_results_file(name):
return get_test_stage(name).join('results.txt') return get_test_stage(name).join('results.txt')
def get_test_by_name(name): def get_test_by_name(name):
test_suite_file = get_test_stage(name).join('specs.lock') test_suite_file = get_test_stage(name).join('specs.lock')
@@ -92,7 +117,7 @@ def __call__(self, *args, **kwargs):
# Create the test log file and report the error. # Create the test log file and report the error.
self.ensure_stage() self.ensure_stage()
msg = 'Testing package {0}\n{1}'\ msg = 'Testing package {0}\n{1}'\
.format(self.test_pkg_id(spec), str(err)) .format(self.test_pkg_id(spec), str(exc))
_add_msg_to_file(self.log_file_for_spec(spec), msg) _add_msg_to_file(self.log_file_for_spec(spec), msg)
self.write_test_result(spec, 'FAILED') self.write_test_result(spec, 'FAILED')

View File

@@ -3,11 +3,11 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import shutil import shutil
import sys import sys
import llnl.util.tty as tty import spack.install_test as sit
from spack import * from spack import *
@@ -388,31 +388,32 @@ def _test_check_versions(self):
] ]
use_short_opt = ['h52gif', 'h5repart', 'h5unjam'] use_short_opt = ['h52gif', 'h5repart', 'h5unjam']
for exe in exes: for exe in exes:
reason = 'test version of {0} is {1}'.format(exe, spec_vers_str) reason = 'test: ensuring version of {0} is {1}' \
.format(exe, spec_vers_str)
option = '-V' if exe in use_short_opt else '--version' option = '-V' if exe in use_short_opt else '--version'
self.run_test(exe, [option], spec_vers_str, installed=True, self.run_test(exe, option, spec_vers_str, installed=True,
purpose=reason, skip_missing=True) purpose=reason, skip_missing=True)
def _test_example(self): def _test_example(self):
"""This test performs copy, dump, and diff on an example hdf5 file.""" """This test performs copy, dump, and diff on an example hdf5 file."""
h5_file = os.path.join(self.test_dir, 'data', 'spack.h5') test_data_dir = self.test_suite.current_test_data_dir
reason = 'test: ensure h5dump produces expected output' filename = 'spack.h5'
dump_file = os.path.join(self.test_dir, 'data', 'dump.out') h5_file = test_data_dir.join(filename)
output = ''
with open(dump_file) as fd:
output == fd.read()
self.run_test('h5dump', [h5_file], output, installed=True,
purpose=reason, skip_missing=True, work_dir='.')
reason = 'test: ensure h5copy runs' reason = 'test: ensuring h5dump produces expected output'
expected = sit.get_expected_output(test_data_dir.join('dump.out'))
self.run_test('h5dump', filename, expected, installed=True,
purpose=reason, skip_missing=True,
work_dir=test_data_dir)
reason = 'test: ensuring h5copy runs'
options = ['-i', h5_file, '-s', 'Spack', '-o', 'test.h5', '-d', 'Spack'] options = ['-i', h5_file, '-s', 'Spack', '-o', 'test.h5', '-d', 'Spack']
self.run_test('h5copy', options, installed=True, self.run_test('h5copy', options, [], installed=True,
purpose=reason, skip_missing=True, work_dir='.') purpose=reason, skip_missing=True, work_dir='.')
reason = 'test: ensure h5diff shows no differences in orig and copy' reason = 'test: ensuring h5diff shows no differences between orig and copy'
options = [h5_file, 'test.h5'] self.run_test('h5diff', [h5_file, 'test.h5'], [], installed=True,
self.run_test('h5diff', options, installed=True,
purpose=reason, skip_missing=True, work_dir='.') purpose=reason, skip_missing=True, work_dir='.')
def test(self): def test(self):

View File

@@ -3,9 +3,10 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import llnl.util.tty as tty import llnl.util.tty as tty
import spack.install_test as sit
from spack import * from spack import *
@@ -38,7 +39,7 @@ def _run_smoke_tests(self):
"""Build and run the added smoke (install) test.""" """Build and run the added smoke (install) test."""
data_dir = self.test_suite.current_test_data_dir data_dir = self.test_suite.current_test_data_dir
prog = 'smoke_test' prog = 'smoke_test'
src = data_dir.join('%s.c' % prog) src = data_dir.join('{0}.c'.format(prog))
options = [ options = [
'-I{0}'.format(self.prefix.include), '-I{0}'.format(self.prefix.include),
@@ -48,18 +49,16 @@ def _run_smoke_tests(self):
'-L{0}'.format(self.prefix.lib), '-L{0}'.format(self.prefix.lib),
'-lsigsegv', '-lsigsegv',
'{0}{1}'.format(self.compiler.cc_rpath_arg, self.prefix.lib)] '{0}{1}'.format(self.compiler.cc_rpath_arg, self.prefix.lib)]
reason = 'test ability to link to the library' reason = 'test: checking ability to link to the library'
self.run_test('cc', options, [], installed=False, purpose=reason) self.run_test('cc', options, [], installed=False, purpose=reason)
# Now run the program and confirm the output matches expectations # Now run the program and confirm the output matches expectations
with open(data_dir.join('smoke_test.out'), 'r') as fd: expected = sit.get_expected_output(data_dir.join('smoke_test.out'))
expected = fd.read() reason = 'test: checking ability to use the library'
reason = 'test ability to use the library'
self.run_test(prog, [], expected, purpose=reason) self.run_test(prog, [], expected, purpose=reason)
def _run_build_tests(self): def _run_build_tests(self):
"""Build and run selected tests pulled from the build.""" """Run selected build tests."""
# Run the build tests to confirm the expected output
passed = 'Test passed' passed = 'Test passed'
checks = { checks = {
'sigsegv1': [passed], 'sigsegv1': [passed],
@@ -70,8 +69,9 @@ def _run_build_tests(self):
} }
for exe, expected in checks.items(): for exe, expected in checks.items():
reason = 'test {0} output'.format(exe) reason = 'test: checking {0} output'.format(exe)
self.run_test(exe, [], expected, purpose=reason, skip_missing=True) self.run_test(exe, [], expected, installed=True, purpose=reason,
skip_missing=True)
def test(self): def test(self):
"""Perform smoke tests on the installed package.""" """Perform smoke tests on the installed package."""

View File

@@ -5,10 +5,7 @@
import re import re
import os import spack.install_test as sit
import re
import llnl.util.tty as tty
class M4(AutotoolsPackage, GNUMirrorPackage): class M4(AutotoolsPackage, GNUMirrorPackage):
@@ -83,22 +80,14 @@ def configure_args(self):
return args return args
def test(self): def test(self):
m4 = which('m4') spec_vers = str(self.spec.version)
assert m4 is not None reason = 'test: ensuring m4 version is {0}'.format(spec_vers)
self.run_test('m4', '--version', spec_vers, installed=True,
purpose=reason, skip_missing=False)
tty.msg('test: Ensuring use of the installed executable') reason = 'test: ensuring m4 example succeeds'
m4_dir = os.path.dirname(m4.path) test_data_dir = self.test_suite.current_test_data_dir
assert m4_dir == self.prefix.bin hello_file = test_data_dir.join('hello.m4')
expected = sit.get_expected_output(test_data_dir.join('hello.out'))
tty.msg('test: Checking version') self.run_test('m4', hello_file, expected, installed=True,
output = m4('--version', output=str.split, error=str.split) purpose=reason, skip_missing=False)
version_regex = re.compile(r'm4(.+){0}'.format(self.spec.version))
assert version_regex.search(output)
tty.msg('test: Ensuring m4 runs')
data_dir = self.test_suite.current_test_data_dir
hello_file = data_dir.join('hello.m4')
output = m4(hello_file, output=str.split, error=str.split)
expected_file = data_dir.join('hello.out')
with open(expected_file) as fd:
assert output == fd.read()

View File

@@ -5,6 +5,7 @@
import os import os
class Mpi(Package): class Mpi(Package):
"""Virtual package for the Message Passing Interface.""" """Virtual package for the Message Passing Interface."""
homepage = 'https://www.mpi-forum.org/' homepage = 'https://www.mpi-forum.org/'
@@ -19,7 +20,7 @@ def test(self):
compiler = os.environ[compiler_var] compiler = os.environ[compiler_var]
exe_name = 'mpi_hello_%s' % lang exe_name = 'mpi_hello_%s' % lang
mpirun = os.path.join(self.prefix.bin, 'mpirun') mpirun = join_path(self.prefix.bin, 'mpirun')
compiled = self.run_test(compiler, compiled = self.run_test(compiler,
options=['-o', exe_name, filename]) options=['-o', exe_name, filename])

View File

@@ -750,14 +750,13 @@ def _test_bin_ops(self):
for exe in checks: for exe in checks:
options, expected, status = checks[exe] options, expected, status = checks[exe]
reason = 'test {0} output'.format(exe) reason = 'test: checking {0} output'.format(exe)
self.run_test(exe, options, expected, status, installed=True, self.run_test(exe, options, expected, status, installed=True,
purpose=reason, skip_missing=True) purpose=reason, skip_missing=True)
def _test_check_versions(self): def _test_check_versions(self):
comp_vers = str(self.spec.compiler.version) comp_vers = str(self.spec.compiler.version)
spec_vers = str(self.spec.version) spec_vers = str(self.spec.version)
bad_option = 'unknown option'
checks = { checks = {
# Binaries available in at least versions 2.0.0 through 4.0.3 # Binaries available in at least versions 2.0.0 through 4.0.3
'mpiCC': ([comp_vers], 0), 'mpiCC': ([comp_vers], 0),
@@ -769,15 +768,8 @@ def _test_check_versions(self):
'mpif90': ([comp_vers], 0), 'mpif90': ([comp_vers], 0),
'mpifort': ([comp_vers], 0), 'mpifort': ([comp_vers], 0),
'mpirun': ([spec_vers], 0), 'mpirun': ([spec_vers], 0),
'ompi-clean': ([bad_option], 213),
'ompi-server': ([bad_option], 1),
'ompi_info': ([spec_vers], 0), 'ompi_info': ([spec_vers], 0),
'opal_wrapper': (['Cannot open configuration file'], 243),
'orte-clean': ([bad_option], 213),
'orte-info': (['did not have enough parameters'], 1),
'orte-server': ([bad_option], 1),
'ortecc': ([comp_vers], 0), 'ortecc': ([comp_vers], 0),
'orted': ([bad_option], 213),
'orterun': ([spec_vers], 0), 'orterun': ([spec_vers], 0),
# Binaries available in versions 2.0.0 through 2.1.6 # Binaries available in versions 2.0.0 through 2.1.6
@@ -786,11 +778,7 @@ def _test_check_versions(self):
# Binaries available in versions 2.0.0 through 3.1.5 # Binaries available in versions 2.0.0 through 3.1.5
'ompi-dvm': ([spec_vers], 0), 'ompi-dvm': ([spec_vers], 0),
'ompi-ps': ([bad_option], 213),
'ompi-top': ([bad_option], 1),
'orte-dvm': ([spec_vers], 0), 'orte-dvm': ([spec_vers], 0),
'orte-ps': ([bad_option], 213),
'orte-top': ([bad_option], 1),
'oshcc': ([comp_vers], 0), 'oshcc': ([comp_vers], 0),
'oshfort': ([comp_vers], 0), 'oshfort': ([comp_vers], 0),
'oshmem_info': ([spec_vers], 0), 'oshmem_info': ([spec_vers], 0),
@@ -813,16 +801,17 @@ def _test_check_versions(self):
for exe in checks: for exe in checks:
expected, status = checks[exe] expected, status = checks[exe]
purpose = 'test version of {0} is {1}'.format(exe, expected[0]) purpose = 'test: ensuring version of {0} is {1}' \
.format(exe, expected[0])
self.run_test(exe, ['--version'], expected, status, installed=True, self.run_test(exe, ['--version'], expected, status, installed=True,
purpose=purpose, skip_missing=True) purpose=purpose, skip_missing=True)
def _test_examples(self): def _test_examples(self):
# First build the examples # First build the examples
work_dir = os.path.join(self.install_test_root,
self.extra_install_tests)
self.run_test('make', ['all'], [], self.run_test('make', ['all'], [],
purpose='test build the examples', work_dir=work_dir) purpose='test: ensuring ability to build the examples',
work_dir=join_path(self.install_test_root,
self.extra_install_tests))
# Now run those with known results # Now run those with known results
have_spml = self.spec.satisfies('@2.0.0:2.1.6') have_spml = self.spec.satisfies('@2.0.0:2.1.6')
@@ -864,10 +853,9 @@ def _test_examples(self):
for exe in checks: for exe in checks:
expected, status = checks[exe] expected, status = checks[exe]
reason = 'test {0} output'.format(exe) reason = 'test: checking example {0} output'.format(exe)
self.run_test(self.spec.prefix.bin.join(exe), self.run_test(exe, [], expected, status, installed=True,
[], expected, status, installed=True, purpose=reason, skip_missing=True)
purpose=reason, skip_missing=True, work_dir=work_dir)
def test(self): def test(self):
"""Perform smoke tests on the installed package.""" """Perform smoke tests on the installed package."""

View File

@@ -20,20 +20,22 @@ class Patchelf(AutotoolsPackage):
version('0.8', sha256='14af06a2da688d577d64ff8dac065bb8903bbffbe01d30c62df7af9bf4ce72fe') version('0.8', sha256='14af06a2da688d577d64ff8dac065bb8903bbffbe01d30c62df7af9bf4ce72fe')
def test(self): def test(self):
# Check patchelf in prefix and reports correct version # Check patchelf in prefix and reports the correct version
purpose_str = 'test patchelf is in prefix and reports correct version' reason = 'test: ensuring patchelf version is {0}' \
.format(self.spec.version)
self.run_test('patchelf', self.run_test('patchelf',
options=['--version'], options='--version',
expected=['patchelf %s' % self.spec.version], expected=['patchelf %s' % self.spec.version],
installed=True, installed=True,
purpose=purpose_str) purpose=reason)
# Check the rpath is changed # Check the rpath is changed
currdir = os.getcwd() currdir = os.getcwd()
hello_file = os.path.join(currdir, 'data', 'hello') hello_file = self.test_suite.current_test_data_dir.join('hello')
self.run_test('patchelf', ['--set-rpath', currdir, hello_file], self.run_test('patchelf', ['--set-rpath', currdir, hello_file],
purpose='test that patchelf can change rpath') purpose='test: ensuring that patchelf can change rpath')
self.run_test('patchelf', self.run_test('patchelf',
options=['--print-rpath', hello_file], options=['--print-rpath', hello_file],
expected=[currdir], expected=[currdir],
purpose='test that patchelf actually changed rpath') purpose='test: ensuring that patchelf changed rpath')

View File

@@ -3,21 +3,12 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import llnl.util.tty as tty import spack.install_test as sit
import re
from spack import * from spack import *
from spack import architecture from spack import architecture
def _read_file(filepath):
"""Read and clean up the expected output from the specified file."""
output = ''
with open(filepath, 'r') as fd:
output = fd.read()
return [re.escape(ln) for ln in output.split('\n')]
class Sqlite(AutotoolsPackage): class Sqlite(AutotoolsPackage):
"""SQLite3 is an SQL database engine in a C library. Programs that """SQLite3 is an SQL database engine in a C library. Programs that
link the SQLite3 library can have SQL database access without link the SQLite3 library can have SQL database access without
@@ -143,21 +134,23 @@ def build_libsqlitefunctions(self):
def _test_example(self): def _test_example(self):
"""Ensure a sequence of commands on example db are successful.""" """Ensure a sequence of commands on example db are successful."""
data_dir = self.test_suite.current_test_data_dir
test_data_dir = self.test_suite.current_test_data_dir
db_filename = test_data_dir.join('packages.db')
exe = 'sqlite3'
# Ensure the database only contains one table # Ensure the database only contains one table
reason = 'test to ensure only table is "packages"' expected = 'packages'
opts = [data_dir.join('packages.db'), '.tables'] reason = 'test: ensuring only table is "{0}"'.format(expected)
self.run_test('sqlite3', opts, 'packages', installed=True, self.run_test(exe, [db_filename, '.tables'], expected, installed=True,
purpose=reason, skip_missing=False) purpose=reason, skip_missing=False)
# Ensure the database dump matches expectations, where special # Ensure the database dump matches expectations, where special
# characters are replaced with spaces in the expected and actual # characters are replaced with spaces in the expected and actual
# output to avoid pattern errors. # output to avoid pattern errors.
reason = 'test dump output' reason = 'test: checking dump output'
opts = [data_dir.join('packages.db'), '.dump'] expected = sit.get_expected_output(test_data_dir.join('dump.out'))
expected = _read_file(data_dir.join('dump.out')) self.run_test(exe, [db_filename, '.dump'], expected, installed=True,
self.run_test('sqlite3', opts, expected, installed=True,
purpose=reason, skip_missing=False) purpose=reason, skip_missing=False)
def _test_version(self): def _test_version(self):
@@ -165,15 +158,12 @@ def _test_version(self):
exe = 'sqlite3' exe = 'sqlite3'
vers_str = str(self.spec.version) vers_str = str(self.spec.version)
reason = 'test version of {0} is {1}'.format(exe, vers_str) reason = 'test: ensuring version of {0} is {1}'.format(exe, vers_str)
self.run_test(exe, '-version', vers_str, installed=True, self.run_test(exe, '-version', vers_str, installed=True,
purpose=reason, skip_missing=False) purpose=reason, skip_missing=False)
def test(self): def test(self):
"""Perform smoke tests on the installed package.""" """Perform smoke tests on the installed package."""
tty.debug('Expected results currently based on simple {0} builds'
.format(self.name))
# Perform a simple version check # Perform a simple version check
self._test_version() self._test_version()