casaconfig 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- casaconfig/__init__.py +15 -0
- casaconfig/__main__.py +143 -0
- casaconfig/config.py +155 -0
- casaconfig/private/CasaconfigErrors.py +42 -0
- casaconfig/private/__init__.py +0 -0
- casaconfig/private/casasiteconfig_example.py +19 -0
- casaconfig/private/config_defaults.py +50 -0
- casaconfig/private/config_defaults_static.py +56 -0
- casaconfig/private/data_available.py +88 -0
- casaconfig/private/data_update.py +364 -0
- casaconfig/private/do_auto_updates.py +77 -0
- casaconfig/private/do_pull_data.py +136 -0
- casaconfig/private/get_argparser.py +31 -0
- casaconfig/private/get_config.py +38 -0
- casaconfig/private/get_data_info.py +227 -0
- casaconfig/private/get_data_lock.py +86 -0
- casaconfig/private/io_redirect.py +74 -0
- casaconfig/private/measures_available.py +59 -0
- casaconfig/private/measures_update.py +387 -0
- casaconfig/private/print_log_messages.py +57 -0
- casaconfig/private/pull_data.py +315 -0
- casaconfig/private/read_readme.py +60 -0
- casaconfig/private/set_casacore_path.py +62 -0
- casaconfig/private/summary.py +90 -0
- casaconfig/private/update_all.py +123 -0
- casaconfig-1.0.2.dist-info/LICENSE +201 -0
- casaconfig-1.0.2.dist-info/METADATA +266 -0
- casaconfig-1.0.2.dist-info/RECORD +31 -0
- casaconfig-1.0.2.dist-info/WHEEL +5 -0
- casaconfig-1.0.2.dist-info/top_level.txt +2 -0
- tests/test_casaconfig.py +860 -0
tests/test_casaconfig.py
ADDED
@@ -0,0 +1,860 @@
|
|
1
|
+
import unittest
|
2
|
+
import os, shutil, stat, sys, subprocess, time
|
3
|
+
from datetime import date, timedelta
|
4
|
+
import site
|
5
|
+
sitepackages = site.getsitepackages()[0]
|
6
|
+
|
7
|
+
import casaconfig
|
8
|
+
|
9
|
+
class casaconfig_test(unittest.TestCase):
|
10
|
+
|
11
|
+
def setUp(self):
|
12
|
+
if os.path.isfile(os.path.expanduser("~/.casa/config.py")):
|
13
|
+
os.replace(os.path.expanduser("~/.casa/config.py"), os.path.expanduser("~/.casa/config.py.user"))
|
14
|
+
|
15
|
+
self.test_configpath = os.path.join(os.path.expanduser("~/.casa/"),"config.py")
|
16
|
+
self.test_siteconfigpath = os.path.join(os.getcwd(),'testsiteconfig.py')
|
17
|
+
|
18
|
+
# testmeasures is used for measures-only tests
|
19
|
+
# testrundata is used for full data install tests (at least casarundata is installed, which includes measures)
|
20
|
+
# emptymeasures is used to test failure modes
|
21
|
+
|
22
|
+
self.testMeasPath = os.path.join(os.getcwd(),'testmeasures')
|
23
|
+
self.testRundataPath = os.path.join(os.getcwd(),'testrundata')
|
24
|
+
self.emptyPath = os.path.join(os.getcwd(), 'emptymeasures')
|
25
|
+
|
26
|
+
# this is set when needed and used if set, only query available versions once
|
27
|
+
self.meas_avail = None
|
28
|
+
|
29
|
+
# just in case something has left them populated
|
30
|
+
self.rmTestDirs()
|
31
|
+
|
32
|
+
def tearDown(self):
|
33
|
+
for f in [self.test_configpath, self.test_siteconfigpath]:
|
34
|
+
if os.path.isfile(f):
|
35
|
+
os.remove(f)
|
36
|
+
|
37
|
+
self.rmTestDirs();
|
38
|
+
|
39
|
+
if os.path.isfile(os.path.expanduser("~/.casa/config.py.user")):
|
40
|
+
os.replace(os.path.expanduser("~/.casa/config.py.user"), os.path.expanduser("~/.casa/config.py"))
|
41
|
+
|
42
|
+
def rmTestDirs(self):
|
43
|
+
if os.path.exists(self.testMeasPath):
|
44
|
+
shutil.rmtree(self.testMeasPath)
|
45
|
+
|
46
|
+
if os.path.exists(self.testRundataPath):
|
47
|
+
# make sure this has write permissions, they can get lost if a test fails badly
|
48
|
+
pstat = os.stat(self.testRundataPath).st_mode
|
49
|
+
yes_write = stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH
|
50
|
+
pstat = pstat | yes_write
|
51
|
+
os.chmod(self.testRundataPath,pstat)
|
52
|
+
shutil.rmtree(self.testRundataPath)
|
53
|
+
|
54
|
+
if os.path.exists(self.emptyPath):
|
55
|
+
shutil.rmtree(self.emptyPath)
|
56
|
+
|
57
|
+
def get_meas_avail(self) :
|
58
|
+
# this caches the list of available measures so measures_available() should only be called once for use by all tests
|
59
|
+
if self.meas_avail is None:
|
60
|
+
self.meas_avail = casaconfig.measures_available()
|
61
|
+
return self.meas_avail
|
62
|
+
|
63
|
+
def populate_testmeasures(self):
|
64
|
+
# ensures that there's some casaconfig populated measures at self.testMeasPath
|
65
|
+
# if there's a known version there it leave it as is
|
66
|
+
# if the data info is None then it populates it with the most recent measures and extracts the observatory table
|
67
|
+
# the data info version can not be illegal or unknown (something unexpected is already there)
|
68
|
+
# this function works as a test, but it happens on demand in an attempt to limit the calls to update_measures
|
69
|
+
|
70
|
+
dataInfo = casaconfig.get_data_info(self.testMeasPath, type='measures')
|
71
|
+
if dataInfo is not None:
|
72
|
+
version = dataInfo['version']
|
73
|
+
self.assertTrue(not (version=="unknown" or version=="illegal"), "unexpected measures version in populate_testmeasures at %s : %s" % (self.testMeasPath,version))
|
74
|
+
|
75
|
+
# it seems to be a valid measures installation, leave as is
|
76
|
+
return
|
77
|
+
|
78
|
+
# install the most recent available
|
79
|
+
# since this is new measures install at path it needs to extract the Observatory table, which requires force to be True
|
80
|
+
measVers = self.get_meas_avail()[-1]
|
81
|
+
casaconfig.measures_update(self.testMeasPath, version=measVers, force=True, use_astron_obs_table=True)
|
82
|
+
|
83
|
+
# check version (this makes this function a test, but it's used as needed elsewhere)
|
84
|
+
dataInfo = casaconfig.get_data_info(self.testMeasPath, type='measures')
|
85
|
+
self.assertTrue(dataInfo['version']==measVers,"unexpected version installed by populate_testmeasures at %s : %s != %s" % (self.testMeasPath, dataInfo['version'], measVers))
|
86
|
+
|
87
|
+
def populate_testrundata(self):
|
88
|
+
# ensures that there's some casaconfig populated casarundata at self.testMeasPath
|
89
|
+
# if there's a known version there it leave it as is
|
90
|
+
# if the data info is None then it populates it with the most recent casarundata
|
91
|
+
# the data info version can not be illegal or unknown (something unexpected is already there)
|
92
|
+
# this function works as a test, but it happens on demand in an attempt to limit the calls to pull_data
|
93
|
+
|
94
|
+
dataInfo = casaconfig.get_data_info(self.testRundataPath, type='casarundata')
|
95
|
+
if dataInfo is not None:
|
96
|
+
version = dataInfo['version']
|
97
|
+
self.assertTrue(not (version=="unknown" or version=="illegal"), "unexpected casarundata version in populate_testrundata at %s : %s" % (self.testRundataPath,version))
|
98
|
+
|
99
|
+
# it seems to be a valid casarundata installation, leave as is
|
100
|
+
return
|
101
|
+
|
102
|
+
# make sure it has write permissions, they can get lost if a test fails badly
|
103
|
+
if os.path.exists(self.testRundataPath):
|
104
|
+
pstat = os.stat(self.testRundataPath).st_mode
|
105
|
+
yes_write = stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH
|
106
|
+
pstat = pstat | yes_write
|
107
|
+
os.chmod(self.testRundataPath,pstat)
|
108
|
+
|
109
|
+
# watch for failed test attempts that tweak the readme files : restore the original readme files if they are found
|
110
|
+
if os.path.exists(os.path.join(self.testRundataPath,'readme.txt.orig')):
|
111
|
+
os.replace(os.path.join(self.testRundataPath,'readme.txt.orig'), os.path.join(self.testRundataPath,'readme.txt'))
|
112
|
+
if os.path.exists(os.path.join(self.testRundataPath,'geodetic/readme.txt.orig')):
|
113
|
+
os.replace(os.path.join(self.testRundataPath,'geodetic/readme.txt.orig'), os.path.join(self.testRundataPath,'geodetic/readme.txt.orig'))
|
114
|
+
|
115
|
+
# install the most recent available
|
116
|
+
# this query is cheap, don't cache it
|
117
|
+
rundataVers = casaconfig.data_available()[-1]
|
118
|
+
casaconfig.pull_data(self.testRundataPath, version=rundataVers)
|
119
|
+
|
120
|
+
# check version (this makes this function a test, but it's used as needed elsewhere)
|
121
|
+
dataInfo = casaconfig.get_data_info(self.testRundataPath, type='casarundata')
|
122
|
+
self.assertTrue(dataInfo['version']==rundataVers, "unexpected version installed by populate_testrundata at %s : %s != %s" % (self.testRundataPath, dataInfo['version'], rundataVers))
|
123
|
+
|
124
|
+
def test_file_exists(self):
|
125
|
+
'''Test Default config.py exists in casaconfig module'''
|
126
|
+
self.assertTrue(os.path.isfile('{}/casaconfig/config.py'.format(sitepackages)))
|
127
|
+
|
128
|
+
@unittest.skipIf(not os.path.exists(os.path.join(sitepackages,'casatools')), "casatools not found")
|
129
|
+
def test_import_casatools_bad_measurespath(self):
|
130
|
+
'''Test that import casatools will return ImportError with measurespath set to an empty directory that cannot be written to'''
|
131
|
+
# Due to casatools / casaconfig caching, run the import of casatools and read stdout/stderr for ImportError
|
132
|
+
# after first creating an empty measurespath directory with the write permissions turned off
|
133
|
+
# and then creating a test config file using the path to that directory as measurespath
|
134
|
+
|
135
|
+
if (not os.path.exists(self.emptyPath)):
|
136
|
+
os.mkdir(self.emptyPath)
|
137
|
+
|
138
|
+
# the current permissions
|
139
|
+
pstat = stat.S_IMODE(os.stat(self.emptyPath).st_mode)
|
140
|
+
# a bitmask that's the opposite of all of the write permission bits
|
141
|
+
no_write = ~stat.S_IWUSR & ~stat.S_IWGRP & ~stat.S_IWOTH
|
142
|
+
# remove the write permissions
|
143
|
+
pstat = pstat & no_write
|
144
|
+
os.chmod(self.emptyPath,pstat)
|
145
|
+
|
146
|
+
f = open(self.test_configpath,"w")
|
147
|
+
f.write("# Test Config File\n")
|
148
|
+
f.write("measurespath='%s'\n" % self.emptyPath)
|
149
|
+
f.close()
|
150
|
+
|
151
|
+
# ensure that any site config is not used
|
152
|
+
proc = subprocess.Popen('{} -c "import casatools" --nositeconfig'.format(sys.executable), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
153
|
+
(output, _) = proc.communicate()
|
154
|
+
|
155
|
+
p_status = proc.wait()
|
156
|
+
ref = True if "NotWritable" in str(output) else False
|
157
|
+
self.assertTrue(ref, "NotWritable Not Found")
|
158
|
+
|
159
|
+
def test_casaconfig_measures_available(self):
|
160
|
+
'''Test That Today or Yesterday measures data is returned'''
|
161
|
+
|
162
|
+
today = date.today()
|
163
|
+
yesterday = today - timedelta(days=1)
|
164
|
+
measuresdata_today = "WSRT_Measures_{}-160001.ztar".format(today.strftime("%Y%m%d"))
|
165
|
+
measuresdata_yesterday= "WSRT_Measures_{}-160001.ztar".format(yesterday.strftime("%Y%m%d"))
|
166
|
+
|
167
|
+
self.assertTrue(any(elem in self.get_meas_avail() for elem in [measuresdata_today, measuresdata_yesterday]))
|
168
|
+
|
169
|
+
def test_casaconfig_measures_update(self):
|
170
|
+
'''Test downgrade to upgrade measures data to location'''
|
171
|
+
|
172
|
+
# make sure something is already there
|
173
|
+
self.populate_testmeasures()
|
174
|
+
versInstalled = casaconfig.get_data_info(path=self.testMeasPath, type='measures')['version']
|
175
|
+
|
176
|
+
# find the most recent version not installed at testPath
|
177
|
+
vers = None
|
178
|
+
for vers in reversed(self.get_meas_avail()):
|
179
|
+
if vers != versInstalled:
|
180
|
+
break
|
181
|
+
|
182
|
+
# install that one
|
183
|
+
casaconfig.measures_update(self.testMeasPath, version=vers, logger=None)
|
184
|
+
|
185
|
+
# make sure that was just installed
|
186
|
+
newVers = casaconfig.get_data_info(path=self.testMeasPath, type='measures')['version']
|
187
|
+
|
188
|
+
self.assertTrue(newVers == vers)
|
189
|
+
|
190
|
+
@unittest.skipIf(not os.path.exists(os.path.join(sitepackages,'casatools')), "casatools not found")
|
191
|
+
def test_read_measurespath_from_user_config(self):
|
192
|
+
'''Test casaconfig downloads specific measures data to location and casatools reads that data location'''
|
193
|
+
|
194
|
+
# this requires that there be the full casarundata already installed
|
195
|
+
self.populate_testrundata()
|
196
|
+
|
197
|
+
# use the most recent version
|
198
|
+
vers = self.get_meas_avail()[-1]
|
199
|
+
|
200
|
+
# if that version is the one already installed then go back to the previous measures version
|
201
|
+
if (casaconfig.get_data_info(path=self.testRundataPath, type='measures')['version'] == vers) :
|
202
|
+
vers = self.get_meas_avail()[-2]
|
203
|
+
|
204
|
+
# start a fresh process with a test config file setting measurespath to the testrundata
|
205
|
+
# directory; in that process, import casaconfig and update the measures data to vers
|
206
|
+
# then import casatools and verify that utils measurespath agrees with casaconfig measurespath
|
207
|
+
|
208
|
+
fc = open(self.test_configpath,"w")
|
209
|
+
fc.write("# Test Config File\n")
|
210
|
+
fc.write('measurespath = "{}"\n'.format(self.testRundataPath))
|
211
|
+
fc.close()
|
212
|
+
|
213
|
+
# the test script to execute via the "-c" option in the process
|
214
|
+
# the string is enclosed in double quotes when used, so only single quotes should appear within the string
|
215
|
+
test_string = ''
|
216
|
+
test_string += "import casaconfig; "
|
217
|
+
test_string += "casaconfig.measures_update(path='{}',version='{}',force=False,logger=None); ".format(self.testRundataPath,vers)
|
218
|
+
test_string += "import casatools; "
|
219
|
+
test_string += "assert('{}' == casatools.utils.utils().measurespath())".format(self.testRundataPath)
|
220
|
+
|
221
|
+
# ensure that no site config file is used
|
222
|
+
proc = subprocess.Popen('{} -c "{}" --nositeconfig'.format(sys.executable,test_string), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
223
|
+
(output, _) = proc.communicate()
|
224
|
+
|
225
|
+
p_status = proc.wait()
|
226
|
+
|
227
|
+
ref = False if "AssertionError" in str(output) else True
|
228
|
+
self.assertTrue(ref, "AssertionError seen in output : expected utils().measurespath() was not seen")
|
229
|
+
|
230
|
+
# final check that the expected version is now installed
|
231
|
+
installedVers = casaconfig.get_data_info(path=self.testRundataPath,type='measures')['version']
|
232
|
+
self.assertTrue(installedVers == vers, "expected version was not installed : %s != %s" % (installedVers, vers))
|
233
|
+
|
234
|
+
@unittest.skipIf(not os.path.exists(os.path.join(sitepackages,'casatools')), "casatools not found")
|
235
|
+
def test_auto_update_measures(self):
|
236
|
+
'''Test Automatic Measures Updates to measurespath'''
|
237
|
+
|
238
|
+
# this requires that there be the full casarundata already installed
|
239
|
+
self.populate_testrundata()
|
240
|
+
|
241
|
+
# make sure the installed version is not the most recent one
|
242
|
+
latestVers = self.get_meas_avail()[-1]
|
243
|
+
versInstalled = casaconfig.get_data_info(self.testRundataPath,type='measures')['version']
|
244
|
+
if (versInstalled == latestVers) :
|
245
|
+
# force an install to the version before the most recent
|
246
|
+
casaconfig.measures_update(self.testRundataPath, version=self.get_meas_avail()[-2], force=True, logger=None)
|
247
|
+
# double check that that worked
|
248
|
+
versInstalled = casaconfig.get_data_info(self.testRundataPath,type='measures')['version']
|
249
|
+
self.assertTrue(versInstalled == self.get_meas_avail()[-2],"downgrade of measures to %s failed at %s, installed is %s" % (self.get_meas_avail()[-2], self.testRundataPath, versInstalled))
|
250
|
+
|
251
|
+
# make sure the timestamp the measures readme files is more than 24 hrs old
|
252
|
+
measuresReadmePath = os.path.join(self.testRundataPath,'geodetic/readme.txt')
|
253
|
+
olderTime = time.time()-2.*24*60*60
|
254
|
+
os.utime(measuresReadmePath,(olderTime,olderTime))
|
255
|
+
|
256
|
+
f = open(self.test_configpath,"w")
|
257
|
+
f.write("# Test Config File\n")
|
258
|
+
f.write('measurespath = "{}"\n'.format(self.testRundataPath))
|
259
|
+
f.write('measures_auto_update = True\n')
|
260
|
+
f.write('data_auto_update = False\n')
|
261
|
+
f.close()
|
262
|
+
|
263
|
+
# start a new casatools, which should update the measures to the most recent version
|
264
|
+
# make sure no site config file is used
|
265
|
+
proc = subprocess.Popen('{} -c "import casatools" --nositeconfig'.format(sys.executable), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
266
|
+
(output, _) = proc.communicate()
|
267
|
+
|
268
|
+
p_status = proc.wait()
|
269
|
+
|
270
|
+
# output should contain the latest version string
|
271
|
+
ref = self.get_meas_avail()[-1] in str(output)
|
272
|
+
self.assertTrue(ref, "Update Failed")
|
273
|
+
|
274
|
+
@unittest.skipIf(not os.path.exists(os.path.join(sitepackages,'casatools')), "casatools not found")
|
275
|
+
def test_auto_install_data(self):
|
276
|
+
'''Test auto install of all data to measurespath on casatools startup'''
|
277
|
+
|
278
|
+
# make sure that testrundata does not exist
|
279
|
+
if os.path.exists(self.testRundataPath):
|
280
|
+
shutil.rmtree(self.testRundataPath)
|
281
|
+
|
282
|
+
# set the user's config file to use testRundataPath as measurespath, with auto updates on
|
283
|
+
fc = open(self.test_configpath,"w")
|
284
|
+
fc.write("# Test Config File\n")
|
285
|
+
fc.write('measurespath = "{}"\n'.format(self.testRundataPath))
|
286
|
+
fc.write('data_auto_update = True\n')
|
287
|
+
fc.write('measures_auto_update = True\n')
|
288
|
+
fc.close()
|
289
|
+
|
290
|
+
# it should fail if this attempt is made when that location does not exist
|
291
|
+
# ensure that no site config file is used
|
292
|
+
proc = subprocess.Popen('{} -c "import casatools" --nositeconfig'.format(sys.executable), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
293
|
+
(output, _) = proc.communicate()
|
294
|
+
|
295
|
+
p_status = proc.wait()
|
296
|
+
ref = True if "AutoUpdatesNotAllowed" in str(output) else False
|
297
|
+
self.assertTrue(ref, "AutoUpdatesNotAllowed not found")
|
298
|
+
|
299
|
+
# create testRundataPath and try again
|
300
|
+
os.mkdir(self.testRundataPath)
|
301
|
+
proc = subprocess.Popen('{} -c "import casatools" --nositeconfig'.format(sys.executable), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
302
|
+
(output, _) = proc.communicate()
|
303
|
+
|
304
|
+
p_status = proc.wait()
|
305
|
+
ref = True if "ImportError" not in str(output) else False
|
306
|
+
self.assertTrue(ref, "ImportError Found")
|
307
|
+
|
308
|
+
# final check that the expected versions were found
|
309
|
+
# if the most recent rundata is < 1 day old then measuresdata will also be < 1 day old the most recent measures on astron
|
310
|
+
# may be newer, also, do not rely on the cached measures versions to check here
|
311
|
+
dataInfo = casaconfig.get_data_info(self.testRundataPath)
|
312
|
+
expectedDataVersion = casaconfig.data_available()[-1]
|
313
|
+
availMeasures = casaconfig.measures_available()
|
314
|
+
expectedMeasVersion = availMeasures[-1]
|
315
|
+
ref = (dataInfo['casarundata']['version'] == expectedDataVersion) and (dataInfo['measures']['version'] == expectedMeasVersion)
|
316
|
+
if not ref:
|
317
|
+
# try the penultimate version
|
318
|
+
expectedMeasVersion = availMeasures[-2]
|
319
|
+
ref = (dataInfo['casarundata']['version'] == expectedDataVersion) and (dataInfo['measures']['version'] == expectedMeasVersion)
|
320
|
+
|
321
|
+
self.assertTrue(ref, "Expected versions not installed")
|
322
|
+
|
323
|
+
def test_daily_update(self):
|
324
|
+
'''test that updates do not happen if the installed data is less than 1 day old and do happen when they are older'''
|
325
|
+
|
326
|
+
# start with an empty testrundata
|
327
|
+
if os.path.exists(self.testRundataPath):
|
328
|
+
shutil.rmtree(self.testRundataPath)
|
329
|
+
|
330
|
+
# populate it with an older version of casarundata
|
331
|
+
oldVersion = casaconfig.data_available()[-2]
|
332
|
+
casaconfig.pull_data(self.testRundataPath, version=oldVersion)
|
333
|
+
|
334
|
+
# get the versions installed
|
335
|
+
dataInfo = casaconfig.get_data_info(self.testRundataPath)
|
336
|
+
rundataVers = dataInfo['casarundata']['version']
|
337
|
+
rundataAge = dataInfo['casarundata']['age']
|
338
|
+
measVers = dataInfo['measures']['version']
|
339
|
+
measAge = dataInfo['measures']['age']
|
340
|
+
|
341
|
+
self.assertTrue(oldVersion == rundataVers, "old version was not installed as expected")
|
342
|
+
self.assertTrue((rundataAge < 1.0) and (measAge < 1.0), "recent installed old versions do not have the expected recent age")
|
343
|
+
|
344
|
+
# updates should do nothing
|
345
|
+
casaconfig.data_update(self.testRundataPath)
|
346
|
+
casaconfig.measures_update(self.testRundataPath)
|
347
|
+
|
348
|
+
# versions should be unchanged
|
349
|
+
dataInfo = casaconfig.get_data_info(self.testRundataPath)
|
350
|
+
checkRundataVers = dataInfo['casarundata']['version']
|
351
|
+
checkMeasVers = dataInfo['measures']['version']
|
352
|
+
|
353
|
+
self.assertTrue((checkRundataVers == rundataVers) and (checkMeasVers == measVers), "unexpected update of recently installed data")
|
354
|
+
|
355
|
+
# back date measures and try to update
|
356
|
+
measuresReadmePath = os.path.join(self.testRundataPath,'geodetic/readme.txt')
|
357
|
+
olderTime = time.time()-2.*24*60*60
|
358
|
+
os.utime(measuresReadmePath,(olderTime,olderTime))
|
359
|
+
|
360
|
+
# measures should update, rundata should not
|
361
|
+
casaconfig.data_update(self.testRundataPath)
|
362
|
+
casaconfig.measures_update(self.testRundataPath)
|
363
|
+
|
364
|
+
dataInfo = casaconfig.get_data_info(self.testRundataPath)
|
365
|
+
checkRundataVers = dataInfo['casarundata']['version']
|
366
|
+
checkRundataAge = dataInfo['casarundata']['age']
|
367
|
+
checkMeasVers = dataInfo['measures']['version']
|
368
|
+
checkMeasAge = dataInfo['measures']['age']
|
369
|
+
|
370
|
+
self.assertTrue((checkRundataVers == rundataVers) and (checkMeasVers != measVers), "versions are not as expected after a measures update")
|
371
|
+
|
372
|
+
# backdate the rundata
|
373
|
+
rundataReadmePath = os.path.join(self.testRundataPath,'readme.txt')
|
374
|
+
os.utime(rundataReadmePath,(olderTime,olderTime))
|
375
|
+
|
376
|
+
# data should update now
|
377
|
+
casaconfig.data_update(self.testRundataPath)
|
378
|
+
# measures should also update now, unless the casaconfig that was just installed was built very recently (within the last day)
|
379
|
+
# first, check the installed measures version, if that IS the most recent version then artifically install the previous one
|
380
|
+
measDataVers = casaconfig.get_data_info(self.testRundataPath, type='measures')['version']
|
381
|
+
if measDataVers == self.get_meas_avail()[-1] :
|
382
|
+
casaconfig.measures_update(self.testRundataPath,version=self.get_meas_avail()[-2])
|
383
|
+
# and backdate the measures data to be sure it updates
|
384
|
+
os.utime(measuresReadmePath,(olderTime,olderTime))
|
385
|
+
|
386
|
+
# now we should expect measures_update to install the most recent version
|
387
|
+
casaconfig.measures_update(self.testRundataPath)
|
388
|
+
|
389
|
+
dataInfo = casaconfig.get_data_info(self.testRundataPath)
|
390
|
+
checkRundataVers = dataInfo['casarundata']['version']
|
391
|
+
checkMeasVers = dataInfo['measures']['version']
|
392
|
+
|
393
|
+
# IF a new measures tarball was made available while this test was running then the updated measure here may be one more than the previous
|
394
|
+
# update, so long as this is the most recent measures this test is OK (do not rely on the cached values for this check)
|
395
|
+
expectedMeasVers = casaconfig.measures_available()[-1]
|
396
|
+
self.assertTrue((checkRundataVers != rundataVers) and (checkMeasVers == expectedMeasVers), "versions are not as expected after a data update")
|
397
|
+
|
398
|
+
def do_config_check(self, expectedDict, noconfig, nositeconfig):
|
399
|
+
'''Launch a separate python to load the config files, using --noconfig --nositeconfig as requested, the expectedDict contains expected values'''
|
400
|
+
|
401
|
+
# the test script produces a dictionary of key,value where the keys are
|
402
|
+
# loaded, failed, measurespath, measures_auto_update, and data_auto_update
|
403
|
+
# all of the values are strings
|
404
|
+
# loaded and failed are len(load_success()) and len(load_failure)
|
405
|
+
# measurespath, measures_auto_update, data_auto_update are those values
|
406
|
+
|
407
|
+
# returns a non-empty string if any of the expected values aren't found in the parsed output of from python subprocess
|
408
|
+
|
409
|
+
# used by test_config_import
|
410
|
+
|
411
|
+
msgs = ""
|
412
|
+
|
413
|
+
# test script to execute via the "-c" option in the process
|
414
|
+
# the string is enclosed in double quotes when used, so only single quotes should appear within the string
|
415
|
+
test_string = ''
|
416
|
+
test_string += "from casaconfig import config; "
|
417
|
+
test_string += "print('failures :%s ' % config.load_failure()); "
|
418
|
+
test_string += "print('loaded : %s' % len(config.load_success())); "
|
419
|
+
test_string += "print('failed : %s' % len(config.load_failure())); "
|
420
|
+
test_string += "print('measurespath : %s' % config.measurespath); "
|
421
|
+
test_string += "print('measures_auto_update : %s' % config.measures_auto_update); "
|
422
|
+
test_string += "print('data_auto_update : %s' % config.data_auto_update); "
|
423
|
+
|
424
|
+
args = ""
|
425
|
+
if noconfig:
|
426
|
+
args += "--noconfig "
|
427
|
+
if nositeconfig:
|
428
|
+
args += "--nositeconfig "
|
429
|
+
|
430
|
+
proc = subprocess.Popen('{} -c "{}" {}'.format(sys.executable,test_string,args), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
431
|
+
(output, _) = proc.communicate()
|
432
|
+
|
433
|
+
p_status = proc.wait()
|
434
|
+
|
435
|
+
resultsDict = {}
|
436
|
+
for l in output.decode('utf-8').splitlines():
|
437
|
+
parts = l.split(":")
|
438
|
+
if (len(parts) != 2): continue
|
439
|
+
|
440
|
+
resultsDict[parts[0].strip()] = parts[1].strip()
|
441
|
+
|
442
|
+
for k in expectedDict:
|
443
|
+
if k not in resultsDict:
|
444
|
+
msgs += 'expected result for "{}" not found; '.format(k)
|
445
|
+
else:
|
446
|
+
if expectedDict[k] != resultsDict[k]:
|
447
|
+
msgs += 'unexpected result for "{}" : "{}" vs "{}"; '.format(k, expectedDict[k], resultsDict[k])
|
448
|
+
return msgs
|
449
|
+
|
450
|
+
|
451
|
+
def test_config_import(self):
|
452
|
+
'''Tests of the config import'''
|
453
|
+
|
454
|
+
# the user's config file
|
455
|
+
f = open(self.test_configpath,"w")
|
456
|
+
f.write("# Test Config File\n")
|
457
|
+
f.write('measurespath = "{}"\n'.format(self.testRundataPath))
|
458
|
+
f.close()
|
459
|
+
|
460
|
+
# the test site config file
|
461
|
+
f = open(self.test_siteconfigpath,"w")
|
462
|
+
f.write("#Test Siteconfig File\n")
|
463
|
+
f.write('measurespath = "/path/doesnot/exist"\n')
|
464
|
+
f.write('measures_auto_update = False\n')
|
465
|
+
f.write('data_auto_update = False\n')
|
466
|
+
f.close()
|
467
|
+
|
468
|
+
|
469
|
+
# set the casasiteconfig env value
|
470
|
+
os.environ['CASASITECONFIG'] = self.test_siteconfigpath
|
471
|
+
|
472
|
+
expectedDict = {"loaded":"3",
|
473
|
+
"failed":"0",
|
474
|
+
"measurespath":self.testRundataPath,
|
475
|
+
"measures_auto_update":"False",
|
476
|
+
"data_auto_update":"False"}
|
477
|
+
|
478
|
+
# test with both, 2 files loaded, no errors, user's measurespath, site's auto update values
|
479
|
+
|
480
|
+
msgs = self.do_config_check(expectedDict, noconfig=False, nositeconfig=False)
|
481
|
+
self.assertTrue(len(msgs)==0, "failed : config import with both user and site config files : " + msgs)
|
482
|
+
|
483
|
+
# test with just the defaults
|
484
|
+
|
485
|
+
expectedDict["loaded"] = "1"
|
486
|
+
expectedDict["measurespath"] = os.path.abspath(os.path.expanduser('~/.casa/data'))
|
487
|
+
expectedDict["measures_auto_update"] = "True"
|
488
|
+
expectedDict["data_auto_update"] = "True"
|
489
|
+
msgs = self.do_config_check(expectedDict, noconfig=True, nositeconfig=True)
|
490
|
+
self.assertTrue(len(msgs)==0, "failed : config import of only defaults : " + msgs)
|
491
|
+
|
492
|
+
# test with user + defaults, no site
|
493
|
+
expectedDict["loaded"] = "2"
|
494
|
+
expectedDict["measurespath"] = self.testRundataPath
|
495
|
+
msgs = self.do_config_check(expectedDict, noconfig=False, nositeconfig=True)
|
496
|
+
self.assertTrue(len(msgs)==0, "failed : config import ignoring site : " + msgs)
|
497
|
+
|
498
|
+
# test with an error in the site config, should report the error and move on, leaving just the user + default expected values
|
499
|
+
|
500
|
+
f = open(self.test_siteconfigpath,"w")
|
501
|
+
f.write("#Test Siteconfig File with error\n")
|
502
|
+
# the value whatever does not exist
|
503
|
+
f.write('measurespath = whatever\n')
|
504
|
+
f.write('measures_auto_update = False\n')
|
505
|
+
f.write('data_auto_update = False\n')
|
506
|
+
f.close()
|
507
|
+
|
508
|
+
# expect 1 failure, with the user+defaults being the final values
|
509
|
+
expectedDict["failed"] = "1"
|
510
|
+
|
511
|
+
msgs = self.do_config_check(expectedDict, noconfig=False, nositeconfig=False)
|
512
|
+
self.assertTrue(len(msgs)==0, "failed : config import with error in site : " + msgs)
|
513
|
+
|
514
|
+
# unset CASASITECONFIG to ignore the site config file and try again, the problem site config should not be seen
|
515
|
+
os.environ.pop('CASASITECONFIG')
|
516
|
+
|
517
|
+
# the failure is now gone
|
518
|
+
expectedDict["failed"] = "0"
|
519
|
+
|
520
|
+
# but there may be a real site config file in a standard location
|
521
|
+
# auto updates are assumed to be on if there is a site config file
|
522
|
+
has_site_config = os.path.exists("/opt/casa/siteconfig.py") or os.path.exists("/home/casa/casasiteconfig.py")
|
523
|
+
if has_site_config:
|
524
|
+
expectedDict["loaded"] = "3"
|
525
|
+
expectedDict["measures_auto_update"] = "False"
|
526
|
+
expectedDict["data_auto_update"] = "False"
|
527
|
+
|
528
|
+
msgs = self.do_config_check(expectedDict, noconfig=False, nositeconfig=False)
|
529
|
+
self.assertTrue(len(msgs)==0, "failed : config import with CASASITECONFIG unset : " + msgs)
|
530
|
+
|
531
|
+
def test_exceptions_no_data(self):
|
532
|
+
'''test that exceptions that do not require any data happen when expected'''
|
533
|
+
from casaconfig.private.get_data_lock import get_data_lock
|
534
|
+
|
535
|
+
# the tests expect this to not exist, it would be insane if it does, but check anyway
|
536
|
+
self.assertFalse(os.path.exists('/this/does/not/exist/'),"/this/does/not/exist/ shouldn't exist, but apparently it does")
|
537
|
+
|
538
|
+
# AutoUpdatesNotAllowed : path does not exist or is not owned by the user
|
539
|
+
exceptionSeen = False
|
540
|
+
try:
|
541
|
+
# path does not exist - measures_update
|
542
|
+
casaconfig.measures_update(path='/this/does/not/exist/',auto_update_rules=True)
|
543
|
+
except casaconfig.AutoUpdatesNotAllowed:
|
544
|
+
exceptionSeen = True
|
545
|
+
except Exception as exc:
|
546
|
+
print("unexpected exception seen when testing for AutoUpdatesNotAllowed in measures_update using path that should not exist")
|
547
|
+
print(str(exc))
|
548
|
+
|
549
|
+
self.assertTrue(exceptionSeen,"AutoUpdatesNotAllowed not seen as expected in testing measures_update using path that should not exist")
|
550
|
+
|
551
|
+
exceptionSeen = False
|
552
|
+
try:
|
553
|
+
# path does not exist - data_update
|
554
|
+
casaconfig.data_update(path='/this/does/not/exist/',auto_update_rules=True)
|
555
|
+
except casaconfig.AutoUpdatesNotAllowed:
|
556
|
+
exceptionSeen = True
|
557
|
+
except Exception as exc:
|
558
|
+
print("unexpected exception seen when testing for AutoUpdatesNotAllowed in data_update using path that should not exist")
|
559
|
+
print(str(exc))
|
560
|
+
self.assertTrue(exceptionSeen,"AutoUpdatesNotAllowed not seen as expected in testing data_update using path that should not exist")
|
561
|
+
|
562
|
+
# path is not owned by the user, /tmp should be useful in most case, but just in case, skip this if that's not a different user
|
563
|
+
if (os.stat('/tmp').st_uid == os.getuid()):
|
564
|
+
print("skipping AutoUpdatesNotAllowed test for path not owned by the user, /tmp is owned by this user")
|
565
|
+
else:
|
566
|
+
exceptionSeen = False
|
567
|
+
try:
|
568
|
+
casaconfig.measures_update(path='/tmp', auto_update_rules=True)
|
569
|
+
except casaconfig.AutoUpdatesNotAllowed:
|
570
|
+
exceptionSeen = True
|
571
|
+
except Exception as exc:
|
572
|
+
print("unexpected exception seen when testing for AutoUpdatesNotAllowed in measures_update using path not owned by user")
|
573
|
+
print(str(exc))
|
574
|
+
self.assertTrue(exceptionSeen,"AutoUpdatesNotAllowed not seen as expected in testing measures_update using path not owned by user")
|
575
|
+
|
576
|
+
exceptionSeen = False
|
577
|
+
try:
|
578
|
+
casaconfig.data_update(path='/tmp', auto_update_rules=True)
|
579
|
+
except casaconfig.AutoUpdatesNotAllowed:
|
580
|
+
exceptionSeen = True
|
581
|
+
except Exception as exc:
|
582
|
+
print("unexpected exception seen when testing for AutoUpdatesNotAllowed in data_update using path not owned by user")
|
583
|
+
print(str(exc))
|
584
|
+
self.assertTrue(exceptionSeen,"AutoUpdatesNotAllowed not seen as expected in testing data_update using path not owned by user")
|
585
|
+
|
586
|
+
# BadLock
|
587
|
+
# path to lock file does not exist
|
588
|
+
exceptionSeen = False
|
589
|
+
try:
|
590
|
+
fd = get_data_lock('/this/does/not/exist', 'test_exceptions')
|
591
|
+
if fd is not None and not fd.close:
|
592
|
+
# this shouldn't happen, but release the lock if it does
|
593
|
+
fd.close()
|
594
|
+
except casaconfig.BadLock as exc:
|
595
|
+
exceptionSeen = True
|
596
|
+
except Exception as exc:
|
597
|
+
print("unexpected exception seen when testing for BadLock when path does not exist")
|
598
|
+
print(str(exc))
|
599
|
+
self.assertTrue(exceptionSeen,"BadLock not seen as expected in testing path does not exist")
|
600
|
+
|
601
|
+
# lock file is not empty
|
602
|
+
exceptionSeen = False
|
603
|
+
fd = None
|
604
|
+
try:
|
605
|
+
# create a non-empty lock file in the current directory
|
606
|
+
cwd = os.getcwd()
|
607
|
+
f = open(os.path.join(cwd,'data_update.lock'),'w')
|
608
|
+
f.write("This file is not empty\n")
|
609
|
+
f.close()
|
610
|
+
fd = get_data_lock(cwd, 'test_exceptions')
|
611
|
+
if fd is not None and not fd.close:
|
612
|
+
# shouldn't happen, but release the lock if it does
|
613
|
+
fd.close()
|
614
|
+
except casaconfig.BadLock as exc:
|
615
|
+
exceptionSeen = True
|
616
|
+
except Exception as exc:
|
617
|
+
print("unexpected exception seen when testing for BadLock and lock file is not empty")
|
618
|
+
print(str(exc))
|
619
|
+
self.assertTrue(exceptionSeen,"BadLock not seen as expected when lock file is not empty")
|
620
|
+
# clean up
|
621
|
+
os.remove(os.path.join(cwd,'data_update.lock'))
|
622
|
+
|
623
|
+
# NoReadme
|
624
|
+
|
625
|
+
# This should work on any non-open path that isn't a measurespath. I think the cwd will
|
626
|
+
# work just fine for that purposes.
|
627
|
+
|
628
|
+
# data_update NoReadme
|
629
|
+
try:
|
630
|
+
exceptionSeen = False
|
631
|
+
# this check happens before the age is determined, so no need to backdate the readme.txt file here
|
632
|
+
casaconfig.data_update(os.getcwd())
|
633
|
+
except casaconfig.NoReadme as exc:
|
634
|
+
exceptionSeen = True
|
635
|
+
except Exception as exc:
|
636
|
+
print("unexpected exception seen when testing for NoReadme in data_update")
|
637
|
+
print(str(exc))
|
638
|
+
self.assertTrue(exceptionSeen, "NoReadme not seen from data_update")
|
639
|
+
|
640
|
+
# measures_update NoReadme
|
641
|
+
try:
|
642
|
+
exceptionSeen = False
|
643
|
+
# this check happens before the age is determined, so no need to backdate the readme.txt file here
|
644
|
+
casaconfig.measures_update(os.getcwd())
|
645
|
+
except casaconfig.NoReadme as exc:
|
646
|
+
exceptionSeen = True
|
647
|
+
except Exception as exc:
|
648
|
+
print("unexpected exception seen when testing for NoReadme in measures_update")
|
649
|
+
print(str(exc))
|
650
|
+
self.assertTrue(exceptionSeen, "NoReadme not seen from measures_update")
|
651
|
+
|
652
|
+
# NotWritable : path is not writable by the user
|
653
|
+
# use the emptyPath
|
654
|
+
if (not os.path.exists(self.emptyPath)):
|
655
|
+
os.mkdir(self.emptyPath)
|
656
|
+
# the current permissions
|
657
|
+
pstat = stat.S_IMODE(os.stat(self.emptyPath).st_mode)
|
658
|
+
# a bitmask that's the opposite of all of the write permission bits
|
659
|
+
no_write = ~stat.S_IWUSR & ~stat.S_IWGRP & ~stat.S_IWOTH
|
660
|
+
# remove the write permissions
|
661
|
+
pstat = pstat & no_write
|
662
|
+
os.chmod(self.emptyPath,pstat)
|
663
|
+
|
664
|
+
# pull_data NotWritable
|
665
|
+
try:
|
666
|
+
exceptionSeen = False
|
667
|
+
casaconfig.pull_data(self.emptyPath)
|
668
|
+
except casaconfig.NotWritable as exc:
|
669
|
+
exceptionSeen = True
|
670
|
+
except Exception as exc:
|
671
|
+
print("unexpected exception seen when testing for NotWritable in pull_data")
|
672
|
+
print(str(exc))
|
673
|
+
self.assertTrue(exceptionSeen, "NotWritable not seen from pull_data")
|
674
|
+
|
675
|
+
# UnsetMeasurespath : measurespath is None
|
676
|
+
|
677
|
+
# test script, set measurespath to None after config import, it will be used by the measures_update call
|
678
|
+
|
679
|
+
test_string_all = ''
|
680
|
+
test_string_all += "from casaconfig import config; "
|
681
|
+
test_string_all += "config.measurespath = None; "
|
682
|
+
test_string_all += "import casaconfig; "
|
683
|
+
|
684
|
+
# measures_update
|
685
|
+
|
686
|
+
test_string = test_string_all
|
687
|
+
test_string += "casaconfig.measures_update(); "
|
688
|
+
# ensure no site config
|
689
|
+
proc = subprocess.Popen('{} -c "{}" --nositeconfig'.format(sys.executable,test_string), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
690
|
+
(output, _) = proc.communicate()
|
691
|
+
|
692
|
+
p_status = proc.wait()
|
693
|
+
|
694
|
+
ref = True if "UnsetMeasurespath" in str(output) else False
|
695
|
+
self.assertTrue(ref, "UnsetMeasurespath not seen in output for measures_update and measurespath=None")
|
696
|
+
|
697
|
+
# pull_data
|
698
|
+
|
699
|
+
test_string = test_string_all
|
700
|
+
test_string += "casaconfig.pull_data(); "
|
701
|
+
# ensure no site config
|
702
|
+
proc = subprocess.Popen('{} -c "{}" --nositeconfig'.format(sys.executable,test_string), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
703
|
+
(output, _) = proc.communicate()
|
704
|
+
|
705
|
+
p_status = proc.wait()
|
706
|
+
|
707
|
+
ref = True if "UnsetMeasurespath" in str(output) else False
|
708
|
+
self.assertTrue(ref, "UnsetMeasurespath not seen in output for pull_data and measurespath=None")
|
709
|
+
|
710
|
+
# data_update
|
711
|
+
|
712
|
+
test_string = test_string_all
|
713
|
+
test_string += "casaconfig.data_update(); "
|
714
|
+
proc = subprocess.Popen('{} -c "{}" --nositeconfig'.format(sys.executable,test_string), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
715
|
+
(output, _) = proc.communicate()
|
716
|
+
|
717
|
+
p_status = proc.wait()
|
718
|
+
|
719
|
+
ref = True if "UnsetMeasurespath" in str(output) else False
|
720
|
+
self.assertTrue(ref, "UnsetMeasurespath not seen in output for data_update and measurespath=None")
|
721
|
+
|
722
|
+
# get_data_info
|
723
|
+
|
724
|
+
test_string = test_string_all
|
725
|
+
test_string += "di=casaconfig.get_data_info(); "
|
726
|
+
proc = subprocess.Popen('{} -c "{}" --nositeconfig'.format(sys.executable,test_string), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
727
|
+
(output, _) = proc.communicate()
|
728
|
+
|
729
|
+
p_status = proc.wait()
|
730
|
+
|
731
|
+
ref = True if "UnsetMeasurespath" in str(output) else False
|
732
|
+
self.assertTrue(ref, "UnsetMeasurespath not seen in output for get_data_info and measurespath=None")
|
733
|
+
|
734
|
+
# do_auto_updates
|
735
|
+
|
736
|
+
test_string = test_string_all
|
737
|
+
test_string += "casaconfig.do_auto_updates(config); "
|
738
|
+
proc = subprocess.Popen('{} -c "{}" --nositeconfig'.format(sys.executable,test_string), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
|
739
|
+
(output, _) = proc.communicate()
|
740
|
+
|
741
|
+
p_status = proc.wait()
|
742
|
+
|
743
|
+
ref = True if "UnsetMeasurespath" in str(output) else False
|
744
|
+
self.assertTrue(ref, "UnsetMeasurespath not seen in output for do_auto_updates and measurespath=None")
|
745
|
+
|
746
|
+
|
747
|
+
def test_exceptions_with_data(self):
|
748
|
+
'''test that exceptions that require data happen when expected'''
|
749
|
+
|
750
|
+
# these tests requires an already installed set of data
|
751
|
+
self.populate_testrundata()
|
752
|
+
|
753
|
+
# BadReadme
|
754
|
+
|
755
|
+
# create a bad data readme.txt file from the valid one
|
756
|
+
dataReadmePath = os.path.join(self.testRundataPath,'readme.txt')
|
757
|
+
# read in the valid contents
|
758
|
+
with open(dataReadmePath, 'r') as fid:
|
759
|
+
readmeLines = fid.readlines()
|
760
|
+
# rename it to preserve it
|
761
|
+
os.replace(dataReadmePath, os.path.join(self.testRundataPath,'readme.txt.orig'))
|
762
|
+
|
763
|
+
# create a readme that does not include the manifest, use just the first 3 lines
|
764
|
+
with open(dataReadmePath, 'w') as fid:
|
765
|
+
fid.writelines(readmeLines[:3])
|
766
|
+
|
767
|
+
# data_update badreadme test
|
768
|
+
try:
|
769
|
+
exceptionSeen = False
|
770
|
+
# this check happens before the age is determined, so no need to backdate the readme.txt file here
|
771
|
+
casaconfig.data_update(self.testRundataPath)
|
772
|
+
except casaconfig.BadReadme as exc:
|
773
|
+
exceptionSeen = True
|
774
|
+
except Exception as exc:
|
775
|
+
print("unexpected exception seen when testing for BadRadme in data_update")
|
776
|
+
print(str(exc))
|
777
|
+
self.assertTrue(exceptionSeen, "BadReadme not seen from data_update")
|
778
|
+
|
779
|
+
# pull_data badreadme test
|
780
|
+
try:
|
781
|
+
exceptionSeen = False
|
782
|
+
# this check happens before the age is determined, so no need to backdate the readme.txt file here
|
783
|
+
casaconfig.pull_data(self.testRundataPath)
|
784
|
+
except casaconfig.BadReadme as exc:
|
785
|
+
exceptionSeen = True
|
786
|
+
except Exception as exc:
|
787
|
+
print("unexpected exception seen when testing for BadRadme in pull_data")
|
788
|
+
print(str(exc))
|
789
|
+
self.assertTrue(exceptionSeen, "BadReadme not seen from pull_data")
|
790
|
+
|
791
|
+
# restore original data readme.txt
|
792
|
+
os.replace(os.path.join(self.testRundataPath,'readme.txt.orig'), dataReadmePath)
|
793
|
+
|
794
|
+
# do something similar for the measures readme.txt and measures_update
|
795
|
+
|
796
|
+
# create a bad data readme.txt file from the valid one
|
797
|
+
measReadmePath = os.path.join(self.testRundataPath,'geodetic/readme.txt')
|
798
|
+
# read in the valid contents
|
799
|
+
with open(measReadmePath, 'r') as fid:
|
800
|
+
readmeLines = fid.readlines()
|
801
|
+
# rename it to preserve it
|
802
|
+
os.replace(measReadmePath, os.path.join(self.testRundataPath,'geodetic/readme.txt.orig'))
|
803
|
+
|
804
|
+
# create a readme with garbage in the the 2nd line
|
805
|
+
readmeLines[1] = "this is not right"
|
806
|
+
with open(measReadmePath, 'w') as fid:
|
807
|
+
fid.writelines(readmeLines[:3])
|
808
|
+
|
809
|
+
# measures_update badreadme test
|
810
|
+
try:
|
811
|
+
exceptionSeen = False
|
812
|
+
# this check happens before the age is determined, so no need to backdate the readme.txt file here
|
813
|
+
casaconfig.measures_update(self.testRundataPath)
|
814
|
+
except casaconfig.BadReadme as exc:
|
815
|
+
print(str(exc))
|
816
|
+
exceptionSeen = True
|
817
|
+
except Exception as exc:
|
818
|
+
print("unexpected exception seen when testing for BadRadme in measures_update")
|
819
|
+
print(str(exc))
|
820
|
+
self.assertTrue(exceptionSeen, "BadReadme not seen from measures_update")
|
821
|
+
|
822
|
+
# restore original measures readme.txt
|
823
|
+
os.replace(os.path.join(self.testRundataPath,'geodetic/readme.txt.orig'), measReadmePath)
|
824
|
+
|
825
|
+
# NotWritable with measures_update requires that there already be measures data there
|
826
|
+
|
827
|
+
# get the current permissions of the testRundataPath
|
828
|
+
orig_pstat = stat.S_IMODE(os.stat(self.testRundataPath).st_mode)
|
829
|
+
print('orig_pstat = %s' % orig_pstat)
|
830
|
+
# a bitmask that's the opposite of all of the write permission bits
|
831
|
+
no_write = ~stat.S_IWUSR & ~stat.S_IWGRP & ~stat.S_IWOTH
|
832
|
+
# remove the write permissions
|
833
|
+
pstat = orig_pstat & no_write
|
834
|
+
print('pstat = %s' % pstat)
|
835
|
+
os.chmod(self.testRundataPath,pstat)
|
836
|
+
|
837
|
+
|
838
|
+
# measures_update NotWritable
|
839
|
+
try:
|
840
|
+
exceptionSeen = False
|
841
|
+
# force and update to test this exception
|
842
|
+
casaconfig.measures_update(self.testRundataPath, force=True)
|
843
|
+
except casaconfig.NotWritable as exc:
|
844
|
+
exceptionSeen = True
|
845
|
+
except Exception as exc:
|
846
|
+
print("unexpected exception seen when testing for NotWritable in measures_update")
|
847
|
+
print(str(exc))
|
848
|
+
import traceback
|
849
|
+
traceback.print_exc()
|
850
|
+
|
851
|
+
# reset to original permissions before anything else is checked
|
852
|
+
os.chmod(self.testRundataPath,orig_pstat)
|
853
|
+
|
854
|
+
self.assertTrue(exceptionSeen, "NotWritable not seen from measures_update")
|
855
|
+
|
856
|
+
|
857
|
+
|
858
|
+
if __name__ == '__main__':
|
859
|
+
|
860
|
+
unittest.main()
|