|
30 | 30 | TEST_DATA_DIR = unitTestDataPath()
|
31 | 31 |
|
32 | 32 |
|
| 33 | +def GDAL_COMPUTE_VERSION(maj, min, rev): |
| 34 | + return ((maj) * 1000000 + (min) * 10000 + (rev) * 100) |
| 35 | + |
| 36 | + |
| 37 | +class ErrorReceiver(): |
| 38 | + |
| 39 | + def __init__(self): |
| 40 | + self.msg = None |
| 41 | + |
| 42 | + def receiveError(self, msg): |
| 43 | + self.msg = msg |
| 44 | + |
| 45 | + |
33 | 46 | class TestPyQgsShapefileProvider(unittest.TestCase, ProviderTestCase):
|
34 | 47 |
|
35 | 48 | @classmethod
|
@@ -380,5 +393,49 @@ def testDeleteShapes(self):
|
380 | 393 |
|
381 | 394 | vl = None
|
382 | 395 |
|
| 396 | + def testRepackUnderFileLocks(self): |
| 397 | + ''' Test fix for #15570 and #15393 ''' |
| 398 | + |
| 399 | + # This requires a GDAL fix done per https://trac.osgeo.org/gdal/ticket/6672 |
| 400 | + # but on non-Windows version the test would succeed |
| 401 | + if int(osgeo.gdal.VersionInfo('VERSION_NUM')) < GDAL_COMPUTE_VERSION(2, 1, 2): |
| 402 | + return |
| 403 | + |
| 404 | + tmpdir = tempfile.mkdtemp() |
| 405 | + self.dirs_to_cleanup.append(tmpdir) |
| 406 | + srcpath = os.path.join(TEST_DATA_DIR, 'provider') |
| 407 | + for file in glob.glob(os.path.join(srcpath, 'shapefile.*')): |
| 408 | + shutil.copy(os.path.join(srcpath, file), tmpdir) |
| 409 | + datasource = os.path.join(tmpdir, 'shapefile.shp') |
| 410 | + |
| 411 | + vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr') |
| 412 | + feature_count = vl.featureCount() |
| 413 | + |
| 414 | + # Keep a file descriptor opened on the .dbf, .shp and .shx |
| 415 | + f_shp = open(os.path.join(tmpdir, 'shapefile.shp'), 'rb') |
| 416 | + f_shx = open(os.path.join(tmpdir, 'shapefile.shx'), 'rb') |
| 417 | + f_dbf = open(os.path.join(tmpdir, 'shapefile.dbf'), 'rb') |
| 418 | + |
| 419 | + # Delete a feature |
| 420 | + self.assertTrue(vl.startEditing()) |
| 421 | + self.assertTrue(vl.deleteFeature(1)) |
| 422 | + |
| 423 | + # Commit changes and check no error is emitted |
| 424 | + cbk = ErrorReceiver() |
| 425 | + vl.dataProvider().raiseError.connect(cbk.receiveError) |
| 426 | + self.assertTrue(vl.commitChanges()) |
| 427 | + self.assertIsNone(cbk.msg) |
| 428 | + |
| 429 | + vl = None |
| 430 | + |
| 431 | + del f_shp |
| 432 | + del f_shx |
| 433 | + del f_dbf |
| 434 | + |
| 435 | + # Test repacking has been done |
| 436 | + ds = osgeo.ogr.Open(datasource) |
| 437 | + self.assertTrue(ds.GetLayer(0).GetFeatureCount(), feature_count - 1) |
| 438 | + ds = None |
| 439 | + |
383 | 440 | if __name__ == '__main__':
|
384 | 441 | unittest.main()
|
0 commit comments