Commit 0838e2611f7cca4896c3c6062c06eeca2cd1d812
1 parent
4c6494dd
Add unit test for csinfo (#1828)
Showing
4 changed files
with
277 additions
and
58 deletions
cscripts/csinfo.py
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # ========================================================================== |
| 3 | 3 | # Print info about Gammalib / ctools to the console. |
| 4 | 4 | # |
| 5 | -# Copyright (C) 2015 Christoph Deil | |
| 5 | +# Copyright (C) 2015-2016 Christoph Deil | |
| 6 | 6 | # |
| 7 | 7 | # This program is free software: you can redistribute it and/or modify |
| 8 | 8 | # it under the terms of the GNU General Public License as published by |
| ... | ... | @@ -21,27 +21,18 @@ |
| 21 | 21 | import sys |
| 22 | 22 | import os |
| 23 | 23 | |
| 24 | - | |
| 25 | -def get_command_output(cmd): | |
| 26 | - """Utility function to get command output on old and new Python versions. | |
| 27 | - """ | |
| 28 | - try: | |
| 29 | - from subprocess import getoutput | |
| 30 | - except ImportError: | |
| 31 | - from commands import getoutput | |
| 32 | - | |
| 33 | - return getoutput(cmd) | |
| 34 | - | |
| 35 | - | |
| 36 | -# Copied and edited a bit from the `doc/source/reference_manual/index.rst` file | |
| 37 | -# The list there and here needs to be manually updated and kept in sync. | |
| 24 | +# Copied and edited a bit from the `doc/source/users/reference_manual/index.rst` | |
| 25 | +# file. The list there and here needs to be manually updated and kept in sync. | |
| 38 | 26 | CTOOL_LIST = """ |
| 39 | 27 | ctbin Generates counts cube |
| 40 | 28 | ctbkgcube Generates background cube |
| 41 | 29 | ctbutterfly Compute butterfly |
| 42 | 30 | ctcubemask Filter counts cube |
| 31 | + ctedispcube Generates energy dispersion cube | |
| 32 | + cterror Calculates likelihood profile errors | |
| 43 | 33 | ctexpcube Generates exposure cube |
| 44 | 34 | ctlike Performs maximum likelihood fitting |
| 35 | + ctmapcube Generates a map cube | |
| 45 | 36 | ctmodel Computes model counts cube |
| 46 | 37 | ctobssim Simulate CTA observations |
| 47 | 38 | ctpsfcube Generates point spread function cube |
| ... | ... | @@ -49,47 +40,112 @@ CTOOL_LIST = """ |
| 49 | 40 | ctskymap Generates sky map |
| 50 | 41 | cttsmap Generates Test Statistics map |
| 51 | 42 | ctulimit Calculates upper limit |
| 52 | - cterror Calculates likelihood profile errors | |
| 53 | 43 | """ |
| 54 | 44 | CSCRIPT_LIST = """ |
| 55 | 45 | cscaldb Lists available instrument response functions |
| 46 | + cslightcrv Computes lightcurve | |
| 56 | 47 | csinfo Checks ctools and GammaLib installations |
| 48 | + csmodelinfo Shows model container content | |
| 49 | + csmodelmerge Merges several model containers into one file | |
| 57 | 50 | csobsdef Generates observation definition file |
| 58 | - cslightcrv Computes lightcurve | |
| 51 | + csobsinfo Shows observation container content | |
| 59 | 52 | cspull Generates pull distribution |
| 53 | + csresmap Generates residual map | |
| 60 | 54 | cssens Computes CTA sensitivity |
| 61 | 55 | csspec Computes spectral points |
| 62 | - csresmap Generates residual map | |
| 63 | 56 | cstsdist Generates TS distribution |
| 57 | + cstsmapsplit Creates commands to split the Test Statistic map computations | |
| 58 | + cstsmapmerge Merges slices from Test Statistic map computations\n | |
| 59 | + csobs2caldb Creates a caldb entry from an input observation | |
| 60 | + csiactdata Shows information about IACT data available on the user machine | |
| 61 | + csiactobs Generates observation definition file for IACT data from observation IDs | |
| 62 | + csfindobs Generates a list of IACT observation IDs | |
| 63 | + csiactcopy Copies IACT data from one location to another | |
| 64 | 64 | """ |
| 65 | 65 | |
| 66 | + | |
| 67 | +# ============================================================ # | |
| 68 | +# Workaround for command output on old and new Python versions # | |
| 69 | +# ============================================================ # | |
| 70 | +def get_command_output(cmd): | |
| 71 | + """ | |
| 72 | + Utility function to get command output on old and new Python versions | |
| 73 | + | |
| 74 | + Parameters | |
| 75 | + ---------- | |
| 76 | + cmd : str | |
| 77 | + Command string | |
| 78 | + | |
| 79 | + Returns | |
| 80 | + ------- | |
| 81 | + output : str | |
| 82 | + Command output | |
| 83 | + """ | |
| 84 | + # Try to import getoutput from subprocess, alternatively get it from | |
| 85 | + # commands | |
| 86 | + try: | |
| 87 | + from subprocess import getoutput | |
| 88 | + except ImportError: | |
| 89 | + from commands import getoutput | |
| 90 | + | |
| 91 | + # Return command output | |
| 92 | + return getoutput(cmd) | |
| 93 | + | |
| 94 | + | |
| 95 | +# ===================================== # | |
| 96 | +# Workaround for print without linefeed # | |
| 97 | +# ===================================== # | |
| 66 | 98 | def log(text, end='\n'): |
| 67 | - """Print text to console. | |
| 99 | + """ | |
| 100 | + Print text to console | |
| 68 | 101 | |
| 69 | 102 | Workaround to have an `end=''` option on old Pythons: |
| 70 | 103 | http://stackoverflow.com/a/493399/498873 |
| 71 | 104 | """ |
| 105 | + # Print without linefeed | |
| 72 | 106 | sys.stdout.write(text + end) |
| 73 | 107 | |
| 108 | + # Return | |
| 109 | + return | |
| 74 | 110 | |
| 111 | + | |
| 112 | +# ====================== # | |
| 113 | +# Print list information # | |
| 114 | +# ====================== # | |
| 75 | 115 | def csinfo_list_tools(): |
| 76 | - """Print available ctools with one-line description to the console. | |
| 77 | 116 | """ |
| 117 | + Print available ctools with one-line description to the console | |
| 118 | + """ | |
| 119 | + # Print list of available ctools | |
| 78 | 120 | print('\nAvailable ctools:') |
| 79 | 121 | print(CTOOL_LIST) |
| 122 | + | |
| 123 | + # Print list of available cscripts | |
| 80 | 124 | print('Available cscripts:') |
| 81 | 125 | print(CSCRIPT_LIST) |
| 82 | 126 | |
| 127 | + # Return | |
| 128 | + return | |
| 83 | 129 | |
| 84 | -def csinfo_setup_check(): | |
| 85 | - print('\nGammalib / ctools setup check:\n') | |
| 86 | 130 | |
| 131 | +# ======================= # | |
| 132 | +# Print check information # | |
| 133 | +# ======================= # | |
| 134 | +def csinfo_setup_check(): | |
| 135 | + """ | |
| 136 | + Print check information | |
| 137 | + """ | |
| 138 | + # Initialise success flags | |
| 87 | 139 | all_ok = True |
| 88 | 140 | gammalib_environ = False |
| 89 | 141 | ctools_environ = False |
| 90 | 142 | gammalib_python = False |
| 91 | 143 | ctools_python = False |
| 92 | 144 | |
| 145 | + # Print header | |
| 146 | + print('\nGammalib / ctools setup check:\n') | |
| 147 | + | |
| 148 | + # Check if GAMMALIB is set | |
| 93 | 149 | log(' GAMMALIB environment variable ... ', end='') |
| 94 | 150 | try: |
| 95 | 151 | gammalib_env = os.environ['GAMMALIB'] |
| ... | ... | @@ -99,6 +155,7 @@ def csinfo_setup_check(): |
| 99 | 155 | all_ok = False |
| 100 | 156 | gammalib_environ = True |
| 101 | 157 | |
| 158 | + # Check if CTOOLS is set | |
| 102 | 159 | log(' CTOOLS environment variable ... ', end='') |
| 103 | 160 | try: |
| 104 | 161 | ctools_env = os.environ['CTOOLS'] |
| ... | ... | @@ -108,6 +165,7 @@ def csinfo_setup_check(): |
| 108 | 165 | all_ok = False |
| 109 | 166 | ctools_environ = True |
| 110 | 167 | |
| 168 | + # Check if gammalib Python module import works | |
| 111 | 169 | log(' gammalib Python import .......... ', end='') |
| 112 | 170 | try: |
| 113 | 171 | import gammalib |
| ... | ... | @@ -117,6 +175,7 @@ def csinfo_setup_check(): |
| 117 | 175 | all_ok = False |
| 118 | 176 | gammalib_python = True |
| 119 | 177 | |
| 178 | + # Check if ctools Python module import works | |
| 120 | 179 | log(' ctools Python import .......... ', end='') |
| 121 | 180 | try: |
| 122 | 181 | import ctools |
| ... | ... | @@ -126,6 +185,8 @@ def csinfo_setup_check(): |
| 126 | 185 | all_ok = False |
| 127 | 186 | ctools_python = True |
| 128 | 187 | |
| 188 | + # Signal if everything is okay, or notify about the problems that have | |
| 189 | + # been encountered | |
| 129 | 190 | if all_ok: |
| 130 | 191 | print('\n ===> Your Gammalib / ctools setup is OK.') |
| 131 | 192 | else: |
| ... | ... | @@ -138,64 +199,107 @@ def csinfo_setup_check(): |
| 138 | 199 | print(' - Did you source gammalib-init.sh?') |
| 139 | 200 | print(' - Did you source ctools-init.sh ?') |
| 140 | 201 | print(' - Are you using the correct Python ?') |
| 141 | - | |
| 142 | 202 | print('') |
| 143 | - print(' Gammalib: http://cta.irap.omp.eu/gammalib-devel/') | |
| 144 | - print(' ctools: http://cta.irap.omp.eu/ctools-devel/') | |
| 145 | - | |
| 203 | + print(' Gammalib: http://cta.irap.omp.eu/gammalib/') | |
| 204 | + print(' ctools: http://cta.irap.omp.eu/ctools/') | |
| 146 | 205 | print('') |
| 147 | 206 | |
| 207 | + # Return | |
| 208 | + return | |
| 148 | 209 | |
| 149 | -def csinfo_setup_info(): | |
| 150 | - print('\nGammalib / ctools setup info:\n') | |
| 151 | - | |
| 152 | - gammalib_version = 'TODO' # a function needs to be added to the library to get the version | |
| 153 | - print(' Gammalib version ................. {0}'.format(gammalib_version)) | |
| 154 | - | |
| 155 | - ctools_version = 'TODO' # a function needs to be added to the library to get the version | |
| 156 | - print(' ctools version ................. {0}'.format(ctools_version)) | |
| 157 | - | |
| 158 | - gammalib_env = os.environ.get('GAMMALIB', 'Not found') | |
| 159 | - print(' $GAMMALIB environment variable ... {0}'.format(gammalib_env)) | |
| 160 | 210 | |
| 161 | - ctools_env = os.environ.get('CTOOLS', 'Not found') | |
| 162 | - print(' $CTOOLS environment variable ... {0}'.format(ctools_env)) | |
| 163 | - | |
| 164 | - print(' Python executable ................ {0}'.format(sys.executable)) | |
| 165 | - | |
| 166 | - log(' gammalib Python package ......... ', end='') | |
| 211 | +# ======================= # | |
| 212 | +# Print setup information # | |
| 213 | +# ======================= # | |
| 214 | +def csinfo_setup_info(): | |
| 215 | + """ | |
| 216 | + Print setup information | |
| 217 | + """ | |
| 218 | + # Try importing GammaLib, and flag if this was unsuccessful | |
| 167 | 219 | try: |
| 168 | 220 | import gammalib |
| 169 | - print(gammalib.__path__[0]) | |
| 221 | + gammalib_path = gammalib.__path__[0] | |
| 222 | + gammalib_version = gammalib.__version__ | |
| 170 | 223 | except ImportError: |
| 171 | - print('Not found') | |
| 224 | + gammalib_path = 'Not found' | |
| 225 | + gammalib_version = 'Unknown' | |
| 172 | 226 | |
| 173 | - log(' ctools Python package ........ ', end='') | |
| 227 | + # Try importing ctools, and flag if this was unsuccessful | |
| 174 | 228 | try: |
| 175 | 229 | import ctools |
| 176 | - print(ctools.__path__[0]) | |
| 230 | + ctools_path = ctools.__path__[0] | |
| 231 | + ctools_version = ctools.__version__ | |
| 177 | 232 | except ImportError: |
| 178 | - print('Not found') | |
| 233 | + ctools_path = 'Not found' | |
| 234 | + ctools_version = 'Unknown' | |
| 235 | + | |
| 236 | + # Get GAMMALIB and CTOOLS environment variables | |
| 237 | + gammalib_env = os.environ.get('GAMMALIB', 'Not found') | |
| 238 | + ctools_env = os.environ.get('CTOOLS', 'Not found') | |
| 239 | + | |
| 240 | + # Print header | |
| 241 | + print('\nGammalib / ctools setup info:\n') | |
| 179 | 242 | |
| 243 | + # Print package versions | |
| 244 | + print(' Gammalib version ................. {0}'.format(gammalib_version)) | |
| 245 | + print(' ctools version ................. {0}'.format(ctools_version)) | |
| 246 | + print(' $GAMMALIB environment variable ... {0}'.format(gammalib_env)) | |
| 247 | + print(' $CTOOLS environment variable ... {0}'.format(ctools_env)) | |
| 248 | + print(' Python executable ................ {0}'.format(sys.executable)) | |
| 249 | + print(' gammalib Python package ......... {0}'.format(gammalib_path)) | |
| 250 | + print(' ctools Python package ........ {0}'.format(ctools_path)) | |
| 180 | 251 | print(' GAMMALIB CFLAGS ................. {0}'.format(get_pkg_config_info('cflags', 'gammalib'))) |
| 181 | 252 | print(' CTOOLS CFLAGS ................. {0}'.format(get_pkg_config_info('cflags', 'ctools'))) |
| 182 | - | |
| 183 | 253 | print(' GAMMALIB LIBS ................. {0}'.format(get_pkg_config_info('libs', 'gammalib'))) |
| 184 | 254 | print(' CTOOLS LIBS ................. {0}'.format(get_pkg_config_info('libs', 'ctools'))) |
| 185 | - | |
| 186 | 255 | print('') |
| 187 | 256 | |
| 257 | + # Return | |
| 258 | + return | |
| 259 | + | |
| 188 | 260 | |
| 261 | +# =============================== # | |
| 262 | +# Get information from pkg-config # | |
| 263 | +# =============================== # | |
| 189 | 264 | def get_pkg_config_info(info, library): |
| 265 | + """ | |
| 266 | + Get information from pkg-config | |
| 267 | + | |
| 268 | + Parameters | |
| 269 | + ---------- | |
| 270 | + info : str | |
| 271 | + Information to extract | |
| 272 | + library : str | |
| 273 | + Library name for which information is to be extracted | |
| 274 | + | |
| 275 | + Returns | |
| 276 | + ------- | |
| 277 | + out : str | |
| 278 | + Information string, 'Not available' if pkg-config is not installed | |
| 279 | + """ | |
| 280 | + # Set pkg-config command | |
| 190 | 281 | cmd = 'pkg-config --{0} {1}'.format(info, library) |
| 282 | + | |
| 283 | + # Execute command | |
| 191 | 284 | out = get_command_output(cmd) |
| 192 | - if 'was not found' in out: | |
| 193 | - return 'Not available' | |
| 194 | - else: | |
| 195 | - return out | |
| 196 | 285 | |
| 286 | + # If the command returns 'was not found' then pkg-config is not | |
| 287 | + # avaailable | |
| 288 | + if 'not found' in out: | |
| 289 | + out = 'Not available' | |
| 290 | + | |
| 291 | + # Return output | |
| 292 | + return out | |
| 197 | 293 | |
| 294 | + | |
| 295 | +# ============================ # | |
| 296 | +# Print help text into console # | |
| 297 | +# ============================ # | |
| 198 | 298 | def csinfo_print_help(): |
| 299 | + """ | |
| 300 | + Print help text into console | |
| 301 | + """ | |
| 302 | + # Print help text | |
| 199 | 303 | print('\nPrint info about Gammalib and ctools to the console.\n') |
| 200 | 304 | print('Available commands:') |
| 201 | 305 | print(' csinfo list List available ctools and cscripts') |
| ... | ... | @@ -203,14 +307,24 @@ def csinfo_print_help(): |
| 203 | 307 | print(' csinfo info Print Gammalib / ctools setup info') |
| 204 | 308 | print('') |
| 205 | 309 | |
| 310 | + # Return | |
| 311 | + return | |
| 312 | + | |
| 206 | 313 | |
| 314 | +# ============================ # | |
| 315 | +# Print information to console # | |
| 316 | +# ============================ # | |
| 207 | 317 | def csinfo(argv): |
| 208 | - """Print info about Gammalib / ctools to the console. | |
| 209 | 318 | """ |
| 319 | + Print information about Gammalib and ctools to the console | |
| 320 | + """ | |
| 321 | + # If there are no command line arguments then print help and exit | |
| 322 | + # with success | |
| 210 | 323 | if len(argv) <= 1: |
| 211 | 324 | csinfo_print_help() |
| 212 | 325 | sys.exit(0) |
| 213 | 326 | |
| 327 | + # Dispatch according to the command line argument | |
| 214 | 328 | cmd = argv[1] |
| 215 | 329 | if cmd == 'list': |
| 216 | 330 | csinfo_list_tools() |
| ... | ... | @@ -223,6 +337,14 @@ def csinfo(argv): |
| 223 | 337 | csinfo_print_help() |
| 224 | 338 | sys.exit(-1) |
| 225 | 339 | |
| 340 | + # Return | |
| 341 | + return | |
| 226 | 342 | |
| 343 | + | |
| 344 | +# ======================== # | |
| 345 | +# Main routine entry point # | |
| 346 | +# ======================== # | |
| 227 | 347 | if __name__ == '__main__': |
| 348 | + | |
| 349 | + # Run the script | |
| 228 | 350 | csinfo(sys.argv) | ... | ... |
test/test_cscaldb.py
test/test_csinfo.py
0 → 100755
| 1 | +#! /usr/bin/env python | |
| 2 | +# ========================================================================== | |
| 3 | +# This scripts performs unit tests for the csinfo script. | |
| 4 | +# | |
| 5 | +# Copyright (C) 2016 Juergen Knoedlseder | |
| 6 | +# | |
| 7 | +# This program is free software: you can redistribute it and/or modify | |
| 8 | +# it under the terms of the GNU General Public License as published by | |
| 9 | +# the Free Software Foundation, either version 3 of the License, or | |
| 10 | +# (at your option) any later version. | |
| 11 | +# | |
| 12 | +# This program is distributed in the hope that it will be useful, | |
| 13 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | +# GNU General Public License for more details. | |
| 16 | +# | |
| 17 | +# You should have received a copy of the GNU General Public License | |
| 18 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 19 | +# | |
| 20 | +# ========================================================================== | |
| 21 | +import gammalib | |
| 22 | +import cscripts | |
| 23 | +from testing import test | |
| 24 | + | |
| 25 | + | |
| 26 | +# ============================ # | |
| 27 | +# Test class for csinfo script # | |
| 28 | +# ============================ # | |
| 29 | +class Test(test): | |
| 30 | + """ | |
| 31 | + Test class for csinfo script | |
| 32 | + """ | |
| 33 | + | |
| 34 | + # Constructor | |
| 35 | + def __init__(self): | |
| 36 | + """ | |
| 37 | + Constructor. | |
| 38 | + """ | |
| 39 | + # Call base class constructor | |
| 40 | + test.__init__(self) | |
| 41 | + | |
| 42 | + # Return | |
| 43 | + return | |
| 44 | + | |
| 45 | + # Set test functions | |
| 46 | + def set(self): | |
| 47 | + """ | |
| 48 | + Set all test functions. | |
| 49 | + """ | |
| 50 | + # Set test name | |
| 51 | + self.name('csinfo') | |
| 52 | + | |
| 53 | + # Append tests | |
| 54 | + self.append(self._test_cmd, 'Test csinfo on command line') | |
| 55 | + | |
| 56 | + # Return | |
| 57 | + return | |
| 58 | + | |
| 59 | + # Test csinfo on command line | |
| 60 | + def _test_cmd(self): | |
| 61 | + """ | |
| 62 | + Test csinfo on the command line. | |
| 63 | + """ | |
| 64 | + # Set script name | |
| 65 | + csinfo = self._script('csinfo') | |
| 66 | + | |
| 67 | + # Setup csinfo command | |
| 68 | + cmd = csinfo | |
| 69 | + | |
| 70 | + # Check if execution of wrong command fails | |
| 71 | + self.test_assert(self._execute('command_that_does_not_exist') != 0, | |
| 72 | + 'Self test of test script') | |
| 73 | + | |
| 74 | + # Execute script without arguments | |
| 75 | + self.test_assert(self._execute(cmd) == 0, | |
| 76 | + 'Check successful execution from command line') | |
| 77 | + | |
| 78 | + # Execute script with "list" argument | |
| 79 | + self.test_assert(self._execute(cmd+' list') == 0, | |
| 80 | + 'Check successful execution with "list" argument from command line') | |
| 81 | + | |
| 82 | + # Execute script with "check" argument | |
| 83 | + self.test_assert(self._execute(cmd+' check') == 0, | |
| 84 | + 'Check successful execution with "check" argument from command line') | |
| 85 | + | |
| 86 | + # Execute script with "info" argument | |
| 87 | + self.test_assert(self._execute(cmd+' info') == 0, | |
| 88 | + 'Check successful execution with "info" argument from command line') | |
| 89 | + | |
| 90 | + # Execute script with invalid argument | |
| 91 | + self.test_assert(self._execute(cmd+' not_a_valid_argument') != 0, | |
| 92 | + 'Check unsuccessful execution with unsupported argument from ' | |
| 93 | + 'command line') | |
| 94 | + | |
| 95 | + # Return | |
| 96 | + return | ... | ... |
test/test_python_cscripts.py
| ... | ... | @@ -25,6 +25,7 @@ import cscripts |
| 25 | 25 | sys.path.append(os.path.dirname(os.path.abspath(__file__))) |
| 26 | 26 | import test_cscaldb |
| 27 | 27 | import test_csfindobs |
| 28 | +import test_csinfo | |
| 28 | 29 | import test_cslightcrv |
| 29 | 30 | import test_csmodelinfo |
| 30 | 31 | import test_csmodelmerge |
| ... | ... | @@ -105,6 +106,7 @@ def test(installed=False, debug=False): |
| 105 | 106 | |
| 106 | 107 | # Allocate test suites |
| 107 | 108 | suite_cscaldb = test_cscaldb.Test() |
| 109 | + suite_csinfo = test_csinfo.Test() | |
| 108 | 110 | suite_cslightcrv = test_cslightcrv.Test() |
| 109 | 111 | suite_csmodelinfo = test_csmodelinfo.Test() |
| 110 | 112 | suite_csmodelmerge = test_csmodelmerge.Test() |
| ... | ... | @@ -123,6 +125,7 @@ def test(installed=False, debug=False): |
| 123 | 125 | |
| 124 | 126 | # Setup unit tests |
| 125 | 127 | suite_cscaldb.set() |
| 128 | + suite_csinfo.set() | |
| 126 | 129 | suite_cslightcrv.set() |
| 127 | 130 | suite_csmodelinfo.set() |
| 128 | 131 | suite_csmodelmerge.set() |
| ... | ... | @@ -141,6 +144,7 @@ def test(installed=False, debug=False): |
| 141 | 144 | |
| 142 | 145 | # Append tests to container |
| 143 | 146 | suites.append(suite_cscaldb) |
| 147 | + suites.append(suite_csinfo) | |
| 144 | 148 | suites.append(suite_cslightcrv) |
| 145 | 149 | suites.append(suite_csmodelinfo) |
| 146 | 150 | suites.append(suite_csmodelmerge) | ... | ... |