Skip to content

Commit 30b19ec

Browse files
committed
feat: test pg_upgrade compatibility with older extension versions
Add test to verify that all extension versions from PostgreSQL 15 can successfully upgrade to PostgreSQL 17 using pg_upgrade. The test now validates: - Each PG 15 extension version can be upgraded to PG 17 - Extension update scripts are properly generated during upgrade - Version handling works correctly with and without update scripts - Final extension versions match expected values after upgrade
1 parent 974db6c commit 30b19ec

File tree

7 files changed

+212
-204
lines changed

7 files changed

+212
-204
lines changed

nix/ext/tests/default.nix

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,16 @@ let
136136
};
137137
testScript =
138138
{ nodes, ... }:
139-
let
140-
pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17";
141-
in
142139
''
143140
from pathlib import Path
144141
versions = {
145142
"15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}],
146143
"17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}],
147144
}
148145
extension_name = "${pname}"
149-
pg17_configuration = "${pg17-configuration}"
146+
system = "${nodes.server.system.build.toplevel}"
147+
pg15_configuration = system
148+
pg17_configuration = f"{system}/specialisation/postgresql17"
150149
ext_has_background_worker = ${
151150
if (installedExtension "15") ? hasBackgroundWorker then "True" else "False"
152151
}
@@ -198,6 +197,33 @@ let
198197
199198
with subtest("Check pg_regress with postgresql 17 after installing the last version"):
200199
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
200+
201+
with subtest("Test pg_upgrade from postgresql 15 to 17 with older extension version"):
202+
# Test that all extension versions from postgresql 15 can be upgraded to postgresql 17 using pg_upgrade
203+
for version in versions["15"]:
204+
server.systemctl("stop postgresql.service")
205+
server.succeed("rm -fr /var/lib/postgresql/update_extensions.sql /var/lib/postgresql/17")
206+
server.succeed(
207+
f"{pg15_configuration}/bin/switch-to-configuration test >&2"
208+
)
209+
test.drop_extension()
210+
test.install_extension(version)
211+
server.succeed(
212+
f"{pg17_configuration}/bin/switch-to-configuration test >&2"
213+
)
214+
has_update_script = server.succeed(
215+
"test -f /var/lib/postgresql/update_extensions.sql && echo 'yes' || echo 'no'"
216+
).strip() == "yes"
217+
if has_update_script:
218+
# Run the extension update script generated during the upgrade
219+
test.run_sql_file("/var/lib/postgresql/update_extensions.sql")
220+
# If there was an update script, the last version should be installed
221+
test.assert_version_matches(versions["17"][-1])
222+
else:
223+
# Otherwise, the version should match the version from postgresql 15
224+
test.assert_version_matches(version)
225+
226+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
201227
'';
202228
};
203229
in
@@ -222,6 +248,7 @@ builtins.listToAttrs (
222248
"pg_jsonschema"
223249
"pg_net"
224250
"pgaudit"
251+
"postgis"
225252
"vector"
226253
"wrappers"
227254
]

nix/ext/tests/lib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def run_sql_file(self, file: str) -> str:
4747
).strip()
4848

4949
def drop_extension(self):
50-
self.run_sql(f"DROP EXTENSION IF EXISTS {self.extension_name};")
50+
self.run_sql(f"DROP EXTENSION IF EXISTS {self.extension_name} CASCADE;")
5151

5252
def install_extension(self, version: str):
5353
self.run_sql(

nix/ext/tests/pgmq.nix

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let
3939
psql_17 = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17;
4040
in
4141
self.inputs.nixpkgs.lib.nixos.runTest {
42-
name = "timescaledb";
42+
name = "pgmq";
4343
hostPkgs = pkgs;
4444
nodes.server =
4545
{ config, ... }:
@@ -105,9 +105,6 @@ self.inputs.nixpkgs.lib.nixos.runTest {
105105
};
106106
testScript =
107107
{ nodes, ... }:
108-
let
109-
pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17";
110-
in
111108
''
112109
from pathlib import Path
113110
versions = {
@@ -116,7 +113,9 @@ self.inputs.nixpkgs.lib.nixos.runTest {
116113
}
117114
extension_name = "${pname}"
118115
support_upgrade = True
119-
pg17_configuration = "${pg17-configuration}"
116+
system = "${nodes.server.system.build.toplevel}"
117+
pg15_configuration = system
118+
pg17_configuration = f"{system}/specialisation/postgresql17"
120119
ext_has_background_worker = ${
121120
if (installedExtension "15") ? hasBackgroundWorker then "True" else "False"
122121
}
@@ -173,5 +172,30 @@ self.inputs.nixpkgs.lib.nixos.runTest {
173172
174173
with subtest("Check pg_regress with postgresql 17 after installing the last version"):
175174
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
175+
176+
with subtest("Test pg_upgrade from postgresql 15 to 17 with older extension version"):
177+
# Test that all extension versions from postgresql 15 can be upgraded to postgresql 17 using pg_upgrade
178+
for version in versions["15"]:
179+
server.systemctl("stop postgresql.service")
180+
server.succeed("rm -fr /var/lib/postgresql/update_extensions.sql /var/lib/postgresql/17")
181+
server.succeed(
182+
f"{pg15_configuration}/bin/switch-to-configuration test >&2"
183+
)
184+
test.drop_extension()
185+
test.install_extension(version)
186+
server.succeed(
187+
f"{pg17_configuration}/bin/switch-to-configuration test >&2"
188+
)
189+
has_update_script = server.succeed(
190+
"test -f /var/lib/postgresql/update_extensions.sql && echo 'yes' || echo 'no'"
191+
).strip() == "yes"
192+
if has_update_script:
193+
# Run the extension update script generated during the upgrade
194+
test.run_sql_file("/var/lib/postgresql/update_extensions.sql")
195+
# If there was an update script, the last version should be installed
196+
test.assert_version_matches(versions["17"][-1])
197+
else:
198+
# Otherwise, the version should match the version from postgresql 15
199+
test.assert_version_matches(version)
176200
'';
177201
}

nix/ext/tests/pgroonga.nix

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,17 +125,16 @@ self.inputs.nixpkgs.lib.nixos.runTest {
125125
};
126126
testScript =
127127
{ nodes, ... }:
128-
let
129-
pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17";
130-
in
131128
''
132129
from pathlib import Path
133130
versions = {
134131
"15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}],
135132
"17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}],
136133
}
137134
extension_name = "${pname}"
138-
pg17_configuration = "${pg17-configuration}"
135+
system = "${nodes.server.system.build.toplevel}"
136+
pg15_configuration = system
137+
pg17_configuration = f"{system}/specialisation/postgresql17"
139138
ext_has_background_worker = ${
140139
if (installedExtension "15") ? hasBackgroundWorker then "True" else "False"
141140
}
@@ -187,5 +186,32 @@ self.inputs.nixpkgs.lib.nixos.runTest {
187186
188187
with subtest("Check pg_regress with postgresql 17 after installing the last version"):
189188
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
189+
190+
with subtest("Test pg_upgrade from postgresql 15 to 17 with older extension version"):
191+
# Test that all extension versions from postgresql 15 can be upgraded to postgresql 17 using pg_upgrade
192+
for version in versions["15"]:
193+
server.systemctl("stop postgresql.service")
194+
server.succeed("rm -fr /var/lib/postgresql/update_extensions.sql /var/lib/postgresql/17")
195+
server.succeed(
196+
f"{pg15_configuration}/bin/switch-to-configuration test >&2"
197+
)
198+
test.drop_extension()
199+
test.install_extension(version)
200+
server.succeed(
201+
f"{pg17_configuration}/bin/switch-to-configuration test >&2"
202+
)
203+
has_update_script = server.succeed(
204+
"test -f /var/lib/postgresql/update_extensions.sql && echo 'yes' || echo 'no'"
205+
).strip() == "yes"
206+
if has_update_script:
207+
# Run the extension update script generated during the upgrade
208+
test.run_sql_file("/var/lib/postgresql/update_extensions.sql")
209+
# If there was an update script, the last version should be installed
210+
test.assert_version_matches(versions["17"][-1])
211+
else:
212+
# Otherwise, the version should match the version from postgresql 15
213+
test.assert_version_matches(version)
214+
215+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
190216
'';
191217
}

nix/ext/tests/pgsodium.nix

Lines changed: 90 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ let
4141
echo 0000000000000000000000000000000000000000000000000000000000000000
4242
''
4343
);
44+
psql_15 = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15;
45+
psql_17 = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17;
4446
in
4547
self.inputs.nixpkgs.lib.nixos.runTest {
4648
name = pname;
@@ -60,7 +62,21 @@ self.inputs.nixpkgs.lib.nixos.runTest {
6062

6163
services.postgresql = {
6264
enable = true;
63-
package = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15;
65+
package = psql_15;
66+
authentication = ''
67+
local all postgres peer map=postgres
68+
local all all peer map=root
69+
'';
70+
identMap = ''
71+
root root supabase_admin
72+
postgres postgres postgres
73+
'';
74+
ensureUsers = [
75+
{
76+
name = "supabase_admin";
77+
ensureClauses.superuser = true;
78+
}
79+
];
6480
settings = {
6581
"shared_preload_libraries" = pname;
6682
"pgsodium.getkey_script" = pgsodiumGetKey;
@@ -69,7 +85,7 @@ self.inputs.nixpkgs.lib.nixos.runTest {
6985

7086
specialisation.postgresql17.configuration = {
7187
services.postgresql = {
72-
package = lib.mkForce (postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17);
88+
package = lib.mkForce psql_17;
7389
};
7490

7591
systemd.services.postgresql-migrate = {
@@ -83,8 +99,8 @@ self.inputs.nixpkgs.lib.nixos.runTest {
8399
};
84100
script =
85101
let
86-
oldPostgresql = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15;
87-
newPostgresql = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17;
102+
oldPostgresql = psql_15;
103+
newPostgresql = psql_17;
88104
oldDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${oldPostgresql.psqlSchema}";
89105
newDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${newPostgresql.psqlSchema}";
90106
in
@@ -110,49 +126,93 @@ self.inputs.nixpkgs.lib.nixos.runTest {
110126
};
111127
testScript =
112128
{ nodes, ... }:
113-
let
114-
pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17";
115-
in
116129
''
130+
from pathlib import Path
117131
versions = {
118132
"15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}],
119133
"17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}],
120134
}
135+
extension_name = "${pname}"
136+
system = "${nodes.server.system.build.toplevel}"
137+
pg15_configuration = system
138+
pg17_configuration = f"{system}/specialisation/postgresql17"
139+
ext_has_background_worker = ${
140+
if (installedExtension "15") ? hasBackgroundWorker then "True" else "False"
141+
}
142+
sql_test_directory = Path("${../../tests}")
143+
pg_regress_test_name = "${(installedExtension "15").pgRegressTestName or pname}"
121144
122-
def run_sql(query):
123-
return server.succeed(f"""sudo -u postgres psql -t -A -F\",\" -c \"{query}\" """).strip()
124-
125-
def check_upgrade_path(pg_version):
126-
with subtest("Check ${pname} upgrade path"):
127-
firstVersion = versions[pg_version][0]
128-
server.succeed("sudo -u postgres psql -c 'DROP EXTENSION IF EXISTS ${pname};'")
129-
run_sql(f"""CREATE EXTENSION ${pname} WITH VERSION '{firstVersion}' CASCADE;""")
130-
installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = '${pname}';""")
131-
assert installed_version == firstVersion, f"Expected ${pname} version {firstVersion}, but found {installed_version}"
132-
for version in versions[pg_version][1:]:
133-
run_sql(f"""ALTER EXTENSION ${pname} UPDATE TO '{version}';""")
134-
installed_version = run_sql(r"""SELECT extversion FROM pg_extension WHERE extname = '${pname}';""")
135-
assert installed_version == version, f"Expected ${pname} version {version}, but found {installed_version}"
145+
${builtins.readFile ./lib.py}
136146
137147
start_all()
138148
139149
server.wait_for_unit("multi-user.target")
140150
server.wait_for_unit("postgresql.service")
141151
142-
check_upgrade_path("15")
152+
test = PostgresExtensionTest(server, extension_name, versions, sql_test_directory)
153+
154+
with subtest("Check upgrade path with postgresql 15"):
155+
test.check_upgrade_path("15")
143156
144-
with subtest("Check ${pname} latest extension version"):
145-
server.succeed("sudo -u postgres psql -c 'DROP EXTENSION ${pname};'")
146-
server.succeed("sudo -u postgres psql -c 'CREATE EXTENSION ${pname} CASCADE;'")
147-
installed_extensions=run_sql(r"""SELECT extname, extversion FROM pg_extension;""")
148-
latestVersion = versions["15"][-1]
149-
assert f"${pname},{latestVersion}" in installed_extensions
157+
with subtest("Check pg_regress with postgresql 15 after extension upgrade"):
158+
test.check_pg_regress(Path("${psql_15}/lib/pgxs/src/test/regress/pg_regress"), "15", pg_regress_test_name)
159+
160+
last_version = None
161+
with subtest("Check the install of the last version of the extension"):
162+
last_version = test.check_install_last_version("15")
163+
164+
if ext_has_background_worker:
165+
with subtest("Test switch_${pname}_version"):
166+
test.check_switch_extension_with_background_worker(Path("${psql_15}/lib/${pname}.so"), "15")
167+
168+
with subtest("Check pg_regress with postgresql 15 after installing the last version"):
169+
test.check_pg_regress(Path("${psql_15}/lib/pgxs/src/test/regress/pg_regress"), "15", pg_regress_test_name)
150170
151171
with subtest("switch to postgresql 17"):
152172
server.succeed(
153-
"${pg17-configuration}/bin/switch-to-configuration test >&2"
173+
f"{pg17_configuration}/bin/switch-to-configuration test >&2"
154174
)
155175
156-
check_upgrade_path("17")
176+
with subtest("Check last version of the extension after postgresql upgrade"):
177+
test.assert_version_matches(last_version)
178+
179+
with subtest("Check upgrade path with postgresql 17"):
180+
test.check_upgrade_path("17")
181+
182+
with subtest("Check pg_regress with postgresql 17 after extension upgrade"):
183+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
184+
185+
with subtest("Check the install of the last version of the extension"):
186+
test.check_install_last_version("17")
187+
188+
with subtest("Check pg_regress with postgresql 17 after installing the last version"):
189+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
190+
191+
with subtest("Test pg_upgrade from postgresql 15 to 17 with older extension version"):
192+
# Test that all extension versions from postgresql 15 can be upgraded to postgresql 17 using pg_upgrade
193+
for version in versions["15"]:
194+
server.systemctl("stop postgresql.service")
195+
server.succeed("rm -fr /var/lib/postgresql/update_extensions.sql /var/lib/postgresql/17")
196+
server.succeed(
197+
f"{pg15_configuration}/bin/switch-to-configuration test >&2"
198+
)
199+
test.drop_extension()
200+
test.install_extension(version)
201+
server.succeed(
202+
f"{pg17_configuration}/bin/switch-to-configuration test >&2"
203+
)
204+
has_update_script = server.succeed(
205+
"test -f /var/lib/postgresql/update_extensions.sql && echo 'yes' || echo 'no'"
206+
).strip() == "yes"
207+
if has_update_script:
208+
# Run the extension update script generated during the upgrade
209+
test.run_sql_file("/var/lib/postgresql/update_extensions.sql")
210+
# If there was an update script, the last version should be installed
211+
test.assert_version_matches(versions["17"][-1])
212+
else:
213+
# Otherwise, the version should match the version from postgresql 15
214+
test.assert_version_matches(version)
215+
216+
test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name)
157217
'';
158218
}

0 commit comments

Comments
 (0)