11
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
+ from typing import List
15
+ from unittest import mock
16
+
14
17
from synapse .app .generic_worker import GenericWorkerServer
15
18
from synapse .storage .database import LoggingDatabaseConnection
16
19
from synapse .storage .prepare_database import PrepareDatabaseException , prepare_database
19
22
from tests .unittest import HomeserverTestCase
20
23
21
24
25
+ def fake_listdir (filepath : str ) -> List [str ]:
26
+ """
27
+ A fake implementation of os.listdir which we can use to mock out the filesystem.
28
+
29
+ Args:
30
+ filepath: The directory to list files for.
31
+
32
+ Returns:
33
+ A list of files and folders in the directory.
34
+ """
35
+ if filepath .endswith ("full_schemas" ):
36
+ return [SCHEMA_VERSION ]
37
+
38
+ return ["99_add_unicorn_to_database.sql" ]
39
+
40
+
22
41
class WorkerSchemaTests (HomeserverTestCase ):
23
42
def make_homeserver (self , reactor , clock ):
24
43
hs = self .setup_test_homeserver (
@@ -51,7 +70,7 @@ def test_rolling_back(self):
51
70
52
71
prepare_database (db_conn , db_pool .engine , self .hs .config )
53
72
54
- def test_not_upgraded (self ):
73
+ def test_not_upgraded_old_schema_version (self ):
55
74
"""Test that workers don't start if the DB has an older schema version"""
56
75
db_pool = self .hs .get_datastore ().db_pool
57
76
db_conn = LoggingDatabaseConnection (
@@ -67,3 +86,34 @@ def test_not_upgraded(self):
67
86
68
87
with self .assertRaises (PrepareDatabaseException ):
69
88
prepare_database (db_conn , db_pool .engine , self .hs .config )
89
+
90
+ def test_not_upgraded_current_schema_version_with_outstanding_deltas (self ):
91
+ """
92
+ Test that workers don't start if the DB is on the current schema version,
93
+ but there are still outstanding delta migrations to run.
94
+ """
95
+ db_pool = self .hs .get_datastore ().db_pool
96
+ db_conn = LoggingDatabaseConnection (
97
+ db_pool ._db_pool .connect (),
98
+ db_pool .engine ,
99
+ "tests" ,
100
+ )
101
+
102
+ # Set the schema version of the database to the current version
103
+ cur = db_conn .cursor ()
104
+ cur .execute ("UPDATE schema_version SET version = ?" , (SCHEMA_VERSION ,))
105
+
106
+ db_conn .commit ()
107
+
108
+ # Path `os.listdir` here to make synapse think that there is a migration
109
+ # file ready to be run.
110
+ # Note that we can't patch this function for the whole method, else Synapse
111
+ # will try to find the file when building the database initially.
112
+ with mock .patch ("os.listdir" , mock .Mock (side_effect = fake_listdir )):
113
+ with self .assertRaises (PrepareDatabaseException ):
114
+ # Synapse should think that there is an outstanding migration file due to
115
+ # patching 'os.listdir' in the function decorator.
116
+ #
117
+ # We expect Synapse to raise an exception to indicate the master process
118
+ # needs to apply this migration file.
119
+ prepare_database (db_conn , db_pool .engine , self .hs .config )
0 commit comments