|
37 | 37 | TEST_DATA_DIR = unitTestDataPath()
|
38 | 38 |
|
39 | 39 |
|
| 40 | +def count_opened_filedescriptors(filename_to_test): |
| 41 | + count = -1 |
| 42 | + if sys.platform.startswith('linux'): |
| 43 | + count = 0 |
| 44 | + open_files_dirname = '/proc/%d/fd' % os.getpid() |
| 45 | + filenames = os.listdir(open_files_dirname) |
| 46 | + for filename in filenames: |
| 47 | + full_filename = open_files_dirname + '/' + filename |
| 48 | + if os.path.exists(full_filename): |
| 49 | + link = os.readlink(full_filename) |
| 50 | + if os.path.basename(link) == os.path.basename(filename_to_test): |
| 51 | + count += 1 |
| 52 | + return count |
| 53 | + |
| 54 | + |
40 | 55 | class TestQgsSpatialiteProvider(unittest.TestCase, ProviderTestCase):
|
41 | 56 |
|
42 | 57 | @classmethod
|
@@ -217,5 +232,75 @@ def test_invalid_iterator(self):
|
217 | 232 | layer = None
|
218 | 233 | os.unlink(corrupt_dbname)
|
219 | 234 |
|
| 235 | + # FIXME: this test case does not work whereas equivalent OGR one does |
| 236 | + # I believe the issue is that spatialite should have a Qgs |
| 237 | + def testNoDanglingFileDescriptorAfterCloseVariant1(self): |
| 238 | + ''' Test that when closing the provider all file handles are released ''' |
| 239 | + |
| 240 | + temp_dbname = self.dbname + '.no_dangling_test1' |
| 241 | + shutil.copy(self.dbname, temp_dbname) |
| 242 | + |
| 243 | + vl = QgsVectorLayer("dbname=%s table=test_n (geometry)" % temp_dbname, "test_n", "spatialite") |
| 244 | + self.assertTrue(vl.isValid()) |
| 245 | + # The iterator will take one extra connection |
| 246 | + myiter = vl.getFeatures() |
| 247 | + print(vl.featureCount()) |
| 248 | + # Consume one feature but the iterator is still opened |
| 249 | + f = next(myiter) |
| 250 | + self.assertTrue(f.isValid()) |
| 251 | + |
| 252 | + if sys.platform.startswith('linux'): |
| 253 | + self.assertEqual(count_opened_filedescriptors(temp_dbname), 2) |
| 254 | + |
| 255 | + # does NO release one file descriptor, because shared with the iterator |
| 256 | + del vl |
| 257 | + |
| 258 | + # Non portable, but Windows testing is done with trying to unlink |
| 259 | + if sys.platform.startswith('linux'): |
| 260 | + self.assertEqual(count_opened_filedescriptors(temp_dbname), 2) |
| 261 | + |
| 262 | + f = next(myiter) |
| 263 | + self.assertTrue(f.isValid()) |
| 264 | + |
| 265 | + # Should release one file descriptor |
| 266 | + del myiter |
| 267 | + |
| 268 | + # Non portable, but Windows testing is done with trying to unlink |
| 269 | + if sys.platform.startswith('linux'): |
| 270 | + self.assertEqual(count_opened_filedescriptors(temp_dbname), 0) |
| 271 | + |
| 272 | + # Check that deletion works well (can only fail on Windows) |
| 273 | + os.unlink(temp_dbname) |
| 274 | + self.assertFalse(os.path.exists(temp_dbname)) |
| 275 | + |
| 276 | + def testNoDanglingFileDescriptorAfterCloseVariant2(self): |
| 277 | + ''' Test that when closing the provider all file handles are released ''' |
| 278 | + |
| 279 | + temp_dbname = self.dbname + '.no_dangling_test2' |
| 280 | + shutil.copy(self.dbname, temp_dbname) |
| 281 | + |
| 282 | + vl = QgsVectorLayer("dbname=%s table=test_n (geometry)" % temp_dbname, "test_n", "spatialite") |
| 283 | + self.assertTrue(vl.isValid()) |
| 284 | + self.assertTrue(vl.isValid()) |
| 285 | + # Consume all features. |
| 286 | + myiter = vl.getFeatures() |
| 287 | + for feature in myiter: |
| 288 | + pass |
| 289 | + # The iterator is closed |
| 290 | + if sys.platform.startswith('linux'): |
| 291 | + self.assertEqual(count_opened_filedescriptors(temp_dbname), 2) |
| 292 | + |
| 293 | + # Should release one file descriptor |
| 294 | + del vl |
| 295 | + |
| 296 | + # Non portable, but Windows testing is done with trying to unlink |
| 297 | + if sys.platform.startswith('linux'): |
| 298 | + self.assertEqual(count_opened_filedescriptors(temp_dbname), 0) |
| 299 | + |
| 300 | + # Check that deletion works well (can only fail on Windows) |
| 301 | + os.unlink(temp_dbname) |
| 302 | + self.assertFalse(os.path.exists(temp_dbname)) |
| 303 | + |
| 304 | + |
220 | 305 | if __name__ == '__main__':
|
221 | 306 | unittest.main()
|
0 commit comments