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