nixpkgs/nixos/tests/nextcloud/default.nix
Maximilian Bosch 0b31ada92b
nixos/nextcloud: refactor tests
The tests had very much duplication and some if it was even wrong! For
instance, `withRcloneEnv` in the MySQL test didn't have the `"$@"` at
the bottom to execute commands passed to it. Because of that, the MySQL
testcase never checked whether files can be uploaded.

Since tests are just another module-system I decided to abstract away
common things by using it:

* Define a base module with
  * an empty `client` node and a `nextcloud` node with defaults
    shared among all tests.
  * rclone scripts that are used by all tests.
  * a `testScript` checking upload/download. Additional checks can be
    added via `test-helpers.extraTests`.

* Make common information such as admin user & password shared via
  options.

Also, changed the following things:

* The `name` of the final derivation also includes the Nextcloud major
  it was tested against.

* Improved the objecstore test by making sure the file was actually
  uploaded into the bucket.
2024-06-12 10:55:26 +02:00

113 lines
3.5 KiB
Nix

{ system ? builtins.currentSystem
, config ? { }
, pkgs ? import ../../.. { inherit system config; }
}:
with pkgs.lib;
let
baseModule = { config, ... }: {
imports = [
{
options.test-helpers = {
rclone = mkOption { type = types.str; };
upload-sample = mkOption { type = types.str; };
check-sample = mkOption { type = types.str; };
init = mkOption { type = types.str; default = ""; };
extraTests = mkOption { type = types.either types.str (types.functionTo types.str); default = ""; };
};
options.adminuser = mkOption { type = types.str; };
options.adminpass = mkOption { type = types.str; };
}
];
adminuser = "root";
adminpass = "hunter2";
test-helpers.rclone = "${pkgs.writeShellScript "rclone" ''
set -euo pipefail
export PATH="${pkgs.rclone}/bin:$PATH"
export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
export RCLONE_CONFIG_NEXTCLOUD_URL="http://nextcloud/remote.php/dav/files/${config.adminuser}"
export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
export RCLONE_CONFIG_NEXTCLOUD_USER="${config.adminuser}"
export RCLONE_CONFIG_NEXTCLOUD_PASS="$(rclone obscure ${config.adminpass})"
exec "$@"
''}";
test-helpers.upload-sample = "${pkgs.writeShellScript "rclone-upload" ''
<<<'hi' rclone rcat nextcloud:test-shared-file
''}";
test-helpers.check-sample = "${pkgs.writeShellScript "check-sample" ''
set -e
diff <(echo 'hi') <(rclone cat nextcloud:test-shared-file)
''}";
nodes = {
client = { ... }: {};
nextcloud = {
networking.firewall.allowedTCPPorts = [ 80 ];
services.nextcloud = {
enable = true;
hostName = "nextcloud";
https = false;
database.createLocally = true;
config = {
adminpassFile = "${pkgs.writeText "adminpass" config.adminpass}"; # Don't try this at home!
};
};
};
};
testScript = args@{ nodes, ... }: let
inherit (config) test-helpers;
in mkBefore ''
nextcloud.start()
client.start()
nextcloud.wait_for_unit("multi-user.target")
${test-helpers.init}
with subtest("Ensure nextcloud-occ is working"):
nextcloud.succeed("nextcloud-occ status")
nextcloud.succeed("curl -sSf http://nextcloud/login")
with subtest("Upload/Download test"):
nextcloud.succeed(
"${test-helpers.rclone} ${test-helpers.upload-sample}"
)
client.wait_for_unit("multi-user.target")
client.succeed(
"${test-helpers.rclone} ${test-helpers.check-sample}"
)
${if builtins.isFunction test-helpers.extraTests then test-helpers.extraTests args else test-helpers.extraTests}
'';
};
genTests = version:
let
testBase.imports = [
baseModule
{
nodes.nextcloud = { pkgs, ... }: {
services.nextcloud.package = pkgs.${"nextcloud${toString version}"};
};
}
];
callNextcloudTest = path:
let
name = "${removeSuffix ".nix" (baseNameOf path)}${toString version}";
in nameValuePair name (import path {
inherit system pkgs testBase;
name = "nextcloud-${name}";
});
in map callNextcloudTest [
./basic.nix
./with-mysql-and-memcached.nix
./with-postgresql-and-redis.nix
./with-objectstore.nix
];
in
listToAttrs (concatMap genTests [ 27 28 29 ])