summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralalazo <massimiliano.culpo@googlemail.com>2016-07-02 12:14:30 +0200
committeralalazo <massimiliano.culpo@googlemail.com>2016-07-02 12:14:30 +0200
commit3100c5948a7278bd1429c316a1c78264b5fafcb3 (patch)
tree112618b7e5938be53dcea5864af241b84ae44be8
parentd10fceaacc7a1f8349f249c8700381f858b359b1 (diff)
downloadspack-3100c5948a7278bd1429c316a1c78264b5fafcb3.tar.gz
spack-3100c5948a7278bd1429c316a1c78264b5fafcb3.tar.bz2
spack-3100c5948a7278bd1429c316a1c78264b5fafcb3.tar.xz
spack-3100c5948a7278bd1429c316a1c78264b5fafcb3.zip
module : added unit tests
-rw-r--r--lib/spack/spack/cmd/module.py28
-rw-r--r--lib/spack/spack/test/__init__.py2
-rw-r--r--lib/spack/spack/test/cmd/module.py82
3 files changed, 101 insertions, 11 deletions
diff --git a/lib/spack/spack/cmd/module.py b/lib/spack/spack/cmd/module.py
index 2c47e9fcb6..374e71a4d8 100644
--- a/lib/spack/spack/cmd/module.py
+++ b/lib/spack/spack/cmd/module.py
@@ -32,12 +32,16 @@ import sys
import llnl.util.tty as tty
import spack.cmd
import spack.cmd.common.arguments as arguments
-from llnl.util.filesystem import mkdirp
+import llnl.util.filesystem as filesystem
from spack.modules import module_types
-#from spack.util.string import *
description = "Manipulate module files"
+# Dictionary that will be populated with the list of sub-commands
+# Each sub-command must be callable and accept 3 arguments :
+# - mtype : the type of the module file
+# - specs : the list of specs to be processed
+# - args : namespace containing the parsed command line arguments
callbacks = {}
@@ -51,6 +55,7 @@ def subcommand(subparser_name):
def setup_parser(subparser):
sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='subparser_name')
+
# spack module refresh
refresh_parser = sp.add_parser('refresh', help='Regenerate module files')
refresh_parser.add_argument('--delete-tree', help='Delete the module file tree before refresh', action='store_true')
@@ -71,11 +76,12 @@ def setup_parser(subparser):
)
loads_parser.add_argument(
'--input-only', action='store_false', dest='shell',
- help='Generate input for module command (instead of a shell script)')
-
+ help='Generate input for module command (instead of a shell script)'
+ )
loads_parser.add_argument(
'-p', '--prefix', dest='prefix', default='',
- help='Prepend to module names when issuing module load commands')
+ help='Prepend to module names when issuing module load commands'
+ )
arguments.add_common_arguments(loads_parser, ['constraint', 'module_type', 'recurse_dependencies'])
@@ -86,8 +92,10 @@ class MultipleMatches(Exception):
class NoMatch(Exception):
pass
+
@subcommand('loads')
def loads(mtype, specs, args):
+ """Prompt the list of modules associated with a list of specs"""
# Get a comprehensive list of specs
if args.recurse_dependencies:
specs_from_user_constraint = specs[:]
@@ -123,6 +131,7 @@ def loads(mtype, specs, args):
d['name'] = mod
print(prompt_template.format(**d))
+
@subcommand('find')
def find(mtype, specs, args):
"""
@@ -146,13 +155,14 @@ def find(mtype, specs, args):
@subcommand('rm')
def rm(mtype, specs, args):
+ """Deletes module files associated with items in specs"""
module_cls = module_types[mtype]
specs_with_modules = [spec for spec in specs if os.path.exists(module_cls(spec).file_name)]
modules = [module_cls(spec) for spec in specs_with_modules]
if not modules:
tty.msg('No module file matches your query')
- return
+ raise SystemExit(1)
# Ask for confirmation
if not args.yes_to_all:
@@ -168,9 +178,7 @@ def rm(mtype, specs, args):
@subcommand('refresh')
def refresh(mtype, specs, args):
- """Regenerate module files for installed packages
-
- """
+ """Regenerate module files for item in specs"""
# Prompt a message to the user about what is going to change
if not specs:
tty.msg('No package matches your query')
@@ -205,7 +213,7 @@ def refresh(mtype, specs, args):
tty.msg('Regenerating {name} module files'.format(name=mtype))
if os.path.isdir(cls.path) and args.delete_tree:
shutil.rmtree(cls.path, ignore_errors=False)
- mkdirp(cls.path)
+ filesystem.mkdirp(cls.path)
for x in writers:
x.write(overwrite=True)
diff --git a/lib/spack/spack/test/__init__.py b/lib/spack/spack/test/__init__.py
index fb91f24721..dfbd73b91f 100644
--- a/lib/spack/spack/test/__init__.py
+++ b/lib/spack/spack/test/__init__.py
@@ -40,7 +40,7 @@ test_names = ['architecture', 'versions', 'url_parse', 'url_substitution', 'pack
'cc', 'link_tree', 'spec_yaml', 'optional_deps',
'make_executable', 'configure_guess', 'lock', 'database',
'namespace_trie', 'yaml', 'sbang', 'environment', 'cmd.find',
- 'cmd.uninstall', 'cmd.test_install', 'cmd.test_compiler_cmd']
+ 'cmd.uninstall', 'cmd.test_install', 'cmd.test_compiler_cmd', 'cmd.module']
def list_tests():
diff --git a/lib/spack/spack/test/cmd/module.py b/lib/spack/spack/test/cmd/module.py
new file mode 100644
index 0000000000..52628f5b3b
--- /dev/null
+++ b/lib/spack/spack/test/cmd/module.py
@@ -0,0 +1,82 @@
+##############################################################################
+# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+import argparse
+import os.path
+
+import spack.cmd.module as module
+import spack.modules as modules
+import spack.test.mock_database
+
+
+class TestModule(spack.test.mock_database.MockDatabase):
+ def _get_module_files(self, args):
+ return [
+ modules.module_types[args.module_type](spec).file_name for spec in args.specs
+ ]
+
+ def test_module_common_operations(self):
+ parser = argparse.ArgumentParser()
+ module.setup_parser(parser)
+ # Try to remove a non existing module [tcl]
+ args = parser.parse_args(['rm', 'doesnotexist'])
+ self.assertRaises(SystemExit, module.module, parser, args)
+ # Remove existing modules [tcl]
+ args = parser.parse_args(['rm', '-y', 'mpileaks'])
+ module_files = self._get_module_files(args)
+ for item in module_files:
+ self.assertTrue(os.path.exists(item))
+ module.module(parser, args)
+ for item in module_files:
+ self.assertFalse(os.path.exists(item))
+ # Add them back [tcl]
+ args = parser.parse_args(['refresh', '-y', 'mpileaks'])
+ module.module(parser, args)
+ for item in module_files:
+ self.assertTrue(os.path.exists(item))
+ # TODO : test the --delete-tree option
+ # TODO : this requires having a separate directory for test modules
+ # Try to find a module with multiple matches
+ args = parser.parse_args(['find', 'mpileaks'])
+ self.assertRaises(SystemExit, module.module, parser, args)
+ # Try to find a module with no matches
+ args = parser.parse_args(['find', 'doesnotexist'])
+ self.assertRaises(SystemExit, module.module, parser, args)
+ # Try to find a module
+ args = parser.parse_args(['find', 'libelf'])
+ module.module(parser, args)
+ # Remove existing modules [dotkit]
+ args = parser.parse_args(['rm', '-y', '-m', 'dotkit', 'mpileaks'])
+ module_files = self._get_module_files(args)
+ for item in module_files:
+ self.assertTrue(os.path.exists(item))
+ module.module(parser, args)
+ for item in module_files:
+ self.assertFalse(os.path.exists(item))
+ # Add them back [dotkit]
+ args = parser.parse_args(['refresh', '-y', '-m', 'dotkit', 'mpileaks'])
+ module.module(parser, args)
+ for item in module_files:
+ self.assertTrue(os.path.exists(item))
+ # TODO : add tests for loads and find to check the prompt format