about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWolfgang Walther2024-11-02 19:49:16 +0100
committerWolfgang Walther2024-11-09 18:24:52 +0100
commitdb2d6a00abe5ec01c9e016d1ac0bc449d06e51ad (patch)
tree9d108dd2064916832360734ad37b67855c043562
parent23c19a255fab8dc09105851748583272755c5db7 (diff)
postgresqlPackages.anonymizer: make passthru.tests work with correct package
Same reasoning as commit before.
-rw-r--r--nixos/tests/pg_anonymizer.nix203
-rw-r--r--pkgs/servers/sql/postgresql/ext/anonymizer.nix6
2 files changed, 114 insertions, 95 deletions
diff --git a/nixos/tests/pg_anonymizer.nix b/nixos/tests/pg_anonymizer.nix
index b26e4dca0580..080b8deabbe8 100644
--- a/nixos/tests/pg_anonymizer.nix
+++ b/nixos/tests/pg_anonymizer.nix
@@ -1,94 +1,111 @@
-import ./make-test-python.nix ({ pkgs, lib, ... }: {
-  name = "pg_anonymizer";
-  meta.maintainers = lib.teams.flyingcircus.members;
-
-  nodes.machine = { pkgs, ... }: {
-    environment.systemPackages = [ pkgs.pg-dump-anon ];
-    services.postgresql = {
-      enable = true;
-      extraPlugins = ps: [ ps.anonymizer ];
-      settings.shared_preload_libraries = [ "anon" ];
+{ system ? builtins.currentSystem
+, config ? {}
+, pkgs ? import ../.. { inherit system config; }
+}:
+
+with import ../lib/testing-python.nix { inherit system pkgs; };
+
+let
+  inherit (pkgs) lib;
+
+  makeAnonymizerTest = postgresqlPackage:
+    makeTest {
+      name = "pg_anonymizer-${postgresqlPackage.name}";
+      meta.maintainers = lib.teams.flyingcircus.members;
+
+      nodes.machine = { pkgs, ... }: {
+        environment.systemPackages = [ pkgs.pg-dump-anon ];
+        services.postgresql = {
+          enable = true;
+          package = postgresqlPackage;
+          extraPlugins = ps: [ ps.anonymizer ];
+          settings.shared_preload_libraries = [ "anon" ];
+        };
+      };
+
+      testScript = ''
+        start_all()
+        machine.wait_for_unit("multi-user.target")
+        machine.wait_for_unit("postgresql.service")
+
+        with subtest("Setup"):
+            machine.succeed("sudo -u postgres psql --command 'create database demo'")
+            machine.succeed(
+                "sudo -u postgres psql -d demo -f ${pkgs.writeText "init.sql" ''
+                  create extension anon cascade;
+                  select anon.init();
+                  create table player(id serial, name text, points int);
+                  insert into player(id,name,points) values (1,'Foo', 23);
+                  insert into player(id,name,points) values (2,'Bar',42);
+                  security label for anon on column player.name is 'MASKED WITH FUNCTION anon.fake_last_name();';
+                  security label for anon on column player.points is 'MASKED WITH VALUE NULL';
+                ''}"
+            )
+
+        def get_player_table_contents():
+            return [
+                x.split(',') for x in machine.succeed("sudo -u postgres psql -d demo --csv --command 'select * from player'").splitlines()[1:]
+            ]
+
+        def check_anonymized_row(row, id, original_name):
+            assert row[0] == id, f"Expected first row to have ID {id}, but got {row[0]}"
+            assert row[1] != original_name, f"Expected first row to have a name other than {original_name}"
+            assert not bool(row[2]), "Expected points to be NULL in first row"
+
+        def find_xsv_in_dump(dump, sep=','):
+            """
+            Expecting to find a CSV (for pg_dump_anon) or TSV (for pg_dump) structure, looking like
+
+                COPY public.player ...
+                1,Shields,
+                2,Salazar,
+                \.
+
+            in the given dump (the commas are tabs in case of pg_dump).
+                  Extract the CSV lines and split by `sep`.
+            """
+
+            try:
+                from itertools import dropwhile, takewhile
+                return [x.split(sep) for x in list(takewhile(
+                    lambda x: x != "\\.",
+                    dropwhile(
+                        lambda x: not x.startswith("COPY public.player"),
+                        dump.splitlines()
+                    )
+                ))[1:]]
+            except:
+                print(f"Dump to process: {dump}")
+                raise
+
+        def check_original_data(output):
+            assert output[0] == ['1','Foo','23'], f"Expected first row from player table to be 1,Foo,23; got {output[0]}"
+            assert output[1] == ['2','Bar','42'], f"Expected first row from player table to be 2,Bar,42; got {output[1]}"
+
+        def check_anonymized_rows(output):
+            check_anonymized_row(output[0], '1', 'Foo')
+            check_anonymized_row(output[1], '2', 'Bar')
+
+        with subtest("Check initial state"):
+            check_original_data(get_player_table_contents())
+
+        with subtest("Anonymous dumps"):
+            check_original_data(find_xsv_in_dump(
+                machine.succeed("sudo -u postgres pg_dump demo"),
+                sep='\t'
+            ))
+            check_anonymized_rows(find_xsv_in_dump(
+                machine.succeed("sudo -u postgres pg_dump_anon -U postgres -h /run/postgresql -d demo"),
+                sep=','
+            ))
+
+        with subtest("Anonymize"):
+            machine.succeed("sudo -u postgres psql -d demo --command 'select anon.anonymize_database();'")
+            check_anonymized_rows(get_player_table_contents())
+      '';
     };
-  };
-
-  testScript = ''
-    start_all()
-    machine.wait_for_unit("multi-user.target")
-    machine.wait_for_unit("postgresql.service")
-
-    with subtest("Setup"):
-        machine.succeed("sudo -u postgres psql --command 'create database demo'")
-        machine.succeed(
-            "sudo -u postgres psql -d demo -f ${pkgs.writeText "init.sql" ''
-              create extension anon cascade;
-              select anon.init();
-              create table player(id serial, name text, points int);
-              insert into player(id,name,points) values (1,'Foo', 23);
-              insert into player(id,name,points) values (2,'Bar',42);
-              security label for anon on column player.name is 'MASKED WITH FUNCTION anon.fake_last_name();';
-              security label for anon on column player.points is 'MASKED WITH VALUE NULL';
-            ''}"
-        )
-
-    def get_player_table_contents():
-        return [
-            x.split(',') for x in machine.succeed("sudo -u postgres psql -d demo --csv --command 'select * from player'").splitlines()[1:]
-        ]
-
-    def check_anonymized_row(row, id, original_name):
-        assert row[0] == id, f"Expected first row to have ID {id}, but got {row[0]}"
-        assert row[1] != original_name, f"Expected first row to have a name other than {original_name}"
-        assert not bool(row[2]), "Expected points to be NULL in first row"
-
-    def find_xsv_in_dump(dump, sep=','):
-        """
-        Expecting to find a CSV (for pg_dump_anon) or TSV (for pg_dump) structure, looking like
-
-            COPY public.player ...
-            1,Shields,
-            2,Salazar,
-            \.
-
-        in the given dump (the commas are tabs in case of pg_dump).
-              Extract the CSV lines and split by `sep`.
-        """
-
-        try:
-            from itertools import dropwhile, takewhile
-            return [x.split(sep) for x in list(takewhile(
-                lambda x: x != "\\.",
-                dropwhile(
-                    lambda x: not x.startswith("COPY public.player"),
-                    dump.splitlines()
-                )
-            ))[1:]]
-        except:
-            print(f"Dump to process: {dump}")
-            raise
-
-    def check_original_data(output):
-        assert output[0] == ['1','Foo','23'], f"Expected first row from player table to be 1,Foo,23; got {output[0]}"
-        assert output[1] == ['2','Bar','42'], f"Expected first row from player table to be 2,Bar,42; got {output[1]}"
-
-    def check_anonymized_rows(output):
-        check_anonymized_row(output[0], '1', 'Foo')
-        check_anonymized_row(output[1], '2', 'Bar')
-
-    with subtest("Check initial state"):
-        check_original_data(get_player_table_contents())
-
-    with subtest("Anonymous dumps"):
-        check_original_data(find_xsv_in_dump(
-            machine.succeed("sudo -u postgres pg_dump demo"),
-            sep='\t'
-        ))
-        check_anonymized_rows(find_xsv_in_dump(
-            machine.succeed("sudo -u postgres pg_dump_anon -U postgres -h /run/postgresql -d demo"),
-            sep=','
-        ))
-
-    with subtest("Anonymize"):
-        machine.succeed("sudo -u postgres psql -d demo --command 'select anon.anonymize_database();'")
-        check_anonymized_rows(get_player_table_contents())
-  '';
-})
+in
+pkgs.lib.concatMapAttrs (n: p: { ${n} = makeAnonymizerTest p; }) pkgs.postgresqlVersions
+// {
+  passthru.override = p: makeAnonymizerTest p;
+}
diff --git a/pkgs/servers/sql/postgresql/ext/anonymizer.nix b/pkgs/servers/sql/postgresql/ext/anonymizer.nix
index 4bb5aa544440..559f7db3f675 100644
--- a/pkgs/servers/sql/postgresql/ext/anonymizer.nix
+++ b/pkgs/servers/sql/postgresql/ext/anonymizer.nix
@@ -1,9 +1,9 @@
-{ lib, stdenv, pg-dump-anon, postgresql, runtimeShell, jitSupport, llvm }:
+{ lib, stdenv, pg-dump-anon, postgresql, runtimeShell, jitSupport, llvm, nixosTests }:
 
 stdenv.mkDerivation (finalAttrs: {
   pname = "postgresql_anonymizer";
 
-  inherit (pg-dump-anon) version src passthru;
+  inherit (pg-dump-anon) version src;
 
   buildInputs = [ postgresql ];
   nativeBuildInputs = [ postgresql ] ++ lib.optional jitSupport llvm;
@@ -26,6 +26,8 @@ stdenv.mkDerivation (finalAttrs: {
     EOF
   '';
 
+  passthru.tests = nixosTests.pg_anonymizer.passthru.override postgresql;
+
   meta = lib.getAttrs [ "homepage" "maintainers" "license" ] pg-dump-anon.meta // {
     description = "Extension to mask or replace personally identifiable information (PII) or commercially sensitive data from a PostgreSQL database";
   };