aboutsummaryrefslogtreecommitdiffstats
path: root/tests/fixtures.sh
Commit message (Collapse)AuthorAgeFilesLines
* populate: stop the ssh master also when a signal ends populatetv25 hours1-0/+8
| | | | | | | | | | | | | | | | The shell doesn't run the EXIT trap when a signal ends it, so an interrupted deploy leaves the ssh master, for an hour, and populate's temporary directory. Populate traps HUP, INT, and TERM and exits, which runs the EXIT trap. The shell runs a trap once the command it waits for ends. A signal to the process group, like the one of an interrupt key, of a closed terminal, or of timeout, ends that command as well. A signal to populate alone takes effect after the step that is running. Phases of scenarios can end populate after some seconds. An edge case does so while a pipe source's command sleeps, and checks that neither the ssh master nor the temporary directory remain.
* populate file: check the .rsync-filter files that really applytv25 hours1-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | rsync reads .rsync-filter files in the directories above a source as well, and their rules apply to the transfer. The check for files that rsync 3.5.0 and later can't read only starts if the source itself contains one, so a subdirectory of a repository with a filter file at its top gets synced without it, silently. The check also starts for filter files above the source. The check's dry run is the transfer it stands for, as far as filtering goes: - It gets the source's exclude and filters, so it doesn't enter directories the transfer skips. - It doesn't run for transfers that apply no .rsync-filter files, i.e. uploads of flakes and patches. - A filter file the user may not read anyway doesn't count: rsync fails on its own when it gets to transfer that file, and --insecure-links changes nothing about it. - rsync prints bytes it takes for unprintable as \#ooo, which depends on the locale. File names get decoded before checking that they exist, so files below, e.g., directories with umlauts in their names don't pass for missing in the C locale. - If rsync doesn't tell which filter files it reads at all, populate warns that it can't tell either. The README mentions that --insecure-links also affects the way to the target path on local targets, and that only rsync 3.5.0 ignores filter files below directories that may be entered but not read. Phases of scenarios can set environment variables for populate. New file scenarios sync a subdirectory whose filter file is above it, and a source with a filter file below a directory with an umlaut in its name, in the C locale.
* populate flake-input: fail on failures, reuse the store, leave out replaced ↵tv25 hours1-0/+102
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | inputs Delivering flakes and flake inputs gets more robust: - With fetchOnTarget, the inputs get collected before the pipeline that links them, so populate fails if the target can't fetch one, instead of linking the flake without its inputs and succeeding. - What the lock file pins gets taken from the store if it's there: the store path is the one of a directory named source with the locked hash, which nix-store --print-fixed-path computes. builtins.fetchTree contacts where the input comes from even then, so redeploying unchanged sources fails without that if a server is unreachable. - With fetchOnTarget, a delivered input that is itself locked to a local path the target lacks fails with populate's error naming the input, like its inputs do. - Inputs that get drawn from other sources are left out, with all they pin: Nix archives an empty flake in their place. So nothing gets fetched, copied, and rooted that no evaluation uses, and a pin that is unreachable doesn't matter if it gets replaced anyway. - flake-input sources get the option requireInputs. By default, populating fails if the inputs that the input's own lock file pins can't be delivered, e.g. because the lock file lacks an input its flake.nix has. With false, populate warns and delivers the input with what Nix locks now, or else without its inputs. A remote flake that the target fetches entirely on its own collects its inputs like everything else does. The Nix function finding its subdirectory moves next to the jq programs. New edge cases cover each of these.
* populate: draw inputs by rewriting lock files, add materialize and patchestv25 hours1-0/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Sources drawing inputs from other sources get the lock file of their flake rewritten with nix flake lock --override-input, so the flake in the source itself uses the other sources, and needs no generated flake to be found. file and git sources get their lock file rewritten in place. flake and flake-input sources get delivered as a copy with the rewritten lock file, which gets added to the store with nix-store --add-fixed, and the target path links to that. With rewriteLock set to false, and for symlink sources, the source stays as it is and gets a generated flake in .populate/flakes/<name>, which writeDeploy's flake parameter uses. flake and flake-input sources get two more options: - patches: patches on the deploying machine, which get uploaded to .populate/patches/<name> and applied in order with patch -p1 on the target, in the directory the target path shows. - materialize: the target path becomes a writable copy instead of a link into the store. Sources that get patched, rewritten, or materialized get delivered to .populate/derived/<name>/original, which also roots the delivered store path, and the flakes step derives the target path from there. Copies get made again only if what they derive from changes, which a key in .populate/derived/<name> records. The matrices of the file, flake, flake-input, and git tests cover both ways of drawing inputs, those of flake and flake-input materialize, the deploy test a source with a rewritten lock file, and features and edge cases run the scenarios drawing inputs both ways. New features cover patches, a patch that doesn't apply, patches in a subdirectory, reusing copies, and materializing.
* populate file: add insecureLinkstv40 hours1-0/+10
| | | | | | | | | | | | | | | | | | | | | | rsync 3.5.0 opens merge files, including per-directory .rsync-filter files, walking the path one directory at a time, refusing symlinks that neither root nor the user running rsync owns, and opening each directory for reading. It treats the files it can't open that way as missing, without saying so. That happens, e.g., below a home directory with mode 711, which the user may enter but not read, or behind another user's symlink. Such a source then got synced without its .rsync-filter rules: excluded files got transferred, and --delete-excluded deleted nothing. Before syncing with rsync 3.5.0 or later a source containing .rsync-filter files, populate asks rsync which of them it reads: a dry run with --debug=FILTER2. If it reports an existing one as missing, the file source type's new insecureLinks option decides: with null, the default, populate fails with an error naming the file; with true, rsync reads such files anyway (--insecure-links); with false, rsync syncs without them. Both print a warning. File scenarios sync a source through a symlink owned by nobody, with each setting.
* tests: check re-locking of generated flakes and git+file: referencestv2 days1-0/+6
| | | | | | | | Deploying the same sources twice doesn't show whether generated flakes get locked again, and the git scenarios' results are the same whether a Git work tree is referred to as git+file: or path:. A feature scenario changes what a source contains between two deploys, and the git scenarios check the reference.
* populate pipe: deliver changed output of the same sizetv2 days1-0/+8
| | | | | | | | | pipe sources get a fixed modification time, so rsync's quick check took changed output of the same size, e.g. a new commit hash or token, for unchanged, and didn't deliver it. pipe sources get synced comparing checksums now. An edge case changes a pipe source's output without changing its size.
* populate: draw inputs from sources that aren't flakestv2 days1-0/+11
| | | | | | | | | Generated flakes declared every source they draw inputs from as a flake, so drawing an input declared with flake = false from a source without flake.nix failed, although the README says it works. Such sources get declared with flake = false now. An edge case draws a non-flake input from a source without flake.nix.
* populate: place overrides on sources with generated flakes correctlytv2 days1-0/+17
| | | | | | | | | An override below an input drawn from a source that has a generated flake itself got placed on that generated flake, which has no such input, so Nix ignored it with a warning. Generated flakes have their source as input of the same name, so the override goes below that. An edge case overrides an input of a source with a generated flake.
* populate flake-input: deliver the inputs the input's own lock file pinstv2 days1-0/+69
| | | | | | | | | | | | | | | | | | | | | | | | | | | | A flake-input source delivers an input as its own flake, which evaluating it uses with its own lock file. Populate, however, took the input's inputs from the parent flake's lock file: on the target, by walking the lock file, and on the deploying machine, from the parent's nix flake archive. That had several consequences: - An empty follows path, which removes an input, or two inputs following each other made the walk loop forever. - Copying left out inputs that follow other inputs, and rejected names through them, e.g. dep/inner where dep's inner follows another input. - Inputs given by relative paths, e.g. path:./lib, which have no lock entry of their own to fetch, broke fetching on the target and flake-input sources. - Where the parent overrides an input's inputs, the input's own lock file pins other versions than the delivered ones. Populate now resolves the name through the parent's lock file, follows included and guarded against cycles, to what to fetch: a locked reference, or the flake itself, which inputs given by relative paths are part of. It fetches that, on the deploying machine or on the target, and then the inputs the input's own lock file pins, using nix flake archive. An input without a lock file comes without its inputs. New edge cases cover lock files with empty and cyclic follows, names through follows, the delivered closure, and relative path inputs.
* tests: add edge cases of flakestv2 days1-0/+39
| | | | | | | | | | | | | | | | | A new test, edge-cases, covers paths that work but have no scenario yet: a flake given by an indirect reference, which the target fetches by its locked reference; a remote flake in a subdirectory; a flake in a subdirectory drawing inputs from sources; a dirty Git work tree; a flake whose lock file needs updating; drawing inputs from a source that isn't a directory; nested names of missing inputs; several sources sharing one flake; and an input locked to a path that the target has. The deploying machine gets a registry entry for the indirect reference. Resolving it fails if the global registry can't be downloaded, which it can't in the VM, and disabling the global registry with flake-registry needs flakes, so the deploying machine enables them, like any deploying machine using indirect references does. The target doesn't, so checks for flake support on targets still mean something.
* tests: add NixOS VM tests for populatetv2 days1-0/+178
tests/default.nix provides one VM test per source type, and one for features spanning sources. Each test runs scenarios from tests/scenarios.nix, which cover every combination of a source type's options, deployed to the deploying machine itself, to a remote target as root, and to a remote target using sudo. A scenario prepares the target directory, deploys, checks the result, and deploys and checks again. Scenarios expecting populate to fail check its error message, or check at evaluation time if populate is expected not to evaluate. The deploying machine creates fixtures using tests/fixtures.sh and serves them via HTTP and git daemon, so flakes can be fetched on the target without further network access. Checks evaluate delivered flakes without network access to the fixtures after collecting garbage, so they verify that the delivered store paths are complete and rooted.