diff --git a/nix/ext/tests/supautils.nix b/nix/ext/tests/supautils.nix new file mode 100644 index 000000000..1eb0bec43 --- /dev/null +++ b/nix/ext/tests/supautils.nix @@ -0,0 +1,140 @@ +{ self, pkgs }: +let + pname = "supautils"; + inherit (pkgs) lib; + installedExtension = + postgresMajorVersion: self.packages.${pkgs.system}."psql_${postgresMajorVersion}/exts/${pname}-all"; + versions = postgresqlMajorVersion: (installedExtension postgresqlMajorVersion).versions; + postgresqlWithExtension = + postgresql: + let + majorVersion = lib.versions.major postgresql.version; + pkg = pkgs.buildEnv { + name = "postgresql-${majorVersion}-${pname}"; + paths = [ + postgresql + postgresql.lib + (installedExtension majorVersion) + ]; + passthru = { + inherit (postgresql) version psqlSchema; + lib = pkg; + withPackages = _: pkg; + }; + nativeBuildInputs = [ pkgs.makeWrapper ]; + pathsToLink = [ + "/" + "/bin" + "/lib" + ]; + postBuild = '' + wrapProgram $out/bin/postgres --set NIX_PGLIBDIR $out/lib + wrapProgram $out/bin/pg_ctl --set NIX_PGLIBDIR $out/lib + wrapProgram $out/bin/pg_upgrade --set NIX_PGLIBDIR $out/lib + ''; + }; + in + pkg; + psql_15 = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_15; + psql_17 = postgresqlWithExtension self.packages.${pkgs.system}.postgresql_17; +in +self.inputs.nixpkgs.lib.nixos.runTest { + name = pname; + hostPkgs = pkgs; + nodes.server = + { config, ... }: + { + services.postgresql = { + enable = true; + package = (postgresqlWithExtension psql_15); + settings = { + shared_preload_libraries = "supautils"; + "supautils.privileged_extensions" = ""; + } // ((installedExtension "15").defaultSettings or { }); + }; + + specialisation.postgresql17.configuration = { + services.postgresql = { + package = lib.mkForce psql_17; + settings = { + shared_preload_libraries = "supautils"; + "supautils.privileged_extensions" = ""; + } // ((installedExtension "17").defaultSettings or { }); + }; + + systemd.services.postgresql-migrate = { + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + User = "postgres"; + Group = "postgres"; + StateDirectory = "postgresql"; + WorkingDirectory = "${builtins.dirOf config.services.postgresql.dataDir}"; + }; + script = + let + oldPostgresql = psql_15; + newPostgresql = psql_17; + oldDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${oldPostgresql.psqlSchema}"; + newDataDir = "${builtins.dirOf config.services.postgresql.dataDir}/${newPostgresql.psqlSchema}"; + in + '' + if [[ ! -d ${newDataDir} ]]; then + install -d -m 0700 -o postgres -g postgres "${newDataDir}" + ${newPostgresql}/bin/initdb -D "${newDataDir}" + ${newPostgresql}/bin/pg_upgrade --old-datadir "${oldDataDir}" --new-datadir "${newDataDir}" \ + --old-bindir "${oldPostgresql}/bin" --new-bindir "${newPostgresql}/bin" \ + --old-options='-c shared_preload_libraries=supautils' --new-options='-c shared_preload_libraries=supautils' + else + echo "${newDataDir} already exists" + fi + ''; + }; + + systemd.services.postgresql = { + after = [ "postgresql-migrate.service" ]; + requires = [ "postgresql-migrate.service" ]; + }; + }; + }; + testScript = + { nodes, ... }: + let + pg17-configuration = "${nodes.server.system.build.toplevel}/specialisation/postgresql17"; + in + '' + from pathlib import Path + versions = { + "15": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "15"))}], + "17": [${lib.concatStringsSep ", " (map (s: ''"${s}"'') (versions "17"))}], + } + extension_name = "${pname}" + support_upgrade = False + pg17_configuration = "${pg17-configuration}" + ext_has_background_worker = ${ + if (installedExtension "15") ? hasBackgroundWorker then "True" else "False" + } + sql_test_directory = Path("${../../tests}") + pg_regress_test_name = "${(installedExtension "15").pgRegressTestName or pname}" + + ${builtins.readFile ./lib.py} + + start_all() + + server.wait_for_unit("multi-user.target") + server.wait_for_unit("postgresql.service") + + test = PostgresExtensionTest(server, extension_name, versions, sql_test_directory, support_upgrade) + + with subtest("Check pg_regress with postgresql 15 after extension upgrade"): + test.check_pg_regress(Path("${psql_15}/lib/pgxs/src/test/regress/pg_regress"), "15", pg_regress_test_name) + + with subtest("switch to postgresql 17"): + server.succeed( + f"{pg17_configuration}/bin/switch-to-configuration test >&2" + ) + + with subtest("Check pg_regress with postgresql 17 after extension upgrade"): + test.check_pg_regress(Path("${psql_17}/lib/pgxs/src/test/regress/pg_regress"), "17", pg_regress_test_name) + ''; +} diff --git a/nix/tests/expected/z_15_supautils.out b/nix/tests/expected/z_15_supautils.out new file mode 100644 index 000000000..cfbfdeba8 --- /dev/null +++ b/nix/tests/expected/z_15_supautils.out @@ -0,0 +1,39 @@ +begin; + load 'supautils'; + -- verify that supautils configuration parameters exist + select current_setting('supautils.privileged_extensions', true) is not null as has_privileged_extensions; + has_privileged_extensions +--------------------------- + t +(1 row) + + select current_setting('supautils.privileged_role', true) is not null as has_privileged_role; + has_privileged_role +--------------------- + t +(1 row) + + -- switch to postgres role and verify access to settings + set role postgres; + select current_setting('supautils.privileged_extensions', true) as privileged_extensions; + privileged_extensions +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + address_standardizer, address_standardizer_data_us, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intarray, isn, ltree, moddatetime, orioledb, pg_buffercache, pg_cron, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_prewarm, pg_repack, pg_stat_monitor, pg_stat_statements, pg_tle, pg_trgm, pg_walinspect, pgaudit, pgcrypto, pgjwt, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgsodium, pgstattuple, pgtap, plcoffee, pljava, plls, plpgsql_check, plv8, postgis, postgis_raster, postgis_sfcgal, postgis_tiger_geocoder, postgis_topology, postgres_fdw, refint, rum, seg, sslinfo, supabase_vault, supautils, tablefunc, tcn, timescaledb, tsm_system_rows, tsm_system_time, unaccent, uuid-ossp, vector, wrappers +(1 row) + + -- create a simple schema to verify normal operations work + create schema v; + create table v.test_table ( + id serial primary key, + data text + ); + insert into v.test_table (data) + values ('test1'), ('test2'); + select * from v.test_table order by id; + id | data +----+------- + 1 | test1 + 2 | test2 +(2 rows) + +rollback; diff --git a/nix/tests/expected/z_17_supautils.out b/nix/tests/expected/z_17_supautils.out new file mode 100644 index 000000000..10fc68e19 --- /dev/null +++ b/nix/tests/expected/z_17_supautils.out @@ -0,0 +1,39 @@ +begin; + load 'supautils'; + -- verify that supautils configuration parameters exist + select current_setting('supautils.privileged_extensions', true) is not null as has_privileged_extensions; + has_privileged_extensions +--------------------------- + t +(1 row) + + select current_setting('supautils.privileged_role', true) is not null as has_privileged_role; + has_privileged_role +--------------------- + t +(1 row) + + -- switch to postgres role and verify access to settings + set role postgres; + select current_setting('supautils.privileged_extensions', true) as privileged_extensions; + privileged_extensions +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + address_standardizer, address_standardizer_data_us, autoinc, bloom, btree_gin, btree_gist, citext, cube, dblink, dict_int, dict_xsyn, earthdistance, fuzzystrmatch, hstore, http, hypopg, index_advisor, insert_username, intarray, isn, ltree, moddatetime, orioledb, pg_buffercache, pg_cron, pg_graphql, pg_hashids, pg_jsonschema, pg_net, pg_prewarm, pg_repack, pg_stat_monitor, pg_stat_statements, pg_tle, pg_trgm, pg_walinspect, pgaudit, pgcrypto, pgjwt, pgroonga, pgroonga_database, pgrouting, pgrowlocks, pgsodium, pgstattuple, pgtap, plcoffee, pljava, plls, plpgsql_check, postgis, postgis_raster, postgis_sfcgal, postgis_tiger_geocoder, postgis_topology, postgres_fdw, refint, rum, seg, sslinfo, supabase_vault, supautils, tablefunc, tcn, tsm_system_rows, tsm_system_time, unaccent, uuid-ossp, vector, wrappers +(1 row) + + -- create a simple schema to verify normal operations work + create schema v; + create table v.test_table ( + id serial primary key, + data text + ); + insert into v.test_table (data) + values ('test1'), ('test2'); + select * from v.test_table order by id; + id | data +----+------- + 1 | test1 + 2 | test2 +(2 rows) + +rollback; diff --git a/nix/tests/sql/z_15_supautils.sql b/nix/tests/sql/z_15_supautils.sql new file mode 100644 index 000000000..35f50b602 --- /dev/null +++ b/nix/tests/sql/z_15_supautils.sql @@ -0,0 +1,25 @@ +begin; + load 'supautils'; + + -- verify that supautils configuration parameters exist + select current_setting('supautils.privileged_extensions', true) is not null as has_privileged_extensions; + select current_setting('supautils.privileged_role', true) is not null as has_privileged_role; + + -- switch to postgres role and verify access to settings + set role postgres; + select current_setting('supautils.privileged_extensions', true) as privileged_extensions; + + -- create a simple schema to verify normal operations work + create schema v; + + create table v.test_table ( + id serial primary key, + data text + ); + + insert into v.test_table (data) + values ('test1'), ('test2'); + + select * from v.test_table order by id; + +rollback; diff --git a/nix/tests/sql/z_17_supautils.sql b/nix/tests/sql/z_17_supautils.sql new file mode 100644 index 000000000..35f50b602 --- /dev/null +++ b/nix/tests/sql/z_17_supautils.sql @@ -0,0 +1,25 @@ +begin; + load 'supautils'; + + -- verify that supautils configuration parameters exist + select current_setting('supautils.privileged_extensions', true) is not null as has_privileged_extensions; + select current_setting('supautils.privileged_role', true) is not null as has_privileged_role; + + -- switch to postgres role and verify access to settings + set role postgres; + select current_setting('supautils.privileged_extensions', true) as privileged_extensions; + + -- create a simple schema to verify normal operations work + create schema v; + + create table v.test_table ( + id serial primary key, + data text + ); + + insert into v.test_table (data) + values ('test1'), ('test2'); + + select * from v.test_table order by id; + +rollback;