{ pkgs, lib, ... }: let pkgs' = pkgs; testLib = pkgs.callPackage ../../../test/common.nix {}; inherit (lib) concatStringsSep concatMapStringsSep getAttrFromPath mkIf optionalAttrs setAttrByPath; inherit (testLib) indent; in { name, providerRoot, modules ? [], username ? "me", sourceDirectories ? [ "/opt/files/A" "/opt/files/B" ], settings, # { repository, config } -> attrset extraConfig ? null, # { username, config } -> attrset }: pkgs.testers.runNixOSTest { inherit name; nodes.machine = { config, ... }: { imports = ( testLib.baseImports pkgs' ) ++ modules; config = lib.mkMerge [ (setAttrByPath providerRoot { request = { inherit sourceDirectories; user = username; }; settings = settings { inherit config; repository = "/opt/repos/${name}"; }; }) (mkIf (username != "root") { users.users.${username} = { isSystemUser = true; extraGroups = [ "sudoers" ]; group = "root"; }; }) (optionalAttrs (extraConfig != null) (extraConfig { inherit username config; })) ]; }; extraPythonPackages = p: [ p.dictdiffer ]; skipTypeCheck = true; testScript = { nodes, ... }: let provider = (getAttrFromPath providerRoot nodes.machine).result; in '' from dictdiffer import diff username = "${username}" sourceDirectories = [ ${concatMapStringsSep ", " (x: ''"${x}"'') sourceDirectories} ] def list_files(dir): files_and_content = {} files = machine.succeed(f"""find {dir} -type f""").split("\n")[:-1] for f in files: content = machine.succeed(f"""cat {f}""").strip() files_and_content[f] = content return files_and_content def assert_files(dir, files): result = list(diff(list_files(dir), files)) if len(result) > 0: raise Exception("Unexpected files:", result) with subtest("Create initial content"): for path in sourceDirectories: machine.succeed(f""" mkdir -p {path} echo repo_fileA_1 > {path}/fileA echo repo_fileB_1 > {path}/fileB chown {username}: -R {path} chmod go-rwx -R {path} """) for path in sourceDirectories: assert_files(path, { f'{path}/fileA': 'repo_fileA_1', f'{path}/fileB': 'repo_fileB_1', }) with subtest("First backup in repo"): print(machine.succeed("systemctl cat ${provider.backupService}")) machine.succeed("systemctl start ${provider.backupService}") with subtest("New content"): for path in sourceDirectories: machine.succeed(f""" echo repo_fileA_2 > {path}/fileA echo repo_fileB_2 > {path}/fileB """) assert_files(path, { f'{path}/fileA': 'repo_fileA_2', f'{path}/fileB': 'repo_fileB_2', }) with subtest("Delete content"): for path in sourceDirectories: machine.succeed(f"""rm -r {path}/*""") assert_files(path, {}) with subtest("Restore initial content from repo"): machine.succeed("""${provider.restoreScript} restore latest""") for path in sourceDirectories: assert_files(path, { f'{path}/fileA': 'repo_fileA_1', f'{path}/fileB': 'repo_fileB_1', }) ''; }