From 28c2cea847026b62c4215aaaa808ee561d8b04ad Mon Sep 17 00:00:00 2001 From: Aneesh Agrawal Date: Mon, 18 Sep 2017 01:46:07 -0700 Subject: [PATCH] radicale: Test migration functionality This also provides an example of how to migrate. --- nixos/doc/manual/release-notes/rl-1709.xml | 2 +- nixos/tests/radicale.nix | 90 +++++++++++++++++++--- 2 files changed, 79 insertions(+), 13 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-1709.xml b/nixos/doc/manual/release-notes/rl-1709.xml index 35534af1f1dc..55b39209f0d5 100644 --- a/nixos/doc/manual/release-notes/rl-1709.xml +++ b/nixos/doc/manual/release-notes/rl-1709.xml @@ -107,7 +107,7 @@ rmdir /var/lib/ipfs/.ipfs The mysql default dataDir has changed from /var/mysql to /var/lib/mysql. - Radicale's default package has changed from 1.x to 2.x. Instructions to migrate can be found here . It is also possible to use the newer version by setting the package to radicale2, which is done automatically when stateVersion is 17.09 or higher. The extraArgs option has been added to allow passing the data migration arguments specified in the instructions. + Radicale's default package has changed from 1.x to 2.x. Instructions to migrate can be found here . It is also possible to use the newer version by setting the package to radicale2, which is done automatically when stateVersion is 17.09 or higher. The extraArgs option has been added to allow passing the data migration arguments specified in the instructions; see the radicale.nix NixOS test for an example migration. diff --git a/nixos/tests/radicale.nix b/nixos/tests/radicale.nix index bec86d2cb284..2c888469d0a4 100644 --- a/nixos/tests/radicale.nix +++ b/nixos/tests/radicale.nix @@ -2,12 +2,8 @@ let user = "someuser"; password = "some_password"; port = builtins.toString 5232; -in - import ./make-test.nix ({ pkgs, lib, ... }: { - name = "radicale"; - meta.maintainers = with lib.maintainers; [ aneeshusa infinisil ]; - machine = { + common = { pkgs, ... }: { services.radicale = { enable = true; config = '' @@ -29,11 +25,81 @@ in ${pkgs.apacheHttpd}/bin/htpasswd -bcB "$out" ${user} ${password} ''; }; - - # This tests whether the web interface is accessible to an authenticated user - testScript = '' - $machine->waitForUnit('radicale.service'); - $machine->waitForOpenPort(${port}); - $machine->succeed('curl --fail http://${user}:${password}@localhost:${port}/.web/'); - ''; + +in + + import ./make-test.nix ({ pkgs, lib, ... }@args: { + name = "radicale"; + meta.maintainers = with lib.maintainers; [ aneeshusa infinisil ]; + + nodes = rec { + radicale = radicale1; # Make the test script read more nicely + radicale1 = lib.recursiveUpdate (common args) { + nixpkgs.overlays = [ + (self: super: { + radicale1 = super.radicale1.overrideAttrs (oldAttrs: { + propagatedBuildInputs = with self.pythonPackages; + (oldAttrs.propagatedBuildInputs or []) ++ [ passlib ]; + }); + }) + ]; + }; + radicale1_export = lib.recursiveUpdate radicale1 { + services.radicale.extraArgs = [ + "--export-storage" "/tmp/collections-new" + ]; + }; + radicale2_verify = lib.recursiveUpdate radicale2 { + services.radicale.extraArgs = [ "--verify-storage" ]; + }; + radicale2 = lib.recursiveUpdate (common args) { + system.stateVersion = "17.09"; + }; + }; + + # This tests whether the web interface is accessible to an authenticated user + testScript = { nodes }: let + switchToConfig = nodeName: let + newSystem = nodes.${nodeName}.config.system.build.toplevel; + in "${newSystem}/bin/switch-to-configuration test"; + in '' + # Check Radicale 1 functionality + $radicale->succeed('${switchToConfig "radicale1"} >&2'); + $radicale->waitForUnit('radicale.service'); + $radicale->waitForOpenPort(${port}); + $radicale->succeed('curl --fail http://${user}:${password}@localhost:${port}/someuser/calendar.ics/'); + + # Export data in Radicale 2 format + $radicale->succeed('systemctl stop radicale'); + $radicale->succeed('ls -al /tmp/collections'); + $radicale->fail('ls -al /tmp/collections-new'); + # Radicale exits immediately after exporting storage + $radicale->succeed('${switchToConfig "radicale1_export"} >&2'); + $radicale->waitUntilFails('systemctl status radicale'); + $radicale->succeed('ls -al /tmp/collections'); + $radicale->succeed('ls -al /tmp/collections-new'); + + # Verify data in Radicale 2 format + $radicale->succeed('rm -r /tmp/collections/${user}'); + $radicale->succeed('mv /tmp/collections-new/collection-root /tmp/collections'); + $radicale->succeed('${switchToConfig "radicale2_verify"} >&2'); + $radicale->waitUntilFails('systemctl status radicale'); + my ($retcode, $logs) = $radicale->execute('journalctl -u radicale -n 5'); + if ($retcode != 0 || index($logs, 'Verifying storage') == -1) { + die "Radicale 2 didn't verify storage" + } + if (index($logs, 'failed') != -1 || index($logs, 'exception') != -1) { + die "storage verification failed" + } + + # Check Radicale 2 functionality + $radicale->succeed('${switchToConfig "radicale2"} >&2'); + $radicale->waitForUnit('radicale.service'); + $radicale->waitForOpenPort(${port}); + my ($retcode, $output) = $radicale->execute('curl --fail http://${user}:${password}@localhost:${port}/someuser/calendar.ics/'); + if ($retcode != 0 || index($output, 'VCALENDAR') == -1) { + die "Could not read calendar from Radicale 2" + } + $radicale->succeed('curl --fail http://${user}:${password}@localhost:${port}/.web/'); + ''; })