diff --git a/.ci/test_blocklist_qt5.txt b/.ci/test_blocklist_qt5.txt index 99c009f4c8e2..db954d7c0162 100644 --- a/.ci/test_blocklist_qt5.txt +++ b/.ci/test_blocklist_qt5.txt @@ -17,7 +17,3 @@ test_core_openclutils # Relies on a broken/unreliable 3rd party service test_core_layerdefinition -# MSSQL requires the MSSQL docker -PyQgsProviderConnectionMssql -PyQgsStyleStorageMssql - diff --git a/.ci/test_flaky.txt b/.ci/test_flaky.txt index 6f8a2519aa18..11ccf98fe139 100644 --- a/.ci/test_flaky.txt +++ b/.ci/test_flaky.txt @@ -4,7 +4,3 @@ test_provider_wcsprovider PyQgsWFSProviderGUI # See https://github.com/qgis/QGIS/issues/48927 test_core_tiledownloadmanager - -# Flaky, the ms odbc driver crashes a lot on the ubuntu docker image. Retest when -# the docker base image is upgraded -PyQgsMssqlProvider diff --git a/.docker/docker-compose-testing-mssql.yml b/.docker/docker-compose-testing-mssql.yml new file mode 100644 index 000000000000..ac768f1c8dbc --- /dev/null +++ b/.docker/docker-compose-testing-mssql.yml @@ -0,0 +1,25 @@ +version: '3' + +services: + mssql: + image: mcr.microsoft.com/mssql/server:2022-latest + environment: + ACCEPT_EULA: Y + MSSQL_SA_PASSWORD: QGIStestSQLServer1234 + ports: + - 1433:1433 + + qgis-deps: + tty: true + image: qgis3-build-deps-binary-image + volumes: + - ${QGIS_WORKSPACE}:/root/QGIS + links: + - mssql + env_file: + - docker-variables.env + environment: + - LANG=C.UTF-8 + - LC_ALL=en_US.UTF-8 + cap_add: + - NET_ADMIN diff --git a/.docker/docker-compose-testing.yml b/.docker/docker-compose-testing.yml index 19dd0dc92c91..1c0f77dcd440 100755 --- a/.docker/docker-compose-testing.yml +++ b/.docker/docker-compose-testing.yml @@ -1,13 +1,6 @@ version: '3' services: -# Proving very fragile! -# mssql: -# image: microsoft/mssql-server-linux:2017-latest -# environment: -# ACCEPT_EULA: Y -# SA_PASSWORD: - httpbin: image: kennethreitz/httpbin:latest @@ -34,7 +27,6 @@ services: - ${QGIS_WORKSPACE}:/root/QGIS - ${QGIS_COMMON_GIT_DIR}:${QGIS_COMMON_GIT_DIR} links: - # - mssql - webdav - minio - httpbin diff --git a/.docker/docker-qgis-build.sh b/.docker/docker-qgis-build.sh index 8ae149e715b2..a914408c64f0 100755 --- a/.docker/docker-qgis-build.sh +++ b/.docker/docker-qgis-build.sh @@ -95,6 +95,7 @@ cmake \ -DENABLE_PGTEST=${WITH_QT5} \ -DENABLE_SAGA_TESTS=${WITH_QT5} \ -DENABLE_MSSQLTEST=${WITH_QT5} \ + -DENABLE_MSSQLTEST_CPP=${WITH_QT5} \ -DENABLE_HANATEST=${WITH_QT5} \ -DENABLE_ORACLETEST=${WITH_QT5} \ -DENABLE_UNITY_BUILDS=${ENABLE_UNITY_BUILDS} \ diff --git a/.docker/docker-qgis-test.sh b/.docker/docker-qgis-test.sh index c7e91d014ca7..9bd72019bccf 100755 --- a/.docker/docker-qgis-test.sh +++ b/.docker/docker-qgis-test.sh @@ -178,12 +178,15 @@ if [ ${RUN_SQLSERVER:-"NO"} == "YES" ]; then # Restore SQL Server test data ############################## + echo "Wait a moment before loading SQL Server database." + sleep 15 + echo "Importing SQL Server test data..." export SQLUSER=sa export SQLHOST=mssql export SQLPORT=1433 - export SQLPASSWORD='' + export SQLPASSWORD=QGIStestSQLServer1234 export SQLDATABASE=qgis_test export PATH=$PATH:/opt/mssql-tools/bin @@ -196,12 +199,14 @@ if [ ${RUN_SQLSERVER:-"NO"} == "YES" ]; then cat < /etc/odbc.ini [ODBC Data Sources] -testsqlserver = ODBC Driver 17 for SQL Server +testsqlserver = ODBC Driver 18 for SQL Server [testsqlserver] -Driver = ODBC Driver 17 for SQL Server +Driver = ODBC Driver 18 for SQL Server Description = Test SQL Server Server = mssql +Encrypt = no +AllowSelfSignedServerCert=1 EOT echo "::endgroup::" diff --git a/.docker/qgis3-qt5-build-deps.dockerfile b/.docker/qgis3-qt5-build-deps.dockerfile index 173e0069a413..606ff8f63d66 100644 --- a/.docker/qgis3-qt5-build-deps.dockerfile +++ b/.docker/qgis3-qt5-build-deps.dockerfile @@ -165,10 +165,12 @@ RUN curl -j -k -L -H "Cookie: eula_3_2_agreed=tools.hana.ondemand.com/developer- ENV PATH="/usr/sap/hdbclient:${PATH}" # MSSQL: client side -# RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - -# RUN curl https://packages.microsoft.com/config/ubuntu/19.04/prod.list | tee /etc/apt/sources.list.d/msprod.list -# RUN apt-get update -# RUN ACCEPT_EULA=Y apt-get install -y --allow-unauthenticated msodbcsql17 mssql-tools +RUN curl -sSL -O https://packages.microsoft.com/config/ubuntu/$(grep VERSION_ID /etc/os-release | cut -d '"' -f 2)/packages-microsoft-prod.deb +RUN dpkg -i packages-microsoft-prod.deb +RUN rm packages-microsoft-prod.deb +RUN apt-get update +RUN ACCEPT_EULA=Y apt-get install -y --allow-unauthenticated msodbcsql18 mssql-tools18 +ENV PATH="/opt/mssql-tools18/bin:${PATH}" FROM binary-only diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 6c3e4470cadc..6c974170a1a0 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -243,7 +243,7 @@ jobs: strategy: matrix: qt-version: [5, 6] - test-batch: [ALL_BUT_PROVIDERS, POSTGRES, HANA] + test-batch: [ALL_BUT_PROVIDERS, POSTGRES, HANA, SQLSERVER] include: - qt-version: 5 @@ -266,6 +266,9 @@ jobs: - qt-version: 6 test-batch: POSTGRES + - qt-version: 6 + test-batch: SQLSERVER + fail-fast: false steps: @@ -351,6 +354,7 @@ jobs: run: | DOCKERFILE=$( ( [[ ${{ matrix.test-batch }} == "ORACLE" ]] && echo "docker-compose-testing-oracle.yml" ) \ || ( [[ ${{ matrix.test-batch }} == "POSTGRES" ]] && echo "docker-compose-testing-postgres.yml" ) \ + || ( [[ ${{ matrix.test-batch }} == "SQLSERVER" ]] && echo "docker-compose-testing-mssql.yml" ) \ || echo "docker-compose-testing.yml" ) [[ ${{ matrix.test-batch }} == "ORACLE" ]] && sudo rm -rf /usr/share/dotnet/sdk echo "TEST_BATCH=$TEST_BATCH" diff --git a/tests/src/providers/CMakeLists.txt b/tests/src/providers/CMakeLists.txt index f8871a827811..0fd9fd76cd2d 100644 --- a/tests/src/providers/CMakeLists.txt +++ b/tests/src/providers/CMakeLists.txt @@ -46,7 +46,7 @@ endif() set(ENABLE_MSSQLTEST_CPP FALSE CACHE BOOL "Enable MSSQL provider C++ tests") if (ENABLE_MSSQLTEST_CPP) - add_qgis_test(testqgsmssqlprovider.cpp MODULE provider LINKEDLIBRARIES provider_mssql_a qgis_core LABELS "MSSQL") + add_qgis_test(testqgsmssqlprovider.cpp MODULE provider LINKEDLIBRARIES provider_mssql_a qgis_core LABELS "SQLSERVER") # also depend on dynamic lib, so that building this test will also build the dynamic lib add_dependencies(test_provider_mssqlprovider provider_mssql) endif() diff --git a/tests/src/providers/testqgsmssqlprovider.cpp b/tests/src/providers/testqgsmssqlprovider.cpp index f5cc91a29d03..e385b3a04030 100644 --- a/tests/src/providers/testqgsmssqlprovider.cpp +++ b/tests/src/providers/testqgsmssqlprovider.cpp @@ -69,7 +69,7 @@ void TestQgsMssqlProvider::initTestCase() QgsApplication::init(); QgsApplication::initQgis(); - mDbConn = qEnvironmentVariable( "QGIS_MSSQLTEST_DB", "service='testsqlserver' user=sa password='' " ); + mDbConn = qEnvironmentVariable( "QGIS_MSSQLTEST_DB", "service='testsqlserver' user=sa password='QGIStestSQLServer1234' " ); mSomeDataWktGeom << QStringLiteral( "Point (-70.33199999999999363 66.32999999999999829)" ) << QStringLiteral( "Point (-68.20000000000000284 70.79999999999999716)" ) diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index fdc833f30323..3dc7cfd21a5b 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -605,7 +605,7 @@ if (ENABLE_MSSQLTEST) ADD_PYTHON_TEST(PyQgsMssqlProvider test_provider_mssql.py) ADD_PYTHON_TEST(PyQgsProviderConnectionMssql test_qgsproviderconnection_mssql.py) ADD_PYTHON_TEST(PyQgsStyleStorageMssql test_stylestorage_mssql.py) - SET_TESTS_PROPERTIES(PyQgsMssqlProvider PyQgsProviderConnectionMssql PyQgsStyleStorageMssql PROPERTIES LABELS "MSSQL") + SET_TESTS_PROPERTIES(PyQgsMssqlProvider PyQgsProviderConnectionMssql PyQgsStyleStorageMssql PROPERTIES LABELS "SQLSERVER") endif() if (ENABLE_ORACLETEST) diff --git a/tests/src/python/test_provider_mssql.py b/tests/src/python/test_provider_mssql.py index cca5c266a12a..9a8c265ff6f8 100644 --- a/tests/src/python/test_provider_mssql.py +++ b/tests/src/python/test_provider_mssql.py @@ -49,7 +49,7 @@ def setUpClass(cls): """Run before all tests""" super().setUpClass() # These are the connection details for the SQL Server instance running on Travis - cls.dbconn = "service='testsqlserver' user=sa password='' " + cls.dbconn = "service='testsqlserver' user=sa password='QGIStestSQLServer1234' " if "QGIS_MSSQLTEST_DB" in os.environ: cls.dbconn = os.environ["QGIS_MSSQLTEST_DB"] # Create test layers diff --git a/tests/src/python/test_qgsproviderconnection_mssql.py b/tests/src/python/test_qgsproviderconnection_mssql.py index d3ce88df5591..9071d4c1dbbb 100644 --- a/tests/src/python/test_qgsproviderconnection_mssql.py +++ b/tests/src/python/test_qgsproviderconnection_mssql.py @@ -43,7 +43,7 @@ def setUpClass(cls): TestPyQgsProviderConnectionBase.setUpClass() # These are the connection details for the SQL Server instance running on Travis - cls.dbconn = "service='testsqlserver' user=sa password='' " + cls.dbconn = "service='testsqlserver' user=sa password='QGIStestSQLServer1234' " if "QGIS_MSSQLTEST_DB" in os.environ: cls.dbconn = os.environ["QGIS_MSSQLTEST_DB"] @@ -59,7 +59,7 @@ def setUpClass(cls): def test_configuration(self): """Test storage and retrieval for configuration parameters""" - uri = "dbname='qgis_test' service='driver={SQL Server};server=localhost;port=1433;database=qgis_test' user='sa' password='' srid=4326 type=Point estimatedMetadata='true' disableInvalidGeometryHandling='1' table=\"qgis_test\".\"someData\" (geom)" + uri = "dbname='qgis_test' service='driver={SQL Server};server=localhost;port=1433;database=qgis_test' user='sa' password='QGIStestSQLServer1234' srid=4326 type=Point estimatedMetadata='true' disableInvalidGeometryHandling='1' table=\"qgis_test\".\"someData\" (geom)" md = QgsProviderRegistry.instance().providerMetadata("mssql") conn = md.createConnection(uri, {}) ds_uri = QgsDataSourceUri(conn.uri()) @@ -70,7 +70,7 @@ def test_configuration(self): self.assertEqual(ds_uri.geometryColumn(), "") self.assertTrue(ds_uri.useEstimatedMetadata()) self.assertEqual(ds_uri.srid(), "") - self.assertEqual(ds_uri.password(), "") + self.assertEqual(ds_uri.password(), "QGIStestSQLServer1234") self.assertEqual(ds_uri.param("disableInvalidGeometryHandling"), "1") conn.store("coronavirus") @@ -83,7 +83,7 @@ def test_configuration(self): self.assertTrue(ds_uri.useEstimatedMetadata()) self.assertEqual(ds_uri.geometryColumn(), "") self.assertEqual(ds_uri.srid(), "") - self.assertEqual(ds_uri.password(), "") + self.assertEqual(ds_uri.password(), "QGIStestSQLServer1234") self.assertEqual(ds_uri.param("disableInvalidGeometryHandling"), "true") conn.remove("coronavirus") diff --git a/tests/src/python/test_stylestorage_mssql.py b/tests/src/python/test_stylestorage_mssql.py index 623c52eb859d..8f41cec7e11f 100644 --- a/tests/src/python/test_stylestorage_mssql.py +++ b/tests/src/python/test_stylestorage_mssql.py @@ -30,7 +30,7 @@ def setUp(self): super().setUp() - dbconn = "service='testsqlserver' user=sa password='' " + dbconn = "service='testsqlserver' user=sa password='QGIStestSQLServer1234' " if "QGIS_MSSQLTEST_DB" in os.environ: dbconn = os.environ["QGIS_MSSQLTEST_DB"] diff --git a/tests/testdata/provider/testdata_mssql.sh b/tests/testdata/provider/testdata_mssql.sh index 4159a5842c6d..5951a1c12404 100755 --- a/tests/testdata/provider/testdata_mssql.sh +++ b/tests/testdata/provider/testdata_mssql.sh @@ -1,3 +1,3 @@ #!/bin/sh -sqlcmd -S $SQLHOST,$SQLPORT -U $SQLUSER -P $SQLPASSWORD -i tests/testdata/provider/testdata_mssql.sql +sqlcmd -C -S $SQLHOST,$SQLPORT -U $SQLUSER -P $SQLPASSWORD -i tests/testdata/provider/testdata_mssql.sql