|
35 | 35 | TEST_DATA_DIR = unitTestDataPath()
|
36 | 36 |
|
37 | 37 |
|
| 38 | +def GDAL_COMPUTE_VERSION(maj, min, rev): |
| 39 | + return ((maj) * 1000000 + (min) * 10000 + (rev) * 100) |
| 40 | + |
| 41 | + |
| 42 | +class ErrorReceiver(): |
| 43 | + |
| 44 | + def __init__(self): |
| 45 | + self.msg = None |
| 46 | + |
| 47 | + def receiveError(self, msg): |
| 48 | + self.msg = msg |
| 49 | + |
| 50 | + |
38 | 51 | class TestPyQgsShapefileProvider(unittest.TestCase, ProviderTestCase):
|
39 | 52 |
|
40 | 53 | @classmethod
|
@@ -262,5 +275,49 @@ def testDeleteGeometry(self):
|
262 | 275 | fet = next(vl.getFeatures())
|
263 | 276 | self.assertIsNone(fet.geometry())
|
264 | 277 |
|
| 278 | + def testRepackUnderFileLocks(self): |
| 279 | + ''' Test fix for #15570 and #15393 ''' |
| 280 | + |
| 281 | + # This requires a GDAL fix done per https://trac.osgeo.org/gdal/ticket/6672 |
| 282 | + # but on non-Windows version the test would succeed |
| 283 | + if int(osgeo.gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 1, 2): |
| 284 | + return |
| 285 | + |
| 286 | + tmpdir = tempfile.mkdtemp() |
| 287 | + self.dirs_to_cleanup.append(tmpdir) |
| 288 | + srcpath = os.path.join(TEST_DATA_DIR, 'provider') |
| 289 | + for file in glob.glob(os.path.join(srcpath, 'shapefile.*')): |
| 290 | + shutil.copy(os.path.join(srcpath, file), tmpdir) |
| 291 | + datasource = os.path.join(tmpdir, 'shapefile.shp') |
| 292 | + |
| 293 | + vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr') |
| 294 | + feature_count = vl.featureCount() |
| 295 | + |
| 296 | + # Keep a file descriptor opened on the .dbf, .shp and .shx |
| 297 | + f_shp = open(os.path.join(tmpdir, 'shapefile.shp'), 'rb') |
| 298 | + f_shx = open(os.path.join(tmpdir, 'shapefile.shx'), 'rb') |
| 299 | + f_dbf = open(os.path.join(tmpdir, 'shapefile.dbf'), 'rb') |
| 300 | + |
| 301 | + # Delete a feature |
| 302 | + self.assertTrue(vl.startEditing()) |
| 303 | + self.assertTrue(vl.deleteFeature(1)) |
| 304 | + |
| 305 | + # Commit changes and check no error is emitted |
| 306 | + cbk = ErrorReceiver() |
| 307 | + vl.dataProvider().raiseError.connect(cbk.receiveError) |
| 308 | + self.assertTrue(vl.commitChanges()) |
| 309 | + self.assertIsNone(cbk.msg) |
| 310 | + |
| 311 | + vl = None |
| 312 | + |
| 313 | + del f_shp |
| 314 | + del f_shx |
| 315 | + del f_dbf |
| 316 | + |
| 317 | + # Test repacking has been done |
| 318 | + ds = osgeo.ogr.Open(datasource) |
| 319 | + self.assertTrue(ds.GetLayer(0).GetFeatureCount(), feature_count - 1) |
| 320 | + ds = None |
| 321 | + |
265 | 322 | if __name__ == '__main__':
|
266 | 323 | unittest.main()
|
0 commit comments