def test_widget(self): """Manual local GUI test for the model""" d = QDialog() l = QVBoxLayout(d) d.setLayout(l) lbl = QLabel('fetching...', d) l.addWidget(lbl) v = QListView() l.addWidget(v) d.show() md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(self.uri, {}) res = conn.execSql('SELECT * FROM qgis_test.random_big_data') model = QgsQueryResultModel(res) v.setModel(model) def _set_row_count(idx, first, last): lbl.setText('Rows %s fetched' % model.rowCount(model.index(-1, -1))) # noqa: F821 model.rowsInserted.connect(_set_row_count) d.exec_() # Because exit handler will exit QGIS and clear the connections pool before # the model is deleted (and it will in turn clear the connection) del (model)
def test_model_stop(self): """Test that when a model is deleted fetching query rows is also interrupted""" md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(self.uri, {}) res = conn.execSql('SELECT * FROM qgis_test.random_big_data') self.model = QgsQueryResultModel(res) def model_deleter(): del (self.model) self.running = True def loop_exiter(): self.running = False QTimer.singleShot(1, model_deleter) QTimer.singleShot(2, loop_exiter) while self.running: QCoreApplication.processEvents() self.assertTrue(res.fetchedRowCount() > 0 and res.fetchedRowCount() < self.NUM_RECORDS)
def test_model(self): """Test the model""" md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(self.uri, {}) res = conn.execSql('SELECT generate_series(1, 1000)') model = QgsQueryResultModel(res) tester = QAbstractItemModelTester(model, QAbstractItemModelTester.FailureReportingMode.Warning) self.assertEqual(model.rowCount(model.index(-1, -1)), 0) while model.rowCount(model.index(-1, -1)) < 1000: QCoreApplication.processEvents() self.assertEqual(model.columnCount(model.index(-1, -1)), 1) self.assertEqual(model.rowCount(model.index(-1, -1)), 1000) self.assertEqual(model.data(model.index(999, 0), Qt.DisplayRole), 1000) # Test data for i in range(1000): self.assertEqual(model.data(model.index(i, 0), Qt.DisplayRole), i + 1) self.assertEqual(model.data(model.index(1000, 0), Qt.DisplayRole), QVariant()) self.assertEqual(model.data(model.index(1, 1), Qt.DisplayRole), QVariant())
class TestPyQgsQgsQueryResultModel(unittest.TestCase): NUM_RECORDS = 100050 @classmethod def setUpClass(cls): """Run before all tests""" QCoreApplication.setOrganizationName("QGIS_Test") QCoreApplication.setOrganizationDomain(cls.__name__) QCoreApplication.setApplicationName(cls.__name__) start_app() cls.postgres_conn = "service='qgis_test'" if 'QGIS_PGTEST_DB' in os.environ: cls.postgres_conn = os.environ['QGIS_PGTEST_DB'] cls.uri = cls.postgres_conn + ' sslmode=disable' # Prepare data for threaded test cls._deleteBigData() md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(cls.uri, {}) conn.executeSql('DROP TABLE IF EXISTS qgis_test.random_big_data CASCADE;') conn.executeSql('SELECT * INTO qgis_test.random_big_data FROM ( SELECT x AS id, md5(random()::text) AS descr FROM generate_series(1,%s) x ) AS foo_row;' % cls.NUM_RECORDS) @classmethod def tearDownClass(cls): cls._deleteBigData() @classmethod def _deleteBigData(cls): try: md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(cls.uri, {}) conn.dropVectorTable('qgis_test', 'random_big_data') except: pass def test_model(self): """Test the model""" md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(self.uri, {}) res = conn.execSql('SELECT generate_series(1, 1000)') model = QgsQueryResultModel(res) tester = QAbstractItemModelTester(model, QAbstractItemModelTester.FailureReportingMode.Warning) self.assertEqual(model.rowCount(model.index(-1, -1)), 0) while model.rowCount(model.index(-1, -1)) < 1000: QCoreApplication.processEvents() self.assertEqual(model.columnCount(model.index(-1, -1)), 1) self.assertEqual(model.rowCount(model.index(-1, -1)), 1000) self.assertEqual(model.data(model.index(999, 0), Qt.DisplayRole), 1000) # Test data for i in range(1000): self.assertEqual(model.data(model.index(i, 0), Qt.DisplayRole), i + 1) self.assertEqual(model.data(model.index(1000, 0), Qt.DisplayRole), QVariant()) self.assertEqual(model.data(model.index(1, 1), Qt.DisplayRole), QVariant()) def test_model_stop(self): """Test that when a model is deleted fetching query rows is also interrupted""" def model_deleter(): del self.model def loop_exiter(): self.running = False md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(self.uri, {}) res = conn.execSql('SELECT * FROM qgis_test.random_big_data') self.model = QgsQueryResultModel(res) self.running = True QTimer.singleShot(15, model_deleter) QTimer.singleShot(600, loop_exiter) while self.running: try: self.model.fetchMore(QModelIndex()) except: pass QCoreApplication.processEvents() row_count = res.fetchedRowCount() self.assertGreater(row_count, 0) self.assertLess(row_count, self.NUM_RECORDS) @unittest.skipIf(os.environ.get('QGIS_CONTINUOUS_INTEGRATION_RUN', 'true'), 'Local manual test: not for CI') def test_widget(self): """Manual local GUI test for the model""" d = QDialog() l = QVBoxLayout(d) d.setLayout(l) lbl = QLabel('fetching...', d) l.addWidget(lbl) v = QListView() l.addWidget(v) d.show() md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(self.uri, {}) res = conn.execSql('SELECT * FROM qgis_test.random_big_data') model = QgsQueryResultModel(res) tester = QAbstractItemModelTester(model, QAbstractItemModelTester.FailureReportingMode.Warning) v.setModel(model) def _set_row_count(idx, first, last): lbl.setText('Rows %s fetched' % model.rowCount(model.index(-1, -1))) # noqa: F821 model.rowsInserted.connect(_set_row_count) d.exec_() # Because exit handler will exit QGIS and clear the connections pool before # the model is deleted (and it will in turn clear the connection) del model