Changeset 29227
- Timestamp:
- Sep 23, 2010, 3:38:03 PM (16 years ago)
- Location:
- branches/sc_branches/psps_testing
- Files:
-
- 2 added
- 10 edited
-
build.py (modified) (2 diffs)
-
psi/psi_inquisitor.py (modified) (5 diffs)
-
psi/web01_configuration.py (modified) (1 diff)
-
testers/batch_file.py (modified) (11 diffs)
-
testers/batch_manifest_file.py (modified) (11 diffs)
-
testers/fits/p2.py (modified) (7 diffs)
-
testers/fits_file.py (modified) (6 diffs)
-
utilities/configuration.py (modified) (1 diff)
-
utilities/psps_logger.py (modified) (10 diffs)
-
utilities/test_product.py (added)
-
utilities/test_report.py (added)
-
utilities/util.py (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/sc_branches/psps_testing/build.py
r29111 r29227 1 1 #!/usr/bin/python 2 2 3 from utilities.psps_logger import PsPsLogger 4 import logging 5 3 6 # Setup logging 4 import logging 5 datefmt = '%H:%M:%S' 6 fmt = '[%(asctime)8s/@%(filename)s/%(funcName)s()/%(lineno)03d %(levelname)5s] %(message)s' 7 logging.basicConfig(level=logging.INFO, format=fmt) 8 logger = logging.Logger("main") 9 handler = logging.StreamHandler() 10 handler.setFormatter(logging.Formatter(fmt, datefmt)) 11 logger.addHandler(handler) 12 logger.setLevel(logging.INFO) 7 # datefmt = '%H:%M:%S' 8 # fmt = '[%(asctime)8s/@%(filename)s/%(funcName)s()/%(lineno)03d %(levelname)5s] %(message)s' 9 # logging.basicConfig(level=logging.INFO, format=fmt) 10 # logger = logging.Logger("main") 11 # handler = logging.StreamHandler() 12 # handler.setFormatter(logging.Formatter(fmt, datefmt)) 13 # logger.addHandler(handler) 14 # logger.setLevel(logging.INFO) 13 15 14 16 # … … 16 18 17 19 FILES_TO_CHECK = [ 'data/samples/B00029152.tar.gz', 18 'data/samples/B00030978.tar.gz',19 'data/samples/B00031481.tar.gz',20 'data/samples/B00032090.tar.gz',21 'data/samples/B00032701.tar.gz',22 'data/samples/B00033107.tar.gz',23 'data/samples/B00033820.tar.gz',24 'data/samples/B00034120.tar.gz',25 'data/samples/B00034574.tar.gz',26 'data/samples/B00035357.tar.gz',20 # 'data/samples/B00030978.tar.gz', 21 # 'data/samples/B00031481.tar.gz', 22 # 'data/samples/B00032090.tar.gz', 23 # 'data/samples/B00032701.tar.gz', 24 # 'data/samples/B00033107.tar.gz', 25 # 'data/samples/B00033820.tar.gz', 26 # 'data/samples/B00034120.tar.gz', 27 # 'data/samples/B00034574.tar.gz', 28 # 'data/samples/B00035357.tar.gz', 27 29 ] 28 30 29 31 if __name__ == '__main__': 30 for file_to_check in FILES_TO_CHECK: 31 logger.info('Testing for entry %s' % (file_to_check)) 32 print BatchFileTester(file_to_check).test() 32 import sys 33 current_argument_position = 1 34 testMode = False 35 PsPsLogger.setLevel(logging.INFO) 36 PsPsLogger.set_stdout() 37 while current_argument_position < len(sys.argv): 38 if sys.argv[current_argument_position] == '-v': 39 PsPsLogger.setLevel(logging.DEBUG) 40 current_argument_position += 1 41 elif sys.argv[current_argument_position] == '-o': 42 PsPsLogger.set_fileout(sys.argv[current_argument_position+1]) 43 current_argument_position += 2 44 elif sys.argv[current_argument_position] == 'test': 45 testMode = True 46 current_argument_position += 1 47 else: 48 filename = sys.argv[current_argument_position] 49 current_argument_position += 1 50 PsPsLogger.info('Command line was: [%s]' % ' '.join(sys.argv)) 51 52 if testMode: 53 for file_to_check in FILES_TO_CHECK: 54 PsPsLogger.info('Testing for entry %s' % (file_to_check)) 55 print BatchFileTester(file_to_check).test().success 56 else: 57 PsPsLogger.info('Testing for file: [%s]' % (filename)) 58 print BatchFileTester(filename).test().success 59 -
branches/sc_branches/psps_testing/psi/psi_inquisitor.py
r29140 r29227 2 2 from suds.xsd.doctor import Import, ImportDoctor 3 3 from suds import sudsobject 4 from utilities.util import convert4 from utilities.util import psi_convert 5 5 import unicodedata 6 from utilities.psps_logger import PsPsLogger 7 from utilities.test_report import TestReport 6 8 7 9 class PsiInquisitor: … … 24 26 # exec 'from %s import Configuration' % configuration_file 25 27 # self.configuration = Configuration 28 PsPsLogger.debug('Creating PsiInquisitor from %s file' % configuration_file) 26 29 self.configuration = __import__(configuration_file, globals(), locals(), 27 ['Configuration'], -1).Configuration 30 ['Configuration'], -1).PsiConfiguration 31 TestReport.info('PsiInquisitor created from %s' % configuration_file) 32 TestReport.info(self.configuration.str()) 28 33 self.authClient = Client(self.configuration.authUrl) 29 34 self.sessionID = self.authClient.service.login(self.configuration.userID, … … 39 44 Make a query in the fast queue. 40 45 46 >>> psiInquisitor = PsiInquisitor('psi.web01_configuration') 41 47 >>> query = 'select frameID from FrameMeta where frameID=105439;' 42 >>> psiInquisitor = PsiInquisitor('psi.web01_configuration')43 48 >>> result = psiInquisitor.query(query) 44 49 >>> # we cannot guarantee the order in result … … 49 54 >>> print result['types'] 50 55 {'[frameID]': 'Integer'} 56 57 >>> query = 'select surveyID from FrameMeta where frameID=105439;' 58 >>> result = psiInquisitor.query(query) 59 >>> # we cannot guarantee the order in result 60 >>> print result['items'] 61 [{'surveyID': 0}] 62 >>> print result['fields'] 63 ['[surveyID]'] 64 >>> print result['types'] 65 {'[surveyID]': 'Byte'} 66 67 >>> query = 'select cameraID from FrameMeta where frameID=105439;' 68 >>> result = psiInquisitor.query(query) 69 >>> # we cannot guarantee the order in result 70 >>> print result['items'] 71 [{'cameraID': 1}] 72 >>> print result['fields'] 73 ['[cameraID]'] 74 >>> print result['types'] 75 {'[cameraID]': 'Integer'} 76 >>> # It should be something expressing that it is a 16-bits integer 77 78 >>> # REAL 4 bytes 79 >>> query = 'select photoScat from FrameMeta where frameID=105439;' 80 >>> result = psiInquisitor.query(query) 81 >>> # we cannot guarantee the order in result 82 >>> print result['items'] 83 [{'photoScat': 0.051822260000000002}] 84 >>> print result['fields'] 85 ['[photoScat]'] 86 >>> print result['types'] 87 {'[photoScat]': 'Float'} 88 >>> # There should be sthg to make the difference between f32 and f64 89 90 >>> # FLOAT 8 bytes 91 >>> query = 'select expStart from FrameMeta where frameID=105439;' 92 >>> result = psiInquisitor.query(query) 93 >>> # we cannot guarantee the order in result 94 >>> print result['items'] 95 [{'expStart': 55163.4545890027}] 96 >>> print result['fields'] 97 ['[expStart]'] 98 >>> print result['types'] 99 {'[expStart]': 'Float'} 100 >>> # There should be sthg to make the difference between f32 and f64 101 51 102 >>> # This test has to be completed with exhaustive ones... 52 103 >>> # e.g. unit tests against the csr data base. 53 104 """ 105 PsPsLogger.debug('Querying PSI: [%s]' % sql_query) 54 106 results = self.jobsClient.service.executeQuickJob(self.sessionID, 55 107 self.configuration.schemaGroup, … … 94 146 '').replace(']', 95 147 '') 96 element[field_name] = convert(types_dictionary[contents['fields'][i]],148 element[field_name] = psi_convert(types_dictionary[contents['fields'][i]], 97 149 values[i]) 98 150 contents['items'].append(element) 151 PsPsLogger.debug('Number of answers: %d' % len(contents['items'])) 99 152 return contents 100 153 101 154 if __name__ == '__main__': 155 import logging 156 PsPsLogger.set_stderr() 157 PsPsLogger.setLevel(logging.DEBUG) 102 158 import doctest 103 159 doctest.testmod() -
branches/sc_branches/psps_testing/psi/web01_configuration.py
r29115 r29227 1 class Configuration: 1 from utilities.psps_logger import PsPsLogger 2 3 class PsiConfiguration: 2 4 """ 3 5 The configuration described as a class... 4 6 """ 5 7 server = 'http://web01.psps.ifa.hawaii.edu/' 6 authUrl = server + 'DFetch/WSDL/AuthService.php.wsdl'7 8 userID = 'schastel' 8 9 password = 'd1str1ct13' 9 10 schemaGroup = 'PS1_SCHEMA'; 10 11 context = 'PS1 3PI'; 12 authUrl = server + 'DFetch/WSDL/AuthService.php.wsdl' 11 13 jobsUrl = server + 'DFetch/WSDL/JobsService.php.wsdl' 14 15 @staticmethod 16 def str(): 17 """ 18 >>> print PsiConfiguration.str() 19 PsiConfiguration 20 Server: http://web01.psps.ifa.hawaii.edu/ 21 User: schastel 22 Password: d1str1ct13 23 SchemaGroup: PS1_SCHEMA 24 Context: PS1 3PI 25 AuthUrl: http://web01.psps.ifa.hawaii.edu/DFetch/WSDL/AuthService.php.wsdl 26 JobsUrl: http://web01.psps.ifa.hawaii.edu/DFetch/WSDL/JobsService.php.wsdl 27 """ 28 return """Configuration 29 Server: %s 30 User: %s 31 Password: %s 32 SchemaGroup: %s 33 Context: %s 34 AuthUrl: %s 35 JobsUrl: %s""" % (PsiConfiguration.server, 36 PsiConfiguration.userID, 37 PsiConfiguration.password, 38 PsiConfiguration.schemaGroup, 39 PsiConfiguration.context, 40 PsiConfiguration.authUrl, 41 PsiConfiguration.jobsUrl) -
branches/sc_branches/psps_testing/testers/batch_file.py
r29116 r29227 1 # Strings managed as files2 from StringIO import StringIO3 1 # Regular expressions 4 2 import re … … 7 5 import os 8 6 from utilities.file_manipulation import FileManipulation 7 from utilities.test_report import TestReport 8 from utilities.test_product import TestProduct 9 # Sub-tests 9 10 from testers.batch_manifest_file import BatchManifestFileTester 10 11 from testers.fits_file import FitsFileTester … … 13 14 # Global definitions 14 15 from utilities.configuration import Configuration 16 # Logging 17 from utilities.psps_logger import PsPsLogger 15 18 16 19 class BatchFileTester: … … 22 25 of the files contained in the archive 23 26 24 >>> print BatchFileTester("data/psut/ok/B000 29152.tar.gz").test()27 >>> print BatchFileTester("data/psut/ok/B00000010.tar.gz").test() 25 28 PSDC-940-006-01, 3.4.1: OK 26 29 PSDC-940-006-01, 3.4: OK … … 42 45 dummy/ 43 46 """ 47 PsPsLogger.debug('Creating BatchFileTester object with filename = [%s]' % filename) 48 TestReport.info('Tests performed on file [%s]' % filename) 44 49 self._filename = filename 45 50 self.expected_basename = os.path.basename(self._filename 46 51 ).replace(Configuration.EXTENSION, 47 52 '') + '/' 53 PsPsLogger.debug(' BatchFileTester object expected basename = [%s]' 54 % self.expected_basename) 48 55 49 56 def test(self, start_dependant_tests = True): … … 52 59 tests are succesful. 53 60 """ 54 report = StringIO() 55 testsOk = True 56 (message, status) = self._test_file_name("PSDC-940-006-01, 3.4.1") 57 report.write(message) 58 testsOk = testsOk and status 59 (message, status) = self._test_file_format("PSDC-940-006-01, 3.4") 60 report.write('\n' + message) 61 testsOk = testsOk and status 62 # Now runs the dependant tests 63 if testsOk and start_dependant_tests: 64 # Uncompress the archive (since it's valid) to some temp dir 61 PsPsLogger.debug('Starting BatchFileTester object test') 62 TestReport.title('Batch file tests') 63 # Set up global test product 64 product = TestProduct() 65 product.success = True 66 # Subtest 67 subproduct = self._test_file_name("PSDC-940-006-01, 3.4.1") 68 product.success = product.success and subproduct.success 69 # Subtest 70 subproduct = self._test_file_format("PSDC-940-006-01, 3.4") 71 product.success = product.success and subproduct.success 72 # Now runs the dependent tests 73 if product.success and start_dependant_tests: 74 # Uncompress the archive (since it is valid) to some temp dir 65 75 tempDir = tempfile.mkdtemp() 66 76 command = '/bin/tar xvfz %s -C %s' % (self._filename, tempDir) 77 PsPsLogger.debug('Unpacking data (%s)' % command) 67 78 (status, 68 79 child_stdout, … … 71 82 batchManifestFileTester = BatchManifestFileTester(self.expected_basename, 72 83 tempDir) 73 (_report, fits_info) = batchManifestFileTester.test() 74 report.write('\n' + _report) 75 # Run the tests on the fits file 76 fitsFileTester = FitsFileTester(fits_info['filename'], 77 self.expected_basename, tempDir, 78 fits_info['filetype']) 79 (_report, info) = fitsFileTester.test() 80 report.write('\n' + _report) 84 subproduct = batchManifestFileTester.test() 85 product.success = product.success and subproduct.success 86 if not product.success: 87 FileManipulation.delete_directory(tempDir) 88 return product 89 # Run the tests on the fits file (subproduct.filename and 90 # subproduct.filetype are supposed to convey such 91 # information) 92 fitsFileTester = FitsFileTester(subproduct.filename, 93 self.expected_basename, 94 tempDir, 95 subproduct.filetype) 96 subproduct = fitsFileTester.test() 97 product.success = product.success and subproduct.success 81 98 # End of test... Delete the temporary directory 82 99 FileManipulation.delete_directory(tempDir) 83 return report.getvalue() 100 else: 101 PsPsLogger.debug('Dependant tests not run (condition on upstream tests is %s and start_dependant_tests variable is %s)' % (str(testsOk), str(start_dependant_tests))) 102 return product 84 103 85 104 def _test_file_name(self, requirement): … … 94 113 95 114 >>> batchFileTester = BatchFileTester('B12345678.tar.gz') 96 >>> print batchFileTester._test_file_name(" REQ_ID")97 ('REQ_ID: OK', True)115 >>> print batchFileTester._test_file_name("(UNIT_TEST_SAMPLE_REQ)").success 116 True 98 117 99 118 >>> batchFileTester = BatchFileTester('B1234567.tar.gz') 100 >>> print batchFileTester._test_file_name(" REQ_ID")101 ("REQ_ID: KO (invalid archive file basename 'B1234567.tar.gz')", False)119 >>> print batchFileTester._test_file_name("(UNIT_TEST_SAMPLE_REQ)").success 120 False 102 121 103 122 >>> batchFileTester = BatchFileTester('B123456789.tar.gz') 104 >>> print batchFileTester._test_file_name(" REQ_ID")105 ("REQ_ID: KO (invalid archive file basename 'B123456789.tar.gz')", False)123 >>> print batchFileTester._test_file_name("(UNIT_TEST_SAMPLE_REQ)").success 124 False 106 125 107 126 >>> batchFileTester = BatchFileTester('B123a5678.tar.gz') 108 >>> print batchFileTester._test_file_name(" REQ_ID")109 ("REQ_ID: KO (invalid archive file basename 'B123a5678.tar.gz')", False)127 >>> print batchFileTester._test_file_name("(UNIT_TEST_SAMPLE_REQ)").success 128 False 110 129 111 130 >>> batchFileTester = BatchFileTester('b12345678.tar.gz') 112 >>> print batchFileTester._test_file_name(" REQ_ID")113 ("REQ_ID: KO (invalid archive file basename 'b12345678.tar.gz')", False)131 >>> print batchFileTester._test_file_name("(UNIT_TEST_SAMPLE_REQ)").success 132 False 114 133 115 134 >>> batchFileTester = BatchFileTester('B12345678.tgz') 116 >>> print batchFileTester._test_file_name(" REQ_ID")117 ("REQ_ID: KO (invalid archive file basename 'B12345678.tgz')", False)135 >>> print batchFileTester._test_file_name("(UNIT_TEST_SAMPLE_REQ)").success 136 False 118 137 119 138 >>> batchFileTester = BatchFileTester('B12345678.TAR.GZ') 120 >>> print batchFileTester._test_file_name(" REQ_ID")121 ("REQ_ID: KO (invalid archive file basename 'B12345678.TAR.GZ')", False)122 """ 123 report = StringIO()139 >>> print batchFileTester._test_file_name("(UNIT_TEST_SAMPLE_REQ)").success 140 False 141 """ 142 PsPsLogger.debug('Running tests on file format') 124 143 basename = os.path.basename(self._filename) 144 product = TestProduct() 125 145 if re.match('B\d{8}\.tar.gz', basename) == None: 126 return ('%s: KO (invalid archive file basename \'%s\')' % (requirement, basename), False) 146 TestReport.ko(requirement, 147 'invalid archive file basename \'%s\'' % basename ) 127 148 else: 128 report.write('%s: OK' % requirement) 129 return (report.getvalue(), True) 149 TestReport.ok(requirement) 150 product.success = True 151 return product 130 152 131 153 def _test_file_format(self, requirement): … … 152 174 (named BatchManifest.xml) and exactly one FITS file. 153 175 154 >>> batchFileTester = BatchFileTester('data/psut/ok/B000 29152.tar.gz')155 >>> print batchFileTester._test_file_format(" REQ_ID")156 ('REQ_ID: OK', True)176 >>> batchFileTester = BatchFileTester('data/psut/ok/B00000010.tar.gz') 177 >>> print batchFileTester._test_file_format("(UNIT_TEST_SAMPLE_REQ)").success 178 True 157 179 158 180 >>> batchFileTester = BatchFileTester('This_file_does_not_exist.tar.gz') 159 >>> print batchFileTester._test_file_format(" REQ_ID")160 ("REQ_ID: KO (invalid tar gzipped archive file 'This_file_does_not_exist.tar.gz')", False)181 >>> print batchFileTester._test_file_format("(UNIT_TEST_SAMPLE_REQ)").success 182 False 161 183 162 184 >>> batchFileTester = BatchFileTester('data/psut/ko/B00000001.tar.gz') 163 >>> print batchFileTester._test_file_format(" REQ_ID")164 ("REQ_ID: KO (invalid directory name in archive 'data/psut/ko/B00000001.tar.gz': Got tmp/ instead of B00000001/)", False)185 >>> print batchFileTester._test_file_format("(UNIT_TEST_SAMPLE_REQ)").success 186 False 165 187 166 188 >>> batchFileTester = BatchFileTester('data/psut/ko/B00000002.tar.gz') 167 >>> print batchFileTester._test_file_format(" REQ_ID")168 ("REQ_ID: KO (missing XML Manifest file in archive 'data/psut/ko/B00000002.tar.gz')", False)189 >>> print batchFileTester._test_file_format("(UNIT_TEST_SAMPLE_REQ)").success 190 False 169 191 170 192 >>> batchFileTester = BatchFileTester('data/psut/ko/B00000003.tar.gz') 171 >>> print batchFileTester._test_file_format(" REQ_ID")172 ("REQ_ID: KO (missing FITS file in archive 'data/psut/ko/B00000003.tar.gz')", False)193 >>> print batchFileTester._test_file_format("(UNIT_TEST_SAMPLE_REQ)").success 194 False 173 195 174 196 >>> batchFileTester = BatchFileTester('data/psut/ko/B00000004.tar.gz') 175 >>> print batchFileTester._test_file_format("REQ_ID") 176 ("REQ_ID: KO (unexpected file 'B00000004/extra' in archive 'data/psut/ko/B00000004.tar.gz')", False) 177 """ 197 >>> print batchFileTester._test_file_format("(UNIT_TEST_SAMPLE_REQ)").success 198 False 199 """ 200 PsPsLogger.debug('Running tests on file format') 178 201 (status, 179 202 child_stdout, 180 203 child_stderr) = FileManipulation.system('/bin/tar tfz ' + self._filename) 204 product = TestProduct() 181 205 # Test 1: if the archive is not valid 182 206 if status != 0: 183 return (requirement + ': KO (invalid tar gzipped archive file \'%s\')' % self._filename, False) 207 TestReport.ko(requirement, 208 'invalid tar gzipped archive file \'%s\'' % self._filename) 209 return product 184 210 # Now check the results of the standard output which must be: 185 211 # <basename>/ … … 199 225 if status == 0: 200 226 if line != self.expected_basename: 201 return (requirement + ': KO (invalid directory name in archive \'%s\': Got %s instead of %s)' % (self._filename, line, self.expected_basename), False) 227 TestReport.ko(requirement, 228 'invalid directory name in archive \'%s\': Got %s instead of %s' 229 % (self._filename, line, self.expected_basename)) 230 return product 202 231 status = 1 203 232 elif status == 1: … … 207 236 xml_file_in_archive = True 208 237 else: 209 return (requirement + ': KO (unexpected file \'%s\' in archive \'%s\')' % (line, self._filename), False) 238 TestReport.ko(requirement, 239 'unexpected file \'%s\' in archive \'%s\'' % (line, self._filename)) 240 return product 210 241 if not xml_file_in_archive: 211 return (requirement + ': KO (missing XML Manifest file in archive \'%s\')' % (self._filename), False) 242 TestReport.ko(requirement, 243 'missing XML Manifest file in archive \'%s\'' % (self._filename)) 244 return product 212 245 if not fits_file_in_archive: 213 return (requirement + ': KO (missing FITS file in archive \'%s\')' % (self._filename), False) 214 return (requirement + ': OK', True) 215 246 TestReport.ko(requirement, 247 'missing FITS file in archive \'%s\'' % (self._filename)) 248 return product 249 product.success = True 250 return product 251 252 ################################################################ 253 # 254 # __main__ 255 # 256 ################################################################ 216 257 if __name__ == '__main__': 217 import doctest 218 doctest.testmod() 258 import logging 259 import sys 260 PsPsLogger.setLevel(logging.DEBUG) 261 current_argument_position = 1 262 while current_argument_position < len(sys.argv): 263 if sys.argv[current_argument_position] == '-v': 264 PsPsLogger.set_stderr() 265 current_argument_position += 1 266 elif sys.argv[current_argument_position] == 'test': 267 print 'Running unittest for BatchFileTester class' 268 import doctest 269 doctest.testmod() 270 sys.exit(0) -
branches/sc_branches/psps_testing/testers/batch_manifest_file.py
r29111 r29227 1 # Strings managed as files2 from StringIO import StringIO3 1 # System call and so on 4 2 from utilities.file_manipulation import FileManipulation … … 9 7 # Load some utilities to compute md5 checksum 10 8 import hashlib 9 # Logging 10 from utilities.psps_logger import PsPsLogger 11 from utilities.test_report import TestReport 12 from utilities.test_product import TestProduct 11 13 12 14 class BatchManifestFileTester: … … 36 38 Creates an instance of a BatchManifestFileTester 37 39 38 >>> basename = 'B000 29152'40 >>> basename = 'B00000010' 39 41 >>> tgz_filename = 'data/psut/ok/' + basename + '.tar.gz' 40 42 >>> # Create the temporary directory for tests … … 43 45 >>> bmft = BatchManifestFileTester(basename, '.tmp') 44 46 >>> print bmft.manifest 45 .tmp/B000 29152/BatchManifest.xml47 .tmp/B00000010/BatchManifest.xml 46 48 >>> # Delete temporary directory 47 49 >>> BatchManifestFileTester._remove_test_environment() … … 57 59 58 60 >>> # Unit test: valid file 59 >>> basename = 'B000 29152'61 >>> basename = 'B00000010' 60 62 >>> tgz_filename = 'data/psut/ok/' + basename + '.tar.gz' 61 63 >>> # Create the temporary directory for tests 62 64 >>> BatchManifestFileTester._setup_test_environment(basename, tgz_filename) 63 65 >>> bmft = BatchManifestFileTester(basename, '.tmp') 64 >>> (report, fits_info) = bmft.test() 65 >>> print report 66 PSDC-940-006-01, 3.5.1.2: OK 67 PSDC-940-006-01, 3.5.1.1: OK 68 PSDC-940-006-01, 3.5.1 (file attributes/name): OK 69 PSDC-940-006-01, 3.5.1 (file attributes/size): OK 70 PSDC-940-006-01, 3.5.1 (file attributes/MD5 checksum of file): OK 71 >>> print fits_info 72 {'filetype': u'P2', 'filename': u'00105439.FITS'} 73 >>> BatchManifestFileTester._remove_test_environment() 66 >>> product = bmft.test() 67 >>> print product.success 68 True 69 >>> print product.filetype 70 P2 71 >>> print product.filename 72 00000010.FITS 73 74 # >>> print fits_info 75 # {'filetype': u'P2', 'filename': u'00000010.FITS'} 76 # >>> BatchManifestFileTester._remove_test_environment() 74 77 75 78 >>> # Unit test: invalid manifest file name in archive … … 79 82 >>> BatchManifestFileTester._setup_test_environment(basename, tgz_filename) 80 83 >>> bmft = BatchManifestFileTester(basename, '.tmp') 81 >>> (report, fits_info) = bmft.test() 82 >>> print report 83 PSDC-940-006-01, 3.5.1.2: KO (No .tmp/B00000005/BatchManifest.xml file) 84 >>> print fits_info 85 None 84 >>> product = bmft.test() 85 >>> print product.success 86 False 86 87 >>> BatchManifestFileTester._remove_test_environment() 87 88 … … 92 93 >>> BatchManifestFileTester._setup_test_environment(basename, tgz_filename) 93 94 >>> bmft = BatchManifestFileTester(basename, '.tmp') 94 >>> (report, fits_info) = bmft.test() 95 >>> print report 96 PSDC-940-006-01, 3.5.1.2: OK 97 PSDC-940-006-01, 3.5.1.1: KO (XML validation through XSD failed: command was [/usr/bin/xmllint --schema data/xsd/BatchManifest.xsd --noout .tmp/B00000006/BatchManifest.xml]) 98 >>> print fits_info 99 None 95 >>> product = bmft.test() 96 >>> print product.success 97 False 100 98 >>> BatchManifestFileTester._remove_test_environment() 101 99 … … 106 104 >>> BatchManifestFileTester._setup_test_environment(basename, tgz_filename) 107 105 >>> bmft = BatchManifestFileTester(basename, '.tmp') 108 >>> (report, fits_filename) = bmft.test() 109 >>> print report 110 PSDC-940-006-01, 3.5.1.2: OK 111 PSDC-940-006-01, 3.5.1.1: OK 112 PSDC-940-006-01, 3.5.1 (file attributes/name): KO (no FITS file is named '.tmp/B00000007/00105439.FITS') 113 >>> print fits_info 114 None 106 >>> print product.success 107 False 115 108 >>> BatchManifestFileTester._remove_test_environment() 116 109 … … 121 114 >>> BatchManifestFileTester._setup_test_environment(basename, tgz_filename) 122 115 >>> bmft = BatchManifestFileTester(basename, '.tmp') 123 >>> (report, fits_info) = bmft.test() 124 >>> print report 125 PSDC-940-006-01, 3.5.1.2: OK 126 PSDC-940-006-01, 3.5.1.1: OK 127 PSDC-940-006-01, 3.5.1 (file attributes/name): OK 128 PSDC-940-006-01, 3.5.1 (file attributes/size): KO (actual size of FITS file is '0' instead of '10336320') 129 >>> print fits_info 130 None 116 >>> product = bmft.test() 117 >>> print product.success 118 False 131 119 >>> BatchManifestFileTester._remove_test_environment() 132 120 … … 137 125 >>> BatchManifestFileTester._setup_test_environment(basename, tgz_filename) 138 126 >>> bmft = BatchManifestFileTester(basename, '.tmp') 139 >>> (report, fits_info) = bmft.test() 140 >>> print report 141 PSDC-940-006-01, 3.5.1.2: OK 142 PSDC-940-006-01, 3.5.1.1: OK 143 PSDC-940-006-01, 3.5.1 (file attributes/name): OK 144 PSDC-940-006-01, 3.5.1 (file attributes/size): OK 145 PSDC-940-006-01, 3.5.1 (file attributes/MD5 checksum of file): KO (actual md5sum of FITS file is 'd41d8cd98f00b204e9800998ecf8427e' instead of '852461f5e14ff6ce5f0b0edd7166b515') 146 >>> print fits_info 147 None 148 >>> BatchManifestFileTester._remove_test_environment() 149 """ 150 151 report = StringIO() 127 >>> product = bmft.test() 128 >>> print product.success 129 False 130 >>> BatchManifestFileTester._remove_test_environment() 131 """ 132 TestReport.title('Batch manifest file tests') 152 133 # Check file existence and proper naming in archive 153 requirement = 'PSDC-940-006-01, 3.5.1.2: ' 134 requirement = 'PSDC-940-006-01, 3.5.1.2' 135 product = TestProduct() 154 136 if not FileManipulation.exists(self.manifest): 155 report.write(requirement + 'KO (No %s file)' % (self.manifest)) 156 return (report.getvalue(), None) 137 TestReport.ko(requirement, 138 'No %s file' % (self.manifest)) 139 return product 157 140 else: 158 report.write(requirement + 'OK')141 TestReport.ok(requirement) 159 142 # Check validation of XML by XSD through xmllint 160 requirement = 'PSDC-940-006-01, 3.5.1.1: ' 161 command = '/usr/bin/xmllint --schema %s --noout %s' 143 requirement = 'PSDC-940-006-01, 3.5.1.1' 144 command = '%s --schema %s --noout %s' % (Configuration.XMLLINT, 145 Configuration.XSD_FILE, 146 self.manifest) 162 147 (status, 163 148 stdout, 164 stderr) = FileManipulation.system(command % (Configuration.XSD_FILE, 165 self.manifest) ) 149 stderr) = FileManipulation.system(command) 166 150 if status != 0: 167 report.write('\n' + requirement + 'KO (XML validation through XSD failed: command was [%s])' % (command % (Configuration.XSD_FILE, self.manifest) ))168 return (report.getvalue(), None)169 else:170 report.write('\n' + requirement + 'OK')151 TestReport.ko(requirement, 152 'XML validation through XSD failed: command was [%s]' % (command)) 153 return product 154 TestReport.ok(requirement) 171 155 # Get XML information concerning FITS file 172 156 # Note: We are only interested in the first <file> element … … 174 158 fileList = xmldoc.getElementsByTagName('file') 175 159 # File existence 176 requirement = 'PSDC-940-006-01, 3.5.1 (file attributes/name) :'160 requirement = 'PSDC-940-006-01, 3.5.1 (file attributes/name)' 177 161 fitsFilename = fileList[0].attributes['name'].value 178 162 fileToLookFor = self._manifest_relative_directory + '/' + fitsFilename 179 163 if not FileManipulation.exists(fileToLookFor): 180 report.write('\n' + requirement + 'KO (no FITS file is named \'%s\')' % (fileToLookFor)) 181 return (report.getvalue(), None) 182 report.write('\n' + requirement + 'OK') 164 TestReport.ko(requirement, 165 'no FITS file is named \'%s\'' % (fileToLookFor)) 166 return product 167 TestReport.ok(requirement) 183 168 # File size match 184 requirement = 'PSDC-940-006-01, 3.5.1 (file attributes/size) :'169 requirement = 'PSDC-940-006-01, 3.5.1 (file attributes/size)' 185 170 expected_size = fileList[0].attributes['bytes'].value 186 171 actual_size = str(FileManipulation.size(fileToLookFor)) 187 172 if actual_size != expected_size: 188 report.write('\n' + requirement + 'KO (actual size of FITS file is \'%s\' instead of \'%s\')' % (actual_size, expected_size)) 189 return (report.getvalue(), None) 190 report.write('\n' + requirement + 'OK') 173 TestReport.ko(requirement, 174 'actual size of FITS file is \'%s\' instead of \'%s\'' 175 % (actual_size, expected_size)) 176 return product 177 TestReport.ok(requirement) 191 178 # File md5sum 192 requirement = 'PSDC-940-006-01, 3.5.1 (file attributes/MD5 checksum of file) :'179 requirement = 'PSDC-940-006-01, 3.5.1 (file attributes/MD5 checksum of file)' 193 180 expected_md5sum = fileList[0].attributes['md5'].value 194 181 actual_md5sum = FileManipulation.md5(fileToLookFor) 195 182 if actual_md5sum != expected_md5sum: 196 report.write('\n' + requirement + 'KO (actual md5sum of FITS file is \'%s\' instead of \'%s\')' % (actual_md5sum, expected_md5sum)) 197 return (report.getvalue(), None) 198 report.write('\n' + requirement + 'OK') 183 TestReport.ko(requirement, 184 'actual md5sum of FITS file is \'%s\' instead of \'%s\'' 185 % (actual_md5sum, expected_md5sum)) 186 return product 187 TestReport.ok(requirement) 199 188 # TODO: Perform some validation of the XML content that XSD can't do 200 189 # e.g.: minObjId < maxObjId. 201 190 # Note: if other objects need to be provided in the output, just add them to the dictionary... 202 191 # e.g.: return (..., {'filename': fitsFilename, 'fitsFilesize': fitsFilesize}) 203 return (report.getvalue(), 204 { 'filename': fitsFilename, 205 'filetype': xmldoc.getElementsByTagName('manifest')[0].attributes['type'].value}) 192 # Extend test product with values useful in next tests 193 product.success = True 194 product.filename = fitsFilename 195 product.filetype = xmldoc.getElementsByTagName('manifest')[0].attributes['type'].value 196 return product 206 197 207 198 if __name__ == '__main__': 208 import doctest 209 doctest.testmod() 199 import logging 200 import sys 201 PsPsLogger.setLevel(logging.DEBUG) 202 current_argument_position = 1 203 while current_argument_position < len(sys.argv): 204 if sys.argv[current_argument_position] == '-v': 205 PsPsLogger.set_stderr() 206 current_argument_position += 1 207 elif sys.argv[current_argument_position] == 'test': 208 print 'Running unittest for BatchManifestFileTester class' 209 import doctest 210 doctest.testmod() 211 sys.exit(0) -
branches/sc_branches/psps_testing/testers/fits/p2.py
r29140 r29227 1 1 from psi.psi_inquisitor import PsiInquisitor 2 2 import pyfits 3 from StringIO import StringIO4 3 from utilities.util import match 4 # Logging 5 from utilities.psps_logger import PsPsLogger 6 from utilities.configuration import Configuration 7 from utilities.test_report import TestReport 8 from utilities.test_product import TestProduct 5 9 6 10 class P2FitsTester: … … 14 18 15 19 Note that the purpose of this class is NOT to test the FITS 16 validity (which can be checked using somepyfits options).20 validity (which can be checked using pyfits options). 17 21 """ 18 22 def __init__(self, fits_file, psi_configuration): … … 25 29 >>> p2ft = P2FitsTester(fits_file, psi_configuration) 26 30 """ 31 PsPsLogger.debug('Creating P2FitsTester object') 27 32 self.fits = fits_file 28 33 self.psi_inquisitor = PsiInquisitor(psi_configuration) 29 34 30 def test(self ):35 def test(self, be_tolerant_for_types = False): 31 36 """ 32 37 Tests a FITS file supposed to contain a P2 frame data set. … … 36 41 >>> psi_configuration = 'psi.web01_configuration' 37 42 >>> p2ft = P2FitsTester(fits_file, psi_configuration) 38 >>> (message, values) = p2ft.test() 39 >>> print message # doctest:+ELLIPSIS 40 PSDC-940-006-01, 3.6.3, 1): OK 41 PSDC-940-006-01, 3.6.6.8: OK 42 PSDC-940-006-01, TBD_test_detections_frames: OK (frame 00 - SELECT * FROM ImageMeta WHERE imageID = 10543901) 43 PSDC-940-006-01, TBD_test_detections_frames: OK (frame 01 - SELECT * FROM ImageMeta WHERE imageID = 10543902) 44 ... 45 PSDC-940-006-01, TBD_test_detections_frames: OK (frame 57 - SELECT * FROM ImageMeta WHERE imageID = 10543976) 46 >>> print values 47 None 48 """ 49 report = StringIO() 43 >>> product = p2ft.test(False) 44 >>> print product.success 45 False 46 47 >>> product = p2ft.test(True) 48 >>> print product.success 49 True 50 """ 51 PsPsLogger.info('Testing P2FitsTester object') 50 52 # 1. There is no image for the PrimaryHDU (at 0) 51 (messages, other) = self.test_primary() 52 report.write(messages) 53 PsPsLogger.debug(' Testing P2FitsTester object: primary') 54 product = self.test_primary() 55 if not product.success: 56 return product 53 57 # 2. Look at the FrameMeta information 54 (messages, values) = self.test_frame_meta() 55 report.write('\n' + messages) 56 if values is None: 57 return (report.getvalue(), None) 58 # 3. There should be values['ota'] sequences of [ImageMeta, 58 PsPsLogger.debug(' Testing P2FitsTester object: frameMeta') 59 product = self.test_frame_meta(be_tolerant_for_types) 60 # Fail if there is any failure and we are type-strict 61 if not product.success and not be_tolerant_for_types: 62 return product 63 # 3. There should be 'product.nOTA' sequences of [ImageMeta, 59 64 # Detection, SkinnyObject, ObjectCalColor] frames 60 frameID = values['frameID']61 nOTA = values['nOTA']65 frameID = product.frameID 66 nOTA = product.nOTA 62 67 if len(self.fits) != 4*nOTA + 2: 63 68 report.write('\nInvalid number of OTA: from FITS file: %d / from FrameMeta %d' … … 65 70 return (report.getvalue(), None) 66 71 for ota_index in range(nOTA): 67 (messages, values) = self.test_detections_frames(frameID, ota_index) 72 PsPsLogger.debug(' Testing P2FitsTester object: OTA (%d/%d)' 73 % ((ota_index+1), nOTA)) 74 (messages, values) = self.test_detections_frames(frameID, ota_index, 75 be_tolerant_for_types) 76 PsPsLogger.debug(messages) 68 77 report.write('\n' + messages) 69 78 return (report.getvalue(), None) 70 79 71 def test_detections_frames(self, frameID, ota_index): 80 ##################################################### 81 def test_detections_frames(self, frameID, ota_index, be_tolerant_for_types): 72 82 """ 73 83 Tests the contents of the 4-frame sequence [ImageMeta, 74 84 Detection, SkinnyObject, ObjectCalColor]. 75 85 Those contents can be queried by: TODO 76 77 """ 78 report = StringIO() 79 # Check that the 4 sequence is correct 86 """ 87 # Check that the 4-frame sequence is correct 80 88 requirement = 'PSDC-940-006-01, TBD_test_detections_frames: ' 81 89 fits_index = 4*ota_index+2 90 product = TestProduct() 91 TestReport.title('Data frames tests') 82 92 if self.fits[fits_index].name != 'IMAGEMETA': 83 return (requirement + 'KO (Not an ImageMeta frame)', None) 93 TestReport.ko(requirement, 94 'Not an ImageMeta frame at index %d' % fits_index) 95 return product 84 96 if self.fits[fits_index+1].name != 'DETECTION': 85 return (requirement + 'KO (Not a Detection frame)', None) 97 TestReport.ko(requirement, 98 'Not a Detection frame at index %d' % fits_index) 99 return product 86 100 if self.fits[fits_index+2].name != 'SKINNYOBJECT': 87 return (requirement + 'KO (Not a SkinnyObject frame)', None) 101 TestReport.ko(requirement, 102 'Not a SkinnyObject frame at index %d' % fits_index) 103 return product 88 104 if self.fits[fits_index+3].name != 'OBJECTCALCOLOR': 89 return (requirement + 'KO (Not a ObjectCalColor frame)', None) 105 TestReport.ko(requirement, 106 'Not an ObjectCalColor frame at index %d' % fits_index) 107 return product 108 TestReport.ok(requirement) 90 109 # Check ImageMeta values (!We get imageID from the FITS file 91 110 # since they are not sorted) 111 PsPsLogger.debug(' Checking ImageMeta values') 92 112 imageID = self.fits[fits_index].data.field('imageID')[0] 93 113 query = 'SELECT * FROM ImageMeta WHERE imageID = %s' % str(imageID) 94 114 answer = self.psi_inquisitor.query(query) 95 (message, status) = match(self.fits[fits_index].data, answer, requirement) 96 if status != 0: 97 return (message + ' (frame %02d - %s)' % (ota_index, query), None) 98 report.write(message) 115 TestReport.title('ImageMeta values tests (frame %d - %s)' 116 % (ota_index, query)) 117 subproduct = match(self.fits[fits_index].data, answer, requirement, 118 tolerance = Configuration.TOLERANCE, 119 max_failures = Configuration.LIMIT) 120 if not subproduct.success and not be_tolerant_for_types: 121 return product 99 122 # Extract the number of detections 100 123 nDetect = int(self.fits[fits_index].data.field('nDetect')[0]) … … 103 126 howMany = self.psi_inquisitor.query(query)['items'][0]['HowMany'] 104 127 if nDetect != howMany: 105 report.write('\nGot %d Detection items from PSI instead of %d for image %s' 106 % (howMany, nDetect, str(imageID)) ) 128 TestReport.ko(requirement, 129 'Got %d Detection items from PSI instead of %d for image %s' 130 % (howMany, nDetect, str(imageID)) ) 131 return product 107 132 # Get the nDetect detections (they are assumed to be sorted in the FITS file) 133 PsPsLogger.debug(' Checking Detection values') 108 134 query = 'SELECT * FROM Detection WHERE imageID = %s ORDER BY detectID' % str(imageID) 109 135 answer = self.psi_inquisitor.query(query) 136 count = 0 110 137 for detection_index in range(nDetect): 111 (message, status) = match(self.fits[fits_index+1].data, answer, 112 requirement, detection_index) 113 report.write('\n' + message) 114 return (report.getvalue() + ' (frame %02d - %s)' % (ota_index, query), None) 115 116 def test_frame_meta(self): 138 PsPsLogger.debug(' Detection index: %d out of %d' 139 % (detection_index+1, nDetect)) 140 subproduct = match(self.fits[fits_index+1].data, 141 answer, 142 requirement, 143 tolerance = Configuration.TOLERANCE, 144 fits_index = detection_index, 145 max_failures = Configuration.LIMIT) 146 if not subproduct.success: 147 TestReport.ko(requirement, 148 'Comparison Matching failed') 149 if not be_tolerant_for_types: 150 return product 151 product.success = True 152 return product 153 154 ################################################# 155 def test_frame_meta(self, be_tolerant_for_types): 117 156 """ 118 157 Tests the contents of the FrameMeta table. … … 124 163 """ 125 164 requirement = 'PSDC-940-006-01, 3.6.6.8: ' 165 product = TestProduct() 166 TestReport.title('MetaFrame tests') 126 167 if self.fits[1].header['NAXIS'] != 2: 127 return (requirement + 'KO (NAXIS != 2)', None) 168 TestReport.ko(requirement, 'NAXIS != 2') 169 return product 128 170 if self.fits[1].header['NAXIS2'] != 1: 129 return (requirement + 'KO (NAXIS2 != 1)', None) 171 TestReport.ko(requirement, 'NAXIS2 != 1') 172 return product 130 173 if self.fits[1].header['TFIELDS'] != 48: 131 return (requirement + 'KO (TFIELDS != 48)', None) 174 TestReport.ko(requirement, 'TFIELDS != 48') 175 return product 132 176 frameID = self.fits[1].data.field('frameID')[0] 133 177 query = "SELECT * FROM FrameMeta WHERE frameID = %d" % frameID 134 178 answer = self.psi_inquisitor.query(query) 135 (message, status) = match(self.fits[1].data, answer, requirement) 136 if status != 0: 137 return (message, None) 138 else: 139 return (message, 140 {'frameID': int(self.fits[1].data.field('frameID')[0]), 141 'nOTA': int(self.fits[1].data.field('nOTA')[0]) }) 179 product = match(self.fits[1].data, 180 answer, 181 requirement, 182 max_failures = Configuration.LIMIT, 183 tolerance = Configuration.TOLERANCE) 184 if not product.success and not be_tolerant_for_types: 185 return product 186 # Extend the product with some useful values 187 product.frameID = int(self.fits[1].data.field('frameID')[0]) 188 product.nOTA = int(self.fits[1].data.field('nOTA')[0]) 189 return product 142 190 191 ####################### 143 192 def test_primary(self): 144 193 """ 145 194 Check that the primary header i.e. fits[0] has no dimension. 146 195 """ 147 requirement = 'PSDC-940-006-01, 3.6.3, 1): ' 196 TestReport.title('Primary frame tests') 197 requirement = 'PSDC-940-006-01, 3.6.3, 1' 198 product = TestProduct() 148 199 if self.fits[0].header['NAXIS'] != 0: 149 return (requirement + 'KO', None) 200 TestReport.ko(requirement, 'Dimension should be 0') 201 return product 150 202 # Add more tests? 151 return (requirement + 'OK', None) 203 product.success = True 204 TestReport.ok(requirement) 205 return product 152 206 153 207 if __name__ == '__main__': 154 import doctest 155 doctest.testmod() 208 import logging 209 import sys 210 PsPsLogger.setLevel(logging.DEBUG) 211 current_argument_position = 1 212 while current_argument_position < len(sys.argv): 213 if sys.argv[current_argument_position] == '-v': 214 PsPsLogger.set_stderr() 215 PsPsLogger.set_fileout('dummy.log') 216 current_argument_position += 1 217 elif sys.argv[current_argument_position] == 'test': 218 print 'Running unittest for P2FitsTester functions' 219 import doctest 220 doctest.testmod() 221 sys.exit(0) -
branches/sc_branches/psps_testing/testers/fits_file.py
r29140 r29227 2 2 import pyfits 3 3 from testers.fits.p2 import P2FitsTester 4 # Logging 5 from utilities.psps_logger import PsPsLogger 6 from utilities.configuration import Configuration 7 from utilities.test_report import TestReport 4 8 5 9 """ … … 8 12 """ 9 13 class FitsFileTester: 10 class Type:11 """12 Definition taken from 5.213 """14 UNKNOWN = {'id': 00, 'code': ''}15 INITIALIZATION = 1016 DETECTION = 2017 STACK = 3018 DIFFERENCE = 4019 OBJECTS = 5020 21 14 _TMPDIR = '.tmp' 22 15 @staticmethod … … 60 53 self.fitsFile = pyfits.open(self.filename) 61 54 self.psi_configuration = psi_configuration 55 TestReport.info(str(self.psi_configuration)) 62 56 63 57 def __del__(self): 64 58 """ 65 Closes the FITS file59 Explicitly closes the FITS file 66 60 """ 67 61 self.fitsFile.close() … … 71 65 Tests the contents of the FITS file 72 66 73 >>> fitsname = '00 105439.FITS'74 >>> basename = 'B000 29152'67 >>> fitsname = '00000010.FITS' 68 >>> basename = 'B00000010' 75 69 >>> tgz_filename = 'data/psut/ok/' + basename + '.tar.gz' 76 70 … … 78 72 >>> FitsFileTester._setup_test_environment(basename, tgz_filename) 79 73 >>> fft = FitsFileTester(fitsname, basename, '.tmp', 'P2') 80 >>> print fft.test() 81 ('BARF', None) 74 >>> product = fft.test() 75 >>> print product.success 76 False 82 77 >>> # Delete temporary directory 83 78 >>> FitsFileTester._remove_test_environment() … … 92 87 """ 93 88 if self.fitsType == "P2": 94 return P2FitsTester(self.fitsFile, self.psi_configuration).test() 89 return P2FitsTester(self.fitsFile, 90 self.psi_configuration).test(Configuration.BE_TYPE_TOLERANT) 95 91 else: 96 92 raise Exception("Unsupported FITS type [%s]" % self.fitsType) 97 93 98 94 if __name__ == '__main__': 99 import doctest 100 doctest.testmod() 95 import logging 96 import sys 97 PsPsLogger.setLevel(logging.DEBUG) 98 current_argument_position = 1 99 while current_argument_position < len(sys.argv): 100 if sys.argv[current_argument_position] == '-v': 101 PsPsLogger.set_stderr() 102 current_argument_position += 1 103 elif sys.argv[current_argument_position] == 'test': 104 print 'Running unittest for FitsFileTester class' 105 import doctest 106 doctest.testmod() 107 sys.exit(0) -
branches/sc_branches/psps_testing/utilities/configuration.py
r29111 r29227 8 8 # The location of the validating XSD file 9 9 XSD_FILE = 'data/xsd/BatchManifest.xsd' 10 # xmllint path 11 XMLLINT = '/usr/bin/xmllint' 12 # Limit to numeric tests failures in match function 13 LIMIT = 15 # Can be None, 100, -1 14 # Tolerance value for floating-point numbers 15 TOLERANCE = 1.0e-5 16 # Be type tolerant (at least until all those promotions concerns 17 # are not fixed). The value is used in FitsFileTester.test() 18 BE_TYPE_TOLERANT = True 19 20 def __repr__(self): 21 from StringIO import StringIO 22 representation = StringIO() 23 representation.write('Tests Configuration Values:\n') 24 representation.write(' File extension: [%s]\n' 25 % Configuration.EXTENSION) 26 representation.write(' Batch manifest name: [%s]\n' 27 % Configuration.BATCH_MANIFEST) 28 representation.write(' XSD file: [%s]\n' 29 % Configuration.XSD_FILE) 30 representation.write(' XML validation tool: [%s]\n' 31 % Configuration.XMLLINT) 32 representation.write(' Limit for test failure in a single test item: [%d]\n' 33 % Configuration.LIMIT) 34 representation.write(' Tolerance for floating-point comparison: [%s]\n' 35 % Configuration.TOLERANCE) 36 if Configuration.BE_TYPE_TOLERANT: 37 tolerant = 'never' 38 else: 39 tolerant = 'always' 40 representation.write(' Different types comparison [%s] fails' 41 % tolerant) 42 return representation.getvalue() -
branches/sc_branches/psps_testing/utilities/psps_logger.py
r29140 r29227 2 2 import sys 3 3 4 class PsPsLogger :4 class PsPsLoggerClass: 5 5 """ 6 6 Logging facility for PSPS Testing framework. … … 8 8 http://code.activestate.com/recipes/52558-the-singleton-pattern-implemented-with-python/ 9 9 10 Check PsPsLogger .__init__() to see how it is used.10 Check PsPsLoggerClass.__init__() to see how it is used. 11 11 """ 12 12 datefmt = '%H:%M:%S' … … 18 18 """Sets logging up""" 19 19 logging.Logger.__init__(self, __name__) 20 logging.basicConfig(level=logging.INFO, format=PsPsLogger .fmt)20 logging.basicConfig(level=logging.INFO, format=PsPsLoggerClass.fmt) 21 21 try: 22 22 handler = logging.NullHandler() 23 23 except AttributeError: # logging.NullHandler only python >= 2.7 24 24 handler = logging.StreamHandler(open('/dev/null', 'w')) 25 handler.setFormatter(logging.Formatter(PsPsLogger .fmt,26 PsPsLogger .datefmt))25 handler.setFormatter(logging.Formatter(PsPsLoggerClass.fmt, 26 PsPsLoggerClass.datefmt)) 27 27 self.addHandler(handler) 28 28 def id(self): … … 37 37 Creates singleton instance. 38 38 39 >>> logger1 = PsPsLogger ()39 >>> logger1 = PsPsLoggerClass() 40 40 >>> logger1.debug('This message is not displayed') 41 >>> logger2 = PsPsLogger ()41 >>> logger2 = PsPsLoggerClass() 42 42 >>> logger1.id() == logger2.id() 43 43 True … … 45 45 >>> logger1.warning('This message is not displayed') 46 46 >>> logger1.setLevel(logging.INFO) 47 >>> PsPsLogger ().debug('This message is not displayed')47 >>> PsPsLoggerClass().debug('This message is not displayed') 48 48 >>> logger1.setLevel(logging.DEBUG) 49 >>> PsPsLogger ().debug('This message is not displayed')49 >>> PsPsLoggerClass().debug('This message is not displayed') 50 50 """ 51 51 # Check whether we already have an instance 52 if PsPsLogger .__instance is None:52 if PsPsLoggerClass.__instance is None: 53 53 # Create and remember instance 54 PsPsLogger .__instance = PsPsLogger.__impl()54 PsPsLoggerClass.__instance = PsPsLoggerClass.__impl() 55 55 # Store instance reference as the only member in the handle 56 self.__dict__['_PsPsLogger __instance'] = PsPsLogger.__instance56 self.__dict__['_PsPsLoggerClass__instance'] = PsPsLoggerClass.__instance 57 57 58 58 def __getattr__(self, attr): … … 67 67 """ 68 68 Set up the logging to sys.stdout 69 >>> logger = PsPsLogger ()69 >>> logger = PsPsLoggerClass() 70 70 >>> logger.set_stdout() 71 71 >>> logger.setLevel(logging.DEBUG) … … 85 85 """ 86 86 Set up the logging to sys.stderr 87 >>> logger = PsPsLogger ()87 >>> logger = PsPsLoggerClass() 88 88 >>> logger.set_stderr() 89 89 >>> logger.setLevel(logging.DEBUG) … … 103 103 """ Set up the logging to some file """ 104 104 if fmt == None: 105 fmt = PsPsLogger .fmt105 fmt = PsPsLoggerClass.fmt 106 106 if datefmt == None: 107 datefmt = PsPsLogger .datefmt107 datefmt = PsPsLoggerClass.datefmt 108 108 handler = logging.StreamHandler(open(filename, 'w')) 109 109 handler.setFormatter(logging.Formatter(fmt, datefmt)) … … 117 117 self.critical('The last is critical') 118 118 119 PsPsLogger = PsPsLoggerClass() 120 119 121 if __name__ == '__main__': 120 122 if len(sys.argv)<2: … … 124 126 # if sys.argv[1] == 'testfile': 125 127 # print 'Testing for %s' % sys.argv[2] 126 # PsPsLogger ().set_fileout(sys.argv[2],128 # PsPsLoggerClass().set_fileout(sys.argv[2], 127 129 # '[%(asctime)8s %(levelname)5s] %(message)s', '%H:%M:%S') 128 # PsPsLogger ().setLevel(logging.INFO)129 # logger = PsPsLogger ()130 # PsPsLoggerClass().setLevel(logging.INFO) 131 # logger = PsPsLoggerClass() 130 132 # logger.setLevel(logging.DEBUG) 131 133 # print '5 messages' -
branches/sc_branches/psps_testing/utilities/util.py
r29140 r29227 1 from StringIO import StringIO2 1 import numpy 3 4 def equal(a, b, tolerance = 1.e-5): 2 from utilities.psps_logger import PsPsLogger 3 from utilities.test_report import TestReport 4 from utilities.test_product import TestProduct 5 6 def equal(a, b, tolerance = 1.e-15): 5 7 """ 6 8 Compares two floating-point numbers and consider them equal if … … 22 24 """ 23 25 try: 24 if a.__class__ != b.__class__:25 # print 'Warning! Comparing different types: %s and %s' % (a.__class__.__name__, b.__class__.__name__)26 b = a.__class__(b)27 26 return abs(a-b)<tolerance 28 27 except TypeError: 29 28 return a == b 30 29 31 def match(fits_data, psi_answer, requirement, tolerance = 1e-5, fits_index=0): 30 def match(fits_data, 31 psi_answer, 32 requirement, 33 tolerance = 1e-15, 34 fits_index=0, 35 max_failures = None): 32 36 """ 33 37 Compares the values of data contained in a FITS file and those … … 44 48 >>> answer['items'] = [{}] 45 49 >>> answer['items'][0]['key'] = 'value' 46 >>> (message, status) = match(fits, answer, 'Req: ') 47 >>> print message 48 Req: OK 49 >>> print status 50 0 50 >>> product = match(fits, answer, 'Req: ') 51 >>> print product.success 52 True 51 53 52 54 >>> answer['items'][0]['key'] = 'VALUE' 53 >>> (message, status) = match(fits, answer, 'Req: ') 54 >>> print message 55 Req: KO Different values for element key (from psi = "VALUE", from FITS = "value") 56 >>> print status 57 1 55 >>> product = match(fits, answer, 'Req: ') 56 >>> print product.success 57 False 58 58 59 59 >>> fits2 = DummyFits() … … 62 62 >>> answer2['items'] = [{}] 63 63 >>> answer2['items'][0]['sky'] = 745.895 64 >>> (message, status) = match(fits2, answer2, 'Req: ') 65 >>> print message 66 Req: OK 67 >>> print status 68 0 64 >>> product = match(fits2, answer2, 'Req: ') 65 >>> print product.success 66 True 69 67 70 68 >>> fits2 = DummyFits() … … 73 71 >>> answer2['items'] = [{}] 74 72 >>> answer2['items'][0]['sky'] = 745.896 75 >>> (message, status) = match(fits2, answer2, 'Req: ') 76 >>> print message 77 Req: KO Different values for element sky (from psi = "745.896", from FITS = "745.895") 78 >>> print status 79 1 73 >>> product = match(fits2, answer2, 'Req: ') 74 >>> print product.success 75 False 80 76 81 77 >>> fits2._fields['sky2'] = [745.895] 82 78 >>> answer2['items'][0]['sky2'] = 745.896 83 >>> (message, status) = match(fits2, answer2, 'Req: ') 84 >>> print message 85 Req: KO Different values for element sky2 (from psi = "745.896", from FITS = "745.895") 86 Req: KO Different values for element sky (from psi = "745.896", from FITS = "745.895") 87 >>> print status 88 1 89 """ 90 status = 0 91 report = StringIO() 79 >>> product = match(fits2, answer2, 'Req: ') 80 >>> print product.success 81 False 82 83 >>> fits2._fields['sky2'] = [1792.05] 84 >>> answer2['items'][0]['sky2'] = 1792.054 85 >>> product = match(fits2, answer2, 'Req: ') 86 >>> print product.success 87 False 88 89 """ 90 product = TestProduct() 91 first_time = True 92 complain = True 93 PsPsLogger.debug('match(): %d rows to compare' % len(psi_answer['items'])) 94 items_count = 1 95 tenPercent = len(psi_answer['items'])/10 96 nextTenthPercents = int(tenPercent) 92 97 for items in psi_answer['items']: 98 if first_time: 99 PsPsLogger.debug('match(): %d items in columns' 100 % (len(items.items()))) 101 first_time = False 102 if items_count == nextTenthPercents: 103 PsPsLogger.debug('match(): %d out of %d' 104 % (items_count, 105 len(psi_answer['items']))) 106 nextTenthPercents += tenPercent 107 items_count += 1 108 failures_count = 0 93 109 for (key, value) in items.items(): 94 same = (fits_data.field(str(key))[fits_index] == value) 95 if not same and not isinstance(value, str): 96 same = equal(fits_data.field(str(key))[0], value) 110 fits_value = fits_data.field(str(key))[fits_index] 111 if fits_value.__class__.__name__ != value.__class__.__name__: 112 if complain: 113 TestReport.ko(requirement, 114 'Classes of FITS value (%s/%s) and PSI value (%s/%s) are different for key \'%s\'' 115 % (fits_value.__class__.__name__, 116 fits_value, 117 value.__class__.__name__, 118 value, 119 str(key))) 120 failures_count += 1 121 complain = complain and __still_complain(max_failures, failures_count) 122 psi_value = fits_value.__class__(value) 123 same = (fits_data.field(str(key))[fits_index] == psi_value) 124 if not same and not isinstance(psi_value, str): 125 same = equal(fits_data.field(str(key))[0], 126 psi_value, 127 tolerance) 97 128 if not same: 98 if status == 1: 99 report.write('\n') 100 report.write('%sKO Different values for element %s (from psi = "%s", from FITS = "%s")' % (requirement, key, str(value), str(fits_data.field(key)[fits_index]))) 101 status = 1 102 if status == 0: 103 report.write(requirement + 'OK') 104 return (report.getvalue(), status) 105 106 def convert(type, value): 107 """ 108 >>> a = convert('Float', '55163.4545890027') 109 >>> b = 55163.454589 129 if complain: 130 TestReport.ko(requirement, 131 'Different values for key %s: PSI = [%s] (%s) / FITS = [%s] (%s) / FITS index = %d' % 132 (key, 133 psi_value, 134 psi_value.__class__.__name__, 135 fits_data.field(key)[fits_index], 136 fits_data.field(key)[fits_index].__class__.__name__, 137 fits_index)) 138 failures_count += 1 139 complain = complain and __still_complain(max_failures, failures_count) 140 if failures_count == 0: 141 product.success = True 142 TestReport.ok(requirement) 143 else: 144 if not complain: 145 # Write the summary of all errors 146 TestReport.ko(requirement, 147 'Total of %d comparison errors for match (comparison over %d rows of %d columns)' 148 % (failures_count, 149 len(psi_answer['items']), 150 len(items.items()))) 151 return product 152 153 def __still_complain(max_failures, failures_count): 154 if max_failures is not None and failures_count >= max_failures: 155 TestReport.ko('INFO', 'Limit of failures reached: %d (total number of errors should follow' % failures_count) 156 return False 157 return True 158 159 def psi_convert(type, value): 160 """ 161 >>> a = psi_convert('Float', '55163.4545890027') 162 >>> b = 55163.4545890027 163 >>> print (a, b) 164 (55163.4545890027, 55163.4545890027) 110 165 >>> equal(a,b) 111 166 True 112 >>> a = convert('Real', '55163.4545890027') 113 >>> b = 55163.454589 167 >>> a = psi_convert('Real', '55163.4545890027') 168 >>> b = 55163.4545890027 169 >>> print (a, b) 170 (55163.453, 55163.4545890027) 114 171 >>> equal(a,b) 115 172 False 116 >>> equal( convert('String', 'Dummy'), 'Dummy')117 True 118 >>> equal( convert('String', 'Dummy'), 'Dumy')119 False 120 >>> convert('UnsupportedType', '45')173 >>> equal(psi_convert('String', 'Dummy'), 'Dummy') 174 True 175 >>> equal(psi_convert('String', 'Dummy'), 'Dumy') 176 False 177 >>> psi_convert('UnsupportedType', '45') 121 178 Traceback (most recent call last): 122 179 ... 123 180 Exception: Type 'UnsupportedType' is not supported 124 181 """ 182 # PsPsLogger.debug('Value class: %s (%s/%s)' 183 # % (value.__class__.__name__, 184 # str(value), type)) 125 185 if type == 'String': 126 186 return str(value).replace('"', '') … … 137 197 raise Exception('Type \'%s\' is not supported' % type) 138 198 199 # def weak_convert(a, b): 200 # """ 201 # If 'a' has a weaker type than 'b', returns the tuple 202 # (a, a.__class__(b)), otherwise returns the tuple 203 # (b.__class__(a), b) 204 205 # Types must be comparable: 206 # - numpy.float32 < numpy.float64 207 # - numpy.int8 < numpy.int16 < numpy.int32 < numpy.int64 208 # """ 209 # if 210 139 211 if __name__ == '__main__': 140 import doctest 141 doctest.testmod() 212 import logging 213 import sys 214 PsPsLogger.setLevel(logging.DEBUG) 215 current_argument_position = 1 216 while current_argument_position < len(sys.argv): 217 if sys.argv[current_argument_position] == '-v': 218 PsPsLogger.set_stderr() 219 current_argument_position += 1 220 elif sys.argv[current_argument_position] == 'test': 221 print 'Running unittest for util functions' 222 import doctest 223 doctest.testmod() 224 sys.exit(0)
Note:
See TracChangeset
for help on using the changeset viewer.
