A fork of attic a self-hostable Nix Binary Cache server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

integration-tests: init

+265 -2
+1 -1
crane.nix
··· 24 24 let 25 25 version = "0.1.0"; 26 26 27 - ignoredPaths = [ ".github" "target" "book" "nixos" ]; 27 + ignoredPaths = [ ".github" "target" "book" "nixos" "integration-tests" ]; 28 28 29 29 src = lib.cleanSourceWith { 30 30 filter = name: type: !(type == "directory" && builtins.elem (baseNameOf name) ignoredPaths);
+12 -1
flake.nix
··· 25 25 craneLib = crane.mkLib pkgs; 26 26 in pkgs.callPackage ./crane.nix { inherit craneLib; }; 27 27 in flake-utils.lib.eachSystem supportedSystems (system: let 28 - pkgs = import nixpkgs { inherit system; }; 28 + pkgs = import nixpkgs { 29 + inherit system; 30 + overlays = []; 31 + }; 29 32 cranePkgs = makeCranePkgs pkgs; 30 33 31 34 inherit (pkgs) lib; ··· 107 110 internal = { 108 111 inherit (cranePkgs) attic-tests cargoArtifacts; 109 112 }; 113 + 114 + checks = lib.optionalAttrs pkgs.stdenv.isLinux (import ./integration-tests { 115 + pkgs = import nixpkgs { 116 + inherit system; 117 + overlays = [ self.overlays.default ]; 118 + }; 119 + flake = self; 120 + }); 110 121 }) // { 111 122 overlays = { 112 123 default = final: prev: let
+3
integration-tests/README.md
··· 1 + # End-to-End Tests 2 + 3 + This directory contains some end-to-end tests for Attic.
+204
integration-tests/basic/default.nix
··· 1 + { pkgs, lib, config, flake, attic, ... }: 2 + let 3 + inherit (lib) types; 4 + 5 + serverConfigFile = config.nodes.server.services.atticd.configFile; 6 + 7 + cmd = { 8 + atticadm = ". /etc/atticd.env && export ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64 && atticadm -f ${serverConfigFile}"; 9 + atticd = ". /etc/atticd.env && export ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64 && atticd -f ${serverConfigFile}"; 10 + }; 11 + 12 + testDrv = pkgs.writeText "test.nix" '' 13 + #!/bin/sh 14 + /*/sh -c "echo hello > $out"; exit 0; */ 15 + derivation { 16 + name = "hello.txt"; 17 + builder = ./test.nix; 18 + system = builtins.currentSystem; 19 + preferLocalBuild = true; 20 + allowSubstitutes = false; 21 + } 22 + ''; 23 + 24 + databaseModules = { 25 + sqlite = {}; 26 + postgres = { 27 + server = { 28 + services.postgresql = { 29 + enable = true; 30 + ensureDatabases = [ "attic" ]; 31 + ensureUsers = [ 32 + { 33 + name = "atticd"; 34 + ensurePermissions = { 35 + "DATABASE attic" = "ALL PRIVILEGES"; 36 + }; 37 + } 38 + 39 + # For testing only - Don't actually do this 40 + { 41 + name = "root"; 42 + ensureClauses = { 43 + superuser = true; 44 + }; 45 + } 46 + ]; 47 + }; 48 + 49 + services.atticd.settings = { 50 + database.url = "postgresql:///attic?host=/run/postgresql"; 51 + }; 52 + }; 53 + }; 54 + }; 55 + 56 + storageModules = { 57 + local = {}; 58 + minio = let 59 + accessKey = "legit"; 60 + secretKey = "111-1111111"; 61 + in { 62 + server = { 63 + services.minio = { 64 + enable = true; 65 + rootCredentialsFile = "/etc/minio.env"; 66 + }; 67 + 68 + # For testing only - Don't actually do this 69 + environment.etc."minio.env".text = '' 70 + MINIO_ROOT_USER=${accessKey} 71 + MINIO_ROOT_PASSWORD=${secretKey} 72 + ''; 73 + 74 + networking.firewall.allowedTCPPorts = [ 9000 ]; 75 + 76 + services.atticd.settings = { 77 + storage = { 78 + type = "s3"; 79 + endpoint = "http://server:9000"; 80 + region = "us-east-1"; 81 + bucket = "attic"; 82 + credentials = { 83 + access_key_id = accessKey; 84 + secret_access_key = secretKey; 85 + }; 86 + }; 87 + }; 88 + }; 89 + testScript = '' 90 + server.succeed("mkdir /var/lib/minio/data/attic") 91 + server.succeed("chown minio: /var/lib/minio/data/attic") 92 + client.wait_until_succeeds("curl http://server:9000", timeout=10) 93 + ''; 94 + }; 95 + }; 96 + in { 97 + options = { 98 + database = lib.mkOption { 99 + type = types.enum [ "sqlite" "postgres" ]; 100 + default = "sqlite"; 101 + }; 102 + storage = lib.mkOption { 103 + type = types.enum [ "local" "minio" ]; 104 + default = "local"; 105 + }; 106 + }; 107 + 108 + config = { 109 + name = "basic-${config.database}-${config.storage}"; 110 + 111 + nodes = { 112 + server = { 113 + imports = [ 114 + flake.nixosModules.atticd 115 + (databaseModules.${config.database}.server or {}) 116 + (storageModules.${config.storage}.server or {}) 117 + ]; 118 + 119 + # For testing only - Don't actually do this 120 + environment.etc."atticd.env".text = '' 121 + ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64="dGVzdCBzZWNyZXQ=" 122 + ''; 123 + 124 + services.atticd = { 125 + enable = true; 126 + credentialsFile = "/etc/atticd.env"; 127 + settings = { 128 + listen = "[::]:8080"; 129 + }; 130 + }; 131 + 132 + networking.firewall.allowedTCPPorts = [ 8080 ]; 133 + }; 134 + 135 + client = { 136 + environment.systemPackages = [ pkgs.attic ]; 137 + }; 138 + }; 139 + 140 + testScript = '' 141 + import time 142 + 143 + start_all() 144 + 145 + ${databaseModules.${config.database}.testScript or ""} 146 + ${storageModules.${config.storage}.testScript or ""} 147 + 148 + server.wait_for_unit('atticd.service') 149 + client.wait_until_succeeds("curl -sL http://server:8080", timeout=10) 150 + 151 + root_token = server.succeed("${cmd.atticadm} make-token --sub 'e2e-root' --validity '1 month' --push '*' --pull '*' --delete '*' --create-cache '*' --destroy-cache '*' --configure-cache '*' --configure-cache-retention '*'") 152 + readonly_token = server.succeed("${cmd.atticadm} make-token --sub 'e2e-root' --validity '1 month' --pull 'test'") 153 + 154 + client.succeed(f"attic login --set-default root http://server:8080 {root_token}") 155 + client.succeed(f"attic login readonly http://server:8080 {readonly_token}") 156 + client.succeed("attic login anon http://server:8080") 157 + 158 + # TODO: Make sure the correct status codes are returned 159 + # (i.e., 500s shouldn't pass the "should fail" tests) 160 + 161 + with subtest("Check that we can create a cache"): 162 + client.succeed("attic cache create test") 163 + 164 + with subtest("Check that we can push a path"): 165 + client.succeed("cat ${testDrv} >test.nix && chmod +x test.nix") 166 + test_file = client.succeed("nix-build --no-out-link test.nix") 167 + test_file_hash = test_file.removeprefix("/nix/store/")[:32] 168 + 169 + client.succeed(f"attic push test {test_file}") 170 + client.succeed(f"nix-store --delete {test_file}") 171 + client.fail(f"grep hello {test_file}") 172 + 173 + with subtest("Check that we can pull a path"): 174 + client.succeed("attic use readonly:test") 175 + client.succeed(f"nix-store -r {test_file}") 176 + client.succeed(f"grep hello {test_file}") 177 + 178 + with subtest("Check that we cannot push without required permissions"): 179 + client.fail(f"attic push readonly:test {test_file}") 180 + client.fail(f"attic push anon:test {test_file} 2>&1") 181 + 182 + with subtest("Check that we can make the cache public"): 183 + client.fail("curl -sL --fail-with-body http://server:8080/test/nix-cache-info") 184 + client.fail(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo") 185 + client.succeed("attic cache configure test --public") 186 + client.succeed("curl -sL --fail-with-body http://server:8080/test/nix-cache-info") 187 + client.succeed(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo") 188 + 189 + with subtest("Check that we can trigger garbage collection"): 190 + test_file_hash = test_file.removeprefix("/nix/store/")[:32] 191 + client.succeed(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo") 192 + client.succeed("attic cache configure test --retention-period 1s") 193 + time.sleep(2) 194 + server.succeed("${cmd.atticd} --mode garbage-collector-once") 195 + client.fail(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo") 196 + 197 + with subtest("Check that we can destroy the cache"): 198 + client.succeed("attic cache info test") 199 + client.succeed("attic cache destroy --no-confirm test") 200 + client.fail("attic cache info test") 201 + client.fail("curl -sL --fail-with-body http://server:8080/test/nix-cache-info") 202 + ''; 203 + }; 204 + }
+38
integration-tests/default.nix
··· 1 + { pkgs ? import ./nixpkgs.nix 2 + , flake ? (import ../flake-compat.nix).defaultNix 3 + }: 4 + 5 + let 6 + inherit (pkgs) lib; 7 + 8 + nixosLib = import (pkgs.path + "/nixos/lib") { }; 9 + 10 + runTest = module: (nixosLib.evalTest ({ config, ... }: { 11 + imports = [ 12 + module 13 + { 14 + hostPkgs = pkgs; 15 + _module.args.flake = flake; 16 + } 17 + ]; 18 + result = config.test; 19 + })).config.result; 20 + 21 + basicTests = let 22 + matrix = { 23 + database = [ "sqlite" "postgres" ]; 24 + storage = [ "local" "minio" ]; 25 + }; 26 + in builtins.listToAttrs (map (e: { 27 + name = "basic-${e.database}-${e.storage}"; 28 + value = runTest { 29 + imports = [ 30 + ./basic 31 + { 32 + inherit (e) database storage; 33 + } 34 + ]; 35 + }; 36 + }) (lib.cartesianProductOfSets matrix)); 37 + in { 38 + } // basicTests
+7
integration-tests/nixpkgs.nix
··· 1 + let 2 + flake = (import ../flake-compat.nix).defaultNix; 3 + in import flake.inputs.nixpkgs.outPath { 4 + overlays = [ 5 + flake.overlays.default 6 + ]; 7 + }