Commit e4488f5e authored by Florian Brandes's avatar Florian Brandes
Browse files

pgadmin4: move package tests back into the package



We test pgadmin in nixosTests, because it needs a running postgresql instance.
This is now unnecessary since we can do so in the package itself.

This reduces the complexity of pgadmin and removes the need for the extra
nixosTests.

Also setting SERVER_MODE in `pkg/pip/setup_pip.py` does not have any effect
on the final package, so we remove it.
In NixOS, we use the module, which expects SERVER_MODE to be true (which it defaults to).
In non-NixOS installations, we will need the directory /var/lib/pgadmin and /var/log/pgadmin

Signed-off-by: default avatarFlorian Brandes <florian.brandes@posteo.de>
parent cfc77dc4
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -513,7 +513,6 @@ in {
  peerflix = handleTest ./peerflix.nix {};
  peering-manager = handleTest ./web-apps/peering-manager.nix {};
  peertube = handleTestOn ["x86_64-linux"] ./web-apps/peertube.nix {};
  pgadmin4 = handleTest ./pgadmin4.nix {};
  pgadmin4-standalone = handleTest ./pgadmin4-standalone.nix {};
  pgjwt = handleTest ./pgjwt.nix {};
  pgmanage = handleTest ./pgmanage.nix {};

nixos/tests/pgadmin4.nix

deleted100644 → 0
+0 −139
Original line number Diff line number Diff line
import ./make-test-python.nix ({ pkgs, lib, buildDeps ? [ ], pythonEnv ? [ ], ... }:

/*
  This test suite replaces the typical pytestCheckHook function in python
  packages. Pgadmin4 test suite needs a running and configured postgresql
  server. This is why this test exists.

  To not repeat all the python dependencies needed, this test is called directly
  from the pgadmin4 derivation, which also passes the currently
  used propagatedBuildInputs and any python overrides.

  Unfortunately, there doesn't seem to be an easy way to otherwise include
  the needed packages here.

  Due the the needed parameters a direct call to "nixosTests.pgadmin4" fails
  and needs to be called as "pgadmin4.tests"

  */

let
  pgadmin4SrcDir = "/pgadmin";
  pgadmin4Dir = "/var/lib/pgadmin";
  pgadmin4LogDir = "/var/log/pgadmin";

in
{
  name = "pgadmin4";
  meta.maintainers = with lib.maintainers; [ gador ];

  nodes.machine = { pkgs, ... }: {
    imports = [ ./common/x11.nix ];
    # needed because pgadmin 6.8 will fail, if those dependencies get updated
    nixpkgs.overlays = [
      (self: super: {
        pythonPackages = pythonEnv;
      })
    ];

    environment.systemPackages = with pkgs; [
      pgadmin4
      postgresql
      chromedriver
      chromium
      # include the same packages as in pgadmin minus speaklater3
      (python3.withPackages
        (ps: buildDeps ++
          [
            # test suite package requirements
            pythonPackages.testscenarios
            pythonPackages.selenium
          ])
      )
    ];
    services.postgresql = {
      enable = true;
      authentication = ''
        host    all             all             localhost               trust
      '';
      ensureUsers = [
        {
          name = "postgres";
          ensurePermissions = {
            "DATABASE \"postgres\"" = "ALL PRIVILEGES";
          };
        }
      ];
    };
  };

  testScript = ''
    machine.wait_for_unit("postgresql")

    # pgadmin4 needs its data and log directories
    machine.succeed(
        "mkdir -p ${pgadmin4Dir} \
        && mkdir -p ${pgadmin4LogDir} \
        && mkdir -p ${pgadmin4SrcDir}"
    )

    machine.succeed(
         "tar xvzf ${pkgs.pgadmin4.src} -C ${pgadmin4SrcDir}"
    )

    machine.wait_for_file("${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/README.md")

    # set paths and config for tests
    # also ensure Server Mode is set to false, which will automatically exclude some unnecessary tests.
    # see https://github.com/pgadmin-org/pgadmin4/blob/fd1c26408bbf154fa455a49ee5c12895933833a3/web/regression/runtests.py#L217-L226
    machine.succeed(
        "cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version} \
        && cp -v web/regression/test_config.json.in web/regression/test_config.json \
        && sed -i 's|PostgreSQL 9.4|PostgreSQL|' web/regression/test_config.json \
        && sed -i 's|/opt/PostgreSQL/9.4/bin/|${pkgs.postgresql}/bin|' web/regression/test_config.json \
        && sed -i 's|\"headless_chrome\": false|\"headless_chrome\": true|' web/regression/test_config.json \
        && sed -i 's|builtins.SERVER_MODE = None|builtins.SERVER_MODE = False|' web/regression/runtests.py"
    )

    # adapt chrome config to run within a sandbox without GUI
    # see https://stackoverflow.com/questions/50642308/webdriverexception-unknown-error-devtoolsactiveport-file-doesnt-exist-while-t#50642913
    # add chrome binary path. use spaces to satisfy python indention (tabs throw an error)
    machine.succeed(
         "cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version} \
         && sed -i '\|options.add_argument(\"--disable-infobars\")|a \ \ \ \ \ \ \ \ options.binary_location = \"${pkgs.chromium}/bin/chromium\"' web/regression/runtests.py \
         && sed -i '\|options.add_argument(\"--no-sandbox\")|a \ \ \ \ \ \ \ \ options.add_argument(\"--headless\")' web/regression/runtests.py \
         && sed -i '\|options.add_argument(\"--disable-infobars\")|a \ \ \ \ \ \ \ \ options.add_argument(\"--disable-dev-shm-usage\")' web/regression/runtests.py \
         && sed -i 's|(chrome_options=options)|(executable_path=\"${pkgs.chromedriver}/bin/chromedriver\", chrome_options=options)|' web/regression/runtests.py \
         && sed -i 's|driver_local.maximize_window()||' web/regression/runtests.py"
    )

    # don't bother to test kerberos authentication
    excluded_tests = [ "browser.tests.test_kerberos_with_mocking",
                       ]

    with subtest("run browser test"):
        machine.succeed(
             'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \
             && python regression/runtests.py \
             --pkg browser \
             --exclude ' + ','.join(excluded_tests)
        )

    with subtest("run resql test"):
      machine.succeed(
           'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \
           && python regression/runtests.py --pkg resql'
      )

    # fontconfig is necessary for chromium to run
    # https://github.com/NixOS/nixpkgs/issues/136207
    # also, the feature_tests require Server Mode = True
    with subtest("run feature test"):
       machine.succeed(
           'cd ${pgadmin4SrcDir}/pgadmin4-${pkgs.pgadmin4.version}/web \
            && export FONTCONFIG_FILE=${pkgs.makeFontsConf { fontDirectories = [];}} \
            && sed -i \'s|builtins.SERVER_MODE = False|builtins.SERVER_MODE = True|\' regression/runtests.py \
            && python regression/runtests.py --pkg feature_tests'
       )
  '';
})
+88 −62
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
, nixosTests
, pkgs
, fetchPypi
, postgresqlTestHook
, postgresql
}:

let
@@ -26,54 +28,6 @@ let
    yarnNix = ./yarn.nix;
  };

  # move buildDeps here to easily pass to test suite
  buildDeps = with pythonPackages; [
    flask
    flask-gravatar
    flask-login
    flask_mail
    flask_migrate
    flask-sqlalchemy
    flask-wtf
    flask-compress
    passlib
    pytz
    simplejson
    sqlparse
    wtforms
    flask-paranoid
    psutil
    psycopg2
    python-dateutil
    sqlalchemy
    itsdangerous
    flask-security-too
    bcrypt
    cryptography
    sshtunnel
    ldap3
    flask-babelex
    flask-babel
    gssapi
    flask-socketio
    eventlet
    httpagentparser
    user-agents
    wheel
    authlib
    qrcode
    pillow
    pyotp
    botocore
    boto3
    azure-mgmt-subscription
    azure-mgmt-rdbms
    azure-mgmt-resource
    azure-identity
    sphinxcontrib-youtube
    dnspython
    greenlet
  ];

  # keep the scope, as it is used throughout the derivation and tests
  # this also makes potential future overrides easier
@@ -149,10 +103,8 @@ pythonPackages.buildPythonApplication rec {

    # relax dependencies
    sed 's|==|>=|g' -i requirements.txt
    # don't use Server Mode (can be overridden later)
    substituteInPlace pkg/pip/setup_pip.py \
      --replace "req = req.replace('psycopg2', 'psycopg2-binary')" "req = req" \
      --replace "builtins.SERVER_MODE = None" "builtins.SERVER_MODE = False"
      --replace "req = req.replace('psycopg2', 'psycopg2-binary')" "req = req"
  '';

  preBuild = ''
@@ -200,21 +152,95 @@ pythonPackages.buildPythonApplication rec {
    pythonPackages.wheel
  ];

  # tests need an own data, log directory
  # and a working and correctly setup postgres database
  # checks will be run through nixos/tests
  doCheck = false;

  # speaklater3 is separate because when passing buildDeps
  # to the test, it fails there due to a collision with speaklater
  propagatedBuildInputs = buildDeps ++ [ pythonPackages.speaklater3 ];
  propagatedBuildInputs = with pythonPackages; [
    flask
    flask-gravatar
    flask-login
    flask_mail
    flask_migrate
    flask-sqlalchemy
    flask-wtf
    flask-compress
    passlib
    pytz
    simplejson
    sqlparse
    wtforms
    flask-paranoid
    psutil
    psycopg2
    python-dateutil
    sqlalchemy
    itsdangerous
    flask-security-too
    bcrypt
    cryptography
    sshtunnel
    ldap3
    flask-babelex
    flask-babel
    gssapi
    flask-socketio
    eventlet
    httpagentparser
    user-agents
    wheel
    authlib
    qrcode
    pillow
    pyotp
    botocore
    boto3
    azure-mgmt-subscription
    azure-mgmt-rdbms
    azure-mgmt-resource
    azure-identity
    sphinxcontrib-youtube
    dnspython
    greenlet
    speaklater3
  ];

  passthru.tests = {
    standalone = nixosTests.pgadmin4-standalone;
    # regression and function tests of the package itself
    package = import ../../../../nixos/tests/pgadmin4.nix { inherit pkgs buildDeps; pythonEnv = pythonPackages; };
    inherit (nixosTests) pgadmin4;
  };

  nativeCheckInputs = [
    postgresqlTestHook
    postgresql
    pythonPackages.testscenarios
    pythonPackages.selenium
  ];

  checkPhase = ''
    runHook preCheck

    ## Setup ##

    # pgadmin needs a home directory to save the configuration
    export HOME=$TMPDIR
    cd pgadmin4

    # set configuration for postgresql test
    # also ensure Server Mode is set to false. If not, the tests will fail, since pgadmin expects read/write permissions
    # in /var/lib/pgadmin and /var/log/pgadmin
    # see https://github.com/pgadmin-org/pgadmin4/blob/fd1c26408bbf154fa455a49ee5c12895933833a3/web/regression/runtests.py#L217-L226
    cp -v regression/test_config.json.in regression/test_config.json
    substituteInPlace regression/test_config.json --replace "localhost" "$PGHOST"
    substituteInPlace regression/runtests.py --replace "builtins.SERVER_MODE = None" "builtins.SERVER_MODE = False"

    ## Browser test ##

    # don't bother to test kerberos authentication
    python regression/runtests.py --pkg browser --exclude browser.tests.test_kerberos_with_mocking

    ## Reverse engineered SQL test ##

    python regression/runtests.py --pkg resql

    runHook postCheck
  '';

  meta = with lib; {
    description = "Administration and development platform for PostgreSQL";
    homepage = "https://www.pgadmin.org/";