ALPHA: wire is a tool to deploy nixos systems wire.althaea.zone/
at rollback-hacking 195 lines 5.5 kB view raw
1# SPDX-License-Identifier: AGPL-3.0-or-later 2# Copyright 2024-2025 wire Contributors 3 4{ 5 self, 6 config, 7 lib, 8 inputs, 9 ... 10}: 11let 12 inherit (lib) 13 mkOption 14 mapAttrsToList 15 flatten 16 cartesianProduct 17 ; 18 inherit (lib.types) 19 submodule 20 lines 21 attrsOf 22 anything 23 lazyAttrsOf 24 ; 25 cfg = config.wire.testing; 26in 27{ 28 imports = [ 29 ./suite/test_remote_deploy 30 ./suite/test_local_deploy 31 ./suite/test_keys 32 ./suite/test_stdin 33 ./suite/test_rollback 34 ]; 35 options.wire.testing = mkOption { 36 type = attrsOf ( 37 submodule ( 38 { name, ... }: 39 { 40 options = { 41 nodes = mkOption { 42 type = lazyAttrsOf anything; 43 }; 44 testScript = mkOption { 45 type = lines; 46 default = ''''; 47 description = "test script for runNixOSTest"; 48 }; 49 testDir = mkOption { 50 default = "${self}/tests/nix/suite/${name}"; 51 readOnly = true; 52 }; 53 }; 54 } 55 ) 56 ); 57 description = "A set of test cases for wire VM testing suite"; 58 }; 59 60 config.perSystem = 61 { 62 pkgs, 63 self', 64 inputs', 65 ... 66 }: 67 let 68 nixNixpkgsCombos = cartesianProduct { 69 nixpkgs = [ 70 inputs'.nixpkgs 71 inputs'.nixpkgs_current_stable 72 # inputs'.nixpkgs_prev_stable 73 ]; 74 # TODO: Update once #126 is solved. 75 nix = [ 76 # "nix" 77 "lix" 78 ]; 79 testName = builtins.attrNames cfg; 80 }; 81 mkTest = 82 { 83 testName, 84 opts, 85 nixpkgs, 86 }: 87 let 88 # TODO: Update once #126 is solved. 89 nixPackage = nixpkgs.legacyPackages.lix; 90 sanitiseName = 91 str: lib.strings.sanitizeDerivationName (builtins.replaceStrings [ "." ] [ "_" ] str); 92 identifier = sanitiseName "${nixpkgs.legacyPackages.lib.trivial.release}-${nixPackage.name}"; 93 path = "tests/nix/suite/${testName}"; 94 95 flakeDirFileset = lib.fileset.toSource { 96 root = ../..; 97 fileset = lib.fileset.union ./. ( 98 lib.fileset.fileFilter (file: (file.hasExt "nix") || (file.hasExt "lock")) ../.. 99 ); 100 }; 101 102 injectedFlakeDir = pkgs.runCommand "injected-flake-dir" { } '' 103 cp -r ${flakeDirFileset} $out 104 chmod -R +w $out 105 substituteInPlace $out/${path}/hive.nix --replace-fail @IDENT@ ${identifier} 106 ''; 107 in 108 rec { 109 name = "vm-${testName}-${identifier}"; 110 value = pkgs.testers.runNixOSTest { 111 inherit (opts) nodes; 112 inherit name; 113 defaults = 114 { 115 pkgs, 116 ... 117 }: 118 let 119 hive = builtins.scopedImport { 120 __nixPath = _b: null; 121 __findFile = _path: name: if name == "nixpkgs" then pkgs.path else throw "oops!!"; 122 } "${injectedFlakeDir}/${path}/hive.nix"; 123 nodes = mapAttrsToList (_: val: val.config.system.build.toplevel.drvPath) hive.nodes; 124 # fetch **all** dependencies of a flake 125 # it's called fetchLayer because my naming skills are awful 126 fetchLayer = 127 input: 128 let 129 subLayers = if input ? inputs then map fetchLayer (builtins.attrValues input.inputs) else [ ]; 130 in 131 [ 132 input.outPath 133 ] 134 ++ subLayers; 135 in 136 { 137 imports = [ ./test-opts.nix ]; 138 nix = { 139 nixPath = [ "nixpkgs=${pkgs.path}" ]; 140 settings.substituters = lib.mkForce [ ]; 141 package = nixPackage; 142 }; 143 144 environment.systemPackages = [ pkgs.ripgrep ]; 145 environment.variables.XDG_RUNTIME_DIR = "/tmp"; 146 virtualisation.memorySize = 4096; 147 virtualisation.additionalPaths = flatten [ 148 injectedFlakeDir 149 nodes 150 (mapAttrsToList (_: fetchLayer) inputs) 151 ]; 152 }; 153 node.specialArgs = { 154 testName = name; 155 snakeOil = import "${pkgs.path}/nixos/tests/ssh-keys.nix" pkgs; 156 inherit (opts) testDir; 157 inherit (self'.packages) wire-small-dev; 158 }; 159 # NOTE: there is surely a better way of doing this in a more 160 # "controlled" manner, but until a need is asked for, this will remain 161 # as is. 162 testScript = '' 163 start_all() 164 165 TEST_DIR="${injectedFlakeDir}/${path}" 166 167 ${builtins.readFile ./tools.py} 168 '' 169 + lib.concatStringsSep "\n" (mapAttrsToList (_: value: value._wire.testScript) value.nodes) 170 + opts.testScript; 171 }; 172 }; 173 in 174 { 175 checks = builtins.listToAttrs ( 176 builtins.map ( 177 { 178 nixpkgs, 179 testName, 180 ... 181 }: 182 let 183 opts = cfg.${testName}; 184 in 185 mkTest { 186 inherit 187 testName 188 opts 189 nixpkgs 190 ; 191 } 192 ) nixNixpkgsCombos 193 ); 194 }; 195}