|
1 | 1 | import logging |
2 | 2 | import os |
3 | 3 | import tempfile |
| 4 | +import subprocess |
4 | 5 | import shutil |
5 | 6 | from datetime import datetime, timedelta |
6 | 7 | import pytest |
@@ -847,6 +848,32 @@ def _is_file_updated(filename, changes_dict): |
847 | 848 | return False |
848 | 849 |
|
849 | 850 |
|
| 851 | +class AnotherSqliteConn: |
| 852 | + """ This simulates another app (e.g. QGIS) having a connection open, potentially |
| 853 | + with some active reader/writer. |
| 854 | +
|
| 855 | + Note: we use a subprocess here instead of just using sqlite3 module from python |
| 856 | + because pygeodiff and python's sqlite3 module have their own sqlite libraries, |
| 857 | + and this does not work well when they are used in a single process. But if we |
| 858 | + use another process, things are fine. This is a limitation of how we package |
| 859 | + pygeodiff currently. |
| 860 | + """ |
| 861 | + def __init__(self, filename): |
| 862 | + self.proc = subprocess.Popen( |
| 863 | + ['python3', os.path.join(os.path.dirname(__file__), 'sqlite_con.py'), filename], |
| 864 | + stdin=subprocess.PIPE, |
| 865 | + stderr=subprocess.PIPE) |
| 866 | + |
| 867 | + def run(self, cmd): |
| 868 | + self.proc.stdin.write(cmd.encode()+b'\n') |
| 869 | + self.proc.stdin.flush() |
| 870 | + |
| 871 | + def close(self): |
| 872 | + out,err = self.proc.communicate(b'stop\n') |
| 873 | + if self.proc.returncode != 0: |
| 874 | + raise ValueError("subprocess error:\n" + err.decode('utf-8')) |
| 875 | + |
| 876 | + |
850 | 877 | def test_push_gpkg_schema_change(mc): |
851 | 878 | """ Test that changes in GPKG get picked up if there were recent changes to it by another |
852 | 879 | client and at the same time geodiff fails to find changes (a new table is added) |
@@ -880,9 +907,8 @@ def test_push_gpkg_schema_change(mc): |
880 | 907 | mp.log.info(' // make changes to DB') |
881 | 908 |
|
882 | 909 | # open a connection and keep it open (qgis does this with a pool of connections too) |
883 | | - con2 = sqlite3.connect(test_gpkg) |
884 | | - cursor2 = con2.cursor() |
885 | | - cursor2.execute('select count(*) from simple;') |
| 910 | + acon2 = AnotherSqliteConn(test_gpkg) |
| 911 | + acon2.run('select count(*) from simple;') |
886 | 912 |
|
887 | 913 | # add a new table to ensure that geodiff will fail due to unsupported change |
888 | 914 | # (this simulates an independent reader/writer like GDAL) |
@@ -921,6 +947,8 @@ def test_push_gpkg_schema_change(mc): |
921 | 947 | # OLD: fails here |
922 | 948 | _check_test_table(test_gpkg_verify) |
923 | 949 |
|
| 950 | + acon2.close() |
| 951 | + |
924 | 952 |
|
925 | 953 | @pytest.mark.parametrize("extra_connection", [False, True]) |
926 | 954 | def test_rebase_local_schema_change(mc, extra_connection): |
|
0 commit comments