Changeset 96e1533 in flex_extract.git for source/pythontest


Ignore:
Timestamp:
Nov 10, 2018, 9:37:36 PM (5 years ago)
Author:
Anne Philipp <anne.philipp@…>
Branches:
master, ctbto, dev
Children:
1abf820
Parents:
8500ba1
Message:

redefined test data dir and completed unittests for tools module

Location:
source/pythontest
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • source/pythontest/TestTools.py

    r25b14be r96e1533  
    1 #!/usr/bin/env python
     1#!/opt/anaconda/bin/python
    22# -*- coding: utf-8 -*-
     3
     4# for the gateway tests, the env vars of ECUID and ECGID have to be set upfront
    35
    46import os
    57import sys
     8import errno
     9from exceptions import OSError
    610import subprocess
    711import pipes
    812import pytest
    9 
    10 sys.path.append('../python')
     13from mock import patch, call
     14#from mock import PropertyMock
     15
     16
    1117import _config
    12 from mods.tools import (get_cmdline_arguments, read_ecenv, clean_up, my_error,
    13                         normal_exit, product, silent_remove, init128,
    14                         to_param_id, get_list_as_string, make_dir,
     18import _config_test
     19from classes.ControlFile import ControlFile
     20from mods.tools import (none_or_str, none_or_int, get_cmdline_arguments,
     21                        read_ecenv, clean_up, my_error, send_mail,
     22                        normal_exit, product, silent_remove,
     23                        init128, to_param_id, get_list_as_string, make_dir,
    1524                        put_file_to_ecserver, submit_job_to_ecserver)
    1625
    17 
    18 class TestTools():
     26class TestTools(object):
    1927    '''
    2028    '''
    2129
    22     def test_get_cmdline_arguments(self):
     30    def setup_method(self):
     31        self.testdir = _config_test.PATH_TEST_DIR
     32        self.testfilesdir = _config_test.PATH_TESTFILES_DIR
     33        self.c = ControlFile(self.testdir+'/Controls/CONTROL.test')
     34
     35    def test_nonestr_none_or_int(self):
     36        assert None == none_or_int('None')
     37
     38    def test_intstr_none_or_int(self):
     39        assert 42 == none_or_int('42')
     40
     41    def test_nonestr_none_or_str(self):
     42        assert None == none_or_str('None')
     43
     44    def test_anystr_none_or_str(self):
     45        assert 'test' == none_or_str('test')
     46
     47    def test_default_get_cmdline_arguments(self):
     48        cmd_dict_control = {'start_date':None,
     49                            'end_date':None,
     50                            'date_chunk':None,
     51                            'basetime':None,
     52                            'step':None,
     53                            'levelist':None,
     54                            'area':None,
     55                            'inputdir':None,
     56                            'outputdir':None,
     57                            'flexpart_root_scripts':None,
     58                            'ppid':None,
     59                            'job_template':'job.temp',
     60                            'queue':None,
     61                            'controlfile':'CONTROL.temp',
     62                            'debug':None,
     63                            'public':None,
     64                            'request':None}
     65
     66        sys.argv = ['dummy.py']
     67
     68        results = get_cmdline_arguments()
     69
     70        assert cmd_dict_control == vars(results)
     71
     72
     73    def test_input_get_cmdline_arguments(self):
    2374        cmd_dict_control = {'start_date':'20180101',
    2475                            'end_date':'20180101',
    25                             'date_chunk':'3',
    26                             'basetime':'12',
     76                            'date_chunk':3,
     77                            'basetime':12,
    2778                            'step':'1',
    2879                            'levelist':'1/to/10',
    2980                            'area':'50/10/60/20',
    3081                            'inputdir':'../work',
    31                             'outputdir':'../work',
     82                            'outputdir':None,
    3283                            'flexpart_root_scripts':'../',
    33                             'ppid':'1234',
     84                            'ppid':1234,
    3485                            'job_template':'job.sh',
    3586                            'queue':'ecgate',
    3687                            'controlfile':'CONTROL.WORK',
    37                             'debug':'1',
    38                             'request':'0'}
     88                            'debug':1,
     89                            'public':None,
     90                            'request':0}
    3991
    4092        sys.argv = ['dummy.py',
     
    4799                    '--area=50/10/60/20',
    48100                    '--inputdir=../work',
    49                     '--outputdir=../work',
     101                    '--outputdir=None',
    50102                    '--flexpart_root_scripts=../',
    51103                    '--ppid=1234',
     
    54106                    '--controlfile=CONTROL.WORK',
    55107                    '--debug=1',
     108                    '--public=None',
    56109                    '--request=0']
    57110
     
    60113        assert cmd_dict_control == vars(results)
    61114
    62     def test_init128(self):
     115    def test_success_init128(self):
    63116        table128 = init128(_config.PATH_GRIBTABLE)
    64         expected = {'078': 'TCLW', '130': 'T', '034': 'SST'}
     117        expected_sample = {'078': 'TCLW', '130': 'T', '034': 'SST'}
    65118        # check a sample of parameters which must have been read in
    66         result = all((k in table128 and table128[k]==v) for k,v in expected.iteritems())
    67         assert result == True
    68 
    69     def test_to_param_id(self):
     119        assert all((k in table128 and table128[k]==v)
     120                   for k,v in expected_sample.iteritems())
     121
     122    @patch('__builtin__.open', side_effect=[OSError(errno.EEXIST)])
     123    def test_fail_open_init128(self, mock_openfile):
     124        with pytest.raises(SystemExit):
     125            table128 = init128(_config.PATH_GRIBTABLE)
     126
     127    @pytest.mark.parametrize(
     128        'ipar_str, opar_listint',
     129        [('SP/LSP/SSHF', [134, 142, 146]),
     130         ('T', [130]),
     131         ('', []),
     132         (None, []),
     133         ('testtest', []),
     134         ('130/142', [130, 142]),
     135         (130, [130]),
     136         (50.56, [])])
     137    def test_to_param_id(self, ipar_str, opar_listint):
    70138        table128 = init128(_config.PATH_GRIBTABLE)
    71         pars = to_param_id("T/SP/LSP/SSHF", table128)
    72         for par in pars:
    73             assert par in [130, 134, 142, 146]
    74 
    75     def test_my_error(self):
    76         with pytest.raises(SystemExit) as pytest_wrapped_e:
    77             my_error(['${USER}', 'anne.philipp@univie.ac.at'], 'Failed!')
    78         assert pytest_wrapped_e.type == SystemExit
    79         assert pytest_wrapped_e.value.code == 1
    80 
    81     def test_read_ecenv(self):
    82         envs_ref = {'ECUID': 'km4a',
    83                     'ECGID': 'at',
    84                     'GATEWAY': 'srvx8.img.univie.ac.at',
    85                     'DESTINATION': 'annep@genericSftp'
     139        ipars = to_param_id(ipar_str, table128)
     140        assert sorted(ipars) == sorted(opar_listint)
     141
     142    @patch('traceback.format_stack', return_value='empty trace')
     143    @patch('mods.tools.send_mail', return_value=0)
     144    def test_success_my_error(self, mock_mail, mock_trace, capfd):
     145        with pytest.raises(SystemExit):
     146            my_error(['any_user'], 'Failed!')
     147            out, err = capfd.readouterr()
     148            assert out == "Failed!\n\nempty_trace\n"
     149
     150    @patch('subprocess.Popen')
     151    @patch('os.getenv', return_value='user')
     152    @patch('os.path.expandvars', return_value='user')
     153    def test_success_userenv_twouser_send_mail(self, mock_os, mock_env, mock_popen, capfd):
     154        mock_popen.return_value = subprocess.Popen(["echo", "Hello Test!"],
     155                                                   stdout=subprocess.PIPE)
     156        send_mail(['${USER}', 'any_user'], 'ERROR', message='error mail')
     157        out, err = capfd.readouterr()
     158        assert out == b'Email sent to user\nEmail sent to user\n'
     159
     160    @patch('subprocess.Popen')
     161    @patch('os.path.expandvars', return_value='any_user')
     162    def test_success_send_mail(self, mock_os,  mock_popen, capfd):
     163        mock_popen.return_value = subprocess.Popen(["echo", "Hello Test!"],
     164                                                   stdout=subprocess.PIPE)
     165        send_mail(['any-user'], 'ERROR', message='error mail')
     166        out, err = capfd.readouterr()
     167        assert out == b'Email sent to any_user\n'
     168
     169    @patch('subprocess.Popen', side_effect=[ValueError, OSError])
     170    @patch('os.path.expandvars', return_value='any_user')
     171    def test_fail_valueerror_send_mail(self, mock_osvar, mock_popen):
     172        with pytest.raises(SystemExit): # ValueError
     173            send_mail(['any-user'], 'ERROR', message='error mail')
     174        with pytest.raises(SystemExit): # OSError
     175            send_mail(['any-user'], 'ERROR', message='error mail')
     176
     177    def test_success_read_ecenv(self):
     178        envs_ref = {'ECUID': 'testuser',
     179                    'ECGID': 'testgroup',
     180                    'GATEWAY': 'gateway.test.ac.at',
     181                    'DESTINATION': 'user@destination'
    86182                   }
    87         envs = read_ecenv(os.getcwd() + '/TestData/ECMWF_ENV')
     183        envs = read_ecenv(self.testfilesdir + '/ECMWF_ENV.test')
    88184
    89185        assert envs_ref == envs
    90186
    91     def test_clean_up(self):
    92 
    93         assert True
    94 
    95     def test_normal_exit(self):
    96         assert True
    97 
    98     def test_product(self):
    99         assert True
    100 
    101     def test_success_silent_remove(self, capfd):
    102         testfile = 'testfile.test'
     187    @patch('__builtin__.open', side_effect=[OSError(errno.EPERM)])
     188    def test_fail_read_ecenv(self, mock_open):
     189        with pytest.raises(SystemExit):
     190            read_ecenv('any_file')
     191
     192    @patch('glob.glob', return_value=[])
     193    @patch('mods.tools.silent_remove')
     194    def test_empty_clean_up(self, mock_rm, mock_clean):
     195        clean_up(self.c)
     196        mock_rm.assert_not_called()
     197
     198    @patch('glob.glob', return_value=['any_file','EIfile'])
     199    @patch('os.remove', return_value=0)
     200    def test_success_clean_up(self, mock_rm, mock_glob):
     201        # ectrans=0; ecstorage=0; ecapi=None; prefix not in filename
     202        clean_up(self.c)
     203        mock_rm.assert_has_calls([call('any_file'), call('EIfile')])
     204        mock_rm.reset_mock()
     205
     206        # ectrans=0; ecstorage=0; ecapi=False; prefix in filename
     207        self.c.prefix = 'EI'
     208        self.c.ecapi = False
     209        clean_up(self.c)
     210        mock_rm.assert_has_calls([call('any_file')])
     211        mock_rm.reset_mock()
     212
     213        # ectrans=0; ecstorage=0; ecapi=True; prefix in filename
     214        self.c.prefix = 'EI'
     215        self.c.ecapi = True
     216        clean_up(self.c)
     217        mock_rm.assert_has_calls([call('any_file')])
     218        mock_rm.reset_mock()
     219
     220        # ectrans=1; ecstorage=0; ecapi=True; prefix in filename
     221        self.c.prefix = 'EI'
     222        self.c.ecapi = True
     223        self.c.ectrans = 1
     224        clean_up(self.c)
     225        mock_rm.assert_has_calls([call('any_file')])
     226        mock_rm.reset_mock()
     227
     228        # ectrans=1; ecstorage=0; ecapi=False; prefix in filename
     229        self.c.prefix = 'EI'
     230        self.c.ecapi = False
     231        self.c.ectrans = 1
     232        clean_up(self.c)
     233        mock_rm.assert_has_calls([call('any_file'), call('EIfile')])
     234        mock_rm.reset_mock()
     235
     236        # ectrans=1; ecstorage=1; ecapi=False; prefix in filename
     237        self.c.prefix = 'EI'
     238        self.c.ecapi = False
     239        self.c.ectrans = 1
     240        self.c.ecstorage = 1
     241        clean_up(self.c)
     242        mock_rm.assert_has_calls([call('any_file'), call('EIfile')])
     243        mock_rm.reset_mock()
     244
     245    def test_default_normal_exit(self, capfd):
     246        normal_exit()
     247        out, err = capfd.readouterr()
     248        assert out == 'Done!\n'
     249
     250    def test_message_normal_exit(self, capfd):
     251        normal_exit('Hi there!')
     252        out, err = capfd.readouterr()
     253        assert out == 'Hi there!\n'
     254
     255    def test_int_normal_exit(self, capfd):
     256        normal_exit(42)
     257        out, err = capfd.readouterr()
     258        assert out == '42\n'
     259
     260    @pytest.mark.parametrize(
     261        'input1, input2, output_list',
     262        [('ABC','xy',[('A','x'),('A','y'),('B','x'),('B','y'),('C','x'),('C','y')]),
     263         (range(1), range(1), [(0,0),(0,1),(1,0),(1,1)])])
     264    def test_success_product(self, input1, input2, output_list):
     265        index = 0
     266        for prod in product(input1, input2):
     267            assert isinstance(prod, tuple)
     268            assert prod == output_list[index]
     269            index += 1
     270
     271    @pytest.mark.parametrize(
     272        'input1, input2, output_list',
     273        [(1,1,(1,1))])
     274    def test_fail_product(self, input1, input2, output_list):
     275        index = 0
     276        with pytest.raises(SystemExit):
     277            for prod in product(input1, input2):
     278                assert isinstance(prod, tuple)
     279                assert prod == output_list[index]
     280                index += 1
     281
     282    def test_success_silent_remove(self):
     283        testfile = self.testfilesdir + 'test.txt'
    103284        open(testfile, 'w').close()
    104285        silent_remove(testfile)
    105         out, err = capfd.readouterr()
    106286        assert os.path.isfile(testfile) == False
    107         assert out == ''
    108 
    109     def test_failnotexist_silent_remove(self, capfd):
    110         testfile = 'testfile.test'
    111         silent_remove(testfile)
    112         out, err = capfd.readouterr()
    113         assert os.path.isfile(testfile) == False
    114         assert out == ''
    115 
    116     @pytest.mark.skip(reason="no way of currently testing this")
    117     def test_failany_silent_remove(self):
    118         testfile = 'testfileany.test'
     287
     288    @patch('os.remove', side_effect=OSError(errno.ENOENT))
     289    def test_fail_notexist_silent_remove(self, mock_rm):
    119290        with pytest.raises(OSError) as pytest_wrapped_e:
    120             silent_remove(testfile)
    121         #out, err = capfd.readouterr()
    122         #assert os.path.isfile(testfile) == False
    123         #assert out == ''
    124 
    125     def test_success_get_list_as_string(self):
    126         list_object =  [1, 2, 3, '...', 'testlist']
    127         list_as_string = '1, 2, 3, ..., testlist'
    128         assert list_as_string == get_list_as_string(list_object)
    129 
    130     @pytest.mark.skip(reason="no way of currently testing this")
    131     def test_fail_get_list_as_string(self):
    132         list_object =  [1, 2, 3, '...', 'testlist']
    133         list_as_string = '1, 2, 3, ..., testlist'
    134         with pytest.raises(Exception) as pytest_wrapped_e:
    135             result = get_list_as_string(list_object)
    136         assert result == list_as_string
    137 
    138     def test_warningexist_make_dir(self, capfd):
    139         testdir = 'TestData'
    140         make_dir(testdir)
    141         out, err = capfd.readouterr()
    142         assert out.strip() == 'WARNING: Directory {0} already exists!'.format(testdir)
    143 
    144     def test_failany_make_dir(self):
    145         testdir = '/test' # force a permission denied error
     291            silent_remove('any_dir')
     292            assert pytest_wrapped_e.e.errno == errno.ENOENT
     293
     294    @patch('os.remove', side_effect=OSError(errno.EEXIST))
     295    def test_fail_any_silent_remove(self, mock_rm):
     296        with pytest.raises(OSError):
     297            silent_remove('any_dir')
     298
     299    @pytest.mark.parametrize(
     300        'input_list, output_list',
     301        [([],''),
     302         ([1, 2, 3.5, '...', 'testlist'], '1, 2, 3.5, ..., testlist'),
     303         ('2', '2')])
     304    def test_success_get_list_as_string(self, input_list, output_list):
     305        assert output_list == get_list_as_string(input_list)
     306
     307    @patch('os.makedirs', side_effect=[OSError(errno.EEXIST)])
     308    def test_warning_exist_make_dir(self, mock_make):
    146309        with pytest.raises(OSError) as pytest_wrapped_e:
    147             make_dir(testdir)
    148         assert pytest_wrapped_e.type == OSError
     310            make_dir('existing_dir')
     311            assert pytest_wrapped_e.e.errno == errno.EEXIST
     312
     313    @patch('os.makedirs', side_effect=OSError)
     314    def test_fail_any_make_dir(self, mock_makedir):
     315        with pytest.raises(OSError):
     316            make_dir('any_dir')
     317
     318    def test_fail_empty_make_dir(self):
     319        with pytest.raises(OSError):
     320            make_dir('')
    149321
    150322    def test_success_make_dir(self):
    151         testdir = 'testing_mkdir'
    152         make_dir(testdir)
    153         assert os.path.exists(testdir) == True
    154         os.rmdir(testdir)
    155 
    156     def test_fail_put_file_to_ecserver(self):
    157         ecuid=os.environ['ECUID']
    158         ecgid=os.environ['ECGID']
    159         with pytest.raises(SystemExit) as pytest_wrapped_e:
    160             put_file_to_ecserver('TestData/', 'testfil.txt',
    161                                  'ecgate', ecuid, ecgid)
    162         assert pytest_wrapped_e.type == SystemExit
    163         assert pytest_wrapped_e.value.code == '... ECACCESS-FILE-PUT FAILED!'
    164 
    165     def test_success_put_file_to_ecserver(self):
    166         ecuid=os.environ['ECUID']
    167         ecgid=os.environ['ECGID']
    168         result = put_file_to_ecserver('TestData/', 'testfile.txt',
    169                                       'ecgate', ecuid, ecgid)
    170         assert result == ''
     323        testdir = '/testing_mkdir'
     324        make_dir(self.testdir + testdir)
     325        assert os.path.exists(self.testdir + testdir) == True
     326        os.rmdir(self.testdir + testdir)
     327
     328
     329    @patch('subprocess.check_output', side_effect=[subprocess.CalledProcessError(1,'test')])
     330    def test_fail_put_file_to_ecserver(self, mock_co):
     331        with pytest.raises(SystemExit):
     332            put_file_to_ecserver(self.testfilesdir, 'test_put_to_ecserver.txt',
     333                                 'ecgate', 'ex_ECUID', 'ex_ECGID')
     334
     335    @patch('subprocess.check_output', return_value=0)
     336    def test_general_success_put_file_to_ecserver(self, mock_co):
     337        result = put_file_to_ecserver(self.testfilesdir, 'test_put_to_ecserver.txt',
     338                                      'ecgate', 'ex_ECUID', 'ex_ECGID')
     339        assert result == None
    171340
    172341    @pytest.mark.msuser_pw
     342    @pytest.mark.gateway
    173343    @pytest.mark.skip(reason="easier to ignore for now - implement in final version")
    174     def test_fullsuccess_put_file_to_ecserver(self):
    175         ecuid=os.environ['ECUID']
    176         ecgid=os.environ['ECGID']
    177         put_file_to_ecserver('TestData/', 'testfile.txt', 'ecgate', ecuid, ecgid)
     344    def test_full_success_put_file_to_ecserver(self):
     345        ecuid = os.environ['ECUID']
     346        ecgid = os.environ['ECGID']
     347        put_file_to_ecserver(self.testfilesdir, 'test_put_to_ecserver.txt',
     348                             'ecgate', ecuid, ecgid)
    178349        assert subprocess.call(['ssh', ecuid+'@ecaccess.ecmwf.int' ,
    179350                                'test -e ' +
    180351                                pipes.quote('/home/ms/'+ecgid+'/'+ecuid)]) == 0
    181352
    182     def test_fail_submit_job_to_ecserver(self):
    183         with pytest.raises(SystemExit) as pytest_wrapped_e:
    184             submit_job_to_ecserver('ecgate', 'job.ksh')
    185         assert pytest_wrapped_e.type == SystemExit
    186         assert pytest_wrapped_e.value.code == '... ECACCESS-JOB-SUBMIT FAILED!'
    187 
     353    @patch('subprocess.check_output', side_effect=[subprocess.CalledProcessError(1,'test'),
     354                                                   OSError])
     355    def test_fail_submit_job_to_ecserver(self, mock_co):
     356        with pytest.raises(SystemExit):
     357            job_id = submit_job_to_ecserver('ecgate', 'job.ksh')
     358
     359    @pytest.mark.msuser_pw
     360    @pytest.mark.gateway
     361    @pytest.mark.skip(reason="easier to ignore for now - implement in final version")
    188362    def test_success_submit_job_to_ecserver(self):
    189         result = submit_job_to_ecserver('ecgate', 'TestData/testfile.txt')
    190         assert result.strip().isdigit() == True
    191 
     363        job_id = submit_job_to_ecserver('ecgate',
     364                                        os.path.join(self.testfilesdir,
     365                                                     'test_put_to_ecserver.txt'))
     366        assert job_id.strip().isdigit() == True
     367
     368
  • source/pythontest/pytest.ini

    r25b14be r96e1533  
    33markers =
    44    msuser_pw: Test that can be executed only as a member-state user. Password required.
     5    gateway: Test that can be executed only in the gateway mode.
Note: See TracChangeset for help on using the changeset viewer.
hosted by ZAMG