source: flex_extract.git/Testing/Regression/Compare_gribfiles/test_cmp_grib_file.py @ 53d3b2a

ctbtodev
Last change on this file since 53d3b2a was 53d3b2a, checked in by Anne Philipp <anne.philipp@…>, 4 years ago

added more tests for grib file comparison and removed detected BUGS

  • Property mode set to 100644
File size: 8.7 KB
Line 
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3"""Comparison of resulting Grib files of two flex_extract versions.
4
5
6
7The script should be called like:
8
9    python test_cmp_grib_files.py -r <path-to-reference-files> -n <path-to-new-files>  -p <file-pattern>
10
11Note
12----
13
14Licence:
15--------
16    (C) Copyright 2014-2019.
17
18    SPDX-License-Identifier: CC-BY-4.0
19
20    This work is licensed under the Creative Commons Attribution 4.0
21    International License. To view a copy of this license, visit
22    http://creativecommons.org/licenses/by/4.0/ or send a letter to
23    Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
24
25
26Example
27-------
28    python test_cmp_grib_file.py -r 7.0.4/EA5/ -n 7.1/EA5/ -p 'EA*'
29"""
30
31# ------------------------------------------------------------------------------
32# MODULES
33# ------------------------------------------------------------------------------
34import os
35import sys
36from datetime import datetime
37from eccodes import GribFile, GribMessage
38
39# ------------------------------------------------------------------------------
40# FUNCTION
41# ------------------------------------------------------------------------------
42def get_cmdline_params(parlist, debug=True):
43
44    import getopt
45
46    iref_path = '' # e.g. Reference_files
47    inew_path = '' # e.g. New_files
48    smatch = '' # e.g. files matching pattern
49
50    try:
51        opts, pars = getopt.getopt(parlist,
52                                   "hr:n:p:",
53                                   ["ipref=", "ipnew=", "pattern="])
54    except getopt.GetoptError:
55        print('test_cmp_grib_file.py -r <ipref> -n <ipnew> -p <pattern>')
56        sys.exit(2)
57
58    for opt, par in opts:
59        if opt == '-h':
60            print('test_cmp_grib_file.py -r <ipref> -n <ipnew> -p <pattern>')
61            sys.exit()
62        elif opt in ("-r", "--ipref"):
63            iref_path = par
64        elif opt in ("-n", "--ipnew"):
65            inew_path = par
66        elif opt in ("-p", "--pattern"):
67            smatch = par
68
69    if iref_path == '':
70        sys.exit('NO REFERENCE INPUT PATH SET!')
71    if inew_path == '':
72        sys.exit('NO "NEW" COMPARISON INPUT PATH SET!')
73    if smatch == '':
74        sys.exit('NO MATCHING PATTERN FOR FILES SET!')
75
76    if debug:
77        print("\n\nWelcome!")
78        print('Reference path is: ', iref_path)
79        print('New path is: ', inew_path)
80        print('Filepattern is: ', smatch)
81
82    return iref_path, inew_path, smatch
83
84def get_files(ipath, matchingstring, debug=True):
85    """
86        @Description:
87            Get filenames from input path matching the
88            string or regular expression and return it.
89
90        @Input:
91            ipath: string
92                Path to the files.
93
94            matchingstring: string
95                A string defining the filenames,
96                with or without regular exprssion.
97
98        @Return
99            filename: list of strings
100                A list of all files matching the pattern of
101                matchingstring.
102    """
103    import fnmatch
104
105    files = []
106
107    for fn in os.listdir(ipath):
108        if fnmatch.fnmatch(fn, matchingstring):
109            files.append(fn)
110
111    filelist = sorted(files)
112    if debug:
113        print('The input files are: %s' %(filelist))
114
115    return filelist
116
117def cmp_files_list(flist1, flist2):
118    '''
119    '''
120
121    # 1. same length?
122    length = len(flist1) == len(flist2)
123    if not length:
124        print('There are not the same amount of files.')
125        sys.exit('Message 1')
126
127    # 2. same content?
128    content = [True for i, j in zip(flist1, flist2) if i == j]
129    if not len(content) == len(flist1):
130        print('Not the same file list')
131        sys.exit('Message 2')
132
133    return True
134
135
136def cmp_number_messages(iref, flist1, inew, flist2):
137
138    ref_dict = {}
139    new_dict = {}
140    res_dict = {}
141    for file in flist1:
142        with GribFile(os.path.join(iref,file)) as grib:
143            ref_dict[file] = len(grib)
144        with GribFile(os.path.join(inew,file)) as grib:
145            new_dict[file] = len(grib)
146
147        res_dict[file] = ref_dict[file] == new_dict[file]
148
149    for k, res in res_dict.items():
150        if not res == True:
151            print('LOG: Amount of messages in files {} are not the same!'.format(k))
152
153    return True
154
155
156def cmp_grib_msg_header(ipath_ref, ipath_new, filelist):
157    from subprocess import Popen, PIPE
158    # ref_dict = {}
159    # new_dict = {}
160    # for file in flist1:
161        # with GribFile(os.path.join(iref,file)) as grib:
162            # for i in range(len(grib)):
163                # msg = GribMessage(grib)
164                # ref_dict[file] = {}
165                # ref_dict[file][i] = [msg['shortName'],msg['level'],
166                                  # msg['editionNumber'],msg['dataDate'],
167                                  # msg['dataTime'],msg['marsClass'],
168                                  # msg['type'], msg['gridType'],
169                                  # msg['stepRange']]
170    error_flag = False
171    cmp_flag = False
172    for file in filelist:
173        try:
174            res = Popen(['grib_compare', '-H',
175                         ipath_ref + '/' + file,
176                         ipath_new + '/' + file],
177                        stdin=PIPE, stdout=PIPE, stderr=PIPE)
178            output, error = res.communicate()#.decode("utf-8"))
179            if error:
180                print('... ERROR: \n\t{}'.format(error.decode()))
181                error_flag = True
182            if output:
183                print('{}'.format(output.decode()))
184                cmp_flag = True
185        except ValueError as e:
186            print('... ERROR CODE: ' + str(e.returncode))
187            print('... ERROR MESSAGE:\n \t ' + str(res))
188            error_flag = True
189        except OSError as e:
190            print('... ERROR CODE: ' + str(e.errno))
191            print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
192            error_flag = True
193
194    if error_flag:
195        sys.exit('... ERROR IN GRIB MESSAGE COMPARISON!')
196    if cmp_flag:
197        sys.exit('... FILES HAVE DIFFERENCES IN GRIB MESSAGES!')
198
199    return True
200
201
202def cmp_grib_msg_statistics(ipath_ref, ipath_new, filelist):
203
204    from subprocess import Popen, PIPE
205
206    error_flag = False
207    cmp_flag = False
208    for file in filelist:
209        try:
210            res = Popen(['grib_compare', '-c', 'statistics:n',
211                         ipath_ref + '/' + file,
212                         ipath_new + '/' + file],
213                        stdin=PIPE, stdout=PIPE, stderr=PIPE)
214            output, error = res.communicate()#.decode("utf-8"))
215            if error:
216                print('... ERROR: \n\t{}'.format(error.decode()))
217                error_flag = True
218            if output:
219                print('\nIn File: {}'.format(file))
220                print('{}'.format(output.decode()))
221                cmp_flag = True
222        except ValueError as e:
223            print('... ERROR CODE: ' + str(e.returncode))
224            print('... ERROR MESSAGE:\n \t ' + str(res))
225            error_flag = True
226        except OSError as e:
227            print('... ERROR CODE: ' + str(e.errno))
228            print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
229            error_flag = True
230
231    if error_flag:
232        sys.exit('... ERROR IN GRIB MESSAGE COMPARISON!')
233    if cmp_flag:
234        sys.exit('... FILES HAVE DIFFERENT STATISTICS!')
235    return True
236
237if __name__ == '__main__':
238
239    # get the parameter list of program call
240    ref_path, new_path, fmatch = get_cmdline_params(sys.argv[1:])
241
242    # get the list of files of both cases
243    ref_files = get_files(ref_path, fmatch)
244    new_files = get_files(new_path, fmatch)
245
246    # flag to store successfull tests
247    suc = True
248
249    # 1. Does the 2 cases contain the same list of files?
250    suc = True if suc and cmp_files_list(ref_files, new_files) else False
251
252    # 2. Does each file in both cases contain the same amount of messages?
253    suc = True if suc and cmp_number_messages(ref_path, ref_files, new_path, new_files) else False
254
255    # 3. Does each file has the same parameters (in Header)?
256    # Since we can be sure that both cases have the same files,
257    # we just use 1 filelist
258    suc = True if suc and cmp_grib_msg_header(ref_path, new_path, new_files) else False
259
260    # 4. Are the statistics of each message the same?
261    # Since we can be sure that both cases have the same files,
262    # we just use 1 filelist
263    suc = True if suc and cmp_grib_msg_statistics(ref_path, new_path, new_files) else False
264
265    # If the program comes this far and flag "suc" = True,
266    # all tests were successful
267    if suc:
268        exit('GRIB_COMPARISON: SUCCESSFULL!')
269    else:
270        exit('GRIB_COMPARISON: FAILURE!')
Note: See TracBrowser for help on using the repository browser.
hosted by ZAMG