integration-tests: init
This commit is contained in:
parent
330f4e4ac7
commit
979108869d
|
@ -24,7 +24,7 @@
|
|||
let
|
||||
version = "0.1.0";
|
||||
|
||||
ignoredPaths = [ ".github" "target" "book" "nixos" ];
|
||||
ignoredPaths = [ ".github" "target" "book" "nixos" "integration-tests" ];
|
||||
|
||||
src = lib.cleanSourceWith {
|
||||
filter = name: type: !(type == "directory" && builtins.elem (baseNameOf name) ignoredPaths);
|
||||
|
|
13
flake.nix
13
flake.nix
|
@ -25,7 +25,10 @@
|
|||
craneLib = crane.mkLib pkgs;
|
||||
in pkgs.callPackage ./crane.nix { inherit craneLib; };
|
||||
in flake-utils.lib.eachSystem supportedSystems (system: let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [];
|
||||
};
|
||||
cranePkgs = makeCranePkgs pkgs;
|
||||
|
||||
inherit (pkgs) lib;
|
||||
|
@ -107,6 +110,14 @@
|
|||
internal = {
|
||||
inherit (cranePkgs) attic-tests cargoArtifacts;
|
||||
};
|
||||
|
||||
checks = lib.optionalAttrs pkgs.stdenv.isLinux (import ./integration-tests {
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ self.overlays.default ];
|
||||
};
|
||||
flake = self;
|
||||
});
|
||||
}) // {
|
||||
overlays = {
|
||||
default = final: prev: let
|
||||
|
|
3
integration-tests/README.md
Normal file
3
integration-tests/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# End-to-End Tests
|
||||
|
||||
This directory contains some end-to-end tests for Attic.
|
204
integration-tests/basic/default.nix
Normal file
204
integration-tests/basic/default.nix
Normal file
|
@ -0,0 +1,204 @@
|
|||
{ pkgs, lib, config, flake, attic, ... }:
|
||||
let
|
||||
inherit (lib) types;
|
||||
|
||||
serverConfigFile = config.nodes.server.services.atticd.configFile;
|
||||
|
||||
cmd = {
|
||||
atticadm = ". /etc/atticd.env && export ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64 && atticadm -f ${serverConfigFile}";
|
||||
atticd = ". /etc/atticd.env && export ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64 && atticd -f ${serverConfigFile}";
|
||||
};
|
||||
|
||||
testDrv = pkgs.writeText "test.nix" ''
|
||||
#!/bin/sh
|
||||
/*/sh -c "echo hello > $out"; exit 0; */
|
||||
derivation {
|
||||
name = "hello.txt";
|
||||
builder = ./test.nix;
|
||||
system = builtins.currentSystem;
|
||||
preferLocalBuild = true;
|
||||
allowSubstitutes = false;
|
||||
}
|
||||
'';
|
||||
|
||||
databaseModules = {
|
||||
sqlite = {};
|
||||
postgres = {
|
||||
server = {
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "attic" ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "atticd";
|
||||
ensurePermissions = {
|
||||
"DATABASE attic" = "ALL PRIVILEGES";
|
||||
};
|
||||
}
|
||||
|
||||
# For testing only - Don't actually do this
|
||||
{
|
||||
name = "root";
|
||||
ensureClauses = {
|
||||
superuser = true;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.atticd.settings = {
|
||||
database.url = "postgresql:///attic?host=/run/postgresql";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
storageModules = {
|
||||
local = {};
|
||||
minio = let
|
||||
accessKey = "legit";
|
||||
secretKey = "111-1111111";
|
||||
in {
|
||||
server = {
|
||||
services.minio = {
|
||||
enable = true;
|
||||
rootCredentialsFile = "/etc/minio.env";
|
||||
};
|
||||
|
||||
# For testing only - Don't actually do this
|
||||
environment.etc."minio.env".text = ''
|
||||
MINIO_ROOT_USER=${accessKey}
|
||||
MINIO_ROOT_PASSWORD=${secretKey}
|
||||
'';
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 9000 ];
|
||||
|
||||
services.atticd.settings = {
|
||||
storage = {
|
||||
type = "s3";
|
||||
endpoint = "http://server:9000";
|
||||
region = "us-east-1";
|
||||
bucket = "attic";
|
||||
credentials = {
|
||||
access_key_id = accessKey;
|
||||
secret_access_key = secretKey;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
server.succeed("mkdir /var/lib/minio/data/attic")
|
||||
server.succeed("chown minio: /var/lib/minio/data/attic")
|
||||
client.wait_until_succeeds("curl http://server:9000", timeout=10)
|
||||
'';
|
||||
};
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
database = lib.mkOption {
|
||||
type = types.enum [ "sqlite" "postgres" ];
|
||||
default = "sqlite";
|
||||
};
|
||||
storage = lib.mkOption {
|
||||
type = types.enum [ "local" "minio" ];
|
||||
default = "local";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
name = "basic-${config.database}-${config.storage}";
|
||||
|
||||
nodes = {
|
||||
server = {
|
||||
imports = [
|
||||
flake.nixosModules.atticd
|
||||
(databaseModules.${config.database}.server or {})
|
||||
(storageModules.${config.storage}.server or {})
|
||||
];
|
||||
|
||||
# For testing only - Don't actually do this
|
||||
environment.etc."atticd.env".text = ''
|
||||
ATTIC_SERVER_TOKEN_HS256_SECRET_BASE64="dGVzdCBzZWNyZXQ="
|
||||
'';
|
||||
|
||||
services.atticd = {
|
||||
enable = true;
|
||||
credentialsFile = "/etc/atticd.env";
|
||||
settings = {
|
||||
listen = "[::]:8080";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 8080 ];
|
||||
};
|
||||
|
||||
client = {
|
||||
environment.systemPackages = [ pkgs.attic ];
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
import time
|
||||
|
||||
start_all()
|
||||
|
||||
${databaseModules.${config.database}.testScript or ""}
|
||||
${storageModules.${config.storage}.testScript or ""}
|
||||
|
||||
server.wait_for_unit('atticd.service')
|
||||
client.wait_until_succeeds("curl -sL http://server:8080", timeout=10)
|
||||
|
||||
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 '*'")
|
||||
readonly_token = server.succeed("${cmd.atticadm} make-token --sub 'e2e-root' --validity '1 month' --pull 'test'")
|
||||
|
||||
client.succeed(f"attic login --set-default root http://server:8080 {root_token}")
|
||||
client.succeed(f"attic login readonly http://server:8080 {readonly_token}")
|
||||
client.succeed("attic login anon http://server:8080")
|
||||
|
||||
# TODO: Make sure the correct status codes are returned
|
||||
# (i.e., 500s shouldn't pass the "should fail" tests)
|
||||
|
||||
with subtest("Check that we can create a cache"):
|
||||
client.succeed("attic cache create test")
|
||||
|
||||
with subtest("Check that we can push a path"):
|
||||
client.succeed("cat ${testDrv} >test.nix && chmod +x test.nix")
|
||||
test_file = client.succeed("nix-build --no-out-link test.nix")
|
||||
test_file_hash = test_file.removeprefix("/nix/store/")[:32]
|
||||
|
||||
client.succeed(f"attic push test {test_file}")
|
||||
client.succeed(f"nix-store --delete {test_file}")
|
||||
client.fail(f"grep hello {test_file}")
|
||||
|
||||
with subtest("Check that we can pull a path"):
|
||||
client.succeed("attic use readonly:test")
|
||||
client.succeed(f"nix-store -r {test_file}")
|
||||
client.succeed(f"grep hello {test_file}")
|
||||
|
||||
with subtest("Check that we cannot push without required permissions"):
|
||||
client.fail(f"attic push readonly:test {test_file}")
|
||||
client.fail(f"attic push anon:test {test_file} 2>&1")
|
||||
|
||||
with subtest("Check that we can make the cache public"):
|
||||
client.fail("curl -sL --fail-with-body http://server:8080/test/nix-cache-info")
|
||||
client.fail(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo")
|
||||
client.succeed("attic cache configure test --public")
|
||||
client.succeed("curl -sL --fail-with-body http://server:8080/test/nix-cache-info")
|
||||
client.succeed(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo")
|
||||
|
||||
with subtest("Check that we can trigger garbage collection"):
|
||||
test_file_hash = test_file.removeprefix("/nix/store/")[:32]
|
||||
client.succeed(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo")
|
||||
client.succeed("attic cache configure test --retention-period 1s")
|
||||
time.sleep(2)
|
||||
server.succeed("${cmd.atticd} --mode garbage-collector-once")
|
||||
client.fail(f"curl -sL --fail-with-body http://server:8080/test/{test_file_hash}.narinfo")
|
||||
|
||||
with subtest("Check that we can destroy the cache"):
|
||||
client.succeed("attic cache info test")
|
||||
client.succeed("attic cache destroy --no-confirm test")
|
||||
client.fail("attic cache info test")
|
||||
client.fail("curl -sL --fail-with-body http://server:8080/test/nix-cache-info")
|
||||
'';
|
||||
};
|
||||
}
|
38
integration-tests/default.nix
Normal file
38
integration-tests/default.nix
Normal file
|
@ -0,0 +1,38 @@
|
|||
{ pkgs ? import ./nixpkgs.nix
|
||||
, flake ? (import ../flake-compat.nix).defaultNix
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (pkgs) lib;
|
||||
|
||||
nixosLib = import (pkgs.path + "/nixos/lib") { };
|
||||
|
||||
runTest = module: (nixosLib.evalTest ({ config, ... }: {
|
||||
imports = [
|
||||
module
|
||||
{
|
||||
hostPkgs = pkgs;
|
||||
_module.args.flake = flake;
|
||||
}
|
||||
];
|
||||
result = config.test;
|
||||
})).config.result;
|
||||
|
||||
basicTests = let
|
||||
matrix = {
|
||||
database = [ "sqlite" "postgres" ];
|
||||
storage = [ "local" "minio" ];
|
||||
};
|
||||
in builtins.listToAttrs (map (e: {
|
||||
name = "basic-${e.database}-${e.storage}";
|
||||
value = runTest {
|
||||
imports = [
|
||||
./basic
|
||||
{
|
||||
inherit (e) database storage;
|
||||
}
|
||||
];
|
||||
};
|
||||
}) (lib.cartesianProductOfSets matrix));
|
||||
in {
|
||||
} // basicTests
|
7
integration-tests/nixpkgs.nix
Normal file
7
integration-tests/nixpkgs.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
let
|
||||
flake = (import ../flake-compat.nix).defaultNix;
|
||||
in import flake.inputs.nixpkgs.outPath {
|
||||
overlays = [
|
||||
flake.overlays.default
|
||||
];
|
||||
}
|
Loading…
Reference in a new issue